Mon, 06 Jun 2022 22:01:22 +0300
Giant refactor
#include "polygoncache.h" #include "documentmanager.h" #include "invert.h" Model* resolve(const QString& name, const ModelId callingModelId, DocumentManager* documents) { return documents->findDependencyByName(callingModelId, name); } /** * @brief Gets the GL polygons of the object at the specified position in the model * @param index Index of object in the model * @param polygons_out Vector to add polygons into * @param context Context to use to resolve subfile references */ static std::vector<gl::Polygon> getPolygonsAt(const Model* model, GetPolygonsContext* context) { std::vector<gl::Polygon> 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(gl::edgeLine(edge, id)); }, [&](const Colored<Triangle>& triangle) { result.push_back(gl::triangle(triangle, id)); }, [&](const Colored<Quadrilateral>& quad) { result.push_back(gl::quadrilateral(quad, id)); }, [&](const Colored<ConditionalEdge>& cedge) { result.push_back(gl::conditionalEdge(cedge, id)); }, [&](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 (cache != nullptr) { const bool needInverting = glm::determinant(ref.transformation) < 0; const std::vector<gl::Polygon>& modelPolygons = getCachedPolygons( cache, dependency, context->documents); result.reserve(result.size() + modelPolygons.size()); for (gl::Polygon polygon : modelPolygons) { for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) { const glm::vec4 homogenousVertex {polygon.vertices[i], 1}; polygon.vertices[i] = ref.transformation * homogenousVertex; } if (needInverting != ref.inverted) { gl::invert(polygon); } if (polygon.color == ldraw::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 std::vector<gl::Polygon> &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; }