src/linetypes/subfilereference.cpp

Wed, 09 Mar 2022 13:01:50 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 09 Mar 2022 13:01:50 +0200
changeset 173
8a3047468994
parent 158
5bd755eaa5a8
child 177
f69d53c053df
permissions
-rw-r--r--

Fix performance issues in Model::find

#include "subfilereference.h"
#include "documentmanager.h"
#include "invert.h"
#include "polygoncache.h"

ldraw::SubfileReference::SubfileReference
(
	const glm::mat4& transformation,
	const QString& referenceName,
	const Color color
) :
	ColoredObject{color},
	transformation{transformation},
	referenceName{referenceName}
{
}

QVariant ldraw::SubfileReference::getProperty(Property property) const
{
	switch (property)
	{
	case Property::Transformation:
		return QVariant::fromValue(this->transformation);
	case Property::ReferenceName:
		return this->referenceName;
	default:
		return ColoredObject::getProperty(property);
	}
}

void ldraw::SubfileReference::setProperty(SetPropertyResult* result, const PropertyKeyValue& pair)
{
	LDRAW_OBJECT_HANDLE_SET_PROPERTY(Transformation, {this->transformation = value;});
	LDRAW_OBJECT_HANDLE_SET_PROPERTY(ReferenceName, {this->referenceName = value;});
	ldraw::ColoredObject::setProperty(result, pair);
}

QString ldraw::SubfileReference::textRepresentation() const
{
	return this->referenceName + " " + utility::vertexToStringParens(this->position());
}

void ldraw::SubfileReference::getPolygons
(
	std::vector<gl::Polygon>& polygons,
	GetPolygonsContext* context
) const
{
	Model* dependency = this->resolve(context->modelId, context->documents);
	PolygonCache* referencedModelPolygonBuilder = nullptr;
	if (dependency != nullptr)
	{
		const auto dependencyModelId = context->documents->findIdForModel(dependency);
		if (dependencyModelId.has_value())
		{
			referencedModelPolygonBuilder = context->documents->getPolygonCacheForModel(dependencyModelId.value());
		}
	}
	if (referencedModelPolygonBuilder != nullptr)
	{
		const bool needInverting = glm::determinant(this->transformation) < 0;
		const std::vector<gl::Polygon> modelPolygons = referencedModelPolygonBuilder->getPolygons(context->documents);
		polygons.reserve(polygons.size() + modelPolygons.size());
		for (gl::Polygon polygon : modelPolygons)
		{
			for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
			{
				glm::vec4 vertex {polygon.vertices[i], 1};
				vertex = this->transformation * vertex;
				polygon.vertices[i] = vertex;
			}
			if (needInverting != this->isInverted)
			{
				gl::invert(polygon);
			}
			if (polygon.color == ldraw::MAIN_COLOR)
			{
				polygon.color = this->colorIndex;
			}
			polygon.id = this->id;
			polygons.push_back(polygon);
		}
	}
}

glm::vec3 ldraw::SubfileReference::position() const
{
	return this->transformation[3];
}

void ldraw::SubfileReference::invert()
{
	this->isInverted = not this->isInverted;
}

Model* ldraw::SubfileReference::resolve(const ModelId callingModelId, DocumentManager* documents) const
{
	return documents->findDependencyByName(callingModelId, this->referenceName);
}

ldraw::Object::Type ldraw::SubfileReference::typeIdentifier() const
{
	return Type::SubfileReference;
}

QDataStream& ldraw::SubfileReference::serialize(QDataStream &stream) const
{
	return ColoredObject::serialize(stream) << this->transformation << this->referenceName << this->isInverted;
}

QDataStream& ldraw::SubfileReference::deserialize(QDataStream &stream)
{
	return ColoredObject::deserialize(stream) >> this->transformation >> this->referenceName >> this->isInverted;
}

QString ldraw::SubfileReference::toLDrawCode() const
{
	QString result;
	if (this->isInverted)
	{
		result += "0 BFC INVERTNEXT\r\n";
	}
	result += utility::format(
		"1 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14",
		this->colorIndex.index,
		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],
		this->referenceName);
	return result;
}

QString ldraw::SubfileReference::iconName() const
{
	return ":/icons/linetype-subfile.png";
}

mercurial