diff -r c595cfb4791c -r 31540c1f22ea src/types.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/types.cc Mon Jan 20 15:04:26 2014 +0200
@@ -0,0 +1,416 @@
+/*
+ * LDForge: LDraw parts authoring CAD
+ * Copyright (C) 2013, 2014 Santeri Piippo
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "main.h"
+#include "types.h"
+#include "misc.h"
+#include "ldtypes.h"
+#include "document.h"
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+QString DoFormat (QList args)
+{
+ assert (args.size() >= 1);
+ QString text = args[0].value();
+
+ for (uchar i = 1; i < args.size(); ++i)
+ text = text.arg (args[i].value());
+
+ return text;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Vertex::Vertex (double x, double y, double z)
+{
+ m_coords[X] = x;
+ m_coords[Y] = y;
+ m_coords[Z] = z;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void Vertex::move (const Vertex& other)
+{
+ for_axes (ax)
+ m_coords[ax] += other[ax];
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+double Vertex::distanceTo (const Vertex& other) const
+{
+ double dx = abs (x() - other.x());
+ double dy = abs (y() - other.y());
+ double dz = abs (z() - other.z());
+ return sqrt ((dx * dx) + (dy * dy) + (dz * dz));
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Vertex Vertex::midpoint (const Vertex& other)
+{
+ Vertex mid;
+
+ for_axes (ax)
+ mid[ax] = (getCoordinate (ax) + other[ax]) / 2;
+
+ return mid;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+QString Vertex::toString (bool mangled) const
+{
+ QString fmtstr = "%1 %2 %3";
+
+ if (mangled)
+ fmtstr = "(%1, %2, %3)";
+
+ return fmt (fmtstr, x(), y(), z());
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void Vertex::transform (const Matrix& matr, const Vertex& pos)
+{
+ double x2 = (matr[0] * x()) + (matr[1] * y()) + (matr[2] * z()) + pos[X];
+ double y2 = (matr[3] * x()) + (matr[4] * y()) + (matr[5] * z()) + pos[Y];
+ double z2 = (matr[6] * x()) + (matr[7] * y()) + (matr[8] * z()) + pos[Z];
+
+ x() = x2;
+ y() = y2;
+ z() = z2;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Vertex Vertex::operator-() const
+{
+ return Vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool Vertex::operator!= (const Vertex& other) const
+{
+ return !operator== (other);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool Vertex::operator== (const Vertex& other) const
+{
+ return getCoordinate (X) == other[X] &&
+ getCoordinate (Y) == other[Y] &&
+ getCoordinate (Z) == other[Z];
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Vertex& Vertex::operator/= (const double d)
+{
+ for_axes (ax)
+ m_coords[ax] /= d;
+
+ return *this;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Vertex Vertex::operator/ (const double d) const
+{
+ Vertex other (*this);
+ return other /= d;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Vertex& Vertex::operator+= (const Vertex& other)
+{
+ move (other);
+ return *this;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Vertex Vertex::operator+ (const Vertex& other) const
+{
+ Vertex newvert (*this);
+ newvert.move (other);
+ return newvert;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+int Vertex::operator< (const Vertex& other) const
+{
+ if (operator== (other))
+ return false;
+
+ if (getCoordinate (X) < other[X])
+ return true;
+
+ if (getCoordinate (X) > other[X])
+ return false;
+
+ if (getCoordinate (Y) < other[Y])
+ return true;
+
+ if (getCoordinate (Y) > other[Y])
+ return false;
+
+ return getCoordinate (Z) < other[Z];
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Matrix::Matrix (double vals[])
+{
+ for (int i = 0; i < 9; ++i)
+ m_vals[i] = vals[i];
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Matrix::Matrix (double fillval)
+{
+ for (int i = 0; i < 9; ++i)
+ m_vals[i] = fillval;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Matrix::Matrix (initlist vals)
+{
+ assert (vals.size() == 9);
+ memcpy (&m_vals[0], & (*vals.begin()), sizeof m_vals);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void Matrix::puts() const
+{
+ for (int i = 0; i < 3; ++i)
+ {
+ for (int j = 0; j < 3; ++j)
+ log ("%1\t", m_vals[ (i * 3) + j]);
+
+ log ("\n");
+ }
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+QString Matrix::toString() const
+{
+ QString val;
+
+ for (int i = 0; i < 9; ++i)
+ {
+ if (i > 0)
+ val += ' ';
+
+ val += QString::number (m_vals[i]);
+ }
+
+ return val;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void Matrix::zero()
+{
+ memset (&m_vals[0], 0, sizeof m_vals);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Matrix Matrix::mult (const Matrix& other) const
+{
+ Matrix val;
+ val.zero();
+
+ for (int i = 0; i < 3; ++i)
+ for (int j = 0; j < 3; ++j)
+ for (int k = 0; k < 3; ++k)
+ val[(i * 3) + j] += m_vals[(i * 3) + k] * other[(k * 3) + j];
+
+ return val;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Matrix& Matrix::operator= (const Matrix& other)
+{
+ memcpy (&m_vals[0], &other.m_vals[0], sizeof m_vals);
+ return *this;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+double Matrix::getDeterminant() const
+{
+ return (val (0) * val (4) * val (8)) +
+ (val (1) * val (5) * val (6)) +
+ (val (2) * val (3) * val (7)) -
+ (val (2) * val (4) * val (6)) -
+ (val (1) * val (3) * val (8)) -
+ (val (0) * val (5) * val (7));
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+bool Matrix::operator== (const Matrix& other) const
+{
+ for (int i = 0; i < 9; ++i)
+ if (val (i) != other[i])
+ return false;
+
+ return true;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+LDBoundingBox::LDBoundingBox()
+{
+ reset();
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDBoundingBox::calculate()
+{
+ reset();
+
+ if (!getCurrentDocument())
+ return;
+
+ for (LDObject* obj : getCurrentDocument()->getObjects())
+ calcObject (obj);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDBoundingBox::calcObject (LDObject* obj)
+{
+ switch (obj->getType())
+ {
+ case LDObject::ELine:
+ case LDObject::ETriangle:
+ case LDObject::EQuad:
+ case LDObject::ECondLine:
+ {
+ for (int i = 0; i < obj->vertices(); ++i)
+ calcVertex (obj->getVertex (i));
+ } break;
+
+ case LDObject::ESubfile:
+ {
+ LDSubfile* ref = static_cast (obj);
+ LDObjectList objs = ref->inlineContents (LDSubfile::DeepCacheInline);
+
+ for (LDObject * obj : objs)
+ {
+ calcObject (obj);
+ obj->deleteSelf();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+LDBoundingBox& LDBoundingBox::operator<< (const Vertex& v)
+{
+ calcVertex (v);
+ return *this;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+LDBoundingBox& LDBoundingBox::operator<< (LDObject* obj)
+{
+ calcObject (obj);
+ return *this;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDBoundingBox::calcVertex (const Vertex& v)
+{
+ for_axes (ax)
+ {
+ m_Vertex0[ax] = min (v[ax], m_Vertex0[ax]);
+ m_Vertex1[ax] = max (v[ax], m_Vertex1[ax]);
+ }
+
+ setEmpty (false);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDBoundingBox::reset()
+{
+ m_Vertex0[X] = m_Vertex0[Y] = m_Vertex0[Z] = 10000.0;
+ m_Vertex1[X] = m_Vertex1[Y] = m_Vertex1[Z] = -10000.0;
+ setEmpty (true);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+double LDBoundingBox::size() const
+{
+ double xscale = (m_Vertex0[X] - m_Vertex1[X]);
+ double yscale = (m_Vertex0[Y] - m_Vertex1[Y]);
+ double zscale = (m_Vertex0[Z] - m_Vertex1[Z]);
+ double size = zscale;
+
+ if (xscale > yscale)
+ {
+ if (xscale > zscale)
+ size = xscale;
+ }
+ elif (yscale > zscale)
+ size = yscale;
+
+ if (abs (size) >= 2.0f)
+ return abs (size / 2);
+
+ return 1.0f;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+Vertex LDBoundingBox::center() const
+{
+ return Vertex (
+ (m_Vertex0[X] + m_Vertex1[X]) / 2,
+ (m_Vertex0[Y] + m_Vertex1[Y]) / 2,
+ (m_Vertex0[Z] + m_Vertex1[Z]) / 2);
+}