Wed, 15 Jun 2022 12:41:57 +0300
Render line segments during draw mode nicer
#include "polygoncache.h" #include "documentmanager.h" #include "invert.h" Model* resolve(const QString& name, const ModelId callingModelId, DocumentManager* documents) { return documents->findDependencyByName(callingModelId, name); } static PolygonElement transformed( PolygonElement element, const glm::mat4& transform) { 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) { std::vector<WithId<PolygonElement>> result; for (int i = 0; i < model->size(); i += 1) { const ModelElement& element = (*model)[i]; const ModelId id = model->idAt(i); std::visit<void>(overloaded{ [&](const Colored<LineSegment>& edge) { result.push_back({{edge, edge.color}, id}); }, [&](const Colored<Triangle>& triangle) { result.push_back({{triangle, triangle.color}, id}); }, [&](const Colored<Quadrilateral>& quad) { result.push_back({{quad, quad.color}, id}); }, [&](const Colored<ConditionalEdge>& cedge) { result.push_back({{cedge, cedge.color}, id}); }, [&result, &id, context](const Colored<SubfileReference>& ref) { Model* dependency = context->documents->findDependencyByName(context->modelId, ref.name); PolygonCache* cache = nullptr; if (dependency != nullptr) { cache = findPolygonCacheForModel(dependency, context->documents); } if (cache != nullptr) { const bool needInverting = glm::determinant(ref.transformation) < 0; const PolygonCache::vector_type* modelPolygons = getCachedPolygons( cache, dependency, context->documents); reserveMore(result, modelPolygons->size()); for (WithId<PolygonElement> polygon : *modelPolygons) { polygon = {transformed(polygon, ref.transformation), polygon.id}; if (needInverting != ref.inverted) { gl::invert(polygon); } if (polygon.color == MAIN_COLOR) { polygon.color = ref.color; } polygon.id = id; result.push_back(polygon); } } }, [](const ModelElement&) {} }, element); } return result; } /** * @brief Gets a list of GL polygons that are used to represent this model. * @details Will build polygons if polygons are outdated. * @param documents Documents to use to resolve subfile references * @return vector of GL polygons */ const PolygonCache::vector_type* getCachedPolygons( PolygonCache *cache, Model *model, DocumentManager *documents) { if (cache->needRecache) { cache->cachedPolygons.clear(); const std::optional<ModelId> modelId = documents->findIdForModel(model); if (modelId.has_value()) { GetPolygonsContext context{modelId.value(), documents}; cache->cachedPolygons = getPolygonsAt(model, &context); } cache->needRecache = false; } return &cache->cachedPolygons; }