├── .gitignore ├── CMakeLists.txt ├── Doxyfile ├── LICENSE.txt ├── README.md ├── TODO.txt ├── cmake └── GNUInstallDirs.cmake ├── doc ├── GroupPicture.png └── GroupPicture.svg ├── images ├── CMakeLists.txt └── generate.cpp ├── include └── generator │ ├── AnyGenerator.hpp │ ├── AnyMesh.hpp │ ├── AnyPath.hpp │ ├── AnyShape.hpp │ ├── Axis.hpp │ ├── AxisFlipMesh.hpp │ ├── AxisSwapMesh.hpp │ ├── AxisSwapPath.hpp │ ├── AxisSwapShape.hpp │ ├── BezierMesh.hpp │ ├── BezierShape.hpp │ ├── BoxMesh.hpp │ ├── CappedConeMesh.hpp │ ├── CappedCylinderMesh.hpp │ ├── CappedTubeMesh.hpp │ ├── CapsuleMesh.hpp │ ├── CircleShape.hpp │ ├── ConeMesh.hpp │ ├── ConvexPolygonMesh.hpp │ ├── CylinderMesh.hpp │ ├── DiskMesh.hpp │ ├── DodecahedronMesh.hpp │ ├── Edge.hpp │ ├── EmptyMesh.hpp │ ├── EmptyPath.hpp │ ├── EmptyShape.hpp │ ├── ExtrudeMesh.hpp │ ├── FlipMesh.hpp │ ├── FlipPath.hpp │ ├── FlipShape.hpp │ ├── GridShape.hpp │ ├── HelixPath.hpp │ ├── IcoSphereMesh.hpp │ ├── IcosahedronMesh.hpp │ ├── Iterator.hpp │ ├── KnotPath.hpp │ ├── LatheMesh.hpp │ ├── LinePath.hpp │ ├── LineShape.hpp │ ├── MergeMesh.hpp │ ├── MergePath.hpp │ ├── MergeShape.hpp │ ├── MeshVertex.hpp │ ├── MirrorMesh.hpp │ ├── ObjWriter.hpp │ ├── ParametricMesh.hpp │ ├── ParametricPath.hpp │ ├── ParametricShape.hpp │ ├── PathVertex.hpp │ ├── PlaneMesh.hpp │ ├── RectangleShape.hpp │ ├── RepeatMesh.hpp │ ├── RepeatPath.hpp │ ├── RepeatShape.hpp │ ├── RotateMesh.hpp │ ├── RotatePath.hpp │ ├── RotateShape.hpp │ ├── RoundedBoxMesh.hpp │ ├── RoundedRectangleShape.hpp │ ├── ScaleMesh.hpp │ ├── ScalePath.hpp │ ├── ScaleShape.hpp │ ├── ShapeToPath.hpp │ ├── ShapeVertex.hpp │ ├── SphereMesh.hpp │ ├── SphericalConeMesh.hpp │ ├── SphericalTriangleMesh.hpp │ ├── SpherifyMesh.hpp │ ├── SpringMesh.hpp │ ├── SubdivideMesh.hpp │ ├── SubdividePath.hpp │ ├── SubdivideShape.hpp │ ├── SvgWriter.hpp │ ├── TeapotMesh.hpp │ ├── TorusKnotMesh.hpp │ ├── TorusMesh.hpp │ ├── TransformMesh.hpp │ ├── TransformPath.hpp │ ├── TransformShape.hpp │ ├── TranslateMesh.hpp │ ├── TranslatePath.hpp │ ├── TranslateShape.hpp │ ├── Triangle.hpp │ ├── TriangleMesh.hpp │ ├── TubeMesh.hpp │ ├── UvFlipMesh.hpp │ ├── UvSwapMesh.hpp │ ├── generator.hpp │ ├── gml │ ├── gml.hpp │ ├── intersect.hpp │ ├── mat.hpp │ ├── quaternion.hpp │ ├── spline.hpp │ ├── texture.hpp │ ├── util.hpp │ └── vec.hpp │ ├── math.hpp │ └── utils.hpp └── src ├── AnyMesh.cpp ├── AnyPath.cpp ├── AnyShape.cpp ├── BoxMesh.cpp ├── CMakeLists.txt ├── CappedConeMesh.cpp ├── CappedCylinderMesh.cpp ├── CappedTubeMesh.cpp ├── CapsuleMesh.cpp ├── CircleShape.cpp ├── ConeMesh.cpp ├── ConvexPolygonMesh.cpp ├── CylinderMesh.cpp ├── DiskMesh.cpp ├── DodecahedronMesh.cpp ├── EmptyMesh.cpp ├── EmptyPath.cpp ├── EmptyShape.cpp ├── GridShape.cpp ├── HelixPath.cpp ├── IcoSphereMesh.cpp ├── IcosahedronMesh.cpp ├── KnotPath.cpp ├── LinePath.cpp ├── LineShape.cpp ├── ObjWriter.cpp ├── ParametricMesh.cpp ├── ParametricPath.cpp ├── ParametricShape.cpp ├── PlaneMesh.cpp ├── RectangleShape.cpp ├── RoundedBoxMesh.cpp ├── RoundedRectangleShape.cpp ├── SphereMesh.cpp ├── SphericalConeMesh.cpp ├── SphericalTriangleMesh.cpp ├── SpringMesh.cpp ├── SvgWriter.cpp ├── TeapotMesh.cpp ├── TorusKnotMesh.cpp ├── TorusMesh.cpp ├── TriangleMesh.cpp └── TubeMesh.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # CMake 31 | CMakeCache.txt 32 | CMakeFiles 33 | CMakeScripts 34 | Makefile 35 | cmake_install.cmake 36 | install_manifest.txt 37 | 38 | # Generator 39 | images/*.svg 40 | doc/html 41 | images/generate 42 | 43 | # Qt-es 44 | /.qmake.cache 45 | /.qmake.stash 46 | *.pro.user 47 | *.pro.user.* 48 | *.qbs.user 49 | *.qbs.user.* 50 | *.moc 51 | moc_*.cpp 52 | qrc_*.cpp 53 | ui_*.h 54 | Makefile* 55 | *build-* 56 | 57 | # QtCreator 58 | *.autosave 59 | 60 | #QtCtreator Qml 61 | *.qmlproject.user 62 | *.qmlproject.user.* 63 | 64 | #QtCtreator CMake 65 | CMakeLists.txt.user 66 | 67 | # It's better to unpack these files and commit the raw source because 68 | # git has its own built in compression methods. 69 | *.7z 70 | *.jar 71 | *.rar 72 | *.zip 73 | *.gz 74 | *.bzip 75 | *.bz2 76 | *.xz 77 | *.lzma 78 | *.cab 79 | 80 | #packing-only formats 81 | *.iso 82 | *.tar 83 | 84 | #package management formats 85 | *.dmg 86 | *.xpi 87 | *.gem 88 | *.egg 89 | *.deb 90 | *.rpm 91 | *.msi 92 | *.msm 93 | *.msp 94 | 95 | # Swap Files # 96 | .*.kate-swp 97 | .swp.* 98 | 99 | *~ 100 | 101 | # temporary files which can be created if a process still has a handle open of a deleted file 102 | .fuse_hidden* 103 | 104 | # KDE directory preferences 105 | .directory 106 | 107 | # Linux trash folder which might appear on any partition or disk 108 | .Trash-* 109 | 110 | # NetBeans 111 | nbproject/private/ 112 | build/ 113 | nbbuild/ 114 | dist/ 115 | nbdist/ 116 | nbactions.xml 117 | .nb-gradle/ 118 | 119 | # Notepad++ backups # 120 | *.bak 121 | 122 | .DS_Store 123 | .AppleDouble 124 | .LSOverride 125 | 126 | # Icon must end with two \r 127 | Icon 128 | 129 | 130 | # Thumbnails 131 | ._* 132 | 133 | # Files that might appear in the root of a volume 134 | .DocumentRevisions-V100 135 | .fseventsd 136 | .Spotlight-V100 137 | .TemporaryItems 138 | .Trashes 139 | .VolumeIcon.icns 140 | 141 | # Directories potentially created on remote AFP share 142 | .AppleDB 143 | .AppleDesktop 144 | Network Trash Folder 145 | Temporary Items 146 | .apdisk 147 | 148 | 149 | # cache files for sublime text 150 | *.tmlanguage.cache 151 | *.tmPreferences.cache 152 | *.stTheme.cache 153 | 154 | # workspace files are user-specific 155 | *.sublime-workspace 156 | 157 | # project files should be checked into the repository, unless a significant 158 | # proportion of contributors will probably not be using SublimeText 159 | # *.sublime-project 160 | 161 | # sftp configuration file 162 | sftp-config.json 163 | 164 | # Windows image file caches 165 | Thumbs.db 166 | ehthumbs.db 167 | 168 | # Folder config file 169 | Desktop.ini 170 | 171 | # Recycle Bin used on file shares 172 | $RECYCLE.BIN/ 173 | 174 | # Windows Installer files 175 | *.cab 176 | *.msi 177 | *.msm 178 | *.msp 179 | 180 | # Windows shortcuts 181 | *.lnk 182 | 183 | # Xcode 184 | # 185 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 186 | 187 | ## Build generated 188 | build/ 189 | DerivedData/ 190 | 191 | ## Various settings 192 | *.pbxuser 193 | !default.pbxuser 194 | *.mode1v3 195 | !default.mode1v3 196 | *.mode2v3 197 | !default.mode2v3 198 | *.perspectivev3 199 | !default.perspectivev3 200 | xcuserdata/ 201 | 202 | ## Other 203 | *.moved-aside 204 | *.xccheckout 205 | *.xcscmblueprint -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | project(generator) 3 | 4 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 5 | set(TARGET_NAME generator) 6 | add_subdirectory(src) 7 | target_include_directories(generator PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/generator) 8 | set_property(TARGET generator PROPERTY POSITION_INDEPENDENT_CODE TRUE) 9 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | - Spline paths 2 | - Nurbs 3 | - Triangulate shapes to meshes. 4 | - Fonts (freetype). 5 | - Tetrahedron 6 | - Octahedron 7 | - Lathe cache shape vertex. 8 | - Uv transform 9 | - UV projection (sphere, cylinder, plane, box) 10 | - Belt shape 11 | - Subdivide shared cache. (shared_ptr?) 12 | - Tagging parts of mesh to support multiple materials. 13 | - Isosurfaces (marching cubes) 14 | - Gear mesh, gear shape 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /doc/GroupPicture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natevm/generator/45440b67becd970e46957b3c269b1595ecf4aec0/doc/GroupPicture.png -------------------------------------------------------------------------------- /images/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(generate${SUFFIX} generate.cpp) 2 | target_link_libraries(generate${SUFFIX} generator${SUFFIX}) 3 | -------------------------------------------------------------------------------- /include/generator/AnyGenerator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ANYGENERATOR_HPP 8 | #define GENERATOR_ANYGENERATOR_HPP 9 | 10 | #include 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// A type erasing container that can store any generator that generates type T. 17 | /// @tparam T Type returned by the generate() -function. 18 | template 19 | class AnyGenerator 20 | { 21 | public: 22 | 23 | template 24 | AnyGenerator(Generator generator) : 25 | base_{new Derived{std::move(generator)}} 26 | { } 27 | 28 | AnyGenerator(const AnyGenerator& that) : base_{that.base_->clone()} { } 29 | 30 | AnyGenerator(AnyGenerator&&) = default; 31 | 32 | AnyGenerator& operator=(const AnyGenerator& that) { 33 | base_ = that.base_->clone(); 34 | return *this; 35 | } 36 | 37 | AnyGenerator& operator=(AnyGenerator&&) = default; 38 | 39 | T generate() const { return base_->generate(); } 40 | 41 | bool done() const noexcept { return base_->done(); } 42 | 43 | void next() { base_->next(); } 44 | 45 | private: 46 | 47 | class Base { 48 | public: 49 | virtual ~Base() { } 50 | virtual std::unique_ptr clone() const = 0; 51 | virtual T generate() const = 0; 52 | virtual bool done() const noexcept = 0; 53 | virtual void next() = 0; 54 | }; 55 | 56 | template 57 | class Derived : public Base { 58 | public: 59 | 60 | Derived(Generator generator) : generator_{std::move(generator)} { } 61 | 62 | virtual std::unique_ptr clone() const override { 63 | return std::unique_ptr(new Derived{generator_}); 64 | } 65 | 66 | virtual T generate() const override { 67 | return generator_.generate(); 68 | } 69 | 70 | virtual bool done() const noexcept override { 71 | return generator_.done(); 72 | } 73 | 74 | virtual void next() override { 75 | generator_.next(); 76 | } 77 | 78 | private: 79 | 80 | Generator generator_; 81 | 82 | }; 83 | 84 | std::unique_ptr base_; 85 | 86 | }; 87 | 88 | } 89 | 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /include/generator/AnyMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ANYMESH_HPP 8 | #define GENERATOR_ANYMESH_HPP 9 | 10 | #include 11 | 12 | #include "AnyGenerator.hpp" 13 | #include "MeshVertex.hpp" 14 | #include "Triangle.hpp" 15 | 16 | 17 | namespace generator { 18 | 19 | 20 | /// A type erasing container that can store any mesh. 21 | class AnyMesh 22 | { 23 | public: 24 | 25 | template 26 | AnyMesh(Mesh mesh) : 27 | base_{new Derived{std::move(mesh)}} 28 | { } 29 | 30 | AnyMesh(const AnyMesh& that); 31 | 32 | AnyMesh(AnyMesh&&) = default; 33 | 34 | AnyMesh& operator=(const AnyMesh& that); 35 | 36 | AnyMesh& operator=(AnyMesh&&) = default; 37 | 38 | AnyGenerator triangles() const noexcept; 39 | 40 | AnyGenerator vertices() const noexcept; 41 | 42 | private: 43 | 44 | class Base { 45 | public: 46 | virtual ~Base(); 47 | virtual std::unique_ptr clone() const = 0; 48 | virtual AnyGenerator triangles() const = 0; 49 | virtual AnyGenerator vertices() const = 0; 50 | }; 51 | 52 | template 53 | class Derived : public Base { 54 | public: 55 | 56 | Derived(Mesh mesh) : mesh_(std::move(mesh)) { } 57 | 58 | virtual std::unique_ptr clone() const override { 59 | return std::unique_ptr{new Derived{mesh_}}; 60 | } 61 | 62 | virtual AnyGenerator triangles() const override { 63 | return mesh_.triangles(); 64 | } 65 | 66 | virtual AnyGenerator vertices() const override { 67 | return mesh_.vertices(); 68 | } 69 | 70 | Mesh mesh_; 71 | 72 | }; 73 | 74 | std::unique_ptr base_; 75 | 76 | }; 77 | 78 | } 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /include/generator/AnyPath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ANYPATH_HPP 8 | #define GENERATOR_ANYPATH_HPP 9 | 10 | #include 11 | 12 | #include "AnyGenerator.hpp" 13 | #include "Edge.hpp" 14 | #include "PathVertex.hpp" 15 | 16 | 17 | namespace generator { 18 | 19 | 20 | /// A type erasing container that can store any path. 21 | class AnyPath 22 | { 23 | public: 24 | 25 | template 26 | AnyPath(Path path) : 27 | base_{new Derived{std::move(path)}} 28 | { } 29 | 30 | AnyPath(const AnyPath& that); 31 | 32 | AnyPath(AnyPath&&) = default; 33 | 34 | AnyPath& operator=(const AnyPath& that); 35 | 36 | AnyPath& operator=(AnyPath&&) = default; 37 | 38 | AnyGenerator edges() const noexcept; 39 | 40 | AnyGenerator vertices() const noexcept; 41 | 42 | private: 43 | 44 | class Base { 45 | public: 46 | virtual ~Base(); 47 | virtual std::unique_ptr clone() const = 0; 48 | virtual AnyGenerator edges() const = 0; 49 | virtual AnyGenerator vertices() const = 0; 50 | }; 51 | 52 | template 53 | class Derived : public Base { 54 | public: 55 | Derived(Path path) : path_(std::move(path)) { } 56 | 57 | virtual std::unique_ptr clone() const override { 58 | return std::unique_ptr{new Derived{path_}}; 59 | } 60 | 61 | virtual AnyGenerator edges() const override { 62 | return path_.edges(); 63 | } 64 | 65 | virtual AnyGenerator vertices() const override { 66 | return path_.vertices(); 67 | } 68 | 69 | Path path_; 70 | }; 71 | 72 | std::unique_ptr base_; 73 | 74 | }; 75 | 76 | } 77 | 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /include/generator/AnyShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ANYSHAPE_HPP 8 | #define GENERATOR_ANYSHAPE_HPP 9 | 10 | #include 11 | 12 | 13 | #include "AnyGenerator.hpp" 14 | #include "Edge.hpp" 15 | #include "ShapeVertex.hpp" 16 | 17 | 18 | namespace generator { 19 | 20 | 21 | /// A type erasing container that can store any shape. 22 | class AnyShape 23 | { 24 | public: 25 | 26 | template 27 | AnyShape(Shape shape) : 28 | base_{new Derived{std::move(shape)}} 29 | { } 30 | 31 | AnyShape(const AnyShape& that); 32 | 33 | AnyShape(AnyShape&&) = default; 34 | 35 | AnyShape& operator=(const AnyShape& that); 36 | 37 | AnyShape& operator=(AnyShape&&) = default; 38 | 39 | AnyGenerator edges() const noexcept; 40 | 41 | AnyGenerator vertices() const noexcept; 42 | 43 | private: 44 | 45 | class Base { 46 | public: 47 | virtual ~Base(); 48 | virtual std::unique_ptr clone() const = 0; 49 | virtual AnyGenerator edges() const = 0; 50 | virtual AnyGenerator vertices() const = 0; 51 | }; 52 | 53 | template 54 | class Derived : public Base { 55 | public: 56 | 57 | Derived(Shape shape) : shape_(std::move(shape)) { } 58 | 59 | virtual std::unique_ptr clone() const override { 60 | return std::unique_ptr{new Derived{shape_}}; 61 | } 62 | 63 | virtual AnyGenerator edges() const override { 64 | return shape_.edges(); 65 | } 66 | 67 | virtual AnyGenerator vertices() const override { 68 | return shape_.vertices(); 69 | } 70 | 71 | Shape shape_; 72 | }; 73 | 74 | std::unique_ptr base_; 75 | 76 | }; 77 | 78 | } 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /include/generator/Axis.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_AXIS_HPP 8 | #define GENERATOR_AXIS_HPP 9 | 10 | namespace generator { 11 | 12 | enum class Axis { 13 | X = 0, 14 | Y = 1, 15 | Z = 2 16 | }; 17 | 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/generator/AxisFlipMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_AXISFLIPMESH_HPP 8 | #define GENERATOR_AXISFLIPMESH_HPP 9 | 10 | #include "TransformMesh.hpp" 11 | #include "Triangle.hpp" 12 | 13 | namespace generator { 14 | 15 | 16 | /// Flips (mirrors) the mesh along one or more axis. 17 | /// Texture coordinates are not flipped. 18 | /// Also reverses triangle vertex order if needed. 19 | template 20 | class AxisFlipMesh 21 | { 22 | private: 23 | 24 | using Impl = TransformMesh; 25 | Impl transformMesh_; 26 | 27 | public: 28 | 29 | class Triangles { 30 | public: 31 | 32 | Triangle generate() const { 33 | Triangle triangle = triangles_.generate(); 34 | if (mesh_->flip_) 35 | std::swap(triangle.vertices[0], triangle.vertices[2]); 36 | return triangle; 37 | } 38 | 39 | bool done() const noexcept { return triangles_.done(); } 40 | 41 | void next() { triangles_.next(); } 42 | 43 | private: 44 | 45 | const AxisFlipMesh* mesh_; 46 | 47 | typename TriangleGeneratorType>::Type triangles_; 48 | 49 | Triangles(const AxisFlipMesh& mesh) : 50 | mesh_{&mesh}, 51 | triangles_{mesh.transformMesh_.triangles()} 52 | { } 53 | 54 | friend class AxisFlipMesh; 55 | }; 56 | 57 | ///@param mesh Source data mesh. 58 | ///@param x Flip x 59 | ///@param y Flip y 60 | ///@param z Flip z 61 | AxisFlipMesh(Mesh mesh, bool x, bool y, bool z) : 62 | transformMesh_{ 63 | std::move(mesh), 64 | [x, y, z] (MeshVertex& vertex) { 65 | if (x) { 66 | vertex.position[0] *= -1.0; 67 | vertex.normal[0] *= -1.0; 68 | } 69 | 70 | if (y) { 71 | vertex.position[1] *= -1.0; 72 | vertex.normal[1] *= -1.0; 73 | } 74 | 75 | if (z) { 76 | vertex.position[2] *= -1.0; 77 | vertex.normal[2] *= -1.0; 78 | } 79 | } 80 | }, 81 | flip_{false} 82 | { 83 | if (x) flip_ = !flip_; 84 | if (y) flip_ = !flip_; 85 | if (z) flip_ = !flip_; 86 | } 87 | 88 | Triangles triangles() const noexcept { return {*this}; } 89 | 90 | using Vertices = typename Impl::Vertices; 91 | 92 | Vertices vertices() const noexcept { return transformMesh_.vertices(); } 93 | 94 | private: 95 | 96 | bool flip_; 97 | 98 | }; 99 | 100 | 101 | template 102 | AxisFlipMesh axisFlipMesh(Mesh mesh, bool x, bool y, bool z) { 103 | return AxisFlipMesh{std::move(mesh), x, y, z}; 104 | } 105 | 106 | 107 | 108 | } 109 | 110 | 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /include/generator/AxisSwapMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_AXISSWAPMESH_HPP 8 | #define GENERATOR_AXISSWAPMESH_HPP 9 | 10 | #include "Axis.hpp" 11 | #include "TransformMesh.hpp" 12 | #include "Triangle.hpp" 13 | 14 | namespace generator { 15 | 16 | 17 | /// Swaps any number of axis in the mesh. 18 | template 19 | class AxisSwapMesh 20 | { 21 | private: 22 | 23 | using Impl = TransformMesh; 24 | Impl transformMesh_; 25 | 26 | public: 27 | 28 | class Triangles { 29 | public: 30 | 31 | Triangle generate() const { 32 | Triangle triangle = triangles_.generate(); 33 | if (mesh_->flip_) 34 | std::swap(triangle.vertices[0], triangle.vertices[2]); 35 | return triangle; 36 | } 37 | 38 | bool done() const noexcept { return triangles_.done(); } 39 | 40 | void next() { triangles_.next(); } 41 | 42 | private: 43 | 44 | const AxisSwapMesh* mesh_; 45 | 46 | typename TriangleGeneratorType>::Type triangles_; 47 | 48 | Triangles(const AxisSwapMesh& mesh) : 49 | mesh_{&mesh}, 50 | triangles_{mesh.transformMesh_.triangles()} 51 | { } 52 | 53 | friend class AxisSwapMesh; 54 | }; 55 | 56 | ///@param mesh Source data mesh. 57 | ///@param x Axis to be used as the x-axis 58 | ///@param y Axis to be used as the y-axis 59 | ///@param z Axis to be used as the z-axis 60 | AxisSwapMesh(Mesh mesh, Axis x, Axis y, Axis z) : 61 | transformMesh_{ 62 | std::move(mesh), 63 | [x, y, z] (MeshVertex& vertex) { 64 | vertex.position = gml::dvec3{ 65 | vertex.position[static_cast(x)], 66 | vertex.position[static_cast(y)], 67 | vertex.position[static_cast(z)] 68 | }; 69 | vertex.normal = gml::dvec3{ 70 | vertex.normal[static_cast(x)], 71 | vertex.normal[static_cast(y)], 72 | vertex.normal[static_cast(z)] 73 | }; 74 | } 75 | }, 76 | flip_{true} 77 | { 78 | if (x != Axis::X) flip_ = !flip_; 79 | if (y != Axis::Y) flip_ = !flip_; 80 | if (z != Axis::Z) flip_ = !flip_; 81 | } 82 | 83 | Triangles triangles() const noexcept { return {*this}; } 84 | 85 | using Vertices = typename Impl::Vertices; 86 | 87 | Vertices vertices() const noexcept { return transformMesh_.vertices(); } 88 | 89 | private: 90 | 91 | bool flip_; 92 | 93 | }; 94 | 95 | 96 | template 97 | AxisSwapMesh axisSwapMesh(Mesh mesh, Axis x, Axis y, Axis z) { 98 | return AxisSwapMesh{std::move(mesh), x, y, z}; 99 | } 100 | 101 | 102 | } 103 | 104 | 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /include/generator/AxisSwapPath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_AXISSWAPPATH_HPP 8 | #define GENERATOR_AXISSWAPPATH_HPP 9 | 10 | #include "Axis.hpp" 11 | #include "TransformPath.hpp" 12 | 13 | namespace generator { 14 | 15 | 16 | 17 | /// Swaps axis in path. 18 | template 19 | class AxisSwapPath 20 | { 21 | private: 22 | 23 | using Impl = TransformPath; 24 | Impl transformPath_; 25 | 26 | public: 27 | 28 | /// @param path Source data path 29 | /// @param x Axis to use as the X-axis 30 | /// @param y Axis to use as the Y-axis 31 | /// @param z Axis to use as the Z-axis 32 | AxisSwapPath(Path path, Axis x, Axis y, Axis z) : 33 | transformPath_{ 34 | std::move(path), 35 | [x, y, z] (PathVertex& vertex) { 36 | vertex.position = gml::dvec3{ 37 | vertex.position[static_cast(x)], 38 | vertex.position[static_cast(y)], 39 | vertex.position[static_cast(z)] 40 | }; 41 | vertex.tangent = gml::dvec3{ 42 | vertex.tangent[static_cast(x)], 43 | vertex.tangent[static_cast(y)], 44 | vertex.tangent[static_cast(z)] 45 | }; 46 | vertex.normal = gml::dvec3{ 47 | vertex.normal[static_cast(x)], 48 | vertex.normal[static_cast(y)], 49 | vertex.normal[static_cast(z)] 50 | }; 51 | } 52 | } 53 | { } 54 | 55 | using Edges = typename Impl::Edges; 56 | 57 | Edges edges() const noexcept { return transformPath_.edges(); } 58 | 59 | using Vertices = typename Impl::Vertices; 60 | 61 | Vertices vertices() const noexcept { return transformPath_.vertices(); } 62 | 63 | }; 64 | 65 | 66 | template 67 | AxisSwapPath axisSwapPath(Path path, Axis x, Axis y, Axis z) { 68 | return AxisSwapPath{std::move(path), x, y, z}; 69 | } 70 | 71 | 72 | } 73 | 74 | 75 | #endif 76 | 77 | -------------------------------------------------------------------------------- /include/generator/AxisSwapShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_AXISSWAPSHAPE_HPP 8 | #define GENERATOR_AXISSWAPSHAPE_HPP 9 | 10 | 11 | #include "TransformShape.hpp" 12 | 13 | namespace generator { 14 | 15 | 16 | /// Swaps the x and y axis. 17 | template 18 | class AxisSwapShape 19 | { 20 | private: 21 | 22 | using Impl = TransformShape; 23 | Impl transformShape_; 24 | 25 | public: 26 | 27 | /// @param shape Source data shape. 28 | AxisSwapShape(Shape shape) : 29 | transformShape_{ 30 | std::move(shape), 31 | [] (ShapeVertex& vertex) { 32 | std::swap(vertex.position[0u], vertex.position[1u]); 33 | std::swap(vertex.tangent[0u], vertex.tangent[1u]); 34 | } 35 | } 36 | { } 37 | 38 | using Edges = typename Impl::Edges; 39 | 40 | Edges edges() const noexcept { return transformShape_.edges(); } 41 | 42 | using Vertices = typename Impl::Vertices; 43 | 44 | Vertices vertices() const noexcept { return transformShape_.vertices(); } 45 | 46 | }; 47 | 48 | 49 | template 50 | AxisSwapShape axisSwapShape(Shape shape) { 51 | return AxisSwapShape{std::move(shape)}; 52 | } 53 | 54 | 55 | } 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/generator/BezierMesh.hpp: -------------------------------------------------------------------------------- 1 | // This library is free software; you can redistribute it and/or 2 | // modify it under the terms of the GNU Lesser General Public 3 | // License as published by the Free Software Foundation; either 4 | // version 2.1 of the License, or (at your option) any later version. 5 | 6 | #ifndef UUID_8FFEADCF19544427BD6E6EC5C071222F 7 | #define UUID_8FFEADCF19544427BD6E6EC5C071222F 8 | 9 | #include 10 | #include 11 | 12 | #include "ParametricMesh.hpp" 13 | 14 | 15 | namespace generator { 16 | 17 | 18 | /// A bezier patch with D0xD1 control points. 19 | /// @tparam D0 Number of control points along the t[0] axis. Must be > 1. 20 | /// @tparam D1 Number of control points along the t[1] axis. Must be > 1. 21 | /// @image html BezierMesh.svg 22 | template 23 | class BezierMesh 24 | { 25 | private: 26 | 27 | static_assert(D0 > 1, "D0 must be > 1."); 28 | static_assert(D1 > 1, "D1 must be > 1."); 29 | 30 | using Impl = ParametricMesh; 31 | Impl mParametricMesh; 32 | 33 | struct ArrayWrapper 34 | { 35 | gml::dvec3 data[D1][D0]; 36 | 37 | ArrayWrapper(const gml::dvec3 (&p)[D1][D0]) 38 | { 39 | std::copy(&p[0][0], &p[0][0] + D1 * D0, &data[0][0]); 40 | } 41 | }; 42 | 43 | explicit BezierMesh( 44 | const ArrayWrapper& p, const gml::ivec2& segments 45 | ) : 46 | mParametricMesh{ 47 | [p] (const gml::dvec2& t) { 48 | MeshVertex vertex; 49 | 50 | vertex.position = gml::bezier2(p.data, t); 51 | 52 | gml::dmat2x3 J = gml::bezier2Jacobian<1>(p.data, t); 53 | vertex.normal = gml::cross(J[0], J[1]); 54 | 55 | // If the normal was zero try a again near by. 56 | const double e = std::numeric_limits::epsilon(); 57 | if (dot(vertex.normal, vertex.normal) < e) { 58 | J = gml::bezier2Jacobian<1>(p.data, t + 10.0 * e); 59 | vertex.normal = gml::cross(J[0], J[1]); 60 | } 61 | vertex.normal = gml::normalize(vertex.normal); 62 | 63 | vertex.texCoord = t; 64 | 65 | return vertex; 66 | }, 67 | segments 68 | } 69 | { } 70 | 71 | public: 72 | 73 | /// @param p Control points 74 | /// @param segments Number of subdivisions along each axis 75 | explicit BezierMesh( 76 | const gml::dvec3 (&p)[D1][D0], const gml::ivec2& segments = {16, 16} 77 | ) : 78 | // Work around a msvc lambda capture bug by wrapping the array. 79 | BezierMesh{ArrayWrapper{p}, segments} 80 | { } 81 | 82 | using Triangles = typename Impl::Triangles; 83 | 84 | Triangles triangles() const noexcept { return mParametricMesh.triangles(); } 85 | 86 | using Vertices = typename Impl::Vertices; 87 | 88 | Vertices vertices() const noexcept { return mParametricMesh.vertices(); } 89 | 90 | }; 91 | 92 | 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /include/generator/BezierShape.hpp: -------------------------------------------------------------------------------- 1 | // This library is free software; you can redistribute it and/or 2 | // modify it under the terms of the GNU Lesser General Public 3 | // License as published by the Free Software Foundation; either 4 | // version 2.1 of the License, or (at your option) any later version. 5 | 6 | #ifndef UUID_781FBB895F744ABCB12D8CDEA0AFA3E4 7 | #define UUID_781FBB895F744ABCB12D8CDEA0AFA3E4 8 | 9 | #include 10 | #include 11 | 12 | #include "ParametricShape.hpp" 13 | 14 | 15 | namespace generator { 16 | 17 | 18 | /// A bezier curve with D control points. 19 | /// @tparam D Number of control points. 4 = cubic curve. Must be > 1. 20 | /// @image html BezierShape.svg 21 | template 22 | class BezierShape 23 | { 24 | private: 25 | 26 | static_assert(D > 1, "D must be > 1."); 27 | 28 | using Impl = ParametricShape; 29 | Impl mParametricShape; 30 | 31 | struct ArrayWrapper 32 | { 33 | gml::dvec2 data[D]; 34 | 35 | ArrayWrapper(const gml::dvec2 (&p)[D]) 36 | { 37 | std::copy(&p[0], &p[0] + D, &data[0]); 38 | } 39 | }; 40 | 41 | 42 | explicit BezierShape(const ArrayWrapper& p, int segments) : 43 | mParametricShape{ 44 | [p] (double t) { 45 | ShapeVertex vertex; 46 | 47 | vertex.position = gml::bezier(p.data, t); 48 | 49 | vertex.tangent = gml::bezierDerivative<1>(p.data, t); 50 | 51 | // If tangent is zero try again near by. 52 | const double e = std::numeric_limits::epsilon(); 53 | if (gml::dot(vertex.tangent, vertex.tangent) < e) { 54 | vertex.tangent = gml::bezierDerivative<1>(p.data, t + 10.0 * e); 55 | } 56 | 57 | vertex.tangent = gml::normalize(vertex.tangent); 58 | 59 | vertex.texCoord = t; 60 | 61 | return vertex; 62 | }, 63 | segments 64 | } 65 | { 66 | } 67 | 68 | public: 69 | 70 | /// @param p Control points 71 | /// @param segments Number of subdivisions 72 | explicit BezierShape(const gml::dvec2 (&p)[D], int segments = 16) : 73 | // Work around a msvc lambda capture bug by wrapping the array. 74 | BezierShape{ArrayWrapper{p}, segments} 75 | { } 76 | 77 | using Edges = typename Impl::Edges; 78 | 79 | Edges edges() const noexcept { return mParametricShape.edges(); } 80 | 81 | using Vertices = typename Impl::Vertices; 82 | 83 | Vertices vertices() const noexcept { return mParametricShape.vertices(); } 84 | 85 | }; 86 | 87 | 88 | } 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /include/generator/BoxMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_BOXMESH_HPP 8 | #define GENERATOR_BOXMESH_HPP 9 | 10 | #include "AxisSwapMesh.hpp" 11 | #include "FlipMesh.hpp" 12 | #include "PlaneMesh.hpp" 13 | #include "MergeMesh.hpp" 14 | #include "TranslateMesh.hpp" 15 | #include "PlaneMesh.hpp" 16 | #include "UvFlipMesh.hpp" 17 | #include "UvSwapMesh.hpp" 18 | 19 | namespace generator { 20 | 21 | namespace detail { 22 | 23 | 24 | class BoxFace 25 | { 26 | private: 27 | 28 | using Impl = TranslateMesh; 29 | Impl translateMesh_; 30 | 31 | public: 32 | 33 | BoxFace(const gml::dvec2& size, const gml::ivec2& segments, double delta); 34 | 35 | using Triangles = typename Impl::Triangles; 36 | 37 | Triangles triangles() const noexcept { return translateMesh_.triangles(); } 38 | 39 | using Vertices = typename Impl::Vertices; 40 | 41 | Vertices vertices() const noexcept { return translateMesh_.vertices(); } 42 | 43 | }; 44 | 45 | 46 | class BoxFaces 47 | { 48 | private: 49 | 50 | using Impl = MergeMesh>>; 51 | Impl mergeMesh_; 52 | 53 | public: 54 | 55 | BoxFaces(const gml::dvec2& size, const gml::ivec2& segments, double delta); 56 | 57 | using Triangles = typename Impl::Triangles; 58 | 59 | Triangles triangles() const noexcept { return mergeMesh_.triangles(); } 60 | 61 | using Vertices = typename Impl::Vertices; 62 | 63 | Vertices vertices() const noexcept { return mergeMesh_.vertices(); } 64 | 65 | }; 66 | 67 | 68 | } 69 | 70 | 71 | 72 | /// Rectangular box centered at origin aligned along the x, y and z axis. 73 | /// @image html BoxMesh.svg 74 | class BoxMesh 75 | { 76 | private: 77 | 78 | using Impl = MergeMesh< 79 | AxisSwapMesh, 80 | UvFlipMesh>, 81 | detail::BoxFaces 82 | >; 83 | Impl mergeMesh_; 84 | 85 | public: 86 | 87 | /// @param size Half of the side length in x (0), y (1) and z (2) direction. 88 | /// @param segments The number of segments in x (0), y (1) and z (2) 89 | /// directions. All should be >= 1. If any one is zero faces in that 90 | /// direction are not genereted. If more than one is zero the mesh is empty. 91 | explicit BoxMesh( 92 | const gml::dvec3& size = {1.0, 1.0, 1.0}, 93 | const gml::ivec3& segments = {8, 8, 8} 94 | ) noexcept; 95 | 96 | using Triangles = typename Impl::Triangles; 97 | 98 | Triangles triangles() const noexcept { return mergeMesh_.triangles(); } 99 | 100 | using Vertices = typename Impl::Vertices; 101 | 102 | Vertices vertices() const noexcept { return mergeMesh_.vertices(); } 103 | 104 | }; 105 | 106 | 107 | } 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /include/generator/CappedConeMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_CAPPEDCONEMESH_HPP 8 | #define GENERATOR_CAPPEDCONEMESH_HPP 9 | 10 | #include "ConeMesh.hpp" 11 | #include "DiskMesh.hpp" 12 | #include "MergeMesh.hpp" 13 | #include "FlipMesh.hpp" 14 | #include "TranslateMesh.hpp" 15 | #include "UvFlipMesh.hpp" 16 | 17 | 18 | namespace generator { 19 | 20 | 21 | 22 | /// A cone with a cap centered at origin pointing towards positive z-axis. 23 | /// @image html CappedConeMesh.svg 24 | class CappedConeMesh 25 | { 26 | private: 27 | 28 | using Impl = MergeMesh< 29 | ConeMesh, 30 | UvFlipMesh>> 31 | >; 32 | Impl mergeMesh_; 33 | 34 | public: 35 | 36 | /// @param radius Radius of the flat (negative z) end along the xy-plane. 37 | /// @param size Half of the length of the cylinder along the z-axis. 38 | /// @param slices Number of subdivisions around the z-axis. 39 | /// @param segments Number of subdivisions along the z-axis. 40 | /// @param rings Number of subdivisions of the cap. 41 | /// @param start Counterclockwise angle around the z-axis relative to the 42 | /// positive x-axis. 43 | /// @param sweep Counterclockwise angle around the z-axis. 44 | CappedConeMesh( 45 | double radius = 1.0, 46 | double size = 1.0, 47 | int slices = 32, 48 | int segments = 8, 49 | int rings = 4, 50 | double start = 0.0, 51 | double sweep = gml::radians(360.0) 52 | ); 53 | 54 | using Triangles = typename Impl::Triangles; 55 | 56 | Triangles triangles() const noexcept { return mergeMesh_.triangles(); } 57 | 58 | using Vertices = typename Impl::Vertices; 59 | 60 | Vertices vertices() const noexcept { return mergeMesh_.vertices(); } 61 | 62 | }; 63 | 64 | 65 | } 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /include/generator/CappedCylinderMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_CAPPEDCYLINDERMESH_HPP 8 | #define GENERATOR_CAPPEDCYLINDERMESH_HPP 9 | 10 | #include "FlipMesh.hpp" 11 | #include "LatheMesh.hpp" 12 | #include "LineShape.hpp" 13 | #include "MergeMesh.hpp" 14 | #include "CylinderMesh.hpp" 15 | #include "TranslateMesh.hpp" 16 | #include "DiskMesh.hpp" 17 | #include "RotateMesh.hpp" 18 | #include "UvFlipMesh.hpp" 19 | 20 | 21 | namespace generator { 22 | 23 | namespace detail { 24 | 25 | class Cap 26 | { 27 | private: 28 | 29 | using Impl = TranslateMesh; 30 | Impl translateMesh_; 31 | 32 | public: 33 | 34 | Cap( 35 | double radius, 36 | double distance, 37 | int slices, 38 | int rings, 39 | double start, 40 | double sweep 41 | ); 42 | 43 | using Triangles = typename Impl::Triangles; 44 | 45 | Triangles triangles() const noexcept { return translateMesh_.triangles(); } 46 | 47 | using Vertices = typename Impl::Vertices; 48 | 49 | Vertices vertices() const noexcept { return translateMesh_.vertices(); } 50 | 51 | }; 52 | 53 | } 54 | 55 | 56 | 57 | /// Like CylinderMesh but with end caps. 58 | /// @image html CappedCylinderMesh.svg 59 | class CappedCylinderMesh 60 | { 61 | private: 62 | 63 | using Impl = MergeMesh< 64 | CylinderMesh, 65 | detail::Cap, 66 | UvFlipMesh> 67 | >; 68 | Impl mergeMesh_; 69 | 70 | public: 71 | 72 | /// @param radius Radius of the cylinder along the xy-plane. 73 | /// @param size Half of the length cylinder along the z-axis. 74 | /// @param slices Number of subdivisions around the z-axis. 75 | /// @param segments Number of subdivisions along the z-axis. 76 | /// @param rings Number of subdivisions on the caps. 77 | /// @param start Counterclockwise angle around the z-axis relative to x-axis. 78 | /// @param sweep Counterclockwise angle around the z-axis. 79 | CappedCylinderMesh( 80 | double radius = 1.0, 81 | double size = 1.0, 82 | int slices = 32, 83 | int segments = 8, 84 | int rings = 4, 85 | double start = 0.0, 86 | double sweep = gml::radians(360.0) 87 | ); 88 | 89 | using Triangles = typename Impl::Triangles; 90 | 91 | Triangles triangles() const noexcept { return mergeMesh_.triangles(); } 92 | 93 | using Vertices = typename Impl::Vertices; 94 | 95 | Vertices vertices() const noexcept { return mergeMesh_.vertices(); } 96 | 97 | }; 98 | 99 | 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /include/generator/CappedTubeMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_CAPPEDTUBEMESH_HPP 8 | #define GENERATOR_CAPPEDTUBEMESH_HPP 9 | 10 | #include "FlipMesh.hpp" 11 | #include "MergeMesh.hpp" 12 | #include "TubeMesh.hpp" 13 | #include "TranslateMesh.hpp" 14 | #include "DiskMesh.hpp" 15 | 16 | 17 | namespace generator { 18 | 19 | namespace detail { 20 | 21 | class TubeCap 22 | { 23 | private: 24 | 25 | using Impl = TranslateMesh; 26 | Impl translateMesh_; 27 | 28 | public: 29 | 30 | TubeCap( 31 | double radius, 32 | double innerRadius, 33 | double distance, 34 | int slices, 35 | int rings, 36 | double start, 37 | double sweep 38 | ); 39 | 40 | using Triangles = typename Impl::Triangles; 41 | 42 | Triangles triangles() const noexcept { return translateMesh_.triangles(); } 43 | 44 | using Vertices = typename Impl::Vertices; 45 | 46 | Vertices vertices() const noexcept { return translateMesh_.vertices(); } 47 | 48 | }; 49 | 50 | } 51 | 52 | 53 | 54 | /// Like TubeMesh but with end caps. 55 | /// @image html CappedTubeMesh.svg 56 | class CappedTubeMesh 57 | { 58 | private: 59 | 60 | using Impl = MergeMesh>; 61 | Impl mergeMesh_; 62 | 63 | public: 64 | 65 | /// @param radius The outer radius of the cylinder on the xy-plane. 66 | /// @param innerRadius The inner radius of the cylinder on the xy-plane. 67 | /// @param size Half of the length of the cylinder along the z-axis. 68 | /// @param slices Number nubdivisions around the z-axis. 69 | /// @param segments Number of subdivisions along the z-axis. 70 | /// @param rings Number radial subdivisions in the cap. 71 | /// @param start Counterclockwise angle around the z-axis relative to the x-axis. 72 | /// @param sweep Counterclockwise angle around the z-axis. 73 | CappedTubeMesh( 74 | double radius = 1.0, 75 | double innerRadius = 0.75, 76 | double size = 1.0, 77 | int slices = 32, 78 | int segments = 8, 79 | int rings = 1, 80 | double start = 0.0, 81 | double sweep = gml::radians(360.0) 82 | ); 83 | 84 | using Triangles = typename Impl::Triangles; 85 | 86 | Triangles triangles() const noexcept { return mergeMesh_.triangles(); } 87 | 88 | using Vertices = typename Impl::Vertices; 89 | 90 | Vertices vertices() const noexcept { return mergeMesh_.vertices(); } 91 | 92 | }; 93 | 94 | 95 | } 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /include/generator/CapsuleMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_CAPSULEMESH_HPP 8 | #define GENERATOR_CAPSULEMESH_HPP 9 | 10 | 11 | #include "CylinderMesh.hpp" 12 | #include "MergeMesh.hpp" 13 | #include "SphereMesh.hpp" 14 | #include "TranslateMesh.hpp" 15 | 16 | 17 | namespace generator { 18 | 19 | 20 | /// Capsule (cylinder with spherical caps) centered at origin aligned along z-axis. 21 | /// @image html CapsuleMesh.svg 22 | class CapsuleMesh 23 | { 24 | private: 25 | 26 | using Impl = MergeMesh< 27 | CylinderMesh, 28 | TranslateMesh, 29 | TranslateMesh 30 | >; 31 | Impl mergeMesh_; 32 | 33 | public: 34 | 35 | /// @param radius Radius of the capsule on the xy-plane. 36 | /// @param size Half of the length between centers of the caps along the z-axis. 37 | /// @param slices Number of subdivisions around the z-axis. 38 | /// @param rings Number of radial subdivisions in the caps. 39 | /// @param start Counterclockwise angle relative to the x-axis. 40 | /// @param sweep Counterclockwise angle. 41 | CapsuleMesh( 42 | double radius = 1.0, 43 | double size = 0.5, 44 | int slices = 32, 45 | int segments = 4, 46 | int rings = 8, 47 | double start = 0.0, 48 | double sweep = gml::radians(360.0) 49 | ); 50 | 51 | using Triangles = typename Impl::Triangles; 52 | 53 | Triangles triangles() const noexcept { return mergeMesh_.triangles(); } 54 | 55 | using Vertices = typename Impl::Vertices; 56 | 57 | Vertices vertices() const noexcept { return mergeMesh_.vertices(); } 58 | 59 | 60 | }; 61 | 62 | 63 | } 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /include/generator/CircleShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_CIRCLESHAPE_HPP 8 | #define GENERATOR_CIRCLESHAPE_HPP 9 | 10 | #include "ParametricShape.hpp" 11 | 12 | namespace generator { 13 | 14 | 15 | /// A circle centered at origin. 16 | /// @image html CircleShape.svg 17 | class CircleShape 18 | { 19 | private: 20 | 21 | using Impl = ParametricShape; 22 | Impl parametricShape_; 23 | 24 | public: 25 | 26 | /// @param radius Radius of the circle 27 | /// @param segments Number of subdivisions around the circle. 28 | /// @param start Counterclockwise angle relative to x-axis. 29 | /// @param sweep Counterclockwise angle. 30 | CircleShape( 31 | double radius = 1.0, 32 | int segments = 32, 33 | double start = 0.0, 34 | double sweep = gml::radians(360.0) 35 | ); 36 | 37 | using Edges = typename Impl::Edges; 38 | 39 | Edges edges() const noexcept { return parametricShape_.edges(); } 40 | 41 | using Vertices = typename Impl::Vertices; 42 | 43 | Vertices vertices() const noexcept { return parametricShape_.vertices(); } 44 | 45 | }; 46 | 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/generator/ConeMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_CONEMESH_HPP 8 | #define GENERATOR_CONEMESH_HPP 9 | 10 | #include "AxisSwapMesh.hpp" 11 | #include "LatheMesh.hpp" 12 | #include "LineShape.hpp" 13 | #include "UvFlipMesh.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | 20 | /// A cone centered at origin tip pointing towards z-axis. 21 | /// @image html ConeMesh.svg 22 | class ConeMesh 23 | { 24 | private: 25 | 26 | using Impl = AxisSwapMesh>; 27 | Impl axisSwapMesh_; 28 | 29 | public: 30 | 31 | ///@param radius Radius of the negative z end on the xy-plane. 32 | ///@param size Half of the length of the cylinder along the z-axis. 33 | ///@param slices Number of subdivisions around the z-axis. 34 | ///@param segments Number subdivisions along the z-axis. 35 | ///@param start Counterclockwise angle around the z-axis relative to the x-axis. 36 | ///@param sweep Counterclockwise angle around the z-axis. 37 | ConeMesh( 38 | double radius = 1.0, 39 | double size = 1.0, 40 | int slices = 32, 41 | int segments = 8, 42 | double start = 0.0, 43 | double sweep = gml::radians(360.0) 44 | ); 45 | 46 | using Triangles = typename Impl::Triangles; 47 | 48 | Triangles triangles() const noexcept { return axisSwapMesh_.triangles(); } 49 | 50 | using Vertices = typename Impl::Vertices; 51 | 52 | Vertices vertices() const noexcept { return axisSwapMesh_.vertices(); } 53 | 54 | }; 55 | 56 | 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/generator/ConvexPolygonMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef UUID_418D292D0BAB4AB4832E1CFEB92F0589 8 | #define UUID_418D292D0BAB4AB4832E1CFEB92F0589 9 | 10 | #include 11 | 12 | #include "math.hpp" 13 | 14 | #include "MeshVertex.hpp" 15 | #include "Triangle.hpp" 16 | 17 | 18 | namespace generator { 19 | 20 | 21 | 22 | /// A polygonal disk with arbitrary number of corners. 23 | /// Subdivided along each side to segments and radially to rings. 24 | /// @image html ConvexPolygonMesh.svg 25 | class ConvexPolygonMesh { 26 | private: 27 | 28 | class Triangles { 29 | public: 30 | bool done() const noexcept; 31 | Triangle generate() const; 32 | void next(); 33 | 34 | private: 35 | 36 | const ConvexPolygonMesh* mMesh; 37 | 38 | bool mOdd; 39 | 40 | int mSegmentIndex; 41 | 42 | int mSideIndex; 43 | 44 | int mRingIndex; 45 | 46 | explicit Triangles(const ConvexPolygonMesh&) noexcept; 47 | 48 | friend class ConvexPolygonMesh; 49 | }; 50 | 51 | class Vertices { 52 | public: 53 | 54 | bool done() const noexcept; 55 | MeshVertex generate() const; 56 | void next(); 57 | 58 | private: 59 | 60 | const ConvexPolygonMesh* mMesh; 61 | 62 | bool mCenterDone; 63 | 64 | int mSegmentIndex; 65 | 66 | int mSideIndex; 67 | 68 | int mRingIndex; 69 | 70 | explicit Vertices(const ConvexPolygonMesh&) noexcept; 71 | 72 | friend class ConvexPolygonMesh; 73 | }; 74 | 75 | std::vector mVertices; 76 | 77 | int mSegments; 78 | 79 | int mRings; 80 | 81 | gml::dvec3 mCenter; 82 | 83 | gml::dvec3 mNormal; 84 | 85 | gml::dvec3 mTangent; 86 | 87 | gml::dvec3 mBitangent; 88 | 89 | gml::dvec2 mTexDelta; 90 | 91 | public: 92 | 93 | /// @param radius The radius the enclosing circle. 94 | /// @param sides The number of sides. Should be >= 3. If <3 an empty mesh 95 | /// is generated. 96 | /// @param segments The number of segments per side. Should be >= 1. If zero 97 | /// an empty mesh is generated. 98 | /// @param rings The number of radial segments. Should be >= 1. = yelds an empty mesh. 99 | explicit ConvexPolygonMesh( 100 | double radius = 1.0, int sides = 5, int segments = 4, int rings = 4 101 | ) noexcept; 102 | 103 | //// @param vertices The corner vertex coordinates. Should form a convex polygon. 104 | explicit ConvexPolygonMesh( 105 | const std::vector& vertices, int segments = 1, int rings = 1 106 | ) noexcept; 107 | 108 | /// @param vertices The corner vertex coordinates. Should be coplanar and 109 | /// form a convex polygon. 110 | /// calculated as an avarage. 111 | explicit ConvexPolygonMesh( 112 | std::vector vertices, int segments = 1, int rings = 1 113 | ) noexcept; 114 | 115 | Triangles triangles() const noexcept; 116 | 117 | Vertices vertices() const noexcept; 118 | 119 | }; 120 | 121 | } 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /include/generator/CylinderMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_CYLINDERMESH_HPP 8 | #define GENERATOR_CYLINDERMESH_HPP 9 | 10 | #include "AxisSwapMesh.hpp" 11 | #include "LatheMesh.hpp" 12 | #include "LineShape.hpp" 13 | #include "UvFlipMesh.hpp" 14 | 15 | namespace generator { 16 | 17 | 18 | 19 | /// Cylinder centered at origin aligned along the z-axis. 20 | /// @image html CylinderMesh.svg 21 | class CylinderMesh 22 | { 23 | private: 24 | 25 | using Impl = AxisSwapMesh>; 26 | Impl axisSwapMesh_; 27 | 28 | public: 29 | 30 | /// @param radius Radius of the cylinder along the xy-plane. 31 | /// @param size Half of the length of the cylinder along the z-axis. 32 | /// @param slices Subdivisions around the z-axis. 33 | /// @param segments Subdivisions along the z-axis. 34 | /// @param start Counterclockwise angle around the z-axis relative to the x-axis. 35 | /// @param sweep Counterclockwise angle around the z-axis. 36 | CylinderMesh( 37 | double radius = 1.0, 38 | double size = 1.0, 39 | int slices = 32, 40 | int segments = 8, 41 | double start = 0.0, 42 | double sweep = gml::radians(360.0) 43 | ); 44 | 45 | using Triangles = typename Impl::Triangles; 46 | 47 | Triangles triangles() const noexcept { return axisSwapMesh_.triangles(); } 48 | 49 | using Vertices = typename Impl::Vertices; 50 | 51 | Vertices vertices() const noexcept { return axisSwapMesh_.vertices(); } 52 | 53 | }; 54 | 55 | 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/generator/DiskMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_DISKMESH_HPP 8 | #define GENERATOR_DISKMESH_HPP 9 | 10 | 11 | #include "AxisSwapMesh.hpp" 12 | #include "LatheMesh.hpp" 13 | #include "LineShape.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | /// A circular disk centered at origin on the xy-plane. 20 | /// @image html DiskMesh.svg 21 | class DiskMesh 22 | { 23 | private: 24 | 25 | using Impl = AxisSwapMesh>; 26 | Impl axisSwapMesh_; 27 | 28 | public: 29 | 30 | /// @param radius Outer radius of the disk on the xy-plane. 31 | /// @param innerRadius radius of the inner circle on the xy-plane. 32 | /// @param slices Number of subdivisions around the z-axis. 33 | /// @param rings Number of subdivisions along the radius. 34 | /// @param start Counterclockwise angle relative to the x-axis 35 | /// @param sweep Counterclockwise angle. 36 | DiskMesh( 37 | double radius = 1.0, 38 | double innerRadius = 0.0, 39 | int slices = 32, 40 | int rings = 4, 41 | double start = 0.0, 42 | double sweep = gml::radians(360.0) 43 | ); 44 | 45 | using Triangles = typename Impl::Triangles; 46 | 47 | Triangles triangles() const noexcept { return axisSwapMesh_.triangles(); } 48 | 49 | using Vertices = typename Impl::Vertices; 50 | 51 | Vertices vertices() const noexcept { return axisSwapMesh_.vertices(); } 52 | 53 | }; 54 | 55 | 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/generator/DodecahedronMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef UUID_8B1E88033CA8420EA606B29D704E10EC 8 | #define UUID_8B1E88033CA8420EA606B29D704E10EC 9 | 10 | #include 11 | #include 12 | 13 | 14 | #include "Triangle.hpp" 15 | #include "MeshVertex.hpp" 16 | #include "ConvexPolygonMesh.hpp" 17 | #include "utils.hpp" 18 | 19 | 20 | namespace generator { 21 | 22 | 23 | /// A regular dodecahedron centered at origin with given radius. 24 | /// Each face optionally subdivided along edges and/or radius. 25 | /// @image html DodecahedronMesh.svg 26 | class DodecahedronMesh { 27 | private: 28 | 29 | class Triangles { 30 | public: 31 | 32 | bool done() const noexcept; 33 | Triangle generate() const; 34 | void next(); 35 | 36 | private: 37 | 38 | const DodecahedronMesh* mMesh; 39 | 40 | int mFaceIndex; 41 | 42 | // Needs be a shared_ptr in order to make copy/move not to mess up the 43 | // internal pointer in mTriangles. 44 | std::shared_ptr mFaceMesh; 45 | 46 | typename TriangleGeneratorType::Type mTriangles; 47 | 48 | explicit Triangles(const DodecahedronMesh& mesh) noexcept; 49 | 50 | friend class DodecahedronMesh; 51 | }; 52 | 53 | 54 | class Vertices { 55 | public: 56 | 57 | bool done() const noexcept; 58 | MeshVertex generate() const; 59 | void next(); 60 | 61 | private: 62 | 63 | const DodecahedronMesh* mMesh; 64 | 65 | int mFaceIndex; 66 | 67 | // Needs be a shared_ptr in order to make copy/move not to mess up the 68 | // internal pointer in mTriangles. 69 | std::shared_ptr mFaceMesh; 70 | 71 | typename VertexGeneratorType::Type mVertices; 72 | 73 | explicit Vertices(const DodecahedronMesh& mesh) noexcept; 74 | 75 | friend class DodecahedronMesh; 76 | }; 77 | 78 | double mRadius; 79 | 80 | int mSegments; 81 | 82 | int mRings; 83 | 84 | int mFaceVertexCount; 85 | 86 | public: 87 | 88 | /// @param radius The radius of the enclosing sphere. 89 | /// @param segments The number segments along each edge. Should be >= 1. 90 | /// If <1 empty mesh is generated. 91 | /// @param rings The number of radial segments on each face. Should be >= 1. 92 | /// If <1 an empty mesh is generated. 93 | explicit DodecahedronMesh( 94 | double radius = 1.0, int segments = 1, int rings = 1 95 | ) noexcept; 96 | 97 | Triangles triangles() const noexcept; 98 | 99 | Vertices vertices() const noexcept; 100 | 101 | }; 102 | 103 | } 104 | 105 | #endif 106 | 107 | -------------------------------------------------------------------------------- /include/generator/Edge.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_EDGE_HPP 8 | #define GENERATOR_EDGE_HPP 9 | 10 | #include "math.hpp" 11 | 12 | namespace generator { 13 | 14 | class Edge { 15 | public: 16 | 17 | gml::ivec2 vertices; 18 | 19 | Edge() noexcept : 20 | vertices{} 21 | { } 22 | 23 | explicit Edge(const gml::ivec2& vertices) noexcept : 24 | vertices{vertices} 25 | { } 26 | 27 | }; 28 | 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/generator/EmptyMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_EMPTYMESH_HPP 8 | #define GENERATOR_EMPTYMESH_HPP 9 | 10 | #include "Iterator.hpp" 11 | #include "MeshVertex.hpp" 12 | #include "Triangle.hpp" 13 | 14 | 15 | namespace generator { 16 | 17 | 18 | /// Empty Mesh with zero vertices and triangles. 19 | class EmptyMesh { 20 | public: 21 | 22 | class Triangles { 23 | public: 24 | Triangle generate() const; 25 | bool done() const noexcept; 26 | void next(); 27 | private: 28 | 29 | Triangles(); 30 | 31 | friend class EmptyMesh; 32 | }; 33 | 34 | class Vertices { 35 | public: 36 | 37 | MeshVertex generate() const; 38 | bool done() const noexcept; 39 | void next(); 40 | 41 | private: 42 | 43 | Vertices(); 44 | 45 | friend class EmptyMesh; 46 | }; 47 | 48 | EmptyMesh(); 49 | 50 | Triangles triangles() const noexcept; 51 | 52 | Vertices vertices() const noexcept; 53 | 54 | }; 55 | 56 | 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/generator/EmptyPath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_EMPTYPATH_HPP 8 | #define GENERATOR_EMPTYPATH_HPP 9 | 10 | #include "Iterator.hpp" 11 | #include "PathVertex.hpp" 12 | #include "Edge.hpp" 13 | 14 | namespace generator { 15 | 16 | 17 | /// Empty path with zero vertices and edges. 18 | class EmptyPath { 19 | public: 20 | 21 | class Edges { 22 | public: 23 | 24 | Edge generate() const; 25 | bool done() const noexcept; 26 | void next(); 27 | 28 | private: 29 | 30 | Edges(); 31 | 32 | friend class EmptyPath; 33 | }; 34 | 35 | class Vertices { 36 | public: 37 | 38 | PathVertex generate() const; 39 | bool done() const noexcept; 40 | void next(); 41 | 42 | private: 43 | 44 | Vertices(); 45 | 46 | friend class EmptyPath; 47 | }; 48 | 49 | EmptyPath(); 50 | 51 | Edges edges() const noexcept; 52 | 53 | Vertices vertices() const noexcept; 54 | 55 | }; 56 | 57 | 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /include/generator/EmptyShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_EMPTYSHAPE_HPP 8 | #define GENERATOR_EMPTYSHAPE_HPP 9 | 10 | #include "ShapeVertex.hpp" 11 | #include "Edge.hpp" 12 | 13 | 14 | namespace generator { 15 | 16 | 17 | /// Empty shape with zero vertices and edges. 18 | class EmptyShape { 19 | public: 20 | 21 | class Edges { 22 | public: 23 | Edge generate() const; 24 | bool done() const noexcept; 25 | void next(); 26 | private: 27 | Edges(); 28 | friend class EmptyShape; 29 | }; 30 | 31 | class Vertices { 32 | public: 33 | ShapeVertex generate() const; 34 | bool done() const noexcept; 35 | void next(); 36 | private: 37 | Vertices(); 38 | friend class EmptyShape; 39 | }; 40 | 41 | Edges edges() const noexcept; 42 | 43 | Vertices vertices() const noexcept; 44 | 45 | }; 46 | 47 | 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /include/generator/FlipMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_FLIPMESH_HPP 8 | #define GENERATOR_FLIPMESH_HPP 9 | 10 | #include "TransformMesh.hpp" 11 | #include "Triangle.hpp" 12 | 13 | 14 | namespace generator { 15 | 16 | 17 | 18 | /// Flips mesh inside out. Reverses triangles and normals. 19 | template 20 | class FlipMesh 21 | { 22 | private: 23 | 24 | using Impl = TransformMesh; 25 | Impl transformMesh_; 26 | 27 | public: 28 | 29 | class Triangles { 30 | public: 31 | 32 | Triangle generate() const { 33 | Triangle triangle = triangles_.generate(); 34 | std::swap(triangle.vertices[0], triangle.vertices[2]); 35 | return triangle; 36 | } 37 | 38 | bool done() const noexcept { return triangles_.done(); } 39 | 40 | void next() { triangles_.next(); } 41 | 42 | private: 43 | 44 | typename TriangleGeneratorType>::Type triangles_; 45 | 46 | Triangles(const TransformMesh& mesh) : 47 | triangles_{mesh.triangles()} 48 | { } 49 | 50 | friend class FlipMesh; 51 | }; 52 | 53 | /// @param mesh Source data mesh. 54 | FlipMesh(Mesh mesh) : 55 | transformMesh_{std::move(mesh), [] (MeshVertex& vertex) { 56 | vertex.normal *= -1.0; 57 | }} 58 | { } 59 | 60 | Triangles triangles() const noexcept { return this->transformMesh_; } 61 | 62 | using Vertices = typename Impl::Vertices; 63 | 64 | Vertices vertices() const noexcept { return transformMesh_.vertices(); } 65 | 66 | 67 | }; 68 | 69 | 70 | template 71 | FlipMesh flipMesh(Mesh mesh) { 72 | return FlipMesh{std::move(mesh)}; 73 | } 74 | 75 | 76 | } 77 | 78 | 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /include/generator/FlipPath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_FLIPPATH_HPP 8 | #define GENERATOR_FLIPPATH_HPP 9 | 10 | 11 | #include "Edge.hpp" 12 | #include "TransformPath.hpp" 13 | 14 | 15 | namespace generator { 16 | 17 | 18 | /// Flips mesh inside out. Reverses triangles and normals. 19 | template 20 | class FlipPath 21 | { 22 | private: 23 | 24 | using Impl = TransformPath; 25 | Impl transformPath_; 26 | 27 | public: 28 | 29 | class Edges { 30 | public: 31 | 32 | Edge generate() const { 33 | Edge edge = edges_.generate(); 34 | std::swap(edge.vertices[0], edge.vertices[1]); 35 | return edge; 36 | } 37 | 38 | bool done() const noexcept { return edges_.done(); } 39 | 40 | void next() { edges_.next(); } 41 | 42 | private: 43 | 44 | typename EdgeGeneratorType>::Type edges_; 45 | 46 | Edges(const TransformPath& path) : 47 | edges_{path.edges()} 48 | { } 49 | 50 | friend class FlipPath; 51 | }; 52 | 53 | /// @param path Source data path. 54 | FlipPath(Path path) : 55 | transformPath_{ 56 | std::move(path), 57 | [] (PathVertex& vertex) { 58 | vertex.tangent *= -1.0; 59 | vertex.normal *= -1.0; 60 | } 61 | } 62 | { } 63 | 64 | Edges edges() const noexcept { return {*this}; } 65 | 66 | using Vertices = typename Impl::Vertices; 67 | 68 | Vertices vertices() const noexcept { return transformPath_.vertices(); } 69 | 70 | 71 | }; 72 | 73 | 74 | template 75 | FlipPath flipPath(Path path) { 76 | return FlipPath{std::move(path)}; 77 | } 78 | 79 | 80 | } 81 | 82 | 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /include/generator/FlipShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_FLIPSHAPE_HPP 8 | #define GENERATOR_FLIPSHAPE_HPP 9 | 10 | 11 | #include "Edge.hpp" 12 | #include "TransformShape.hpp" 13 | 14 | 15 | namespace generator { 16 | 17 | 18 | /// Flips shape direction. Reverses edges and tangents. 19 | template 20 | class FlipShape 21 | { 22 | private: 23 | 24 | using Impl = TransformShape; 25 | Impl transformShape_; 26 | 27 | public: 28 | 29 | class Edges { 30 | public: 31 | 32 | Edge generate() const { 33 | Edge edge = edges_.generate(); 34 | std::swap(edge.vertices[0], edge.vertices[1]); 35 | return edge; 36 | } 37 | 38 | bool done() const noexcept { return edges_.done(); } 39 | 40 | void next() { edges_.next(); } 41 | 42 | private: 43 | 44 | typename EdgeGeneratorType>::Type edges_; 45 | 46 | Edges(const TransformShape& shape) : 47 | edges_{shape.edges()} 48 | { } 49 | 50 | friend class FlipShape; 51 | }; 52 | 53 | /// @param shape Source data shape. 54 | FlipShape(Shape shape) : 55 | transformShape_{ 56 | std::move(shape), 57 | [] (ShapeVertex& vertex) { 58 | vertex.tangent *= -1.0; 59 | } 60 | } 61 | { } 62 | 63 | Edges edges() const noexcept { return {*this}; } 64 | 65 | using Vertices = typename Impl::Vertices; 66 | 67 | Vertices vertices() const noexcept { return transformShape_.vertices(); } 68 | 69 | 70 | }; 71 | 72 | 73 | template 74 | FlipShape flipShape(Shape shape) { 75 | return FlipShape{std::move(shape)}; 76 | } 77 | 78 | 79 | } 80 | 81 | 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /include/generator/GridShape.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UUID_D7746018E901B4EE35CEDC635307152F 2 | #define UUID_D7746018E901B4EE35CEDC635307152F 3 | 4 | #include 5 | 6 | #include "Edge.hpp" 7 | #include "ShapeVertex.hpp" 8 | #include "MergeShape.hpp" 9 | #include "RepeatShape.hpp" 10 | #include "LineShape.hpp" 11 | 12 | 13 | namespace generator 14 | { 15 | 16 | 17 | /** 18 | * A 2d regular grid. 19 | */ 20 | class GridShape 21 | { 22 | private: 23 | 24 | using Impl = MergeShape, RepeatShape>; 25 | 26 | Impl mImpl; 27 | 28 | public: 29 | 30 | using Edges = Impl::Edges; 31 | 32 | using Vertices = Impl::Vertices; 33 | 34 | /// @param size A half of the side length of the grid. 35 | /// @param segments The Number of cells in the grid. 36 | /// If <1 an empty shape results. 37 | /// @param subSegments The number of segment along each cell edge. 38 | /// If <1 an empty shape results. 39 | explicit GridShape( 40 | const gml::dvec2& size = {1.0, 1.0}, 41 | const gml::ivec2& segments = {4, 4}, 42 | const gml::ivec2& subSegments = {2, 2} 43 | ) noexcept; 44 | 45 | Edges edges() const noexcept; 46 | 47 | Vertices vertices() const noexcept; 48 | 49 | }; 50 | 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /include/generator/HelixPath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_HELIXPATH_HPP 8 | #define GENERATOR_HELIXPATH_HPP 9 | 10 | #include "ParametricPath.hpp" 11 | 12 | namespace generator { 13 | 14 | 15 | /// A helix cented at origin aligned along the z-axis. 16 | /// @image html HelixPath.svg 17 | class HelixPath 18 | { 19 | private: 20 | 21 | using Impl = ParametricPath; 22 | Impl parametricPath_; 23 | 24 | public: 25 | 26 | /// @param radius Radius from the z-axis 27 | /// @param size Half of the length along the z-axis. 28 | /// @param segments Number of subdivisions along the path. 29 | /// @param start Counterclockwise angle around the z-axis relative to the x-axis. 30 | /// @param sweep Counterclockwise angle around the z-axis. 31 | HelixPath( 32 | double radius = 1.0, 33 | double size = 1.0, 34 | int segments = 32, 35 | double start = 0.0, 36 | double sweep = gml::radians(720.0) 37 | ); 38 | 39 | using Edges = typename Impl::Edges; 40 | 41 | Edges edges() const noexcept { return parametricPath_.edges(); } 42 | 43 | using Vertices = typename Impl::Vertices; 44 | 45 | Vertices vertices() const noexcept { return parametricPath_.vertices(); } 46 | 47 | }; 48 | 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /include/generator/IcoSphereMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ICOSPHEREMESH_HPP 8 | #define GENERATOR_ICOSPHEREMESH_HPP 9 | 10 | 11 | #include "IcosahedronMesh.hpp" 12 | #include "SpherifyMesh.hpp" 13 | 14 | 15 | namespace generator { 16 | 17 | /// Icosphere aka spherical subdivided icosahedron 18 | /// @image html IcoSphereMesh.svg 19 | class IcoSphereMesh 20 | { 21 | private: 22 | 23 | using Impl = SpherifyMesh; 24 | Impl spherifyMesh_; 25 | 26 | public: 27 | 28 | /// @param radius The radius of the containing sphere. 29 | /// @param segments The number of segments per icosahedron edge. Must be >= 1. 30 | IcoSphereMesh(double radius = 1.0, int segments = 4); 31 | 32 | using Triangles = typename Impl::Triangles; 33 | 34 | Triangles triangles() const noexcept { return spherifyMesh_.triangles(); } 35 | 36 | using Vertices = typename Impl::Vertices; 37 | 38 | Vertices vertices() const noexcept { return spherifyMesh_.vertices(); } 39 | 40 | }; 41 | 42 | 43 | } 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/generator/IcosahedronMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ICOSAHEDRONMESH_HPP 8 | #define GENERATOR_ICOSAHEDRONMESH_HPP 9 | 10 | #include 11 | #include 12 | 13 | 14 | #include "Triangle.hpp" 15 | #include "MeshVertex.hpp" 16 | #include "TriangleMesh.hpp" 17 | #include "utils.hpp" 18 | 19 | 20 | namespace generator { 21 | 22 | 23 | /// Regular icosahedron centered at origin with given radius. 24 | /// @image html IcosahedronMesh.svg 25 | class IcosahedronMesh { 26 | public: 27 | 28 | class Triangles { 29 | public: 30 | 31 | bool done() const noexcept; 32 | Triangle generate() const; 33 | void next(); 34 | 35 | private: 36 | 37 | const IcosahedronMesh* mesh_; 38 | 39 | int i_; 40 | 41 | // Needs be a shared_ptr in order to make copy/move not to mess up the 42 | // internal pointer in triangles_. 43 | std::shared_ptr triangleMesh_; 44 | 45 | typename TriangleGeneratorType::Type triangles_; 46 | 47 | Triangles(const IcosahedronMesh& mesh); 48 | 49 | friend class IcosahedronMesh; 50 | }; 51 | 52 | 53 | class Vertices { 54 | public: 55 | 56 | bool done() const noexcept; 57 | MeshVertex generate() const; 58 | void next(); 59 | 60 | private: 61 | 62 | const IcosahedronMesh* mesh_; 63 | 64 | int i_; 65 | 66 | // Needs be a shared_ptr in order to make copy/move not to mess up the 67 | // internal pointer in triangles_. 68 | std::shared_ptr triangleMesh_; 69 | 70 | typename VertexGeneratorType::Type vertices_; 71 | 72 | Vertices(const IcosahedronMesh& mesh); 73 | 74 | friend class IcosahedronMesh; 75 | }; 76 | 77 | private: 78 | 79 | double radius_; 80 | 81 | int segments_; 82 | 83 | int faceVertexCount_; 84 | 85 | public: 86 | 87 | /// @param radius The radius of the enclosing sphere. 88 | /// @param segments The number segments along each edge. Must be >= 1. 89 | IcosahedronMesh(double radius = 1.0, int segments = 1); 90 | 91 | Triangles triangles() const noexcept; 92 | 93 | Vertices vertices() const noexcept; 94 | 95 | }; 96 | 97 | } 98 | 99 | #endif 100 | 101 | -------------------------------------------------------------------------------- /include/generator/Iterator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ITERATOR_HPP 8 | #define GENERATOR_ITERATOR_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "utils.hpp" 15 | 16 | 17 | namespace generator { 18 | 19 | 20 | 21 | 22 | /// An iterator that can be used to "drive" a generator. 23 | /// Note that iterator mutates the generator. 24 | template 25 | class Iterator 26 | { 27 | private: 28 | 29 | Generator* generator_; 30 | 31 | typename GeneratedType::Type value_; 32 | 33 | public: 34 | 35 | using iterator_category = std::input_iterator_tag; 36 | 37 | using value_type = typename GeneratedType::Type; 38 | 39 | using difference_type = std::ptrdiff_t; 40 | 41 | using pointer = value_type*; 42 | 43 | using reference = value_type&; 44 | 45 | /// Creates a dummy end iterator. 46 | Iterator() noexcept : 47 | generator_{nullptr}, 48 | value_{} 49 | { } 50 | 51 | /// Iterator to the given generator. 52 | Iterator(Generator& generator) noexcept : 53 | generator_{&generator}, 54 | value_{} 55 | { 56 | if (generator_->done()) generator_ = nullptr; 57 | else value_ = generator_->generate(); 58 | } 59 | 60 | /// Advance the iterator. 61 | /// Might make the iterator "out of range". 62 | /// @throws std::out_of_range If the iterator is out of range. 63 | Iterator& operator++() { 64 | if (!generator_) throw std::out_of_range("Iterator out of range!"); 65 | generator_->next(); 66 | if (generator_->done()) generator_ = nullptr; 67 | else value_ = generator_->generate(); 68 | return *this; 69 | } 70 | 71 | /// Get reference to the current generated value. 72 | /// @throws std::out_of_range If the iterator is out of range. 73 | const typename Iterator::value_type& operator*() const { 74 | if (!generator_) throw std::out_of_range("Iterator out of range!"); 75 | return value_; 76 | } 77 | 78 | /// Get pointer to the current generated value. 79 | /// @throws std::out_of_range If the iterator is out of range 80 | const typename Iterator::value_type* operator->() const { 81 | if (!generator_) throw std::out_of_range("Iterator out of range!"); 82 | return &value_; 83 | } 84 | 85 | /// Iterators are equal if both are out of range or both iterate the same 86 | /// generator. 87 | bool operator==(const Iterator& that) const noexcept { 88 | return generator_ == that.generator_; 89 | } 90 | 91 | bool operator!=(const Iterator& that) const noexcept { 92 | return generator_ != that.generator_; 93 | } 94 | 95 | }; 96 | 97 | 98 | /// Will return an iterator to the generator. 99 | template 100 | Iterator begin(Generator& generator) noexcept { 101 | return Iterator{generator}; 102 | } 103 | 104 | 105 | /// Returns a dummy end iterator 106 | template 107 | Iterator end(const Generator&) noexcept { 108 | return Iterator{}; 109 | } 110 | 111 | 112 | } 113 | 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /include/generator/KnotPath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TORUSKNOTPATH_HPP 8 | #define GENERATOR_TORUSKNOTPATH_HPP 9 | 10 | #include "CircleShape.hpp" 11 | #include "ExtrudeMesh.hpp" 12 | #include "ParametricPath.hpp" 13 | 14 | namespace generator { 15 | 16 | 17 | 18 | /// A circle winding multiple times around. 19 | /// @image html KnotPath.svg 20 | class KnotPath 21 | { 22 | private: 23 | 24 | using Impl = ParametricPath; 25 | Impl parametricPath_; 26 | 27 | public: 28 | 29 | /// @param q Times around a circle 30 | /// @param p Times around z axis 31 | /// @param segments Number of subdivisions along the path. 32 | KnotPath( 33 | int p = 2, 34 | int q = 3, 35 | int segments = 96 36 | ); 37 | 38 | using Edges = typename Impl::Edges; 39 | 40 | Edges edges() const noexcept { return parametricPath_.edges(); } 41 | 42 | using Vertices = typename Impl::Vertices; 43 | 44 | Vertices vertices() const noexcept { return parametricPath_.vertices(); } 45 | 46 | }; 47 | 48 | } 49 | 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /include/generator/LinePath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_LINEPATH_HPP 8 | #define GENERATOR_LINEPATH_HPP 9 | 10 | #include "ParametricPath.hpp" 11 | 12 | namespace generator { 13 | 14 | 15 | /// A path from point to point. 16 | /// @image html LinePath.svg 17 | class LinePath 18 | { 19 | private: 20 | 21 | using Impl = ParametricPath; 22 | Impl parametricPath_; 23 | 24 | public: 25 | 26 | /// @param start Start point of the line. 27 | /// @param end End point of the line. 28 | /// @param normal Line normal. Should be parallel to the line. 29 | /// @param segments Number of subdivisions along the line. 30 | LinePath( 31 | const gml::dvec3& start = {0.0, 0.0, -1.0}, 32 | const gml::dvec3& end = {0.0, 0.0, 1.0}, 33 | const gml::dvec3& normal = {1.0, 0.0, 0.0}, 34 | int segments = 8 35 | ); 36 | 37 | using Edges = typename Impl::Edges; 38 | 39 | Edges edges() const noexcept { return parametricPath_.edges(); } 40 | 41 | using Vertices = typename Impl::Vertices; 42 | 43 | Vertices vertices() const noexcept { return parametricPath_.vertices(); } 44 | 45 | }; 46 | 47 | 48 | } 49 | 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /include/generator/LineShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_LINESHAPE_HPP 8 | #define GENERATOR_LINESHAPE_HPP 9 | 10 | #include "ParametricShape.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// A line from a point to a point. 17 | /// @image html LineShape.svg 18 | class LineShape 19 | { 20 | private: 21 | 22 | using Impl = ParametricShape; 23 | Impl parametricShape_; 24 | 25 | public: 26 | 27 | /// @param start Start position 28 | /// @param end End position 29 | /// @param segments Number of subdivisions 30 | LineShape( 31 | const gml::dvec2& start = {0.0, -1.0}, 32 | const gml::dvec2& end = {0.0, 1.0}, 33 | int segments = 8 34 | ); 35 | 36 | using Edges = typename Impl::Edges; 37 | 38 | Edges edges() const noexcept { return parametricShape_.edges(); } 39 | 40 | using Vertices = typename Impl::Vertices; 41 | 42 | Vertices vertices() const noexcept { return parametricShape_.vertices(); } 43 | 44 | }; 45 | 46 | 47 | } 48 | 49 | #endif /* LINE_HPP_ */ 50 | -------------------------------------------------------------------------------- /include/generator/MergeMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_MERGEMESH_HPP 8 | #define GENERATOR_MERGEMESH_HPP 9 | 10 | 11 | #include "MeshVertex.hpp" 12 | #include "EmptyMesh.hpp" 13 | #include "utils.hpp" 14 | 15 | namespace generator { 16 | 17 | 18 | /// Merges (concatenates) multiple meshes to to together. 19 | template 20 | class MergeMesh; // undefined 21 | 22 | 23 | template <> 24 | class MergeMesh<> : public EmptyMesh { }; 25 | 26 | 27 | template 28 | class MergeMesh { 29 | public: 30 | 31 | class Triangles { 32 | public: 33 | 34 | Triangle generate() const { 35 | if (!head_.done()) return head_.generate(); 36 | 37 | Triangle triangle = tail_.generate(); 38 | triangle.vertices += head_VertexCount; 39 | return triangle; 40 | } 41 | 42 | bool done() const noexcept { return mAllDone; } 43 | 44 | void next() { 45 | if (!head_.done()) head_.next(); 46 | else tail_.next(); 47 | 48 | mAllDone = tail_.done() && head_.done(); 49 | } 50 | 51 | private: 52 | 53 | typename TriangleGeneratorType::Type head_; 54 | typename TriangleGeneratorType>::Type tail_; 55 | 56 | int head_VertexCount; 57 | 58 | bool mAllDone; 59 | 60 | Triangles(const MergeMesh& mesh) : 61 | head_{mesh.head_.triangles()}, 62 | tail_(mesh.tail_.triangles()), 63 | head_VertexCount{count(mesh.head_.vertices())}, 64 | mAllDone{tail_.done() && head_.done()} 65 | { } 66 | 67 | friend class MergeMesh; 68 | }; 69 | 70 | 71 | class Vertices { 72 | public: 73 | 74 | MeshVertex generate() const { 75 | if (!head_.done()) return head_.generate(); 76 | return tail_.generate(); 77 | } 78 | 79 | bool done() const noexcept { return mAllDone; } 80 | 81 | void next() { 82 | if (!head_.done()) head_.next(); 83 | else tail_.next(); 84 | 85 | mAllDone = tail_.done() && head_.done(); 86 | } 87 | 88 | private: 89 | 90 | typename VertexGeneratorType::Type head_; 91 | typename VertexGeneratorType>::Type tail_; 92 | 93 | bool mAllDone; 94 | 95 | Vertices(const MergeMesh& mesh) : 96 | head_{mesh.head_.vertices()}, 97 | tail_(mesh.tail_.vertices()), 98 | mAllDone{tail_.done() && head_.done()} 99 | { } 100 | 101 | friend class MergeMesh; 102 | }; 103 | 104 | 105 | 106 | MergeMesh(Head head, Tail... tail) : 107 | head_{std::move(head)}, 108 | tail_{std::move(tail)...} 109 | { } 110 | 111 | Triangles triangles() const noexcept { return *this; } 112 | 113 | Vertices vertices() const noexcept { return *this; } 114 | 115 | 116 | private: 117 | 118 | Head head_; 119 | MergeMesh tail_; 120 | 121 | }; 122 | 123 | 124 | 125 | template 126 | MergeMesh mergeMesh(Mesh... meshes) { 127 | return MergeMesh{std::move(meshes)...}; 128 | } 129 | 130 | } 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /include/generator/MergePath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_MERGEPath_HPP 8 | #define GENERATOR_MERGEPath_HPP 9 | 10 | 11 | #include "PathVertex.hpp" 12 | #include "EmptyPath.hpp" 13 | #include "utils.hpp" 14 | 15 | namespace generator { 16 | 17 | 18 | /// Merges (concatenates) multiple paths together. 19 | template 20 | class MergePath; // undefined 21 | 22 | 23 | template <> 24 | class MergePath<> : public EmptyPath { }; 25 | 26 | 27 | template 28 | class MergePath { 29 | public: 30 | 31 | class Edges { 32 | public: 33 | 34 | Edge generate() const { 35 | if (!head_.done()) return head_.generate(); 36 | return tail_.generate() + head_VertexCount; 37 | } 38 | 39 | bool done() const noexcept { return mAllDone; } 40 | 41 | void next() { 42 | if (!head_.done()) head_.next(); 43 | else tail_.next(); 44 | 45 | mAllDone = tail_.done() && head_.done(); 46 | } 47 | 48 | private: 49 | 50 | typename EdgeGeneratorType::type head_; 51 | typename EdgeGeneratorType>::type tail_; 52 | 53 | int head_VertexCount; 54 | 55 | bool mAllDone; 56 | 57 | Edges(const MergePath& path) : 58 | head_{path.head_.triangles()}, 59 | tail_(path.tail_.triangles()), 60 | head_VertexCount{count(path.head_.vertices())}, 61 | mAllDone{tail_.done() && head_.done()} 62 | { } 63 | 64 | friend class MergePath; 65 | }; 66 | 67 | 68 | class Vertices { 69 | public: 70 | 71 | PathVertex generate() const { 72 | if (!head_.done()) return head_.generate(); 73 | return tail_.generate(); 74 | } 75 | 76 | bool done() const noexcept { return mAllDone; } 77 | 78 | void next() { 79 | if (!head_.done()) head_.next(); 80 | else tail_.next(); 81 | 82 | mAllDone = tail_.done() && head_.done(); 83 | } 84 | 85 | private: 86 | 87 | typename VertexGeneratorType::type head_; 88 | typename VertexGeneratorType>::type tail_; 89 | bool mAllDone; 90 | 91 | Vertices(const MergePath& path) : 92 | head_{path.head_.vertices()}, 93 | tail_(path.tail_.vertices()), 94 | mAllDone{tail_.done() && head_.done()} 95 | { } 96 | 97 | friend class MergePath; 98 | }; 99 | 100 | 101 | 102 | MergePath(Head head, Tail... tail) : 103 | head_{head}, 104 | tail_{tail...} 105 | { } 106 | 107 | Edges edges() const noexcept { return *this; } 108 | 109 | Vertices vertices() const noexcept { return *this; } 110 | 111 | 112 | private: 113 | 114 | Head head_; 115 | MergePath tail_; 116 | 117 | }; 118 | 119 | 120 | 121 | template 122 | MergePath mergePath(Path... paths) { 123 | return MergePath{std::move(paths)...}; 124 | } 125 | 126 | } 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /include/generator/MergeShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_MERGESHAPE_HPP 8 | #define GENERATOR_MERGESHAPE_HPP 9 | 10 | 11 | #include "ShapeVertex.hpp" 12 | #include "EmptyShape.hpp" 13 | #include "utils.hpp" 14 | 15 | namespace generator { 16 | 17 | 18 | /// Merges (concatenates) multiple shapes together. 19 | template 20 | class MergeShape; // undefined 21 | 22 | 23 | template <> 24 | class MergeShape<> : public EmptyShape { }; 25 | 26 | 27 | template 28 | class MergeShape { 29 | public: 30 | 31 | class Edges { 32 | public: 33 | 34 | Edge generate() const { 35 | if (!head_.done()) return head_.generate(); 36 | 37 | Edge edge = tail_.generate(); 38 | edge.vertices += head_VertexCount; 39 | return edge; 40 | } 41 | 42 | bool done() const noexcept { return mAllDone; } 43 | 44 | void next() { 45 | if (!head_.done()) head_.next(); 46 | else tail_.next(); 47 | 48 | mAllDone = tail_.done() && head_.done(); 49 | } 50 | 51 | private: 52 | 53 | typename EdgeGeneratorType::Type head_; 54 | typename EdgeGeneratorType>::Type tail_; 55 | 56 | int head_VertexCount; 57 | 58 | bool mAllDone; 59 | 60 | Edges(const MergeShape& shape) : 61 | head_{shape.head_.edges()}, 62 | tail_(shape.tail_.edges()), 63 | head_VertexCount{count(shape.head_.vertices())}, 64 | mAllDone{tail_.done() && head_.done()} 65 | { } 66 | 67 | friend class MergeShape; 68 | }; 69 | 70 | 71 | class Vertices { 72 | public: 73 | 74 | ShapeVertex generate() const { 75 | if (!head_.done()) return head_.generate(); 76 | return tail_.generate(); 77 | } 78 | 79 | bool done() const noexcept { return mAllDone; } 80 | 81 | void next() { 82 | if (!head_.done()) head_.next(); 83 | else tail_.next(); 84 | 85 | mAllDone = tail_.done() && head_.done(); 86 | } 87 | 88 | private: 89 | 90 | typename VertexGeneratorType::Type head_; 91 | typename VertexGeneratorType>::Type tail_; 92 | bool mAllDone; 93 | 94 | Vertices(const MergeShape& shape) : 95 | head_{shape.head_.vertices()}, 96 | tail_(shape.tail_.vertices()), 97 | mAllDone{tail_.done() && head_.done()} 98 | { } 99 | 100 | friend class MergeShape; 101 | }; 102 | 103 | 104 | 105 | MergeShape(Head head, Tail... tail) : 106 | head_{head}, 107 | tail_{tail...} 108 | { } 109 | 110 | Edges edges() const noexcept { return *this; } 111 | 112 | Vertices vertices() const noexcept { return *this; } 113 | 114 | 115 | private: 116 | 117 | Head head_; 118 | MergeShape tail_; 119 | 120 | }; 121 | 122 | 123 | 124 | template 125 | MergeShape mergeShape(Shape... shapes) { 126 | return MergeShape{std::move(shapes)...}; 127 | } 128 | 129 | } 130 | 131 | #endif 132 | 133 | 134 | -------------------------------------------------------------------------------- /include/generator/MeshVertex.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_MESHVERTEX_HPP 8 | #define GENERATOR_MESHVERTEX_HPP 9 | 10 | #include "math.hpp" 11 | 12 | namespace generator { 13 | 14 | 15 | class MeshVertex { 16 | public: 17 | 18 | gml::dvec3 position; 19 | 20 | /// Unit vector perpendicular to the surface. 21 | gml::dvec3 normal; 22 | 23 | /// UV texture coordinates 24 | gml::dvec2 texCoord; 25 | 26 | MeshVertex() noexcept : 27 | position{}, 28 | normal{}, 29 | texCoord{} 30 | { } 31 | 32 | }; 33 | 34 | 35 | 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/generator/MirrorMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_MIRRORMESH_HPP 8 | #define GENERATOR_MIRRORMESH_HPP 9 | 10 | 11 | #include "Axis.hpp" 12 | #include "AxisFlipMesh.hpp" 13 | #include "MergeMesh.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | /// Duplicates the mesh by mirrorring it along an axis. 20 | template 21 | class MirrorMesh 22 | { 23 | private: 24 | 25 | using Impl = MergeMesh>; 26 | Impl mergeMesh_; 27 | 28 | public: 29 | 30 | /// @param mesh Source data mesh. 31 | /// @param axis The axis to mirror along. 32 | MirrorMesh(Mesh mesh, Axis axis) : 33 | mergeMesh_{ 34 | mesh, {mesh, axis == Axis::X, axis == Axis::Y, axis == Axis::Z} 35 | } 36 | { } 37 | 38 | using Triangles = typename Impl::Triangles; 39 | 40 | Triangles triangles() const noexcept { return mergeMesh_.triangles(); } 41 | 42 | using Vertices = typename Impl::Vertices; 43 | 44 | Vertices vertices() const noexcept { return mergeMesh_.vertices(); } 45 | 46 | }; 47 | 48 | 49 | template 50 | MirrorMesh mirrorMesh(Mesh mesh) { 51 | return MirrorMesh{std::move(mesh)}; 52 | } 53 | 54 | } 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /include/generator/ObjWriter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_OBJWRITER_HPP 8 | #define GENERATOR_OBJWRITER_HPP 9 | 10 | #include 11 | 12 | #include "MeshVertex.hpp" 13 | #include "Triangle.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | /// A class for generating obj files for preview and debug purposes. 20 | class ObjWriter { 21 | public: 22 | 23 | ObjWriter(); 24 | 25 | template 26 | void writeMesh(const Mesh& mesh) { 27 | int newBase = base_; 28 | 29 | for (const MeshVertex& vertex : mesh.vertices()) { 30 | ++newBase; 31 | 32 | ss_ 33 | << "v " 34 | << vertex.position[0] << " " 35 | << vertex.position[1] << " " 36 | << vertex.position[2] << "\n"; 37 | 38 | ss_ 39 | << "vn " 40 | << vertex.normal[0] << " " 41 | << vertex.normal[1] << " " 42 | << vertex.normal[2] << "\n"; 43 | 44 | ss_ 45 | << "vt " 46 | << vertex.texCoord[0] << " " 47 | << vertex.texCoord[1] << "\n"; 48 | } 49 | 50 | for (const Triangle& triangle : mesh.triangles()) { 51 | auto t = triangle.vertices + base_; 52 | ss_ 53 | << "f " 54 | << t[0] << "/" << t[0] << "/" << t[0] << " " 55 | << t[1] << "/" << t[1] << "/" << t[1] << " " 56 | << t[2] << "/" << t[2] << "/" << t[2] << "\n"; 57 | } 58 | 59 | base_ = newBase; 60 | } 61 | 62 | std::string str() { return ss_.str(); } 63 | 64 | private: 65 | 66 | int base_; 67 | 68 | std::stringstream ss_; 69 | 70 | }; 71 | 72 | } 73 | 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /include/generator/ParametricMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_PARAMETRICMESH_HPP 8 | #define GENERATOR_PARAMETRICMESH_HPP 9 | 10 | #include 11 | 12 | 13 | #include "Triangle.hpp" 14 | #include "MeshVertex.hpp" 15 | 16 | 17 | namespace generator { 18 | 19 | 20 | /// A mesh with values evaluated using a callback function. 21 | class ParametricMesh { 22 | public: 23 | 24 | class Triangles { 25 | public: 26 | 27 | Triangle generate() const; 28 | bool done() const noexcept; 29 | void next(); 30 | 31 | private: 32 | 33 | Triangles(const ParametricMesh& mesh); 34 | 35 | const ParametricMesh* mesh_; 36 | 37 | gml::ivec2 i_; 38 | 39 | bool even_; 40 | 41 | friend class ParametricMesh; 42 | }; 43 | 44 | class Vertices { 45 | public: 46 | 47 | MeshVertex generate() const; 48 | bool done() const noexcept; 49 | void next(); 50 | 51 | private: 52 | 53 | Vertices(const ParametricMesh& mesh); 54 | 55 | const ParametricMesh* mesh_; 56 | 57 | gml::ivec2 i_; 58 | 59 | friend class ParametricMesh; 60 | }; 61 | 62 | 63 | /// @param eval A callback that returns a MeshVertex for a given value. 64 | /// @param segments The number of segments along the surface. 65 | /// Both should be >= 1. If either is zero an empty mesh is generated. 66 | explicit ParametricMesh( 67 | std::function eval, 68 | const gml::ivec2& segments = {16, 16} 69 | ) noexcept; 70 | 71 | Triangles triangles() const noexcept; 72 | 73 | Vertices vertices() const noexcept; 74 | 75 | private: 76 | 77 | std::function eval_; 78 | 79 | gml::ivec2 segments_; 80 | 81 | gml::dvec2 delta_; 82 | 83 | }; 84 | 85 | 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /include/generator/ParametricPath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_PARAMETRICPATH_HPP 8 | #define GENERATOR_PARAMETRICPATH_HPP 9 | 10 | #include 11 | 12 | #include "Edge.hpp" 13 | #include "PathVertex.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | /// Path generated by evaluating callback functions at even intervals. 20 | class ParametricPath { 21 | public: 22 | 23 | class Edges { 24 | public: 25 | 26 | Edge generate() const; 27 | bool done() const noexcept; 28 | void next(); 29 | 30 | private: 31 | 32 | Edges(const ParametricPath& path); 33 | 34 | const ParametricPath* path_; 35 | 36 | int i_; 37 | 38 | 39 | friend class ParametricPath; 40 | }; 41 | 42 | class Vertices { 43 | public: 44 | 45 | PathVertex generate() const; 46 | bool done() const noexcept; 47 | void next(); 48 | 49 | private: 50 | 51 | Vertices(const ParametricPath& path); 52 | 53 | const ParametricPath* path_; 54 | 55 | int i_; 56 | 57 | friend class ParametricPath; 58 | }; 59 | 60 | 61 | /// @param eval A callback that should return a PathVertex for a given value. 62 | /// @param segments The number of segments along the path. 63 | /// Should be >= 1. Zero yields an empry path. 64 | explicit ParametricPath( 65 | std::function eval, 66 | int segments = 16 67 | ) noexcept; 68 | 69 | Edges edges() const noexcept; 70 | 71 | Vertices vertices() const noexcept; 72 | 73 | private: 74 | 75 | std::function eval_; 76 | 77 | int segments_; 78 | 79 | double delta_; 80 | 81 | }; 82 | 83 | 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/generator/ParametricShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_PARAMETRICSHAPE_HPP 8 | #define GENERATOR_PARAMETRICSHAPE_HPP 9 | 10 | #include 11 | 12 | 13 | #include "Edge.hpp" 14 | #include "ShapeVertex.hpp" 15 | 16 | namespace generator { 17 | 18 | 19 | /// A shape with values evaluated using a callback function. 20 | class ParametricShape { 21 | public: 22 | 23 | class Edges { 24 | public: 25 | 26 | Edge generate() const; 27 | bool done() const noexcept; 28 | void next(); 29 | 30 | private: 31 | 32 | Edges(const ParametricShape& shape); 33 | 34 | const ParametricShape* shape_; 35 | 36 | int i_; 37 | 38 | friend class ParametricShape; 39 | }; 40 | 41 | class Vertices { 42 | public: 43 | 44 | ShapeVertex generate() const; 45 | bool done() const noexcept; 46 | void next(); 47 | 48 | private: 49 | 50 | Vertices(const ParametricShape& shape); 51 | 52 | const ParametricShape* shape_; 53 | 54 | int i_; 55 | 56 | friend class ParametricShape; 57 | }; 58 | 59 | 60 | /// @param eval A callback that returns a ShapeVertex for a given value. 61 | /// @param segments The number of segments along the shape. 62 | /// Should be >= 1. Zero yields an empty shape. 63 | explicit ParametricShape( 64 | std::function eval, 65 | int segments = 16 66 | ) noexcept; 67 | 68 | Edges edges() const noexcept; 69 | 70 | Vertices vertices() const noexcept; 71 | 72 | private: 73 | 74 | std::function eval_; 75 | 76 | int segments_; 77 | 78 | double delta_; 79 | 80 | }; 81 | 82 | 83 | } 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /include/generator/PathVertex.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_PATHVERTEX_HPP 8 | #define GENERATOR_PATHVERTEX_HPP 9 | 10 | #include "math.hpp" 11 | 12 | namespace generator { 13 | 14 | class PathVertex { 15 | public: 16 | 17 | /// Unit length vector perpendicular to the path at this point. 18 | /// Also the x-axis of the path coordinate system at this point. 19 | gml::dvec3 normal; 20 | 21 | gml::dvec3 position; 22 | 23 | /// Unit length vector parallel to the path at this point. 24 | /// Also the z-axis of the path at this point. 25 | gml::dvec3 tangent; 26 | 27 | double texCoord; 28 | 29 | PathVertex() : 30 | normal{}, 31 | position{}, 32 | tangent{}, 33 | texCoord{} 34 | { } 35 | 36 | /// Returns tangent x normal. 37 | /// Also the y-axis of the path coordinate system. 38 | /// See: http://mathworld.wolfram.com/BinormalVector.html 39 | gml::dvec3 binormal() const noexcept { 40 | return cross(tangent, normal); 41 | } 42 | 43 | }; 44 | 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/generator/PlaneMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_PLANE_HPP 8 | #define GENERATOR_PLANE_HPP 9 | 10 | #include "ParametricMesh.hpp" 11 | 12 | namespace generator { 13 | 14 | 15 | 16 | /// A plane (rectangular grid) on the xy -plane normal pointing towards z-axis. 17 | /// @image html PlaneMesh.svg 18 | class PlaneMesh 19 | { 20 | private: 21 | 22 | using Impl = ParametricMesh; 23 | Impl parametricMesh_; 24 | 25 | public: 26 | 27 | /// @param size Half of the side length in x (0) and y (1) direction. 28 | /// @param segments Number of subdivisions in the x (0) and y (1) direction. 29 | PlaneMesh( 30 | const gml::dvec2& size = {1.0, 1.0}, 31 | const gml::ivec2& segments = {8, 8} 32 | ); 33 | 34 | using Triangles = typename Impl::Triangles; 35 | 36 | Triangles triangles() const noexcept { return parametricMesh_.triangles(); } 37 | 38 | using Vertices = typename Impl::Vertices; 39 | 40 | Vertices vertices() const noexcept { return parametricMesh_.vertices(); } 41 | 42 | }; 43 | 44 | 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/generator/RectangleShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_RECTANGLESHAPE_HPP 8 | #define GENERATOR_RECTANGLESHAPE_HPP 9 | 10 | 11 | #include "LineShape.hpp" 12 | #include "MergeShape.hpp" 13 | 14 | 15 | namespace generator { 16 | 17 | 18 | 19 | /// Rectangle centered at origin aligned along the x and y axis. 20 | /// @image html RectangleShape.svg 21 | class RectangleShape 22 | { 23 | private: 24 | 25 | using Impl = MergeShape; 26 | Impl mergeShape_; 27 | 28 | public: 29 | 30 | /// @param size Half of the length of an edge. 31 | /// @param segments Number of subdivisions per edge. 32 | RectangleShape( 33 | const gml::dvec2& size = gml::dvec2{1.0, 1.0}, 34 | const gml::ivec2& segments = gml::ivec2{8, 8} 35 | ); 36 | 37 | using Edges = typename Impl::Edges; 38 | 39 | Edges edges() const noexcept { return mergeShape_.edges(); } 40 | 41 | using Vertices = typename Impl::Vertices; 42 | 43 | Vertices vertices() const noexcept { return mergeShape_.vertices(); } 44 | 45 | }; 46 | 47 | 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /include/generator/RepeatPath.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UUID_580A4434BBE9A17A6302CC90C22DE898 2 | #define UUID_580A4434BBE9A17A6302CC90C22DE898 3 | 4 | #include "utils.hpp" 5 | #include "PathVertex.hpp" 6 | #include "Edge.hpp" 7 | 8 | namespace generator 9 | { 10 | 11 | 12 | /** 13 | * Repeats the same path a given number of time at given intervals. 14 | */ 15 | template 16 | class RepeatPath 17 | { 18 | public: 19 | 20 | class Edges 21 | { 22 | public: 23 | 24 | bool done() const noexcept 25 | { 26 | return mIndex >= mRepeatPath->mInstances; 27 | } 28 | 29 | Edge generate() const 30 | { 31 | Edge temp = mEdges.generate(); 32 | temp.vertices += mDelta; 33 | return temp; 34 | } 35 | 36 | void next() noexcept 37 | { 38 | mEdges.next(); 39 | 40 | if (mEdges.done()) { 41 | ++mIndex; 42 | mDelta += mRepeatPath->mVertexCount; 43 | mEdges = mRepeatPath->mPath.edges(); 44 | } 45 | } 46 | 47 | private: 48 | 49 | const RepeatPath* mRepeatPath; 50 | 51 | typename EdgeGeneratorType::Type mEdges; 52 | 53 | int mIndex; 54 | 55 | int mDelta; 56 | 57 | explicit Edges(const RepeatPath* repeatPath) noexcept : 58 | mRepeatPath{repeatPath}, 59 | mEdges{repeatPath->mPath.edges()}, 60 | mIndex{repeatPath->mVertexCount > 0 ? 0 : repeatPath->mInstances}, 61 | mDelta{0} 62 | { 63 | 64 | } 65 | 66 | friend class RepeatPath; 67 | }; 68 | 69 | 70 | class Vertices 71 | { 72 | public: 73 | 74 | bool done() const noexcept 75 | { 76 | return mIndex >= mRepeatPath->mInstances; 77 | } 78 | 79 | PathVertex generate() const 80 | { 81 | PathVertex temp = mVertices.generate(); 82 | temp.position += mDelta; 83 | return temp; 84 | } 85 | 86 | void next() 87 | { 88 | mVertices.next(); 89 | 90 | if (mVertices.done()) { 91 | ++mIndex; 92 | mDelta += mRepeatPath->mDelta; 93 | mVertices = mRepeatPath->mPath.vertices(); 94 | } 95 | } 96 | 97 | private: 98 | 99 | explicit Vertices(const RepeatPath* repeatPath) : 100 | mRepeatPath{repeatPath}, 101 | mVertices{repeatPath->mPath.vertices()}, 102 | mIndex{repeatPath->mVertexCount > 0 ? 0 : repeatPath->mInstances}, 103 | mDelta{} 104 | { } 105 | 106 | const RepeatPath* mRepeatPath; 107 | 108 | typename VertexGeneratorType::Type mVertices; 109 | 110 | int mIndex; 111 | 112 | gml::dvec3 mDelta; 113 | 114 | int countVertices() const noexcept 115 | { 116 | if (mRepeatPath->mInstances < 1) return 0; 117 | 118 | return 119 | mRepeatPath->mVertexCount * 120 | (mRepeatPath->mInstances - mIndex - 1) + 121 | count(mVertices); 122 | } 123 | 124 | friend 125 | int count(const Vertices& generator) noexcept 126 | { 127 | return generator.countVertices(); 128 | } 129 | 130 | friend class RepeatPath; 131 | }; 132 | 133 | 134 | /// @param path The path to repeat. 135 | /// @param instances Number of times to repeat. If <1 an empty path results. 136 | /// @param delta An offset aplied to each copy. 137 | explicit RepeatPath(Path path, int instances, const gml::dvec3& delta) noexcept : 138 | mPath{std::move(path)}, 139 | mInstances{instances}, 140 | mDelta{delta}, 141 | mVertexCount{count(mPath.vertices())} 142 | { } 143 | 144 | Edges edges() const noexcept 145 | { 146 | return Edges{this}; 147 | } 148 | 149 | Vertices vertices() const noexcept 150 | { 151 | return Vertices{this}; 152 | } 153 | 154 | private: 155 | 156 | Path mPath; 157 | 158 | int mInstances; 159 | 160 | gml::dvec3 mDelta; 161 | 162 | int mVertexCount; 163 | 164 | }; 165 | 166 | 167 | template 168 | RepeatPath repeatPath(Path path, int instances, const gml::dvec3& delta) noexcept 169 | { 170 | return RepeatPath{std::move(path), instances, delta}; 171 | } 172 | 173 | 174 | } 175 | 176 | #endif 177 | -------------------------------------------------------------------------------- /include/generator/RepeatShape.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UUID_768F8730AFFB92752C688F5439A49976 2 | #define UUID_768F8730AFFB92752C688F5439A49976 3 | 4 | #include "utils.hpp" 5 | #include "ShapeVertex.hpp" 6 | #include "Edge.hpp" 7 | 8 | namespace generator 9 | { 10 | 11 | 12 | /** 13 | * Repeats the same shape a given number of time at given intervals. 14 | */ 15 | template 16 | class RepeatShape 17 | { 18 | public: 19 | 20 | class Edges 21 | { 22 | public: 23 | 24 | bool done() const noexcept 25 | { 26 | return mIndex >= mRepeatShape->mInstances; 27 | } 28 | 29 | Edge generate() const 30 | { 31 | Edge temp = mEdges.generate(); 32 | temp.vertices += mDelta; 33 | return temp; 34 | } 35 | 36 | void next() noexcept 37 | { 38 | mEdges.next(); 39 | 40 | if (mEdges.done()) { 41 | ++mIndex; 42 | mDelta += mRepeatShape->mVertexCount; 43 | mEdges = mRepeatShape->mShape.edges(); 44 | } 45 | } 46 | 47 | private: 48 | 49 | const RepeatShape* mRepeatShape; 50 | 51 | typename EdgeGeneratorType::Type mEdges; 52 | 53 | int mIndex; 54 | 55 | int mDelta; 56 | 57 | explicit Edges(const RepeatShape* repeatShape) noexcept : 58 | mRepeatShape{repeatShape}, 59 | mEdges{repeatShape->mShape.edges()}, 60 | mIndex{repeatShape->mVertexCount > 0 ? 0 : repeatShape->mInstances}, 61 | mDelta{0} 62 | { } 63 | 64 | int countEdges() const noexcept 65 | { 66 | if (mRepeatShape->mInstances < 1) return 0; 67 | 68 | return 69 | count(mRepeatShape->mShape.edges()) * 70 | (mRepeatShape->mInstances - mIndex - 1) + 71 | count(mEdges); 72 | } 73 | 74 | friend 75 | int count(const Edges& generator) noexcept 76 | { 77 | return generator.countEdges(); 78 | } 79 | 80 | friend class RepeatShape; 81 | }; 82 | 83 | 84 | class Vertices 85 | { 86 | public: 87 | 88 | bool done() const noexcept 89 | { 90 | return mIndex >= mRepeatShape->mInstances; 91 | } 92 | 93 | ShapeVertex generate() const 94 | { 95 | ShapeVertex temp = mVertices.generate(); 96 | temp.position += mDelta; 97 | return temp; 98 | } 99 | 100 | void next() 101 | { 102 | mVertices.next(); 103 | 104 | if (mVertices.done()) { 105 | ++mIndex; 106 | mDelta += mRepeatShape->mDelta; 107 | mVertices = mRepeatShape->mShape.vertices(); 108 | } 109 | } 110 | 111 | private: 112 | 113 | explicit Vertices(const RepeatShape* repeatShape) : 114 | mRepeatShape{repeatShape}, 115 | mVertices{repeatShape->mShape.vertices()}, 116 | mIndex{repeatShape->mVertexCount > 0 ? 0 : repeatShape->mInstances}, 117 | mDelta{} 118 | { } 119 | 120 | const RepeatShape* mRepeatShape; 121 | 122 | typename VertexGeneratorType::Type mVertices; 123 | 124 | int mIndex; 125 | 126 | gml::dvec2 mDelta; 127 | 128 | int countVertices() const noexcept 129 | { 130 | if (mRepeatShape->mInstances < 1) return 0; 131 | 132 | return 133 | mRepeatShape->mVertexCount * 134 | (mRepeatShape->mInstances - mIndex - 1) + 135 | count(mVertices); 136 | } 137 | 138 | friend 139 | int count(const Vertices& generator) noexcept 140 | { 141 | return generator.countVertices(); 142 | } 143 | 144 | friend class RepeatShape; 145 | }; 146 | 147 | 148 | /// @param shape The shape to repeat. 149 | /// @param instances Number of times to repeat. If <1 an empty shape results. 150 | /// @param delta An offset aplied to each copy. 151 | explicit RepeatShape(Shape shape, int instances, const gml::dvec2& delta) noexcept : 152 | mShape{std::move(shape)}, 153 | mInstances{instances}, 154 | mDelta{delta}, 155 | mVertexCount{count(mShape.vertices())} 156 | { } 157 | 158 | Edges edges() const noexcept 159 | { 160 | return Edges{this}; 161 | } 162 | 163 | Vertices vertices() const noexcept 164 | { 165 | return Vertices{this}; 166 | } 167 | 168 | private: 169 | 170 | Shape mShape; 171 | 172 | int mInstances; 173 | 174 | gml::dvec2 mDelta; 175 | 176 | int mVertexCount; 177 | 178 | }; 179 | 180 | 181 | template 182 | RepeatShape repeatShape(Shape shape, int instances, const gml::dvec2& delta) noexcept 183 | { 184 | return RepeatShape{std::move(shape), instances, delta}; 185 | } 186 | 187 | 188 | } 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /include/generator/RotateMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ROTATEMESH_HPP 8 | #define GENERATOR_ROTATEMESH_HPP 9 | 10 | #include "Axis.hpp" 11 | #include "TransformMesh.hpp" 12 | 13 | 14 | namespace generator { 15 | 16 | 17 | /// Rotates vertices and normals. 18 | template 19 | class RotateMesh 20 | { 21 | private: 22 | 23 | using Impl = TransformMesh; 24 | Impl transformMesh_; 25 | 26 | public: 27 | 28 | /// @param mesh Source mesh data. 29 | /// @param rotation Quaternion presenting the rotation. 30 | RotateMesh(Mesh mesh, const gml::dquat& rotation) : 31 | transformMesh_{ 32 | std::move(mesh), 33 | [rotation] (MeshVertex& value) { 34 | value.position = gml::transform(rotation, value.position); 35 | value.normal = gml::transform(rotation, value.normal); 36 | } 37 | } 38 | { } 39 | 40 | /// @param mesh Source mesh data. 41 | /// @param angle Counterclockwise angle around the given axis. 42 | /// @param axis Unit length axis to rotate around. 43 | RotateMesh(Mesh mesh, double angle, const gml::dvec3& axis) : 44 | RotateMesh{std::move(mesh), gml::qrotate(angle, axis)} 45 | { } 46 | 47 | RotateMesh(Mesh mesh, double angle, Axis axis) : 48 | RotateMesh{ 49 | std::move(mesh), 50 | gml::qrotate( 51 | angle, 52 | axis == Axis::X ? 53 | gml::dvec3{1.0, 0.0, 0.0} : 54 | (axis == Axis::Y ? gml::dvec3{0.0, 1.0, 0.0} : gml::dvec3{0.0, 0.0, 1.0}) 55 | ) 56 | } 57 | { } 58 | 59 | using Triangles = typename Impl::Triangles; 60 | 61 | Triangles triangles() const noexcept { return transformMesh_.triangles(); } 62 | 63 | using Vertices = typename Impl::Vertices; 64 | 65 | Vertices vertices() const noexcept { return transformMesh_.vertices(); } 66 | 67 | }; 68 | 69 | 70 | template 71 | RotateMesh rotateMesh(Mesh mesh, const gml::dquat& rotation) { 72 | return RotateMesh{std::move(mesh), rotation}; 73 | } 74 | 75 | 76 | template 77 | RotateMesh rotateMesh(Mesh mesh, double angle, const gml::dvec3& axis) { 78 | return RotateMesh{std::move(mesh), angle, axis}; 79 | } 80 | 81 | 82 | template 83 | RotateMesh rotateMesh(Mesh mesh, double angle, Axis axis) { 84 | return RotateMesh{std::move(mesh), angle, axis}; 85 | } 86 | 87 | } 88 | 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /include/generator/RotatePath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ROTATEPATH_HPP 8 | #define GENERATOR_ROTATEPATH_HPP 9 | 10 | #include "Axis.hpp" 11 | #include "TransformPath.hpp" 12 | 13 | 14 | namespace generator { 15 | 16 | 17 | /// Rotates vertices, tangents and normals. 18 | template 19 | class RotatePath 20 | { 21 | private: 22 | 23 | using Impl = TransformPath; 24 | Impl transformPath_; 25 | 26 | public: 27 | 28 | RotatePath(Path path, const gml::dquat& rotation) : 29 | transformPath_{ 30 | std::move(path), 31 | [rotation] (PathVertex& value) { 32 | value.position = gml::transform(rotation, value.position); 33 | value.normal = gml::transform(rotation, value.normal); 34 | } 35 | } 36 | { } 37 | 38 | RotatePath(Path path, double angle, const gml::dvec3& axis) : 39 | RotatePath{std::move(path), gml::qrotate(angle, axis)} 40 | { } 41 | 42 | RotatePath(Path path, double angle, Axis axis) : 43 | RotatePath{ 44 | std::move(path), 45 | gml::qrotate( 46 | angle, 47 | axis == Axis::X ? 48 | gml::dvec3{1.0, 0.0, 0.0} : 49 | (axis == Axis::Y ? gml::dvec3{0.0, 1.0, 0.0} : gml::dvec3{0.0, 0.0, 1.0}) 50 | ) 51 | } 52 | { } 53 | 54 | using Edges = typename Impl::Edges; 55 | 56 | Edges edges() const noexcept { return transformPath_.edges(); } 57 | 58 | using Vertices = typename Impl::Vertices; 59 | 60 | Vertices vertices() const noexcept { return transformPath_.vertices(); } 61 | 62 | }; 63 | 64 | 65 | template 66 | RotatePath rotatePath(Path path, const gml::dquat& rotation) { 67 | return RotatePath{std::move(path), rotation}; 68 | } 69 | 70 | 71 | template 72 | RotatePath rotatePath(Path path, double angle, const gml::dvec3& axis) { 73 | return RotatePath{std::move(path), angle, axis}; 74 | } 75 | 76 | 77 | template 78 | RotatePath rotatePath(Path path, double angle, Axis axis) { 79 | return RotatePath{std::move(path), angle, axis}; 80 | } 81 | 82 | 83 | } 84 | 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/generator/RotateShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ROTATESHAPE_HPP 8 | #define GENERATOR_ROTATESHAPE_HPP 9 | 10 | #include "TransformShape.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// Rotates a shape around the origin on the xy-plane. 17 | template 18 | class RotateShape 19 | { 20 | private: 21 | 22 | using Impl = TransformShape; 23 | Impl transformShape_; 24 | 25 | public: 26 | 27 | /// @param shape Source data shape. 28 | /// @param angle Counterclockwise angle. 29 | RotateShape(Shape shape, double angle) : 30 | transformShape_{ 31 | std::move(shape), 32 | [angle] (ShapeVertex& value) { 33 | auto rotation = gml::rotate(angle); 34 | value.position = gml::transform(rotation, value.position); 35 | value.tangent = gml::transform(rotation, value.tangent); 36 | } 37 | } 38 | { } 39 | 40 | using Edges = typename Impl::Edges; 41 | 42 | Edges edges() const noexcept { return transformShape_.edges(); } 43 | 44 | using Vertices = typename Impl::Vertices; 45 | 46 | Vertices vertices() const noexcept { return transformShape_.vertices(); } 47 | 48 | }; 49 | 50 | 51 | template 52 | RotateShape rotateShape(Shape shape, double angle) { 53 | return RotateShape{std::move(shape), angle}; 54 | } 55 | 56 | } 57 | 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/generator/RoundedRectangleShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_ROUNDEDRECTANGLESHAPE_HPP 8 | #define GENERATOR_ROUNDEDRECTANGLESHAPE_HPP 9 | 10 | #include "CircleShape.hpp" 11 | #include "LineShape.hpp" 12 | #include "MergeShape.hpp" 13 | #include "TranslateShape.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | 20 | /// Rectangle with rounded corners centered at origin aligned along the x and y axis. 21 | class RoundedRectangleShape 22 | { 23 | private: 24 | 25 | using Impl = MergeShape< 26 | LineShape, TranslateShape, 27 | LineShape, TranslateShape, 28 | LineShape, TranslateShape, 29 | LineShape, TranslateShape 30 | >; 31 | Impl mergeShape_; 32 | 33 | public: 34 | 35 | /// @param radius Radius of the rounded corners. 36 | /// @param size Half of a length of an edge. 37 | /// @param slices Number of subdivisions in each rounded corner. 38 | /// @param segments Number of subdivisions along each edge. 39 | RoundedRectangleShape( 40 | double radius = 0.25, 41 | const gml::dvec2& size = {0.75, 0.75}, 42 | int slices = 4, 43 | const gml::ivec2& segments = {8, 8} 44 | ); 45 | 46 | using Edges = typename Impl::Edges; 47 | 48 | Edges edges() const noexcept { return mergeShape_.edges(); } 49 | 50 | using Vertices = typename Impl::Vertices; 51 | 52 | Vertices vertices() const noexcept { return mergeShape_.vertices(); } 53 | 54 | }; 55 | 56 | 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/generator/ScaleMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SCALEMESH_HPP 8 | #define GENERATOR_SCALEMESH_HPP 9 | 10 | #include "TransformMesh.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// Scales a mesh (keeps normals unit length) 17 | template 18 | class ScaleMesh 19 | { 20 | private: 21 | 22 | using Impl = TransformMesh; 23 | Impl transformMesh_; 24 | 25 | public: 26 | 27 | /// @param mesh Source data mesh. 28 | /// @param scale Scale factors. Must not be zero! 29 | ScaleMesh(Mesh mesh, const gml::dvec3& scale) : 30 | transformMesh_{ 31 | std::move(mesh), 32 | [scale] (MeshVertex& value) { 33 | value.position *= scale; 34 | value.normal = normalize(scale * value.normal); 35 | } 36 | } 37 | { } 38 | 39 | using Triangles = typename Impl::Triangles; 40 | 41 | Triangles triangles() const noexcept { return transformMesh_.triangles(); } 42 | 43 | using Vertices = typename Impl::Vertices; 44 | 45 | Vertices vertices() const noexcept { return transformMesh_.vertices(); } 46 | 47 | }; 48 | 49 | 50 | template 51 | ScaleMesh scaleMesh(Mesh mesh, const gml::dvec3& delta) { 52 | return ScaleMesh{std::move(mesh), delta}; 53 | } 54 | 55 | } 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /include/generator/ScalePath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SCALEPATH_HPP 8 | #define GENERATOR_SCALEPATH_HPP 9 | 10 | #include "TransformPath.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// Scales a path. Keeps tangents and normals unit length. 17 | template 18 | class ScalePath 19 | { 20 | private: 21 | 22 | using Impl = TransformPath; 23 | Impl transformPath_; 24 | 25 | public: 26 | 27 | /// @param path Source data path. 28 | /// @param scale Scale Factor. Must not have zero components! 29 | ScalePath(Path path, const gml::dvec3& scale) : 30 | transformPath_{ 31 | std::move(path), 32 | [scale] (PathVertex& value) { 33 | value.position *= scale; 34 | value.tangent = gml::normalize(scale * value.tangent); 35 | value.normal = gml::normalize(scale * value.normal); 36 | } 37 | } 38 | { } 39 | 40 | using Edges = typename Impl::Edges; 41 | 42 | Edges edges() const noexcept { return transformPath_.edges(); } 43 | 44 | using Vertices = typename Impl::Vertices; 45 | 46 | Vertices vertices() const noexcept { return transformPath_.vertices(); } 47 | 48 | }; 49 | 50 | 51 | template 52 | ScalePath scalePath(Path path, const gml::dvec3& scale) { 53 | return ScalePath{std::move(path), scale}; 54 | } 55 | 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/generator/ScaleShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SCALESHAPE_HPP 8 | #define GENERATOR_SCALESHAPE_HPP 9 | 10 | #include "TransformShape.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// Scales a shape keeping tangents unit length. 17 | template 18 | class ScaleShape 19 | { 20 | private: 21 | 22 | using Impl = TransformShape; 23 | Impl transformShape_; 24 | 25 | public: 26 | 27 | /// @param shape Source data shape. 28 | /// @param scale Scale factor. 29 | ScaleShape(Shape shape, const gml::dvec2& scale) : 30 | transformShape_{ 31 | std::move(shape), 32 | [scale] (ShapeVertex& value) { 33 | value.position *= scale; 34 | value.tangent = normalize(scale * value.tangent); 35 | } 36 | } 37 | { } 38 | 39 | using Edges = typename Impl::Edges; 40 | 41 | Edges edges() const noexcept { return transformShape_.edges(); } 42 | 43 | using Vertices = typename Impl::Vertices; 44 | 45 | Vertices vertices() const noexcept { return transformShape_.vertices(); } 46 | 47 | }; 48 | 49 | 50 | template 51 | ScaleShape scaleShape(Shape shape, const gml::dvec2& scale) { 52 | return ScaleShape{std::move(shape), scale}; 53 | } 54 | 55 | } 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /include/generator/ShapeToPath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SHAPETOPATH_HPP 8 | #define GENERATOR_SHAPETOPATH_HPP 9 | 10 | 11 | #include "PathVertex.hpp" 12 | #include "ShapeVertex.hpp" 13 | #include "utils.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | 20 | /// Converts a Shape to a Path. 21 | /// The shape position coordinates are used as the x and y and 0 is used as z. 22 | /// Shape tangent becomes the path tangent and z-axis becomes normal vector and 23 | /// thus the shape normal becomes the path binormal. 24 | template 25 | class ShapeToPath 26 | { 27 | private: 28 | 29 | using Impl = Shape; 30 | Impl shape_; 31 | 32 | public: 33 | 34 | class Vertices { 35 | public: 36 | 37 | PathVertex generate() const { 38 | 39 | ShapeVertex shapeVertex = vertices_.generate(); 40 | 41 | PathVertex vertex; 42 | 43 | vertex.position = gml::dvec3(shapeVertex.position, 0.0); 44 | 45 | vertex.tangent = gml::dvec3(shapeVertex.tangent, 0.0); 46 | vertex.normal = gml::dvec3{0.0, 0.0, 1.0}; 47 | 48 | vertex.texCoord = shapeVertex.texCoord; 49 | 50 | return vertex; 51 | } 52 | 53 | bool done() const noexcept { return vertices_.done(); } 54 | 55 | void next() { vertices_.next(); } 56 | 57 | private: 58 | 59 | typename VertexGeneratorType::Type vertices_; 60 | 61 | Vertices(const Shape& shape) : 62 | vertices_{shape.vertices()} 63 | { } 64 | 65 | friend class ShapeToPath; 66 | }; 67 | 68 | ShapeToPath(Shape shape) : 69 | shape_{std::move(shape)} 70 | { } 71 | 72 | using Edges = typename Impl::Edges; 73 | 74 | Edges edges() const noexcept { return shape_.edges(); } 75 | 76 | Vertices vertices() const { return *this; } 77 | 78 | }; 79 | 80 | 81 | 82 | template 83 | ShapeToPath shapeToPath(Shape shape) { 84 | return ShapeToPath{std::move(shape)}; 85 | } 86 | 87 | 88 | } 89 | 90 | 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /include/generator/ShapeVertex.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SHAPEGENERATOR_HPP 8 | #define GENERATOR_SHAPEGENERATOR_HPP 9 | 10 | #include "math.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// A point on a path. 17 | /// Position and assosiated coordinate system. 18 | class ShapeVertex { 19 | public: 20 | 21 | gml::dvec2 position; 22 | 23 | /// Unit length vector parallel to the shape at this point. 24 | /// Also the y-axis of the shape's local coordinate system. 25 | gml::dvec2 tangent; 26 | 27 | double texCoord; 28 | 29 | ShapeVertex() : 30 | position{}, 31 | tangent{}, 32 | texCoord{} 33 | { } 34 | 35 | /// Returns the tangent rotated 90 dec clockwise. 36 | /// Also the x-axis of the shape's local coordinate system. 37 | gml::dvec2 normal() const noexcept { 38 | return -gml::cross(tangent); 39 | } 40 | 41 | }; 42 | 43 | 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/generator/SphereMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SPHERE_HPP 8 | #define GENERATOR_SPHERE_HPP 9 | 10 | #include "AxisSwapMesh.hpp" 11 | #include "CircleShape.hpp" 12 | #include "LatheMesh.hpp" 13 | #include "UvFlipMesh.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | 20 | /// A sphere of the given radius centered around the origin. 21 | /// Subdivided around the z-axis in slices and along the z-axis in segments. 22 | /// @image html SphereMesh.svg 23 | class SphereMesh 24 | { 25 | private: 26 | 27 | using Impl = AxisSwapMesh>; 28 | Impl axisSwapMesh_; 29 | 30 | public: 31 | 32 | /// @param radius The radius of the sphere 33 | /// @param slices Subdivisions around the z-azis (longitudes). 34 | /// @param segments Subdivisions along the z-azis (latitudes). 35 | /// @param sliceStart Counterclockwise angle around the z-axis relative to x-axis. 36 | /// @param sliceSweep Counterclockwise angle. 37 | /// @param segmentStart Counterclockwise angle relative to the z-axis. 38 | /// @param segmentSweep Counterclockwise angle. 39 | SphereMesh( 40 | double radius = 1.0, 41 | int slices = 32, 42 | int segments = 16, 43 | double sliceStart = 0.0, 44 | double sliceSweep = gml::radians(360.0), 45 | double segmentStart = 0.0, 46 | double segmentSweep = gml::radians(180.0) 47 | ); 48 | 49 | using Triangles = typename Impl::Triangles; 50 | 51 | Triangles triangles() const noexcept { return axisSwapMesh_.triangles(); } 52 | 53 | using Vertices = typename Impl::Vertices; 54 | 55 | Vertices vertices() const noexcept { return axisSwapMesh_.vertices(); } 56 | 57 | }; 58 | 59 | } 60 | 61 | #endif 62 | 63 | 64 | -------------------------------------------------------------------------------- /include/generator/SphericalConeMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SPHERICALCONEMESH_HPP 8 | #define GENERATOR_SPHERICALCONEMESH_HPP 9 | 10 | 11 | #include "AxisFlipMesh.hpp" 12 | #include "ConeMesh.hpp" 13 | #include "MergeMesh.hpp" 14 | #include "SphereMesh.hpp" 15 | #include "TranslateMesh.hpp" 16 | 17 | 18 | namespace generator { 19 | 20 | 21 | /// A cone with a spherical cap centered at origin tip pointing towards z-axis. 22 | /// Each point on the cap has equal distance from the tip. 23 | /// @image html SphericalConeMesh.svg 24 | class SphericalConeMesh 25 | { 26 | private: 27 | 28 | using Impl = TranslateMesh>>>; 29 | Impl translateMesh_; 30 | 31 | public: 32 | 33 | /// @param radius Radius of the negative z end on the xy-plane. 34 | /// @param size Half of the distance between cap and tip along the z-axis. 35 | /// @param slices Number of subdivisions around the z-axis. 36 | /// @param segments Number subdivisions along the z-axis. 37 | /// @param rings Number subdivisions in the cap. 38 | /// @param start Counterclockwise angle around the z-axis relative to the positive x-axis. 39 | /// @param sweep Counterclockwise angle around the z-axis. 40 | SphericalConeMesh( 41 | double radius = 1.0, 42 | double size = 1.0, 43 | int slices = 32, 44 | int segments = 8, 45 | int rings = 4, 46 | double start = 0.0, 47 | double sweep = gml::radians(360.0) 48 | ); 49 | 50 | using Triangles = typename Impl::Triangles; 51 | 52 | Triangles triangles() const noexcept { return translateMesh_.triangles(); } 53 | 54 | using Vertices = typename Impl::Vertices; 55 | 56 | Vertices vertices() const noexcept { return translateMesh_.vertices(); } 57 | 58 | }; 59 | 60 | 61 | } 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /include/generator/SphericalTriangleMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SPHERICALTRIANGLEMESH_HPP 8 | #define GENERATOR_SPHERICALTRIANGLEMESH_HPP 9 | 10 | #include "math.hpp" 11 | 12 | #include "MeshVertex.hpp" 13 | #include "Triangle.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | /// A triangular region on a surface of a sphere. 20 | /// @image html SphericalTriangleMesh.svg 21 | class SphericalTriangleMesh 22 | { 23 | public: 24 | 25 | class Triangles { 26 | public: 27 | 28 | bool done() const noexcept; 29 | 30 | Triangle generate() const; 31 | 32 | void next(); 33 | 34 | private: 35 | 36 | const SphericalTriangleMesh* mesh_; 37 | int row_; 38 | int col_; 39 | int i_; 40 | 41 | Triangles(const SphericalTriangleMesh& mesh); 42 | 43 | friend class SphericalTriangleMesh; 44 | }; 45 | 46 | class Vertices { 47 | public: 48 | 49 | bool done() const noexcept; 50 | 51 | MeshVertex generate() const; 52 | 53 | void next(); 54 | 55 | private: 56 | 57 | const SphericalTriangleMesh* mesh_; 58 | int row_; 59 | int col_; 60 | 61 | Vertices(const SphericalTriangleMesh& mesh); 62 | 63 | friend class SphericalTriangleMesh; 64 | }; 65 | 66 | /// @param radius Radius of the containing sphere. 67 | /// @param segments Number of subdivisions along each edge. 68 | SphericalTriangleMesh( 69 | double radius = 1.0, 70 | int segments = 4 71 | ); 72 | 73 | /// @param segments Number of subdivisions along each edge. 74 | SphericalTriangleMesh( 75 | const gml::dvec3& v0, const gml::dvec3& v1, const gml::dvec3& v2, 76 | int segments = 4 77 | ); 78 | 79 | Triangles triangles() const noexcept; 80 | 81 | Vertices vertices() const noexcept; 82 | 83 | private: 84 | 85 | gml::dvec3 v0_, v1_, v2_; 86 | 87 | gml::dvec3 normal_; 88 | 89 | int segments_; 90 | 91 | }; 92 | 93 | 94 | } 95 | 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /include/generator/SpherifyMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef SPHERIFYMESH_HPP 8 | #define SPHERIFYMESH_HPP 9 | 10 | #include "TransformMesh.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// Projects vertices on a sphere centered at origin. 17 | template 18 | class SpherifyMesh 19 | { 20 | private: 21 | 22 | using Impl = TransformMesh; 23 | Impl transformMesh_; 24 | 25 | public: 26 | 27 | SpherifyMesh(Mesh mesh, double radius, double factor) : 28 | transformMesh_{ 29 | std::move(mesh), 30 | [radius, factor] (MeshVertex& value) { 31 | value.position = gml::mix( 32 | value.position, 33 | radius * gml::normalize(value.position), 34 | factor 35 | ); 36 | value.normal = gml::normalize(gml::mix( 37 | value.normal, 38 | gml::normalize(value.position), 39 | factor 40 | )); 41 | } 42 | } 43 | { } 44 | 45 | using Triangles = typename Impl::Triangles; 46 | 47 | Triangles triangles() const noexcept { return transformMesh_.triangles(); } 48 | 49 | using Vertices = typename Impl::Vertices; 50 | 51 | Vertices vertices() const noexcept { return transformMesh_.vertices(); } 52 | 53 | }; 54 | 55 | 56 | template 57 | SpherifyMesh spherifyMesh(Mesh mesh, double radius, double factor) { 58 | return SpherifyMesh{std::move(mesh), radius, factor}; 59 | } 60 | 61 | } 62 | 63 | #endif 64 | 65 | -------------------------------------------------------------------------------- /include/generator/SpringMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SPRINGMESH_HPP 8 | #define GENERATOR_SPRINGMESH_HPP 9 | 10 | #include "CircleShape.hpp" 11 | #include "ExtrudeMesh.hpp" 12 | #include "HelixPath.hpp" 13 | 14 | namespace generator { 15 | 16 | 17 | /// A spring aligned along the z-axis winding counterclockwise 18 | /// @image html SpringMesh.svg 19 | class SpringMesh 20 | { 21 | private: 22 | 23 | using Impl = ExtrudeMesh; 24 | Impl extrudeMesh_; 25 | 26 | public: 27 | 28 | /// @param minor Radius of the spring it self. 29 | /// @param major Radius from the z-axis 30 | /// @param size Half of the length along the z-axis. 31 | /// @param slices Subdivisions around the spring. 32 | /// @param segments Subdivisions along the path. 33 | /// @param majorStart Counterclockwise angle around the z-axis relative to the x-axis. 34 | /// @param majorSweep Counterclockwise angle arounf the z-axis. 35 | SpringMesh( 36 | double minor = 0.25, 37 | double major = 1.0, 38 | double size = 1.0, 39 | int slices = 8, 40 | int segments = 32, 41 | double minorStart = 0.0, 42 | double minorSweep = gml::radians(360.0), 43 | double majorStart = 0.0, 44 | double majorSweep = gml::radians(720.0) 45 | ); 46 | 47 | using Triangles = typename Impl::Triangles; 48 | 49 | Triangles triangles() const noexcept { return extrudeMesh_.triangles(); } 50 | 51 | using Vertices = typename Impl::Vertices; 52 | 53 | Vertices vertices() const noexcept { return extrudeMesh_.vertices(); } 54 | 55 | }; 56 | 57 | } 58 | 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /include/generator/SubdividePath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SUBDIVIDEPATH_HPP 8 | #define GENERATOR_SUBDIVIDEPATH_HPP 9 | 10 | #include "Edge.hpp" 11 | #include "PathVertex.hpp" 12 | #include "utils.hpp" 13 | #include "ShapeVertex.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | template 20 | class SubdividePath { 21 | public: 22 | 23 | class Edges { 24 | public: 25 | 26 | bool done() const noexcept { return edges_.done(); } 27 | 28 | Edge generate() const { 29 | Edge edge_ = edges_.generate(); 30 | 31 | if (i_ % 2 == 0) return Edge{{ 32 | edge_.vertices[0], 33 | static_cast(path_->vertexCache_.size()) + i_ / 2 34 | }}; 35 | 36 | return Edge{{ 37 | static_cast(path_->vertexCache_.size()) + i_ / 2, 38 | edge_.vertices[1] 39 | }}; 40 | } 41 | 42 | void next() { 43 | ++i_; 44 | if (i_ % 2 == 0) edges_.next(); 45 | } 46 | 47 | private: 48 | 49 | const SubdividePath* path_; 50 | 51 | typename EdgeGeneratorType::Type edges_; 52 | 53 | int i_; 54 | 55 | Edges(const SubdividePath& path) : 56 | path_{&path}, 57 | edges_{path.path_.edges()}, 58 | i_{0} 59 | { } 60 | 61 | friend class SubdividePath; 62 | }; 63 | 64 | 65 | class Vertices { 66 | public: 67 | 68 | bool done() const noexcept { 69 | return vertexIndex_ == path_->vertexCache_.size() && edges_.done(); 70 | } 71 | 72 | PathVertex generate() const { 73 | if (vertexIndex_ < path_->vertexCache_.size()) 74 | return path_->vertexCache_[vertexIndex_]; 75 | 76 | const Edge edge = edges_.generate(); 77 | const PathVertex& v1 = path_->vertexCache_[edge.vertices[0]]; 78 | const PathVertex& v2 = path_->vertexCache_[edge.vertices[1]]; 79 | 80 | PathVertex vertex; 81 | vertex.position = gml::mix(v1.position, v2.position, 0.5); 82 | vertex.tangent = gml::normalize(gml::mix(v1.tangent, v2.tangent, 0.5)); 83 | vertex.normal = gml::normalize(gml::mix(v1.normal, v2.normal, 0.5)); 84 | vertex.texCoord = 0.5 * v1.texCoord + 0.5 * v2.texCoord; 85 | return vertex; 86 | } 87 | 88 | void next() { 89 | if (vertexIndex_ < path_->vertexCache_.size()) ++vertexIndex_; 90 | else edges_.next(); 91 | } 92 | 93 | private: 94 | 95 | const SubdividePath* path_; 96 | 97 | int vertexIndex_; 98 | 99 | typename EdgeGeneratorType::Type edges_; 100 | 101 | Vertices(const SubdividePath& path) : 102 | path_{&path}, 103 | vertexIndex_{0}, 104 | edges_{path.path_.edges()} 105 | { } 106 | 107 | friend class SubdividePath; 108 | }; 109 | 110 | 111 | SubdividePath(Path path) : 112 | path_(std::move(path)), 113 | vertexCache_{} 114 | { 115 | for (const PathVertex& vertex : path_.vertices()) { 116 | vertexCache_.push_back(vertex); 117 | } 118 | } 119 | 120 | Edges edges() const { return *this; } 121 | 122 | Vertices vertices() const { return *this; } 123 | 124 | private: 125 | 126 | Path path_; 127 | 128 | std::vector vertexCache_; 129 | 130 | }; 131 | 132 | 133 | template 134 | SubdividePath subdividePath(Path path) { 135 | return SubdividePath{std::move(path)}; 136 | } 137 | 138 | 139 | } 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /include/generator/SubdivideShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SUBDIVIDESHAPE_HPP 8 | #define GENERATOR_SUBDIVIDESHAPE_HPP 9 | 10 | #include "Edge.hpp" 11 | #include "ShapeVertex.hpp" 12 | #include "utils.hpp" 13 | 14 | 15 | namespace generator { 16 | 17 | 18 | /// Cuts each edge in half 19 | template 20 | class SubdivideShape { 21 | public: 22 | 23 | class Edges { 24 | public: 25 | 26 | bool done() const noexcept { return edges_.done(); } 27 | 28 | Edge generate() const { 29 | Edge edge_ = edges_.generate(); 30 | 31 | if (i_ % 2 == 0) return Edge{ 32 | edge_.vertices[0], 33 | static_cast(shape_->vertexCache_.size()) + i_ / 2 34 | }; 35 | 36 | return Edge{ 37 | static_cast(shape_->vertexCache_.size()) + i_ / 2, 38 | edge_.vertices[1] 39 | }; 40 | } 41 | 42 | void next() { 43 | ++i_; 44 | if (i_ % 2 == 0) edges_.next(); 45 | } 46 | 47 | private: 48 | 49 | const SubdivideShape* shape_; 50 | 51 | typename EdgeGeneratorType::Type edges_; 52 | 53 | int i_; 54 | 55 | Edges(const SubdivideShape& shape) : 56 | shape_{&shape}, 57 | edges_{shape.shape_.edges()}, 58 | i_{0} 59 | { } 60 | 61 | friend class SubdivideShape; 62 | }; 63 | 64 | 65 | class Vertices { 66 | public: 67 | 68 | bool done() const noexcept { 69 | return vertexIndex_ == shape_->vertexCache_.size() && edges_.done(); 70 | } 71 | 72 | ShapeVertex generate() const { 73 | if (vertexIndex_ < shape_->vertexCache_.size()) 74 | return shape_->vertexCache_[vertexIndex_]; 75 | 76 | const Edge edge = edges_.generate(); 77 | const ShapeVertex& v1 = shape_->vertexCache_[edge.vertices[0]]; 78 | const ShapeVertex& v2 = shape_->vertexCache_[edge.vertices[1]]; 79 | 80 | ShapeVertex vertex; 81 | vertex.position = gml::mix(v1.position, v2.position, 0.5); 82 | vertex.tangent = gml::normalize(gml::mix(v1.tangent, v2.tangent, 0.5)); 83 | vertex.texCoord = 0.5 * v1.texCoord + 0.5 * v2.texCoord; 84 | return vertex; 85 | } 86 | 87 | void next() { 88 | if (vertexIndex_ < shape_->vertexCache_.size()) ++vertexIndex_; 89 | else edges_.next(); 90 | } 91 | 92 | private: 93 | 94 | const SubdivideShape* shape_; 95 | 96 | int vertexIndex_; 97 | 98 | typename EdgeGeneratorType::Type edges_; 99 | 100 | Vertices(const SubdivideShape& shape) : 101 | shape_{&shape}, 102 | vertexIndex_{0}, 103 | edges_{shape.shape_.edges()} 104 | { } 105 | 106 | friend class SubdivideShape; 107 | }; 108 | 109 | 110 | SubdivideShape(Shape shape) : 111 | shape_(std::move(shape)), 112 | vertexCache_{} 113 | { 114 | for (const ShapeVertex& vertex : shape_.vertices()) { 115 | vertexCache_.push_back(vertex); 116 | } 117 | } 118 | 119 | Edges edges() const noexcept { return *this; } 120 | 121 | Vertices vertices() const noexcept { return *this; } 122 | 123 | private: 124 | 125 | Shape shape_; 126 | 127 | std::vector vertexCache_; 128 | 129 | }; 130 | 131 | 132 | } 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /include/generator/TeapotMesh.hpp: -------------------------------------------------------------------------------- 1 | // This library is free software; you can redistribute it and/or 2 | // modify it under the terms of the GNU Lesser General Public 3 | // License as published by the Free Software Foundation; either 4 | // version 2.1 of the License, or (at your option) any later version. 5 | 6 | #ifndef UUID_88C28B4C2B304C399A34364D99D2EC26 7 | #define UUID_88C28B4C2B304C399A34364D99D2EC26 8 | 9 | #include 10 | #include 11 | 12 | 13 | #include "Triangle.hpp" 14 | #include "MeshVertex.hpp" 15 | #include "BezierMesh.hpp" 16 | #include "utils.hpp" 17 | 18 | 19 | namespace generator { 20 | 21 | 22 | /// The Utah Teapot. 23 | /// https://en.wikipedia.org/wiki/Utah_teapot 24 | /// @image html TeapotMesh.svg 25 | class TeapotMesh { 26 | public: 27 | 28 | class Triangles { 29 | public: 30 | 31 | bool done() const noexcept; 32 | Triangle generate() const; 33 | void next(); 34 | 35 | private: 36 | 37 | const TeapotMesh* mMesh; 38 | 39 | int mIndex; 40 | 41 | std::shared_ptr> mPatchMesh; 42 | 43 | typename TriangleGeneratorType>::Type mTriangles; 44 | 45 | explicit Triangles(const TeapotMesh& mesh) noexcept; 46 | 47 | friend class TeapotMesh; 48 | }; 49 | 50 | 51 | class Vertices { 52 | public: 53 | 54 | bool done() const noexcept; 55 | MeshVertex generate() const; 56 | void next(); 57 | 58 | private: 59 | 60 | const TeapotMesh* mMesh; 61 | 62 | int mIndex; 63 | 64 | // Needs be a shared_ptr in order to make copy/move not to mess up the 65 | // internal pointer in mTriangles. 66 | std::shared_ptr> mPatchMesh; 67 | 68 | typename VertexGeneratorType>::Type mVertices; 69 | 70 | explicit Vertices(const TeapotMesh& mesh) noexcept; 71 | 72 | friend class TeapotMesh; 73 | }; 74 | 75 | 76 | /// Generates the Utah teapot using the original data. 77 | /// The lid is pointing towards the z axis and the spout towards the x axis. 78 | /// @param segments The number segments along each patch. Should be >= 1. 79 | /// If zero empty mesh is generated. 80 | explicit TeapotMesh(int segments = 8) noexcept; 81 | 82 | Triangles triangles() const noexcept; 83 | 84 | Vertices vertices() const noexcept; 85 | 86 | private: 87 | 88 | int mSegments; 89 | 90 | int mPatchVertexCount; 91 | 92 | }; 93 | 94 | } 95 | 96 | #endif 97 | 98 | -------------------------------------------------------------------------------- /include/generator/TorusKnotMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TORUSKNOTMESH_HPP 8 | #define GENERATOR_TORUSKNOTMESH_HPP 9 | 10 | #include "CircleShape.hpp" 11 | #include "ExtrudeMesh.hpp" 12 | #include "KnotPath.hpp" 13 | 14 | namespace generator { 15 | 16 | 17 | /// A Circle extruded along a knot path. 18 | /// @image html TorusKnotMesh.svg 19 | class TorusKnotMesh 20 | { 21 | private: 22 | 23 | using Impl = ExtrudeMesh; 24 | Impl extrudeMesh_; 25 | 26 | public: 27 | 28 | /// @param slices Number subdivisions around the circle. 29 | /// @param segments Number of subdivisions around the path. 30 | TorusKnotMesh( 31 | int p = 2, 32 | int q = 3, 33 | int slices = 8, 34 | int segments = 96 35 | ); 36 | 37 | using Triangles = typename Impl::Triangles; 38 | 39 | Triangles triangles() const noexcept { return extrudeMesh_.triangles(); } 40 | 41 | using Vertices = typename Impl::Vertices; 42 | 43 | Vertices vertices() const noexcept { return extrudeMesh_.vertices(); } 44 | 45 | }; 46 | 47 | } 48 | 49 | 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /include/generator/TorusMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TORUS_HPP 8 | #define GENERATOR_TORUS_HPP 9 | 10 | #include "AxisSwapMesh.hpp" 11 | #include "CircleShape.hpp" 12 | #include "LatheMesh.hpp" 13 | #include "TranslateShape.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | /// Torus centered at origin on the xy-plane. 20 | /// @image html TorusMesh.svg 21 | class TorusMesh 22 | { 23 | private: 24 | 25 | using Impl = AxisSwapMesh>>; 26 | Impl axisSwapMesh_; 27 | 28 | public: 29 | 30 | /// @param minor Radius of the minor (inner) ring 31 | /// @param major Radius of the major (outer) ring 32 | /// @param slices Subdivisions around the minor ring 33 | /// @param segments Subdivisions around the major ring 34 | /// @param minorStart Counterclockwise angle relative to the xy-plane. 35 | /// @param minorSweep Counterclockwise angle around the circle. 36 | /// @param majorStart Counterclockwise angle around the z-axis relative to the x-axis. 37 | /// @param majorSweep Counterclockwise angle around the z-axis. 38 | TorusMesh( 39 | double minor = 0.25, 40 | double major = 1.0, 41 | int slices = 16, 42 | int segments = 32, 43 | double minorStart = 0.0, 44 | double minorSweep = gml::radians(360.0), 45 | double majorStart = 0.0, 46 | double majorSweep = gml::radians(360.0) 47 | ); 48 | 49 | using Triangles = typename Impl::Triangles; 50 | 51 | Triangles triangles() const noexcept { return axisSwapMesh_.triangles(); } 52 | 53 | using Vertices = typename Impl::Vertices; 54 | 55 | Vertices vertices() const noexcept { return axisSwapMesh_.vertices(); } 56 | 57 | }; 58 | 59 | 60 | } 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /include/generator/TransformMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TRANSLATOR_HPP 8 | #define GENERATOR_TRANSLATOR_HPP 9 | 10 | #include 11 | 12 | #include "MeshVertex.hpp" 13 | #include "utils.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | /// Apply a mutator function to each vertex. 20 | template 21 | class TransformMesh 22 | { 23 | private: 24 | 25 | using Impl = Mesh; 26 | Impl mesh_; 27 | 28 | public: 29 | 30 | class Vertices { 31 | public: 32 | 33 | MeshVertex generate() const { 34 | auto vertex = vertices_.generate(); 35 | mesh_->mutate_(vertex); 36 | return vertex; 37 | } 38 | 39 | bool done() const noexcept { return vertices_.done(); } 40 | 41 | void next() { vertices_.next(); } 42 | 43 | private: 44 | 45 | const TransformMesh* mesh_; 46 | 47 | typename VertexGeneratorType::Type vertices_; 48 | 49 | explicit Vertices(const TransformMesh& mesh) : 50 | mesh_{&mesh}, 51 | vertices_{mesh.mesh_.vertices()} 52 | { } 53 | 54 | friend class TransformMesh; 55 | }; 56 | 57 | /// @param mesh Source data mesh. 58 | /// @param mutate Callback function that gets called once per vertex. 59 | explicit TransformMesh(Mesh mesh, std::function mutate) : 60 | mesh_{std::move(mesh)}, 61 | mutate_{std::move(mutate)} 62 | { } 63 | 64 | using Triangles = typename Impl::Triangles; 65 | 66 | Triangles triangles() const noexcept { return mesh_.triangles(); } 67 | 68 | Vertices vertices() const noexcept { return Vertices{*this}; } 69 | 70 | private: 71 | 72 | std::function mutate_; 73 | 74 | }; 75 | 76 | 77 | template 78 | TransformMesh transformMesh( 79 | Mesh mesh, std::function mutate 80 | ) { 81 | return TransformMesh{std::move(mesh), std::move(mutate)}; 82 | } 83 | 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/generator/TransformPath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TRANSFORMPATH_HPP 8 | #define GENERATOR_TRANSFORMPATH_HPP 9 | 10 | #include 11 | 12 | #include "PathVertex.hpp" 13 | #include "utils.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | /// Apply a mutator function to each vertex. 20 | template 21 | class TransformPath 22 | { 23 | private: 24 | 25 | using Impl = Path; 26 | Impl path_; 27 | 28 | public: 29 | 30 | class Vertices { 31 | public: 32 | 33 | PathVertex generate() const { 34 | auto vertex = vertices_.generate(); 35 | path_->mutate_(vertex); 36 | return vertex; 37 | } 38 | 39 | bool done() const noexcept { return vertices_.done(); } 40 | 41 | void next() { vertices_.next(); } 42 | 43 | private: 44 | 45 | Vertices(const TransformPath& path) : 46 | path_{&path}, 47 | vertices_{path.path_.vertices()} 48 | { } 49 | 50 | const TransformPath* path_; 51 | 52 | typename VertexGeneratorType::Type vertices_; 53 | 54 | friend class TransformPath; 55 | }; 56 | 57 | /// @param path Source data path. 58 | /// @param mutate Callback function that gets called once per vertex. 59 | TransformPath(Path path, std::function mutate) : 60 | path_{std::move(path)}, 61 | mutate_{mutate} 62 | { } 63 | 64 | Vertices vertices() const noexcept { return*this; } 65 | 66 | using Edges = typename Impl::Edges; 67 | 68 | Edges edges() const noexcept { return path_.edges(); } 69 | 70 | private: 71 | 72 | std::function mutate_; 73 | 74 | }; 75 | 76 | 77 | template 78 | TransformPath transformPath( 79 | Path path, std::function mutate 80 | ) { 81 | return TransformPath{std::move(path), std::move(mutate)}; 82 | } 83 | 84 | 85 | } 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /include/generator/TransformShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_SHAPETRANSLATOR_HPP 8 | #define GENERATOR_SHAPETRANSLATOR_HPP 9 | 10 | #include "ShapeVertex.hpp" 11 | #include "utils.hpp" 12 | 13 | namespace generator { 14 | 15 | 16 | 17 | /// Apply a mutator function to each vertex. 18 | template 19 | class TransformShape 20 | { 21 | private: 22 | 23 | using Impl = Shape; 24 | Impl shape_; 25 | 26 | public: 27 | 28 | class Vertices { 29 | public: 30 | 31 | ShapeVertex generate() const { 32 | auto temp = vertices_.generate(); 33 | shape_->mutate_(temp); 34 | return temp; 35 | } 36 | 37 | bool done() const noexcept { return vertices_.done(); } 38 | 39 | void next() { vertices_.next(); } 40 | 41 | private: 42 | 43 | const TransformShape* shape_; 44 | 45 | typename VertexGeneratorType::Type vertices_; 46 | 47 | Vertices(const TransformShape& shape) : 48 | shape_{&shape}, 49 | vertices_{shape.shape_.vertices()} 50 | { } 51 | 52 | friend class TransformShape; 53 | }; 54 | 55 | /// @param shape Source data shape. 56 | /// @param mutate Callback function that gets called once per vertex. 57 | TransformShape(Shape shape, std::function mutate) : 58 | shape_{std::move(shape)}, 59 | mutate_{mutate} 60 | { 61 | 62 | } 63 | 64 | using Edges = typename Impl::Edges; 65 | 66 | Edges edges() const noexcept { return shape_.edges(); } 67 | 68 | Vertices vertices() const noexcept { return *this; } 69 | 70 | private: 71 | 72 | std::function mutate_; 73 | 74 | }; 75 | 76 | 77 | template 78 | TransformShape transformShape( 79 | Shape shape, std::function mutate 80 | ) { 81 | return TransformShape{std::move(shape), std::move(mutate)}; 82 | } 83 | 84 | 85 | } 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /include/generator/TranslateMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TRANSLATEMESH_HPP 8 | #define GENERATOR_TRANSLATEMESH_HPP 9 | 10 | #include "TransformMesh.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// Translates the position of each vertex by given amount. 17 | template 18 | class TranslateMesh 19 | { 20 | private: 21 | 22 | using Impl = TransformMesh; 23 | Impl transformMesh_; 24 | 25 | public: 26 | 27 | /// @param mesh Source data mesh. 28 | /// @param delta Amount to increment vertex positions. 29 | TranslateMesh(Mesh mesh, const gml::dvec3& delta) : 30 | transformMesh_{ 31 | std::move(mesh), 32 | [delta] (MeshVertex& value) { value.position += delta; } 33 | } 34 | { } 35 | 36 | using Triangles = typename Impl::Triangles; 37 | 38 | Triangles triangles() const noexcept { return transformMesh_.triangles(); } 39 | 40 | using Vertices = typename Impl::Vertices; 41 | 42 | Vertices vertices() const noexcept { return transformMesh_.vertices(); } 43 | 44 | }; 45 | 46 | 47 | template 48 | TranslateMesh translateMesh(Mesh mesh, const gml::dvec3& delta) { 49 | return TranslateMesh{std::move(mesh), delta}; 50 | } 51 | 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /include/generator/TranslatePath.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TRANSLATEPATH_HPP 8 | #define GENERATOR_TRANSLATEPATH_HPP 9 | 10 | #include "math.hpp" 11 | 12 | #include "TransformPath.hpp" 13 | 14 | namespace generator { 15 | 16 | 17 | /// Translates the position of each vertex by given amount. 18 | template 19 | class TranslatePath 20 | { 21 | private: 22 | 23 | using Impl = TransformPath; 24 | Impl transformPath_; 25 | 26 | public: 27 | 28 | /// @param path Source data path. 29 | /// @param delta Amount to increment each vertex position. 30 | TranslatePath(Path path, const gml::dvec3& delta) : 31 | transformPath_{ 32 | std::move(path), 33 | [delta] (PathVertex& value) { value.position += delta; } 34 | } 35 | { } 36 | 37 | using Edges = typename Impl::Edges; 38 | 39 | Edges edges() const noexcept { return transformPath_.edges(); } 40 | 41 | using Vertices = typename Impl::Vertices; 42 | 43 | Vertices vertices() const noexcept { return transformPath_.vertices(); } 44 | 45 | }; 46 | 47 | 48 | template 49 | TranslatePath translatePath(Path path, const gml::dvec3& delta) { 50 | return TranslatePath{std::move(path), delta}; 51 | } 52 | 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/generator/TranslateShape.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TRANSLATESHAPE_HPP 8 | #define GENERATOR_TRANSLATESHAPE_HPP 9 | 10 | #include "math.hpp" 11 | 12 | #include "TransformShape.hpp" 13 | 14 | namespace generator { 15 | 16 | 17 | /// Translates the position of each vertex by given amount. 18 | template 19 | class TranslateShape 20 | { 21 | private: 22 | 23 | using Impl = TransformShape; 24 | Impl transformShape_; 25 | 26 | public: 27 | 28 | /// @param shape Source data shape. 29 | /// @param delta Amount to increment vertex positions. 30 | TranslateShape(Shape shape, const gml::dvec2& delta) : 31 | transformShape_{ 32 | std::move(shape), 33 | [delta] (ShapeVertex& value) { value.position += delta; } 34 | } 35 | { } 36 | 37 | using Edges = typename Impl::Edges; 38 | 39 | Edges edges() const noexcept { return transformShape_.edges(); } 40 | 41 | using Vertices = typename Impl::Vertices; 42 | 43 | Vertices vertices() const noexcept { return transformShape_.vertices(); } 44 | 45 | }; 46 | 47 | 48 | template 49 | TranslateShape translateShape(Shape shape, const gml::dvec2& delta) { 50 | return TranslateShape{std::move(shape), delta}; 51 | } 52 | 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/generator/Triangle.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TRIANGLE_HPP 8 | #define GENERATOR_TRIANGLE_HPP 9 | 10 | #include "math.hpp" 11 | 12 | namespace generator { 13 | 14 | 15 | 16 | class Triangle { 17 | public: 18 | 19 | /// Zero based indices of the triangle vertices in counterclockwise order. 20 | gml::ivec3 vertices; 21 | 22 | Triangle() noexcept : 23 | vertices{} 24 | { } 25 | 26 | explicit Triangle(const gml::ivec3& vertices) noexcept : 27 | vertices{vertices} 28 | { } 29 | 30 | }; 31 | 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/generator/TriangleMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TRIANGLEMESH_HPP 8 | #define GENERATOR_TRIANGLEMESH_HPP 9 | 10 | #include "math.hpp" 11 | 12 | 13 | #include "MeshVertex.hpp" 14 | #include "Triangle.hpp" 15 | 16 | 17 | namespace generator { 18 | 19 | 20 | /// A triangular mesh on the xy -plane. 21 | /// @image html TriangleMesh.svg 22 | class TriangleMesh 23 | { 24 | public: 25 | 26 | class Triangles { 27 | public: 28 | 29 | bool done() const noexcept; 30 | Triangle generate() const; 31 | void next(); 32 | 33 | private: 34 | 35 | const TriangleMesh* mesh_; 36 | int row_; 37 | int col_; 38 | int i_; 39 | 40 | Triangles(const TriangleMesh& mesh); 41 | 42 | friend class TriangleMesh; 43 | }; 44 | 45 | class Vertices { 46 | public: 47 | 48 | bool done() const noexcept; 49 | MeshVertex generate() const; 50 | void next(); 51 | 52 | private: 53 | 54 | const TriangleMesh* mesh_; 55 | int row_; 56 | int col_; 57 | 58 | Vertices(const TriangleMesh& mesh); 59 | 60 | friend class TriangleMesh; 61 | }; 62 | 63 | /// Makes a regular triangle centered at origin. 64 | /// @param radius The radius of the containing circle. 65 | /// @param segments The number of segments along each edge. Must be >= 1. 66 | explicit TriangleMesh(double radius = 1.0, int segments = 4); 67 | 68 | /// @param v0,v1,v2 The vertex positions of the triangle. 69 | /// @param segments The number of segments along each edge. Must be >= 1. 70 | TriangleMesh( 71 | const gml::dvec3& v0, const gml::dvec3& v1, const gml::dvec3& v2, 72 | int segments = 4 73 | ); 74 | 75 | Triangles triangles() const noexcept; 76 | 77 | Vertices vertices() const noexcept; 78 | 79 | private: 80 | 81 | gml::dvec3 v0_, v1_, v2_; 82 | 83 | gml::dvec3 normal_; 84 | 85 | int segments_; 86 | 87 | }; 88 | 89 | 90 | } 91 | 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /include/generator/TubeMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_TUBEMESH_HPP 8 | #define GENERATOR_TUBEMESH_HPP 9 | 10 | #include "CylinderMesh.hpp" 11 | #include "FlipMesh.hpp" 12 | #include "MergeMesh.hpp" 13 | #include "UvFlipMesh.hpp" 14 | 15 | 16 | namespace generator { 17 | 18 | 19 | /// Tube (thick cylinder) centered at origin aligned along the z-axis. 20 | /// @image html TubeMesh.svg 21 | class TubeMesh 22 | { 23 | private: 24 | 25 | using Impl = MergeMesh>>; 26 | Impl mergeMesh_; 27 | 28 | public: 29 | 30 | /// @param radius The outer radius of the cylinder on the xy-plane. 31 | /// @param innerRadius The inner radius of the cylinder on the xy-plane. 32 | /// @param size Half of the length of the cylinder along the z-axis. 33 | /// @param slices Subdivisions around the z-axis. 34 | /// @param segments Subdivisions along the z-axis. 35 | /// @param start Counterclockwise angle around the z-axis relative to the x-axis. 36 | /// @param sweep Counterclockwise angle around the z-axis. 37 | TubeMesh( 38 | double radius = 1.0, 39 | double innerRadius = 0.75, 40 | double size = 1.0, 41 | int slices = 32, 42 | int segments = 8, 43 | double start = 0.0, 44 | double sweep = gml::radians(360.0) 45 | ); 46 | 47 | using Triangles = typename Impl::Triangles; 48 | 49 | Triangles triangles() const noexcept { return mergeMesh_.triangles(); } 50 | 51 | using Vertices = typename Impl::Vertices; 52 | 53 | Vertices vertices() const noexcept { return mergeMesh_.vertices(); } 54 | 55 | }; 56 | 57 | 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /include/generator/UvFlipMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_UVFLIPMESH_HPP 8 | #define GENERATOR_UVFLIPMESH_HPP 9 | 10 | #include "TransformMesh.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// Flips texture coordinate axis directions. 17 | template 18 | class UvFlipMesh 19 | { 20 | private: 21 | 22 | using Impl = TransformMesh; 23 | Impl transformMesh_; 24 | 25 | public: 26 | 27 | /// @param mesh Source data mesh. 28 | /// @param u Flip u 29 | /// @param v Flip v 30 | UvFlipMesh(Mesh mesh, bool u, bool v) : 31 | transformMesh_{ 32 | std::move(mesh), 33 | [u, v] (MeshVertex& vertex) { 34 | if (u) vertex.texCoord[0] = 1.0 - vertex.texCoord[0]; 35 | if (v) vertex.texCoord[1] = 1.0 - vertex.texCoord[1]; 36 | } 37 | } 38 | { } 39 | 40 | using Triangles = typename Impl::Triangles; 41 | 42 | Triangles triangles() const noexcept { return transformMesh_.triangles(); } 43 | 44 | using Vertices = typename Impl::Vertices; 45 | 46 | Vertices vertices() const noexcept { return transformMesh_.vertices(); } 47 | 48 | }; 49 | 50 | 51 | template 52 | UvFlipMesh uvFlipMesh(Mesh mesh) { 53 | return UvFlipMesh{std::move(mesh)}; 54 | } 55 | 56 | 57 | } 58 | 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /include/generator/UvSwapMesh.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_UVSWAPMESH_HPP 8 | #define GENERATOR_UVSWAPMESH_HPP 9 | 10 | #include "TransformMesh.hpp" 11 | 12 | 13 | namespace generator { 14 | 15 | 16 | /// Swaps the texture coordinates axis u and v. 17 | template 18 | class UvSwapMesh 19 | { 20 | private: 21 | 22 | using Impl = TransformMesh; 23 | Impl transformMesh_; 24 | 25 | public: 26 | 27 | /// @param mesh Source data mesh 28 | UvSwapMesh(Mesh mesh) : 29 | transformMesh_{ 30 | std::move(mesh), 31 | [] (MeshVertex& vertex) { 32 | std::swap(vertex.texCoord[0], vertex.texCoord[1]); 33 | } 34 | } 35 | { } 36 | 37 | using Triangles = typename Impl::Triangles; 38 | 39 | Triangles triangles() const noexcept { return transformMesh_.triangles(); } 40 | 41 | using Vertices = typename Impl::Vertices; 42 | 43 | Vertices vertices() const noexcept { return transformMesh_.vertices(); } 44 | 45 | }; 46 | 47 | template 48 | UvSwapMesh uvSwapMesh(Mesh mesh) { 49 | return UvSwapMesh{std::move(mesh)}; 50 | } 51 | 52 | 53 | } 54 | 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /include/generator/generator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_HPP 8 | #define GENERATOR_HPP 9 | 10 | #include "AnyGenerator.hpp" 11 | #include "AnyMesh.hpp" 12 | #include "AnyPath.hpp" 13 | #include "AnyShape.hpp" 14 | #include "RepeatMesh.hpp" 15 | #include "RepeatPath.hpp" 16 | #include "RepeatShape.hpp" 17 | #include "Axis.hpp" 18 | #include "AxisFlipMesh.hpp" 19 | #include "AxisSwapMesh.hpp" 20 | #include "AxisSwapPath.hpp" 21 | #include "AxisSwapShape.hpp" 22 | #include "BezierMesh.hpp" 23 | #include "BezierShape.hpp" 24 | #include "BoxMesh.hpp" 25 | #include "CappedConeMesh.hpp" 26 | #include "CappedCylinderMesh.hpp" 27 | #include "CappedTubeMesh.hpp" 28 | #include "CapsuleMesh.hpp" 29 | #include "CircleShape.hpp" 30 | #include "ConeMesh.hpp" 31 | #include "ConvexPolygonMesh.hpp" 32 | #include "CylinderMesh.hpp" 33 | #include "DiskMesh.hpp" 34 | #include "DodecahedronMesh.hpp" 35 | #include "Edge.hpp" 36 | #include "EmptyMesh.hpp" 37 | #include "EmptyPath.hpp" 38 | #include "EmptyShape.hpp" 39 | #include "ExtrudeMesh.hpp" 40 | #include "FlipMesh.hpp" 41 | #include "FlipPath.hpp" 42 | #include "FlipShape.hpp" 43 | #include "GridShape.hpp" 44 | #include "HelixPath.hpp" 45 | #include "IcosahedronMesh.hpp" 46 | #include "IcoSphereMesh.hpp" 47 | #include "Iterator.hpp" 48 | #include "KnotPath.hpp" 49 | #include "LatheMesh.hpp" 50 | #include "LinePath.hpp" 51 | #include "LineShape.hpp" 52 | #include "math.hpp" 53 | #include "MergeMesh.hpp" 54 | #include "MergePath.hpp" 55 | #include "MergeShape.hpp" 56 | #include "MeshVertex.hpp" 57 | #include "MirrorMesh.hpp" 58 | #include "ObjWriter.hpp" 59 | #include "ParametricMesh.hpp" 60 | #include "ParametricPath.hpp" 61 | #include "ParametricShape.hpp" 62 | #include "PathVertex.hpp" 63 | #include "PlaneMesh.hpp" 64 | #include "RectangleShape.hpp" 65 | #include "RotateMesh.hpp" 66 | #include "RotatePath.hpp" 67 | #include "RotateShape.hpp" 68 | #include "RoundedBoxMesh.hpp" 69 | #include "RoundedRectangleShape.hpp" 70 | #include "ScaleMesh.hpp" 71 | #include "ScalePath.hpp" 72 | #include "ScaleShape.hpp" 73 | #include "ShapeToPath.hpp" 74 | #include "ShapeVertex.hpp" 75 | #include "SphereMesh.hpp" 76 | #include "SpherifyMesh.hpp" 77 | #include "SphericalConeMesh.hpp" 78 | #include "SphericalTriangleMesh.hpp" 79 | #include "SpringMesh.hpp" 80 | #include "SubdivideMesh.hpp" 81 | #include "SubdividePath.hpp" 82 | #include "SubdivideShape.hpp" 83 | #include "SvgWriter.hpp" 84 | #include "TeapotMesh.hpp" 85 | #include "TorusKnotMesh.hpp" 86 | #include "TorusMesh.hpp" 87 | #include "TransformMesh.hpp" 88 | #include "TransformPath.hpp" 89 | #include "TransformShape.hpp" 90 | #include "TranslateMesh.hpp" 91 | #include "TranslatePath.hpp" 92 | #include "TranslateShape.hpp" 93 | #include "Triangle.hpp" 94 | #include "TriangleMesh.hpp" 95 | #include "TubeMesh.hpp" 96 | #include "utils.hpp" 97 | #include "UvFlipMesh.hpp" 98 | #include "UvSwapMesh.hpp" 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /include/generator/gml/gml.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GML_INCLUDE 2 | #define GML_INCLUDE 3 | 4 | #include "util.hpp" 5 | #include "vec.hpp" 6 | #include "quaternion.hpp" 7 | #include "mat.hpp" 8 | #include "spline.hpp" 9 | #include "texture.hpp" 10 | #include "intersect.hpp" 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /include/generator/utils.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #ifndef GENERATOR_UTILS_HPP 8 | #define GENERATOR_UTILS_HPP 9 | 10 | namespace generator { 11 | 12 | 13 | /// Will have a type named "Type" that has same type as value returned by method 14 | /// generate() of type Generator. 15 | template 16 | class GeneratedType { 17 | public: 18 | 19 | using Type = decltype(static_cast(nullptr)->generate()); 20 | 21 | }; 22 | 23 | 24 | /// Will have a type named "Type" that has same type as value returned by method 25 | /// edges() for type Primitive. 26 | template 27 | class EdgeGeneratorType { 28 | public: 29 | 30 | using Type = decltype(static_cast(nullptr)->edges()); 31 | 32 | }; 33 | 34 | 35 | /// Will have a type named "Type" that has same type as value returned by method 36 | /// triangles() for type Primitive. 37 | template 38 | class TriangleGeneratorType { 39 | public: 40 | 41 | using Type = decltype(static_cast(nullptr)->triangles()); 42 | 43 | }; 44 | 45 | 46 | /// Will have a type named "Type" that has same type as value returned by method 47 | /// vertices() for type Primitive. 48 | template 49 | class VertexGeneratorType { 50 | public: 51 | 52 | using Type = decltype(static_cast(nullptr)->vertices()); 53 | 54 | }; 55 | 56 | 57 | /// Counts the number of steps left in the generator. 58 | template 59 | int count(const Generator& generator) noexcept { 60 | Generator temp{generator}; 61 | int c = 0; 62 | while (!temp.done()) { 63 | ++c; 64 | temp.next(); 65 | } 66 | return c; 67 | } 68 | 69 | 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/AnyMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/AnyMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | 15 | AnyMesh::Base::~Base() { } 16 | 17 | 18 | AnyMesh::AnyMesh(const AnyMesh& that) : 19 | base_{that.base_->clone()} 20 | { } 21 | 22 | 23 | AnyMesh& AnyMesh::operator=(const AnyMesh& that) { 24 | base_ = that.base_->clone(); 25 | return *this; 26 | } 27 | 28 | 29 | AnyGenerator AnyMesh::triangles() const noexcept { 30 | return base_->triangles(); 31 | } 32 | 33 | 34 | AnyGenerator AnyMesh::vertices() const noexcept { 35 | return base_->vertices(); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/AnyPath.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #include "generator/AnyPath.hpp" 8 | 9 | 10 | using namespace generator; 11 | 12 | 13 | AnyPath::Base::~Base() { } 14 | 15 | 16 | AnyPath::AnyPath(const AnyPath& that) : 17 | base_{that.base_->clone()} 18 | { } 19 | 20 | 21 | AnyPath& AnyPath::operator=(const AnyPath& that) { 22 | base_ = that.base_->clone(); 23 | return *this; 24 | } 25 | 26 | 27 | AnyGenerator AnyPath::edges() const noexcept { 28 | return base_->edges(); 29 | } 30 | 31 | 32 | AnyGenerator AnyPath::vertices() const noexcept { 33 | return base_->vertices(); 34 | } 35 | -------------------------------------------------------------------------------- /src/AnyShape.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #include "generator/AnyShape.hpp" 8 | 9 | 10 | using namespace generator; 11 | 12 | 13 | AnyShape::Base::~Base() { } 14 | 15 | 16 | AnyShape::AnyShape(const AnyShape& that) : 17 | base_{that.base_->clone()} 18 | { } 19 | 20 | 21 | AnyShape& AnyShape::operator=(const AnyShape& that) { 22 | base_ = that.base_->clone(); 23 | return *this; 24 | } 25 | 26 | 27 | AnyGenerator AnyShape::edges() const noexcept { 28 | return base_->edges(); 29 | } 30 | 31 | 32 | AnyGenerator AnyShape::vertices() const noexcept { 33 | return base_->vertices(); 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/BoxMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/BoxMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | using namespace generator::detail; 14 | 15 | 16 | 17 | 18 | BoxFace::BoxFace( 19 | const gml::dvec2& size, const gml::ivec2& segments, double delta 20 | ) : 21 | translateMesh_{{size, segments}, {0.0, 0.0, delta}} 22 | { } 23 | 24 | 25 | BoxFaces::BoxFaces( 26 | const gml::dvec2& size, const gml::ivec2& segments, double delta 27 | ) : 28 | mergeMesh_{ 29 | {size, segments, delta}, 30 | {{{size, segments, -delta}}, true, false} 31 | } 32 | { } 33 | 34 | 35 | 36 | BoxMesh::BoxMesh(const gml::dvec3& size, const gml::ivec3& segments) noexcept : 37 | mergeMesh_{ 38 | { 39 | {{size[1], size[2]}, {segments[1], segments[2]}, size[0]}, 40 | Axis::Z, Axis::X, Axis::Y 41 | }, 42 | { 43 | { 44 | {{size[0], size[2]}, {segments[0], segments[2]}, size[1]}, 45 | Axis::X, Axis::Z, Axis::Y 46 | }, 47 | true, false 48 | }, 49 | {{size[0], size[1]}, {segments[0], segments[1]}, size[2]} 50 | } 51 | { } 52 | 53 | -------------------------------------------------------------------------------- /src/CappedConeMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/CappedConeMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | CappedConeMesh::CappedConeMesh( 15 | double radius, 16 | double size, 17 | int slices, 18 | int segments, 19 | int rings, 20 | double start, 21 | double sweep 22 | ) : 23 | mergeMesh_{ 24 | {radius, size, slices, segments, start, sweep}, 25 | {{{ 26 | DiskMesh{radius, 0.0, slices, rings}, 27 | gml::dvec3{0.0, 0.0, -size} 28 | }}, true, false} 29 | } 30 | { } 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/CappedCylinderMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/CappedCylinderMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | using namespace generator::detail; 13 | 14 | 15 | Cap::Cap( 16 | double radius, 17 | double distance, 18 | int slices, 19 | int rings, 20 | double start, 21 | double sweep 22 | ) : 23 | translateMesh_{ 24 | {radius, 0.0, slices, rings, start, sweep}, 25 | {0.0, 0.0, distance} 26 | } 27 | { } 28 | 29 | 30 | CappedCylinderMesh::CappedCylinderMesh( 31 | double radius, 32 | double size, 33 | int slices, 34 | int segments, 35 | int rings, 36 | double start, 37 | double sweep 38 | ) : 39 | mergeMesh_{ 40 | {radius, size, slices, segments, start, sweep}, 41 | {radius, size, slices, rings, start, sweep}, 42 | {{{radius, -size, slices, rings, start, sweep}}, true, false} 43 | } 44 | { } 45 | 46 | -------------------------------------------------------------------------------- /src/CappedTubeMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/CappedTubeMesh.hpp" 9 | 10 | using namespace generator; 11 | 12 | using namespace generator::detail; 13 | 14 | 15 | TubeCap::TubeCap( 16 | double radius, 17 | double innerRadius, 18 | double distance, 19 | int slices, 20 | int rings, 21 | double start, 22 | double sweep 23 | ) : 24 | translateMesh_{ 25 | {radius, innerRadius, slices, rings, start, sweep}, 26 | {0.0, 0.0, distance} 27 | } 28 | { } 29 | 30 | 31 | CappedTubeMesh::CappedTubeMesh( 32 | double radius, 33 | double innerRadius, 34 | double size, 35 | int slices, 36 | int segments, 37 | int rings, 38 | double start, 39 | double sweep 40 | ) : 41 | mergeMesh_{ 42 | {radius, innerRadius, size, slices, segments, start, sweep}, 43 | {radius, innerRadius, size, slices, rings, start, sweep}, 44 | {{radius, innerRadius, -size, slices, rings, start, sweep}}, 45 | } 46 | { } 47 | 48 | -------------------------------------------------------------------------------- /src/CapsuleMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/CapsuleMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | CapsuleMesh::CapsuleMesh( 15 | double radius, 16 | double size, 17 | int slices, 18 | int segments, 19 | int rings, 20 | double start, 21 | double sweep 22 | ) : 23 | mergeMesh_{ 24 | {radius, size, slices, segments, start, sweep}, 25 | { 26 | {radius, slices, rings, start, sweep, 0.0, gml::radians(90.0)}, 27 | {0.0, 0.0, size} 28 | }, 29 | { 30 | { 31 | radius, slices, rings, start, sweep, 32 | gml::radians(90.0), gml::radians(90.0) 33 | }, 34 | {0.0, 0.0, -size} 35 | } 36 | } 37 | { 38 | 39 | } 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/CircleShape.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #include "generator/CircleShape.hpp" 8 | 9 | 10 | using namespace generator; 11 | 12 | 13 | CircleShape::CircleShape( 14 | double radius, 15 | int segments, 16 | double start, 17 | double sweep 18 | ) : 19 | parametricShape_{ 20 | [radius, start, sweep] (double t) { 21 | const double angle = t * sweep + start; 22 | const double sine = std::sin(angle); 23 | const double cosine = std::cos(angle); 24 | 25 | ShapeVertex vertex; 26 | vertex.position = gml::dvec2{radius * cosine, radius * sine}; 27 | vertex.tangent = gml::dvec2{-sine, cosine}; 28 | vertex.texCoord = t; 29 | 30 | return vertex; 31 | }, 32 | segments 33 | } 34 | { } 35 | -------------------------------------------------------------------------------- /src/ConeMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/ConeMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | ConeMesh::ConeMesh( 15 | double radius, 16 | double size, 17 | int slices, 18 | int segments, 19 | double start, 20 | double sweep 21 | ) : 22 | axisSwapMesh_{ 23 | { 24 | {{size, 0.0}, {-size, radius}, segments}, 25 | {1.0, 0.0}, slices, start, sweep 26 | }, 27 | Axis::Y, Axis::Z, Axis::X 28 | } 29 | { } 30 | -------------------------------------------------------------------------------- /src/CylinderMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/CylinderMesh.hpp" 9 | 10 | using namespace generator; 11 | 12 | CylinderMesh::CylinderMesh( 13 | double radius, 14 | double size, 15 | int slices, 16 | int segments, 17 | double start, 18 | double sweep 19 | ) : 20 | axisSwapMesh_{ 21 | { 22 | {{size, radius}, {-size, radius}, segments}, 23 | {1.0, 0.0}, slices, start, sweep 24 | }, 25 | Axis::Y, Axis::Z, Axis::X 26 | } 27 | { } 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/DiskMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #include "generator/DiskMesh.hpp" 8 | 9 | 10 | using namespace generator; 11 | 12 | 13 | DiskMesh::DiskMesh( 14 | double radius, 15 | double innerRadius, 16 | int slices, 17 | int rings, 18 | double start, 19 | double sweep 20 | ) : 21 | axisSwapMesh_{ 22 | { 23 | {{0.0, innerRadius}, {0.0, radius}, rings}, 24 | {1.0, 0.0}, slices, start, sweep 25 | }, 26 | Axis::Y, Axis::Z, Axis::X 27 | } 28 | { } 29 | -------------------------------------------------------------------------------- /src/EmptyMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/EmptyMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | EmptyMesh::Triangles::Triangles() { } 15 | 16 | Triangle EmptyMesh::Triangles::generate() const { 17 | throw std::out_of_range("Called generate on an EmptyMesh!"); 18 | } 19 | 20 | bool EmptyMesh::Triangles::done() const noexcept { 21 | return true; 22 | } 23 | 24 | void EmptyMesh::Triangles::next() { 25 | throw std::out_of_range("Called next on an EmptyMesh!"); 26 | } 27 | 28 | 29 | 30 | 31 | EmptyMesh::Vertices::Vertices() { } 32 | 33 | MeshVertex EmptyMesh::Vertices::generate() const { 34 | throw std::out_of_range("Called generate on an EmptyMesh!"); 35 | } 36 | 37 | bool EmptyMesh::Vertices::done() const noexcept { 38 | return true; 39 | } 40 | 41 | void EmptyMesh::Vertices::next() { 42 | throw std::out_of_range("Called next on an EmptyMesh!"); 43 | } 44 | 45 | 46 | 47 | EmptyMesh::EmptyMesh() {} 48 | 49 | EmptyMesh::Triangles EmptyMesh::triangles() const noexcept { 50 | return {}; 51 | } 52 | 53 | EmptyMesh::Vertices EmptyMesh::vertices() const noexcept { 54 | return {}; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/EmptyPath.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/EmptyPath.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | 15 | Edge EmptyPath::Edges::generate() const { 16 | throw std::out_of_range("Called generate on an EmptyPath!"); 17 | } 18 | 19 | bool EmptyPath::Edges::done() const noexcept { 20 | return true; 21 | } 22 | 23 | void EmptyPath::Edges::next() { 24 | throw std::out_of_range("Called next on an EmptyPath!"); 25 | } 26 | 27 | 28 | 29 | EmptyPath::Edges::Edges() {} 30 | 31 | 32 | 33 | 34 | PathVertex EmptyPath::Vertices::generate() const { 35 | throw std::out_of_range("Called generate on an EmptyPath!"); 36 | } 37 | 38 | bool EmptyPath::Vertices::done() const noexcept { 39 | return true; 40 | } 41 | 42 | void EmptyPath::Vertices::next() { 43 | throw std::out_of_range("Called next on an EmptyPath!"); 44 | } 45 | 46 | 47 | EmptyPath::Vertices::Vertices() { } 48 | 49 | 50 | EmptyPath::EmptyPath() {} 51 | 52 | EmptyPath::Edges EmptyPath::edges() const noexcept { 53 | return {}; 54 | } 55 | 56 | EmptyPath::Vertices EmptyPath::vertices() const noexcept { 57 | return {}; 58 | } 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/EmptyShape.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/EmptyShape.hpp" 9 | 10 | #include 11 | 12 | using namespace generator; 13 | 14 | 15 | EmptyShape::Edges::Edges() { } 16 | 17 | 18 | Edge EmptyShape::Edges::generate() const { 19 | throw std::out_of_range("Called generate on an EmptyShape!"); 20 | } 21 | 22 | bool EmptyShape::Edges::done() const noexcept { 23 | return true; 24 | } 25 | 26 | void EmptyShape::Edges::next() { 27 | throw std::out_of_range("Called next on an EmptyShape!"); 28 | } 29 | 30 | 31 | 32 | 33 | EmptyShape::Vertices::Vertices() { } 34 | 35 | 36 | ShapeVertex EmptyShape::Vertices::generate() const { 37 | throw std::out_of_range("Called generate on an EmptyShape!"); 38 | } 39 | 40 | bool EmptyShape::Vertices::done() const noexcept { 41 | return true; 42 | } 43 | 44 | void EmptyShape::Vertices::next() { 45 | throw std::out_of_range("Called next on an EmptyShape!"); 46 | } 47 | 48 | 49 | 50 | EmptyShape::Edges EmptyShape::edges() const noexcept { 51 | return {}; 52 | } 53 | 54 | EmptyShape::Vertices EmptyShape::vertices() const noexcept { 55 | return {}; 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/GridShape.cpp: -------------------------------------------------------------------------------- 1 | #include "generator/GridShape.hpp" 2 | 3 | using namespace generator; 4 | 5 | GridShape::GridShape( 6 | const gml::dvec2& size, 7 | const gml::ivec2& segments, const gml::ivec2& subSegments 8 | ) noexcept : 9 | mImpl{ 10 | // Horizontal lines 11 | RepeatShape{ 12 | LineShape{ 13 | gml::dvec2{-size[0], -size[1]}, gml::dvec2{size[0], -size[1]}, 14 | segments[0] * subSegments[0] 15 | }, 16 | segments[1] < 1 ? 0 : segments[1] + 1, 17 | gml::dvec2{0.0, 2.0 * size[1] / std::max(segments[1], 1)} 18 | }, 19 | // Vertical lines 20 | RepeatShape{ 21 | LineShape{ 22 | gml::dvec2{-size[0], -size[1]}, gml::dvec2{-size[0], size[1]}, 23 | segments[1] * subSegments[1] 24 | }, 25 | segments[0] < 1 ? 0 : segments[0] + 1, 26 | gml::dvec2{2.0 * size[0] / std::max(segments[0], 1), 0.0} 27 | }, 28 | } 29 | { 30 | // 31 | } 32 | 33 | 34 | GridShape::Edges GridShape::edges() const noexcept 35 | { 36 | return mImpl.edges(); 37 | } 38 | 39 | 40 | GridShape::Vertices GridShape::vertices() const noexcept 41 | { 42 | return mImpl.vertices(); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/HelixPath.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/HelixPath.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | HelixPath::HelixPath( 15 | double radius, 16 | double size, 17 | int segments, 18 | double start, 19 | double sweep 20 | ) : 21 | parametricPath_{ 22 | [radius, size, start, sweep] (double t) { 23 | PathVertex vertex; 24 | const double angle = start + t * sweep; 25 | const double sine = std::sin(angle); 26 | const double cosine = std::cos(angle); 27 | 28 | vertex.position = gml::dvec3{ 29 | radius * cosine, 30 | radius * sine, 31 | 2.0 * t * size - size 32 | }; 33 | 34 | vertex.tangent = gml::normalize(gml::dvec3{ 35 | -radius * sine, 36 | radius * cosine, 37 | 2.0 * size / sweep, 38 | }); 39 | 40 | vertex.normal = gml::dvec3{cosine, sine, 0.0}; 41 | 42 | vertex.texCoord = t; 43 | 44 | return vertex; 45 | }, 46 | segments 47 | } 48 | { } 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/IcoSphereMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/IcoSphereMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | IcoSphereMesh::IcoSphereMesh(double radius, int segments) : 15 | spherifyMesh_{{1.0, segments}, radius, 1.0} 16 | { } 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/KnotPath.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/KnotPath.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | namespace { 15 | 16 | gml::dvec3 knot(int p, int q, double t) { 17 | t *= gml::radians(360.0); 18 | 19 | const double pt = p * t; 20 | const double qt = q * t; 21 | 22 | const double sinpt = std::sin(pt); 23 | const double cospt = std::cos(pt); 24 | const double sinqt = std::sin(qt); 25 | const double cosqt = std::cos(qt); 26 | 27 | const double r = 0.5 * (2.0 + sinqt); 28 | 29 | return gml::dvec3{r * cospt, r * sinpt, r * cosqt}; 30 | } 31 | 32 | } 33 | 34 | 35 | KnotPath::KnotPath( 36 | int p, 37 | int q, 38 | int segments 39 | ) : 40 | parametricPath_{ 41 | [p, q] (double t) { 42 | PathVertex vertex; 43 | 44 | vertex.position = knot(p, q, t); 45 | 46 | const gml::dvec3 prev = knot(p, q, t - 0.01); 47 | const gml::dvec3 next = knot(p, q, t + 0.01); 48 | 49 | vertex.tangent = normalize(next - prev); 50 | 51 | vertex.normal = normalize(cross(next - prev, next + prev)); 52 | 53 | vertex.texCoord = t; 54 | 55 | return vertex; 56 | }, 57 | segments 58 | } 59 | { } 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/LinePath.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #include "generator/LinePath.hpp" 8 | 9 | 10 | using namespace generator; 11 | 12 | 13 | LinePath::LinePath( 14 | const gml::dvec3& start, 15 | const gml::dvec3& end, 16 | const gml::dvec3& normal, 17 | int segments 18 | ): 19 | parametricPath_{ 20 | [start, end, normal] (double t) { 21 | PathVertex vertex; 22 | 23 | vertex.position = start + t * (end - start); 24 | vertex.tangent = normalize(end - start); 25 | vertex.normal = normal; 26 | vertex.texCoord = t; 27 | 28 | return vertex; 29 | }, 30 | segments 31 | } 32 | { } 33 | 34 | -------------------------------------------------------------------------------- /src/LineShape.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/LineShape.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | LineShape::LineShape( 15 | const gml::dvec2& start, 16 | const gml::dvec2& end, 17 | int segments 18 | ) : 19 | parametricShape_{ 20 | [start, end] (double t) { 21 | ShapeVertex vertex; 22 | 23 | vertex.position = start + t * (end - start); 24 | vertex.tangent = normalize(end - start); 25 | vertex.texCoord = t; 26 | 27 | return vertex; 28 | }, 29 | segments 30 | } 31 | { 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/ObjWriter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #include "generator/ObjWriter.hpp" 8 | 9 | 10 | using namespace generator; 11 | 12 | 13 | ObjWriter::ObjWriter() : 14 | base_{1}, 15 | ss_{} 16 | { } 17 | -------------------------------------------------------------------------------- /src/ParametricMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/ParametricMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | ParametricMesh::Triangles::Triangles(const ParametricMesh& mesh) : 15 | mesh_{&mesh}, 16 | i_{0}, 17 | even_{false} 18 | { } 19 | 20 | 21 | Triangle ParametricMesh::Triangles::generate() const { 22 | if (done()) throw std::out_of_range("Done!"); 23 | 24 | Triangle triangle; 25 | 26 | const int base = i_[1] * (mesh_->segments_[0] + 1) + i_[0]; 27 | 28 | if (!even_) { 29 | triangle.vertices = { 30 | base, 31 | base + 1, 32 | base + mesh_->segments_[0] + 1 33 | }; 34 | } 35 | else { 36 | triangle.vertices = { 37 | base + 1, 38 | base + mesh_->segments_[0] + 2, 39 | base + mesh_->segments_[0] + 1 40 | }; 41 | } 42 | 43 | return triangle; 44 | } 45 | 46 | bool ParametricMesh::Triangles::done() const noexcept { 47 | if (mesh_->segments_[0] == 0 || mesh_->segments_[1] == 0) return true; 48 | return i_[1] == mesh_->segments_[1]; 49 | } 50 | 51 | void ParametricMesh::Triangles::next() { 52 | if (done()) throw std::out_of_range("Done!"); 53 | 54 | even_ = !even_; 55 | 56 | if (!even_) { 57 | ++i_[0]; 58 | if (i_[0] == mesh_->segments_[0]) { 59 | i_[0] = 0; 60 | ++i_[1]; 61 | } 62 | } 63 | } 64 | 65 | 66 | 67 | 68 | ParametricMesh::Vertices::Vertices(const ParametricMesh& mesh) : 69 | mesh_{&mesh}, i_{0} 70 | { } 71 | 72 | 73 | 74 | MeshVertex ParametricMesh::Vertices::generate() const { 75 | if (done()) throw std::out_of_range("Done!"); 76 | 77 | return mesh_->eval_({i_[0] * mesh_->delta_[0], i_[1] * mesh_->delta_[1]}); 78 | } 79 | 80 | 81 | bool ParametricMesh::Vertices::done() const noexcept { 82 | if (mesh_->segments_[0] == 0 || mesh_->segments_[1] == 0) return true; 83 | return i_[1] > mesh_->segments_[1]; 84 | } 85 | 86 | 87 | void ParametricMesh::Vertices::next() { 88 | if (done()) throw std::out_of_range("Done!"); 89 | 90 | ++i_[0]; 91 | if (i_[0] > mesh_->segments_[0]) { 92 | i_[0] = 0; 93 | ++i_[1]; 94 | } 95 | } 96 | 97 | 98 | 99 | 100 | ParametricMesh::ParametricMesh( 101 | std::function eval, 102 | const gml::ivec2& segments 103 | ) noexcept : 104 | eval_{std::move(eval)}, 105 | segments_{segments}, 106 | delta_{1.0 / segments[0], 1.0 / segments[1]} 107 | { } 108 | 109 | 110 | ParametricMesh::Triangles ParametricMesh::triangles() const noexcept { 111 | return *this; 112 | } 113 | 114 | 115 | ParametricMesh::Vertices ParametricMesh::vertices() const noexcept { 116 | return *this; 117 | } 118 | 119 | -------------------------------------------------------------------------------- /src/ParametricPath.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/ParametricPath.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | ParametricPath::Edges::Edges(const ParametricPath& path) : 15 | path_{&path}, 16 | i_{0} 17 | { 18 | 19 | } 20 | 21 | 22 | Edge ParametricPath::Edges::generate() const { 23 | if (done()) throw std::out_of_range("Done!"); 24 | return Edge{{i_, i_ + 1}}; 25 | } 26 | 27 | 28 | bool ParametricPath::Edges::done() const noexcept { 29 | return i_ == path_->segments_; 30 | } 31 | 32 | 33 | void ParametricPath::Edges::next() { 34 | if (done()) throw std::out_of_range("Done!"); 35 | ++i_; 36 | } 37 | 38 | 39 | 40 | 41 | ParametricPath::Vertices::Vertices(const ParametricPath& path) : 42 | path_{&path}, 43 | i_{0} 44 | { } 45 | 46 | 47 | 48 | PathVertex ParametricPath::Vertices::generate() const { 49 | if (done()) throw std::out_of_range("Done!"); 50 | 51 | return path_->eval_(i_ * path_->delta_); 52 | } 53 | 54 | bool ParametricPath::Vertices::done() const noexcept { 55 | if (path_->segments_ == 0) return true; 56 | return i_ == path_->segments_ + 1; 57 | } 58 | 59 | void ParametricPath::Vertices::next() { 60 | if (done()) throw std::out_of_range("Done!"); 61 | ++i_; 62 | } 63 | 64 | 65 | 66 | 67 | 68 | ParametricPath::ParametricPath( 69 | std::function eval, 70 | int segments 71 | ) noexcept : 72 | eval_{std::move(eval)}, 73 | segments_{segments}, 74 | delta_{1.0 / segments} 75 | { } 76 | 77 | 78 | ParametricPath::Edges ParametricPath::edges() const noexcept { 79 | return *this; 80 | } 81 | 82 | 83 | ParametricPath::Vertices ParametricPath::vertices() const noexcept { 84 | return *this; 85 | } 86 | 87 | 88 | -------------------------------------------------------------------------------- /src/ParametricShape.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/ParametricShape.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | ParametricShape::Edges::Edges(const ParametricShape& shape) : 15 | shape_{&shape}, 16 | i_{0} 17 | { } 18 | 19 | 20 | Edge ParametricShape::Edges::generate() const { 21 | if (done()) throw std::out_of_range("Done!"); 22 | 23 | return Edge{{i_, i_ + 1}}; 24 | } 25 | 26 | bool ParametricShape::Edges::done() const noexcept { 27 | return i_ == shape_->segments_; 28 | } 29 | 30 | void ParametricShape::Edges::next() { 31 | if (done()) throw std::out_of_range("Done!"); 32 | ++i_; 33 | } 34 | 35 | 36 | 37 | 38 | ShapeVertex ParametricShape::Vertices::generate() const { 39 | if (done()) throw std::out_of_range("Done!"); 40 | 41 | return shape_->eval_(i_ * shape_->delta_); 42 | } 43 | 44 | 45 | 46 | ParametricShape::Vertices::Vertices(const ParametricShape& shape) : 47 | shape_{&shape}, i_{0} 48 | { } 49 | 50 | bool ParametricShape::Vertices::done() const noexcept { 51 | if (shape_->segments_ == 0) return true; 52 | return i_ == shape_->segments_ + 1; 53 | } 54 | 55 | void ParametricShape::Vertices::next() { 56 | if (done()) throw std::out_of_range("Done!"); 57 | ++i_; 58 | } 59 | 60 | 61 | 62 | ParametricShape::ParametricShape( 63 | std::function eval, 64 | int segments 65 | ) noexcept : 66 | eval_{std::move(eval)}, 67 | segments_{segments}, 68 | delta_{1.0 / segments} 69 | { } 70 | 71 | 72 | 73 | ParametricShape::Edges ParametricShape::edges() const noexcept { 74 | return *this; 75 | } 76 | 77 | ParametricShape::Vertices ParametricShape::vertices() const noexcept { 78 | return *this; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /src/PlaneMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/PlaneMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | PlaneMesh::PlaneMesh( 15 | const gml::dvec2& size, 16 | const gml::ivec2& segments 17 | ) : 18 | parametricMesh_{ 19 | [size] (const gml::dvec2& t) { 20 | MeshVertex vertex; 21 | vertex.position = gml::dvec3{-size + 2.0 * t * size, 0.0}; 22 | vertex.normal = gml::dvec3{0.0, 0.0, 1.0}; 23 | vertex.texCoord = t; 24 | return vertex; 25 | }, 26 | segments 27 | } 28 | { 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/RectangleShape.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/RectangleShape.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | RectangleShape::RectangleShape( 15 | const gml::dvec2& size, 16 | const gml::ivec2& segments 17 | ) : 18 | mergeShape_{ 19 | {{size[0], -size[1]}, size, segments[1]}, 20 | {size, {-size[0], size[1]}, segments[0]}, 21 | {{-size[0], size[1]}, -size, segments[1]}, 22 | {-size, {size[0], -size[1]}, segments[0]} 23 | } 24 | { } 25 | 26 | -------------------------------------------------------------------------------- /src/RoundedBoxMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/RoundedBoxMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | using namespace generator::detail; 13 | 14 | 15 | 16 | 17 | BoxEdge::BoxEdge( 18 | const gml::dvec2& position, double radius, double size, 19 | int slices, int segments 20 | ) : 21 | translateMesh_{ 22 | {radius, size, slices, segments, 0.0, gml::radians(90.0)}, 23 | gml::dvec3{position, 0.0} 24 | } 25 | { } 26 | 27 | 28 | BoxEdges::BoxEdges( 29 | const gml::dvec3& size, double radius, 30 | int slices, int segments 31 | ) : 32 | mirrorMesh_{ 33 | { 34 | {gml::dvec2{size}, radius, size[2], slices, segments}, 35 | Axis::Y 36 | }, 37 | Axis::X 38 | } 39 | { } 40 | 41 | 42 | BoxCorner::BoxCorner( 43 | const gml::dvec3& position, double radius, int slices 44 | ) : 45 | translateMesh_{ 46 | { 47 | gml::dvec3{radius, 0.0, 0.0}, 48 | gml::dvec3{0.0, radius, 0.0}, 49 | gml::dvec3{0.0, 0.0, radius}, 50 | slices 51 | }, 52 | position 53 | } 54 | { } 55 | 56 | 57 | BoxCorners::BoxCorners(const gml::dvec3& size, double radius, int slices) : 58 | mirrorMesh_{{{{size, radius, slices}, Axis::X}, Axis::Y}, Axis::Z} 59 | { } 60 | 61 | 62 | 63 | RoundedBoxMesh::RoundedBoxMesh( 64 | double radius, 65 | const gml::dvec3& size, 66 | int slices, 67 | const gml::ivec3& segments 68 | ) : 69 | mergeMesh_{ 70 | { 71 | {{size[1], size[2]}, {segments[1], segments[2]}, size[0] + radius}, 72 | Axis::Z, Axis::X, Axis::Y 73 | }, 74 | { 75 | { 76 | {{size[0], size[2]}, {segments[0], segments[2]}, size[1] + radius}, 77 | Axis::X, Axis::Z, Axis::Y 78 | }, 79 | true, false 80 | }, 81 | {{size[0], size[1]}, {segments[0], segments[1]}, size[2] + radius}, 82 | { 83 | {{size[2], size[1], size[0]}, radius, slices, segments[0]}, 84 | Axis::Z, Axis::Y, Axis::X 85 | }, 86 | { 87 | {{size[0], size[2], size[1]}, radius, slices, segments[1]}, 88 | Axis::X, Axis::Z, Axis::Y 89 | }, 90 | {size, radius, slices, segments[2]}, 91 | {size, radius, slices} 92 | } 93 | { } 94 | 95 | -------------------------------------------------------------------------------- /src/RoundedRectangleShape.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/RoundedRectangleShape.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | 15 | RoundedRectangleShape::RoundedRectangleShape( 16 | double radius, 17 | const gml::dvec2& size, 18 | int slices, 19 | const gml::ivec2& segments 20 | ) : 21 | mergeShape_{ 22 | {{size[0]+radius, -size[1]}, {size[0]+radius, size[1]}, segments[1]}, 23 | {{radius, slices, 0.0, gml::radians(90.0)}, size}, 24 | {{size[0], size[1]+radius}, {-size[0], size[1]+radius}, segments[0]}, 25 | {{radius, slices, gml::radians(90.0), gml::radians(90.0)}, {-size[0], size[1]}}, 26 | {{-size[0]-radius, size[1]}, {-size[0]-radius, -size[1]}, segments[1]}, 27 | {{radius, slices, gml::radians(180.0), gml::radians(90.0)}, -size}, 28 | {{-size[0], -size[1]-radius}, {size[0], -size[1]-radius}, segments[0]}, 29 | {{radius, slices, gml::radians(270.0), gml::radians(90.0)}, {size[0], -size[1]}} 30 | } 31 | { } 32 | 33 | -------------------------------------------------------------------------------- /src/SphereMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #include "generator/SphereMesh.hpp" 8 | 9 | using namespace generator; 10 | 11 | 12 | SphereMesh::SphereMesh( 13 | double radius, 14 | int slices, 15 | int segments, 16 | double sliceStart, 17 | double sliceSweep, 18 | double segmentStart, 19 | double segmentSweep 20 | ) : 21 | axisSwapMesh_{ 22 | { 23 | {radius, segments, segmentStart, segmentSweep}, 24 | {1.0, 0.0}, slices, sliceStart, sliceSweep 25 | }, 26 | Axis::Y, Axis::Z, Axis::X 27 | } 28 | { } 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/SphericalConeMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | #include "generator/SphericalConeMesh.hpp" 8 | 9 | 10 | using namespace generator; 11 | 12 | 13 | namespace { 14 | 15 | double calcSize(double radius, double size) { 16 | return 0.5 * std::sqrt(std::pow(2.0 * size, 2.0) - radius * radius); 17 | } 18 | 19 | } 20 | 21 | 22 | 23 | SphericalConeMesh::SphericalConeMesh( 24 | double radius, 25 | double size, 26 | int slices, 27 | int segments, 28 | int rings, 29 | double start, 30 | double sweep 31 | ) : 32 | translateMesh_{ 33 | { 34 | {radius, calcSize(radius, size), slices, segments, start, sweep}, 35 | { 36 | { 37 | { 38 | 2.0 * size, slices, rings, 39 | start, sweep, 0.0, std::asin(radius/(2.0*size)) 40 | }, 41 | {0.0, 0.0, -calcSize(radius, size)} 42 | }, 43 | false, false, true 44 | } 45 | }, 46 | {0.0, 0.0, size - calcSize(radius, size)} 47 | } 48 | { } 49 | 50 | -------------------------------------------------------------------------------- /src/SphericalTriangleMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/SphericalTriangleMesh.hpp" 9 | 10 | #include 11 | 12 | 13 | using namespace generator; 14 | 15 | 16 | SphericalTriangleMesh::Triangles::Triangles(const SphericalTriangleMesh& mesh) : 17 | mesh_{&mesh}, 18 | row_{0}, 19 | col_{0}, 20 | i_{0} 21 | { } 22 | 23 | 24 | bool SphericalTriangleMesh::Triangles::done() const noexcept { 25 | return row_ == mesh_->segments_; 26 | } 27 | 28 | Triangle SphericalTriangleMesh::Triangles::generate() const { 29 | if (done()) throw std::out_of_range("Done!"); 30 | 31 | Triangle triangle; 32 | 33 | if (col_ % 2 == 0) { 34 | triangle.vertices[0] = i_; 35 | triangle.vertices[1] = i_ + 1; 36 | triangle.vertices[2] = i_ + 1 + mesh_->segments_ - row_; 37 | } 38 | else { 39 | triangle.vertices[0] = i_; 40 | triangle.vertices[1] = i_ + 1 + mesh_->segments_- row_; 41 | triangle.vertices[2] = i_ + mesh_->segments_ - row_; 42 | } 43 | 44 | return triangle; 45 | } 46 | 47 | void SphericalTriangleMesh::Triangles::next() { 48 | if (done()) throw std::out_of_range("Done!"); 49 | 50 | if (col_ % 2 == 0) ++i_; 51 | 52 | ++col_; 53 | if (col_ == 2 * (mesh_->segments_ - row_) - 1) { 54 | ++i_; 55 | col_ = 0; 56 | ++row_; 57 | } 58 | } 59 | 60 | 61 | 62 | SphericalTriangleMesh::Vertices::Vertices(const SphericalTriangleMesh& mesh) : 63 | mesh_{&mesh}, 64 | row_{0}, 65 | col_{0} 66 | { } 67 | 68 | 69 | bool SphericalTriangleMesh::Vertices::done() const noexcept { 70 | return row_ > mesh_->segments_; 71 | } 72 | 73 | MeshVertex SphericalTriangleMesh::Vertices::generate() const { 74 | if (done()) throw std::out_of_range("Done!"); 75 | 76 | MeshVertex vertex; 77 | 78 | if (row_ == mesh_->segments_) { 79 | vertex.position = mesh_->v2_; 80 | vertex.texCoord = gml::dvec2{0.5, 1.0}; 81 | } 82 | else { 83 | const double t = 1.0 / mesh_->segments_ * row_; 84 | const double t2 = 1.0 / (mesh_->segments_ - row_) * col_; 85 | 86 | const auto e1 = gml::slerp(mesh_->v0_, mesh_->v2_, t); 87 | const auto e2 = gml::slerp(mesh_->v1_, mesh_->v2_, t); 88 | vertex.position = gml::slerp(e1, e2, t2); 89 | 90 | vertex.texCoord[0] = t2; 91 | vertex.texCoord[1] = t; 92 | } 93 | 94 | vertex.normal = gml::normalize(vertex.position); 95 | return vertex; 96 | } 97 | 98 | void SphericalTriangleMesh::Vertices::next() { 99 | if (done()) throw std::out_of_range("Done!"); 100 | 101 | ++col_; 102 | if (col_ > mesh_->segments_ - row_) { 103 | col_ = 0; 104 | ++row_; 105 | } 106 | } 107 | 108 | 109 | 110 | SphericalTriangleMesh::SphericalTriangleMesh( 111 | double radius, 112 | int segments 113 | ) : 114 | SphericalTriangleMesh{ 115 | gml::dvec3{radius, 0.0, 0.0}, 116 | gml::dvec3{0.0, radius, 0.0}, 117 | gml::dvec3{0.0, 0.0, radius}, 118 | segments 119 | } 120 | { } 121 | 122 | 123 | SphericalTriangleMesh::SphericalTriangleMesh( 124 | const gml::dvec3& v0, const gml::dvec3& v1, const gml::dvec3& v2, 125 | int segments 126 | ) : 127 | v0_{v0}, 128 | v1_{v1}, 129 | v2_{v2}, 130 | normal_{gml::normal(v0, v1, v2)}, 131 | segments_{segments} 132 | { } 133 | 134 | 135 | SphericalTriangleMesh::Triangles SphericalTriangleMesh::triangles() const noexcept { 136 | return *this; 137 | } 138 | 139 | SphericalTriangleMesh::Vertices SphericalTriangleMesh::vertices() const noexcept { 140 | return *this; 141 | } 142 | 143 | 144 | -------------------------------------------------------------------------------- /src/SpringMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/SpringMesh.hpp" 9 | 10 | using namespace generator; 11 | 12 | 13 | SpringMesh::SpringMesh( 14 | double minor, 15 | double major, 16 | double size, 17 | int slices, 18 | int segments, 19 | double minorStart, 20 | double minorSweep, 21 | double majorStart, 22 | double majorSweep 23 | ) : 24 | extrudeMesh_{ 25 | {minor, slices, minorStart, minorSweep}, 26 | {major, size, segments, majorStart, majorSweep} 27 | } 28 | { } 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/TorusKnotMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/TorusKnotMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | TorusKnotMesh::TorusKnotMesh( 15 | int p, 16 | int q, 17 | int slices, 18 | int segments 19 | ) : 20 | extrudeMesh_{ 21 | {0.25, slices, 0.0, gml::radians(360.0)}, 22 | {p, q, segments} 23 | } 24 | { } 25 | 26 | -------------------------------------------------------------------------------- /src/TorusMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/TorusMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | 15 | TorusMesh::TorusMesh( 16 | double minor, 17 | double major, 18 | int slices, 19 | int segments, 20 | double minorStart, 21 | double minorSweep, 22 | double majorStart, 23 | double majorSweep 24 | ) : 25 | axisSwapMesh_{ 26 | { 27 | { 28 | {minor, slices, minorStart+gml::radians(90.0), minorSweep}, 29 | {0.0, major} 30 | }, 31 | {1.0, 0.0}, segments, majorStart, majorSweep 32 | }, 33 | Axis::Y, Axis::Z, Axis::X 34 | } 35 | { } 36 | 37 | -------------------------------------------------------------------------------- /src/TriangleMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/TriangleMesh.hpp" 9 | 10 | #include 11 | 12 | using namespace generator; 13 | 14 | 15 | 16 | TriangleMesh::Triangles::Triangles(const TriangleMesh& mesh) : 17 | mesh_{&mesh}, 18 | row_{0}, 19 | col_{0}, 20 | i_{0} 21 | { } 22 | 23 | bool TriangleMesh::Triangles::done() const noexcept { 24 | return row_ == mesh_->segments_; 25 | } 26 | 27 | Triangle TriangleMesh::Triangles::generate() const { 28 | if (done()) throw std::out_of_range("Done!"); 29 | 30 | Triangle triangle; 31 | 32 | if (col_ % 2 == 0) { 33 | triangle.vertices[0] = i_; 34 | triangle.vertices[1] = i_ + 1; 35 | triangle.vertices[2] = i_ + 1 + mesh_->segments_- row_; 36 | } 37 | else { 38 | triangle.vertices[0] = i_; 39 | triangle.vertices[1] = i_ + 1 + mesh_->segments_- row_; 40 | triangle.vertices[2] = i_ + mesh_->segments_- row_; 41 | } 42 | 43 | return triangle; 44 | } 45 | 46 | void TriangleMesh::Triangles::next() { 47 | if (done()) throw std::out_of_range("Done!"); 48 | 49 | if (col_ % 2 == 0) ++i_; 50 | 51 | ++col_; 52 | if (col_ == 2 * (mesh_->segments_ - row_) - 1) { 53 | ++i_; 54 | col_ = 0; 55 | ++row_; 56 | } 57 | } 58 | 59 | 60 | 61 | 62 | TriangleMesh::Vertices::Vertices(const TriangleMesh& mesh) : 63 | mesh_{&mesh}, 64 | row_{0}, 65 | col_{0} 66 | { } 67 | 68 | bool TriangleMesh::Vertices::done() const noexcept { 69 | return row_ > mesh_->segments_; 70 | } 71 | 72 | MeshVertex TriangleMesh::Vertices::generate() const { 73 | if (done()) throw std::out_of_range("Done!"); 74 | 75 | MeshVertex vertex; 76 | 77 | if (row_ == mesh_->segments_) { 78 | vertex.position = mesh_->v2_; 79 | vertex.texCoord = gml::dvec2{0.5, 1.0}; 80 | } 81 | else { 82 | const double t = 1.0 / mesh_->segments_ * row_; 83 | const double t2 = 1.0 / (mesh_->segments_ - row_) * col_; 84 | 85 | const auto e1 = gml::mix(mesh_->v0_, mesh_->v2_, t); 86 | const auto e2 = gml::mix(mesh_->v1_, mesh_->v2_, t); 87 | 88 | vertex.position = gml::mix(e1, e2, t2); 89 | 90 | vertex.texCoord[0] = t2; 91 | vertex.texCoord[1] = t; 92 | } 93 | 94 | vertex.normal = mesh_->normal_; 95 | return vertex; 96 | } 97 | 98 | void TriangleMesh::Vertices::next() { 99 | if (done()) throw std::out_of_range("Done!"); 100 | 101 | ++col_; 102 | if (col_ > mesh_->segments_ - row_) { 103 | col_ = 0; 104 | ++row_; 105 | } 106 | } 107 | 108 | 109 | 110 | 111 | TriangleMesh::TriangleMesh(double radius, int segments) : 112 | TriangleMesh{ 113 | radius * gml::normalize(gml::dvec3{-1.0, -1.0, 0.0}), 114 | radius * gml::normalize(gml::dvec3{1.0, -1.0, 0.0}), 115 | gml::dvec3{0.0, radius, 0.0}, 116 | segments 117 | } 118 | { } 119 | 120 | 121 | 122 | TriangleMesh::TriangleMesh( 123 | const gml::dvec3& v0, const gml::dvec3& v1, const gml::dvec3& v2, 124 | int segments 125 | ) : 126 | v0_{v0}, 127 | v1_{v1}, 128 | v2_{v2}, 129 | normal_{gml::normal(v0, v1, v2)}, 130 | segments_{segments} 131 | { } 132 | 133 | TriangleMesh::Triangles TriangleMesh::triangles() const noexcept { 134 | return {*this}; 135 | } 136 | 137 | TriangleMesh::Vertices TriangleMesh::vertices() const noexcept { 138 | return {*this}; 139 | } 140 | 141 | -------------------------------------------------------------------------------- /src/TubeMesh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Markus Ilmola 2 | // This library is free software; you can redistribute it and/or 3 | // modify it under the terms of the GNU Lesser General Public 4 | // License as published by the Free Software Foundation; either 5 | // version 2.1 of the License, or (at your option) any later version. 6 | 7 | 8 | #include "generator/TubeMesh.hpp" 9 | 10 | 11 | using namespace generator; 12 | 13 | 14 | TubeMesh::TubeMesh( 15 | double radius, 16 | double innerRadius, 17 | double size, 18 | int slices, 19 | int segments, 20 | double start, 21 | double sweep 22 | ) : 23 | mergeMesh_{ 24 | {radius, size, slices, segments, start, sweep}, 25 | {{{innerRadius, size, slices, segments, start, sweep}, true, false}} 26 | } 27 | { } 28 | 29 | --------------------------------------------------------------------------------