Wed, 25 May 2022 17:42:02 +0300
Simplify PolygonCache
#include "compoundobject.h" #include "documentmanager.h" #include "invert.h" #include "polygoncache.h" ldraw::CompoundObject::CompoundObject ( const glm::mat4& transformation, const Color color ) : ColoredObject{color}, transformation{transformation} { } QVariant ldraw::CompoundObject::getProperty(Property property) const { switch (property) { case Property::Transformation: return QVariant::fromValue(this->transformation); case Property::IsInverted: return this->isInverted; default: return ColoredObject::getProperty(property); } } void ldraw::CompoundObject::setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) { LDRAW_OBJECT_HANDLE_SET_PROPERTY(Transformation, {this->transformation = value;}); LDRAW_OBJECT_HANDLE_SET_PROPERTY(IsInverted, {this->isInverted = value;}); ldraw::ColoredObject::setProperty(result, pair); } glm::vec3 ldraw::CompoundObject::position() const { return this->transformation[3]; } void ldraw::CompoundObject::invert(GetPolygonsContext *context) { const std::optional<Axis> flatDimension = context ? this->flatDimension(context) : std::optional<Axis>{}; if (flatDimension.has_value()) { glm::mat4 matrix = glm::identity<glm::mat4>(); matrix[*flatDimension][*flatDimension] = -1.0f; this->transformation *= matrix; } else { this->isInverted = not this->isInverted; } } QDataStream& ldraw::CompoundObject::serialize(QDataStream &stream) const { return ColoredObject::serialize(stream) << this->transformation << this->isInverted; } QDataStream& ldraw::CompoundObject::deserialize(QDataStream &stream) { return ColoredObject::deserialize(stream) >> this->transformation >> this->isInverted; } /** * @brief Finds out in which dimension the object is flat in. In that dimension all vertices have a value of 0. * If the object is not flat, this does not return a value. * @param model Model to find out flatness of * @param documents Where to look for subfiles * @returns dimension the model is flat in, if such dimension exists, no value otherwise. */ std::optional<Axis> ldraw::CompoundObject::flatDimension(GetPolygonsContext *context) const { // The dimensions that this model is potentially flat in. QVector<Axis> dimensions = {X, Y, Z}; std::vector<gl::Polygon> polygons; this->getPolygons(polygons, context); for (const gl::Polygon& polygon : polygons) { for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) { const glm::vec3& v_i = polygon.vertices[i]; if (not qFuzzyCompare(v_i.x, 0.0f)) { dimensions.removeOne(X); } if (not qFuzzyCompare(v_i.y, 0.0f)) { dimensions.removeOne(Y); } if (not qFuzzyCompare(v_i.z, 0.0f)) { dimensions.removeOne(Z); } } // If there are no more dimensions left, we can exit the loop. if (dimensions.isEmpty()) { break; } } if (dimensions.size() == 1) { // The model is flat in one dimension, return that. // If the model is flat in two or three dimensions, it's not really a valid model. return dimensions[0]; } else { // The model is not flat. return {}; } } QString ldraw::CompoundObject::transformToBareString() const { return utility::format( "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12", this->transformation[3][0], this->transformation[3][1], this->transformation[3][2], this->transformation[0][0], this->transformation[1][0], this->transformation[2][0], this->transformation[0][1], this->transformation[1][1], this->transformation[2][1], this->transformation[0][2], this->transformation[1][2], this->transformation[2][2]); }