{"id":13532870,"url":"https://github.com/ilmola/generator","last_synced_at":"2025-04-01T21:31:13.952Z","repository":{"id":35113695,"uuid":"39299605","full_name":"ilmola/generator","owner":"ilmola","description":"A procedural geometry generation library for C++11","archived":false,"fork":false,"pushed_at":"2023-01-02T23:15:03.000Z","size":397,"stargazers_count":211,"open_issues_count":10,"forks_count":26,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-11-02T20:31:59.015Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"projectcalico/go-build","license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ilmola.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-18T13:45:53.000Z","updated_at":"2024-10-06T21:20:18.000Z","dependencies_parsed_at":"2023-01-15T14:06:17.743Z","dependency_job_id":null,"html_url":"https://github.com/ilmola/generator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilmola%2Fgenerator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilmola%2Fgenerator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilmola%2Fgenerator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilmola%2Fgenerator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ilmola","download_url":"https://codeload.github.com/ilmola/generator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246713052,"owners_count":20821836,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T07:01:14.493Z","updated_at":"2025-04-01T21:31:11.805Z","avatar_url":"https://github.com/ilmola.png","language":"C++","funding_links":[],"categories":["C++","Libraries","GameProgramming"],"sub_categories":["C++"],"readme":"# Generator - A procedural geometry generation library.\n\n![Examples](doc/GroupPicture.png)\n\nThe purpose of this library is to easily generate procedural meshes of geometric\nprimitives such as spheres, boxes, cones, cylinders etc.\n\nGenerator is **not** a graphics library. It will only produce data for any graphics\nlibrary to use.\n\n\n## Compiling ##\n\nTo compile you will need a C++11 compatible compiler (tested with gcc 4.8) and\ncmake (tested with cmake 2.8).\n\nGenerator needs a vector math library to work. It will use [GML](https://github.com/ilmola/gml.git).\nThere are no other dependencies.\n\nCompile with:\n~~~console\ncmake .\nmake\n~~~\n\nIf GML is not in the include path, you can give it's path with: `-DGML_INCLUDE_DIR`\ncommand line argument.\n\n~~~console\ncmake . -DGML_INCLUDE_DIR=path/to/gml\nmake\n~~~\n\nThe library `libgenerator` will be in the `lib` directory.\n\nIn `images` directory there is a program called `generate` that can generate svg\ntest images.\n\nYou can generate documentation with Doxygen. Run `generate` in the `images`\ndirectory before `doxygen` as the documentation uses images generated by it.\n\n\n## Usage ##\n\nMake sure that that Generator and the GML math library are in the include path.\n\nTo include all primitives use:\n~~~c++\n#include \u003cgenerator/generator.hpp\u003e\n~~~\n\nTo include individual primitives include a header file that has the same name as\nthe primitive class.\n~~~c++\n#include \u003cgenerator/SphereMesh.hpp\u003e\n#include \u003cgenerator/HelixPath.hpp\u003e\n#include \u003cgenerator/CircleShape.hpp\u003e\n~~~\n\nIf you'd prefer to use [GLM](http://glm.g-truc.net/), a similar (but more heavyweight)\nlibrary, build with the `#define` `GENERATOR_USE_GLM`.\n\nEverything in the library is under the namespace `generator`.\nThe examples in this document will omit this namespace.\n\nYou will also need to link with `libgenerator`.\n\n\n## Coordinate systems ##\n\nGenerator uses a right handed coordinate system, just like OpenGL does.\n\nAll angles are in radians positive, with the direction being counterclockwise\nwhen looking towards the axis.\n\nVertices in triangles are in counterclockwise order.\n\nAll calculations are done `double` precision.\n\n\n## Concepts ##\n\nThere are two main concepts in the library: \"primitives\" and \"generators\".\n\nPrimitives produce generators. Generators generate values such as vertex\ncoordinates.\n\n\n## Primitives ##\n\nThere are three types of primitives: \"shapes\", \"paths\" and \"meshes\". All\nprimitive class names end with their type e.g. `SphereMesh`, `HelixPath` or\n`CircleShape`.\n\n\n### Shapes ###\n\nShapes are a set of `ShapeVertex`es on the 2d xy-plane and a set of `Edge`s\nconnecting them.\n~~~c++\nclass ShapeVertex {\npublic:\n\tgml::dvec2 position;\n\tgml::dvec2 tangent;\n\tgml::dvec2 normal() const noexcept;\n\tdouble texCoord;\n};\n~~~\n~~~c++\nclass Edge {\npublic:\n\tgml::uvec2 vertices;\n};\n~~~\n\nAll shapes have these methods:\n~~~c++\nEdgeGenerator edges() const noexcept;\nVertexGenerator vertices() const noexcept;\n~~~\n\nWhere `EdgeGenerator` and `VertexGenerator` can be a arbitrary types. The shape\n**must** outlive the generators it produces. If the shape is mutated the generators\nare invalidated. Shapes can be mutated only via assignment. The are no setter\nmethods.\n\nAvailable shapes are:\n\n- `BezierShape`\n- `CircleShape`\n- `GridShape`\n- `LineShape`\n- `ParametricShape`\n- `RectangleShape`\n- `RoundedRectangleShape`\n\n\n### Paths ###\n\nPaths are a set of `PathVertex`es in 3d space and a set of `Edge`s connecting them.\n\n~~~c++\nclass PathVertex {\npublic:\n\tgml::dvec3 position;\n\tgml::dvec3 tangent;\n\tgml::dvec3 normal;\n\tgml::dvec3 binormal() const noexcept;\n\tdouble texCoord;\n};\n~~~\n\nAll paths have these methods:\n~~~c++\nEdgeGenerator edges() const noexcept;\nVertexGenerator vertices() const noexcept;\n~~~\n\n`EdgeGenerator` and `VertexGenerator` are arbitrary types.\n\nAvailable paths are:\n\n- `HelixPath`\n- `KnotPath`\n- `LinePath`\n- `ParametricPath`\n\n\n### Meshes ###\n\nMeshes are a set of `MeshVertex`es in 3d space and a set of `Triangle`s connecting\nthem.\n\n~~~c++\nclass MeshVertex {\npublic:\n\tgml::dvec3 position;\n\tgml::dvec3 normal;\n\tgml::dvec2 texCoord;\n};\n~~~\n~~~c++\nclass Triangle {\npublic:\n\tgml::uvec3 vertices;\n};\n~~~\n\n\nAll meshes have these methods:\n~~~c++\nTriangleGenerator triangles() const noexcept;\nVertexGenerator vertices() const noexcept;\n~~~\n\nAgain, `TriangleGenerator` and `VertexGenerator` can be any type.\n\nAvailable meshes are:\n\n- `BezierMesh`\n- `BoxMesh`\n- `CappedConeMesh`\n- `CappedCylinderMesh`\n- `CappedTubeMesh`\n- `CapsuleMesh`\n- `ConeMesh`\n- `ConvexPolygonMesh`\n- `CylinderMesh`\n- `DiskMesh`\n- `DodecahedronMesh`\n- `PlaneMesh`\n- `IcosahedronMesh`\n- `IcoSphereMesh`\n- `ParametricMesh`\n- `RoundedBoxMesh`\n- `SphereMesh`\n- `SphericalConeMesh`\n- `SphericalTriangleMesh`\n- `SpringMesh`\n- `TeapotMesh`\n- `TorusMesh`\n- `TorusKnotMesh`\n- `TriangleMesh`\n- `TubeMesh`\n\n\n## Generators ##\n\nExcept for cached values (which should be considered an implementation detail),\nprimitives don't store any data (vertices etc).  All data is generated on the\nfly with generators.\n\nGenerators are made by calling `edges()`, `triangles()` or `vertices()` on the\nprimitive. Generators are lightweight objects analogous to iterators. They\ntypically only contain a pointer back to the Primitive and state info for iteration.\nAny number of generators for the same primitive can exist at the same time.\n\nGenerators can have arbitrary types. Use the keyword `auto` to avoid the need\nto explicitly specify them.\n\n~~~c++\nSphereMesh sphere{};\nauto vertices = sphere.vertices();\n~~~\n\nFor cases where `auto` cannot be used, the helper class templates `EdgeGeneratorType`,\n`TriangleGeneratorType` and `VertexGeneratorType` are provided in `util.hpp`.\n\n~~~c++\ntypename VertexGeneratorType\u003cSphereMesh\u003e::Type vertices = sphere.vertices();\n~~~\n\nIf the generator type is known only at runtime, the type-erasing class template\n`AnyGenerator` can be used (in `AnyGenerator.hpp`).\n\n~~~c++\nAnyGenerator\u003cMeshVertex\u003e vertices = sphere.vertices();\n~~~\n\nIf the generator's primitive type is known at compile time, the `AnyShape`, `AnyPath`,\nand `AnyMesh` types may be used for respectively storing shapes, path and meshes.\n\nAll generators have the following methods:\n~~~c++\nbool done() const noexcept;\nValue generate() const;\nvoid next();\n~~~\n\nWhere `Value` can be `Edge`, `Triangle`, `ShapeVertex`, `PathVertex` or\n`MeshVertex`.\n\nThese methods can be used to iterate over all values in the generators.\n\n~~~c++\nSphereMesh sphere{};\nauto vertices = sphere.vertices();\nwhile (!vertices.done()) {\n\tMeshVertex vertex = vertices.generate();\n\t// Do something with vertex\n\tvertices.next();\n}\n~~~\n\nOnce `done()` returns `true`, calling `next()` or `generate()` will throw\n`std::out_of_bounds`. There is no way to rewind the generator.\n\nIf the vertex/edge/triangle count needs to be known before iteration use the\nhelper function `count` from `util.hpp`.\n\n~~~c++\ncount(sphere.vertices());\n~~~\n\n\n## Iterators ##\n\nIt is possible to use an iterator to drive a generator. Use free functions\n`begin` and `end` on the generator to get the iterators. If the generator is\ndeleted the iterators are invalid.\n\n~~~c++\nSphereMesh sphere{};\nauto vertices = sphere.vertices();\nstd::for_each(begin(vertices), end(vertices), [] (const MeshVertex\u0026 vertex) {\n\t// do something with vertex\n});\n~~~\n\n`for` loops will also work.\n~~~c++\nSphereMesh sphere{};\nfor (const MeshVertex\u0026 vertex : sphere.vertices()) {\n\t// do something with vertex\n}\n~~~\n\n**NOTE:** Be aware of a lifetime issue with a temporary primitive and the for loop.\n~~~c++\nfor (const MeshVertex\u0026 vertex : SphereMesh{}.vertices()) {\n\t// Error! Undefined behaviour!\n}\n~~~\n\n\n## Modifiers ##\n\nSome primitives such as `TranslateMesh` do not generate data of their own.\nInstead they modify data generated by another primitives. They are called\n\"modifiers\".\n\nModifiers store the primitive they modify.\n\n~~~c++\nTranslateMesh\u003cSphereMesh\u003e translatedSphere{SphereMesh{}, {1.0f, 0.0f, 0.0f}};\nfor (const auto\u0026 vertex : translatedSphere.vertices()) { }\n~~~\n\nMultiple modifiers can be nested.\n\nEach modifier also has a function to make one. The function form has the same\nname as the class but starts with a lower case letter. `translateMesh` instead\nof `TranslateMesh` etc. This makes template argument deduction possible.\n\n~~~c++\nauto result = translateMesh(\n\trotateMesh(\n\t\tscaleMesh(TorusMesh{}, {0.5f, 1.0f, 1.0}),\n\t\tgml::radians(90.0), Axis::Y\n\t),\n\t{1.0f, 0.0f, 0.0f}\n);\nfor (const MeshVertex\u0026 vertex : result.vertices()) { }\n~~~\n\nAvailable modifiers for shapes are:\n\n\n- `AxisSwapShape`\n- `FlipShape`\n- `MergeShape`\n- `RepeatShape`\n- `RotateShape`\n- `ScaleShape`\n- `SubdivideShape`\n- `TransformShape`\n- `TranslateShape`\n\n\nAvailable modifiers for paths are:\n\n- `AxisSwapPath`\n- `FlipPath`\n- `MergePath`\n- `RepeatPath`\n- `RotatePath`\n- `ScalePath`\n- `SubdividePath`\n- `TransformPath`\n- `TranslatePath`\n\n\nAvailable modifiers for meshes are:\n\n- `AxisSwapMesh`\n- `ExtrudeMesh`\n- `FlipMesh`\n- `LatheMesh`\n- `MergeMesh`\n- `RepeatMesh`\n- `RotateMesh`\n- `ScaleMesh`\n- `SpherifyMesh`\n- `SubdivideMesh`\n- `TransformMesh`\n- `TranslateMesh`\n- `UvSwapMesh`\n\n\n\n## Preview and debug ##\n\nFor preview and debug purposes generator has class `SvgWriter` that can create\nSVG images of primitives.\n\nIt also has class `ObjWriter` that can write OBJ files of meshes that can be\nviewed with most 3d programs such as [Blender](http://www.blender.org).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filmola%2Fgenerator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filmola%2Fgenerator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filmola%2Fgenerator/lists"}