Thu, 09 Jun 2022 19:11:27 +0300
Now builds again
src/gl/compiler.cpp | file | annotate | diff | comparison | revisions | |
src/model.h | file | annotate | diff | comparison | revisions | |
src/polygoncache.cpp | file | annotate | diff | comparison | revisions | |
src/polygoncache.h | file | annotate | diff | comparison | revisions |
--- a/src/gl/compiler.cpp Thu Jun 09 13:32:55 2022 +0300 +++ b/src/gl/compiler.cpp Thu Jun 09 19:11:27 2022 +0300 @@ -125,6 +125,36 @@ } )"; +template<typename Fn> +constexpr void pointsToRender(const PolygonElement& element, Fn func) +{ + visitPolygon<void>( + [&func](const LineSegment& edge) + { + func(edge.p1, glm::vec3{}); + func(edge.p2, glm::vec3{}); + }, + [&func](const Triangle& tri) + { + func(tri.p1, normalVector({tri.p3, tri.p1, tri.p2})); + func(tri.p2, normalVector({tri.p1, tri.p2, tri.p3})); + func(tri.p3, normalVector({tri.p2, tri.p3, tri.p1})); + }, + [&func](const Quadrilateral& quad) + { + func(quad.p1, normalVector({quad.p4, quad.p1, quad.p2})); + func(quad.p2, normalVector({quad.p1, quad.p2, quad.p3})); + func(quad.p3, normalVector({quad.p2, quad.p3, quad.p4})); + func(quad.p4, normalVector({quad.p3, quad.p4, quad.p1})); + }, + [&func](const ConditionalEdge& cedge) + { + func(cedge.p1, glm::vec3{}); + func(cedge.p2, glm::vec3{}); + }, + element); +} + void gl::buildShaders( QOpenGLShaderProgram* shaderProgram, const char* vertexShaderSource, @@ -165,10 +195,8 @@ void gl::initializeModelShaders(gl::ModelShaders *modelShaders) { - if (not modelShaders->initialized) - { - for (auto& shader : modelShaders->shaderObjects) - { + if (not modelShaders->initialized) { + for (auto& shader : modelShaders->shaderObjects) { shader.program = std::make_unique<QOpenGLShaderProgram>(); gl::buildShaders(shader.program.get(), ::vertexShaderSource, ::fragmentShaderSource); shader.program->bind(); @@ -177,8 +205,7 @@ shader.buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); shader.vertexArray.create(); shader.vertexArray.bind(); - for (int k : {0, 1, 2, 3, 4}) - { + for (int k : {0, 1, 2, 3, 4}) { shader.program->enableAttributeArray(k); } using Vertex = ModelShaders::Vertex; @@ -209,16 +236,11 @@ template<typename Fn> void iterateModelPolygons(Model* model, DocumentManager* context, Fn&& fn) { - std::optional<ModelId> modelId = context->findIdForModel(model); - if (modelId.has_value()) - { - PolygonCache* cache = context->getPolygonCacheForModel(modelId.value()); - if (cache != nullptr) - { - for (const WithId<PolygonElement>& polygon : getCachedPolygons(cache, model, context)) - { - fn(polygon); - } + PolygonCache* cache = findPolygonCacheForModel(model, context); + if (cache != nullptr) { + const PolygonCache::vector_type* polygons = getCachedPolygons(cache, model, context); + for (const WithId<PolygonElement>& polygon : *polygons) { + fn(polygon); } } } @@ -255,9 +277,9 @@ BoundingBox result = emptyBoundingBox; iterateModelPolygons(model, context, [&](const PolygonElement& polygon) { - visitPoints( - [&result](const glm::vec3& p) { addPointToBox(result, p); }, - polygon); + visitPoints([&result](const glm::vec3& p) { + addPointToBox(result, p); + }, polygon); }); return result; } @@ -275,24 +297,18 @@ for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) { shader.cachedData.clear(); } - iterateModelPolygons(model, context, [&](const PolygonElement& polygon) + iterateModelPolygons(model, context, [&](const WithId<PolygonElement>& polygon) { const int index = static_cast<int>(classifyPolygon(polygon)); std::vector<gl::ModelShaders::Vertex>& vertexBuffer = shaders->shaderObjects[index].cachedData; - auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices()); - reserveMore(vertexBuffer, polygon.numPolygonVertices()); const QColor color = getColorForPolygon(polygon, preferences, colorTable); - for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) - { - const glm::vec3& v1 = vertexRing[i - 1]; - const glm::vec3& v2 = vertexRing[i]; - const glm::vec3& v3 = vertexRing[i + 1]; + pointsToRender(polygon, [&](const glm::vec3& point, const glm::vec3& normal){ gl::ModelShaders::Vertex& vertex = vertexBuffer.emplace_back(); - vertex.position = polygon.vertices[i]; - vertex.normal = glm::normalize(glm::cross(v1 - v2, v3 - v2)); + vertex.position = point; + vertex.normal = normal; vertex.color = glm::vec4{color.redF(), color.greenF(), color.blueF(), color.alphaF()}; vertex.id = polygon.id.value; - } + }); }); for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) {
--- a/src/model.h Thu Jun 09 13:32:55 2022 +0300 +++ b/src/model.h Thu Jun 09 19:11:27 2022 +0300 @@ -60,6 +60,12 @@ }; template<typename T, typename R> +struct transfer_reference<const T&, R> +{ + using type = const std::remove_reference_t<R>&; +}; + +template<typename T, typename R> struct transfer_reference<T&&, R> { using type = std::remove_reference_t<R>&&; @@ -88,7 +94,7 @@ ConditionalEdge>>; template<typename T> -struct remove_color { using type = T; }; +struct remove_color {}; template<typename T> struct remove_color<Colored<T>> { using type = T; }; @@ -97,30 +103,43 @@ struct remove_color<Colored<T>&> { using type = T&; }; template<typename T> +struct remove_color<const Colored<T>&> { using type = const T&; }; + +template<typename T> struct remove_color<Colored<T>&&> { using type = T&&; }; template<typename T> using remove_color_t = typename remove_color<T>::type; +static_assert(std::is_same_v<remove_color_t<Colored<Triangle>>, Triangle>); +static_assert(std::is_same_v<remove_color_t<Colored<Triangle>&>, Triangle&>); +static_assert(std::is_same_v<remove_color_t<const Colored<Triangle>&>, const Triangle&>); + template<typename T> constexpr remove_color_t<T&&> extract_colored(T&& x) { return static_cast<remove_color_t<T&&>>(x); } -template<typename Ret, typename T> -constexpr auto visitPolygon( - std::function<Ret(transfer_reference_t<T&&, LineSegment>)> f1, - std::function<Ret(transfer_reference_t<T&&, Triangle>)> f2, - std::function<Ret(transfer_reference_t<T&&, Quadrilateral>)> f3, - std::function<Ret(transfer_reference_t<T&&, ConditionalEdge>)> f4, - T&& element) +template<typename Ret, typename Fn1, typename Fn2, typename Fn3, typename Fn4, typename T> +constexpr auto visitPolygon(Fn1&& f1, Fn2&& f2, Fn3&& f3, Fn4&& f4, T&& element) { - return std::visit(overloaded{f1, f2, f3, f4}, extract_colored(element)); + if (std::holds_alternative<LineSegment>(element)) { + return f1(std::get<LineSegment>(element)); + } + else if (std::holds_alternative<Triangle>(element)) { + return f2(std::get<Triangle>(element)); + } + else if (std::holds_alternative<Quadrilateral>(element)) { + return f3(std::get<Quadrilateral>(element)); + } + else { + return f4(std::get<ConditionalEdge>(element)); + } } template<typename T, typename Fn> -constexpr void visitPoints(T&& element, Fn func) +constexpr void visitPoints(Fn&& func, T&& element) { visitPolygon<void>( [&func](transfer_reference_t<T&&, LineSegment> edge)
--- a/src/polygoncache.cpp Thu Jun 09 13:32:55 2022 +0300 +++ b/src/polygoncache.cpp Thu Jun 09 19:11:27 2022 +0300 @@ -11,12 +11,23 @@ PolygonElement element, const glm::mat4& transform) { - visitPoints(element, [&transform](glm::vec3& p) { + visitPoints([&transform](glm::vec3& p) { p = transform * glm::vec4{p, 1}; - }); + }, element); return element; } +PolygonCache* findPolygonCacheForModel(Model* model, DocumentManager* context) +{ + std::optional<ModelId> modelId = context->findIdForModel(model); + if (modelId.has_value()) { + return context->getPolygonCacheForModel(modelId.value()); + } + else { + return nullptr; + } +} + static std::vector<WithId<PolygonElement>> getPolygonsAt( const Model* model, GetPolygonsContext* context) @@ -39,24 +50,20 @@ [&](const Colored<ConditionalEdge>& cedge) { result.push_back({{cedge, cedge.color}, id}); }, - [&](const Colored<SubfileReference>& ref) { + [&result, &id, context](const Colored<SubfileReference>& ref) { Model* dependency = context->documents->findDependencyByName(context->modelId, ref.name); PolygonCache* cache = nullptr; - if (dependency != nullptr) - { - const auto dependencyModelId = context->documents->findIdForModel(dependency); - if (dependencyModelId.has_value()) { - cache = context->documents->getPolygonCacheForModel(dependencyModelId.value()); - } + if (dependency != nullptr) { + cache = findPolygonCacheForModel(dependency, context->documents); } if (cache != nullptr) { const bool needInverting = glm::determinant(ref.transformation) < 0; - const auto& modelPolygons = getCachedPolygons( + const PolygonCache::vector_type* modelPolygons = getCachedPolygons( cache, dependency, context->documents); - result.reserve(result.size() + modelPolygons.size()); - for (WithId<PolygonElement> polygon : modelPolygons) { + reserveMore(result, modelPolygons->size()); + for (WithId<PolygonElement> polygon : *modelPolygons) { polygon = {transformed(polygon, ref.transformation), polygon.id}; if (needInverting != ref.inverted) { gl::invert(polygon); @@ -81,7 +88,7 @@ * @param documents Documents to use to resolve subfile references * @return vector of GL polygons */ -const std::vector<WithId<PolygonElement>> &getCachedPolygons( +const PolygonCache::vector_type* getCachedPolygons( PolygonCache *cache, Model *model, DocumentManager *documents) @@ -97,5 +104,5 @@ } cache->needRecache = false; } - return cache->cachedPolygons; + return &cache->cachedPolygons; }
--- a/src/polygoncache.h Thu Jun 09 13:32:55 2022 +0300 +++ b/src/polygoncache.h Thu Jun 09 19:11:27 2022 +0300 @@ -17,11 +17,13 @@ struct PolygonCache { - std::vector<WithId<PolygonElement>> cachedPolygons; + using vector_type = std::vector<WithId<PolygonElement>>; + vector_type cachedPolygons; bool needRecache = true; }; -const std::vector<WithId<PolygonElement>>& getCachedPolygons( +const PolygonCache::vector_type* getCachedPolygons( PolygonCache* cache, Model* model, class DocumentManager* documents); +PolygonCache* findPolygonCacheForModel(Model* model, DocumentManager* context);