--- a/src/ldtypes.cpp Wed Sep 25 11:02:44 2013 +0300 +++ b/src/ldtypes.cpp Wed Oct 23 12:46:10 2013 +0300 @@ -31,7 +31,7 @@ cfg (Int, ld_defaultlicense, 0); // List of all LDObjects -List<LDObject*> g_LDObjects; +QList<LDObject*> g_LDObjects; // ============================================================================= // LDObject constructors @@ -44,13 +44,15 @@ qObjListEntry (null), m_glinit (false) { + memset (m_coords, 0, sizeof m_coords); + // Determine ID int32 id = 1; // 0 is invalid - + for (LDObject* obj : g_LDObjects) if (obj->id() >= id) id = obj->id() + 1; - + setID (id); g_LDObjects << this; } @@ -60,34 +62,34 @@ // actually called, for a subclass-less LDObject should never come into existance. // These exist only to satisfy the linker. // ----------------------------------------------------------------------------- -LDObject::Type LDObject::getType() const { - return LDObject::Unidentified; +LDObject::Type LDObject::getType() const +{ return LDObject::Unidentified; } -bool LDObject::hasMatrix() const { - return false; +bool LDObject::hasMatrix() const +{ return false; } -bool LDObject::isColored() const { - return false; +bool LDObject::isColored() const +{ return false; } -bool LDObject::isScemantic() const { - return false; +bool LDObject::isScemantic() const +{ return false; } -str LDObject::typeName() const { - return ""; +str LDObject::typeName() const +{ return ""; } -short LDObject::vertices() const { - return 0; +short LDObject::vertices() const +{ return 0; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::setVertexCoord (int i, Axis ax, double value) { - vertex v = getVertex (i); +void LDObject::setVertexCoord (int i, Axis ax, double value) +{ vertex v = getVertex (i); v[ax] = value; setVertex (i, v); } @@ -96,14 +98,14 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDComment::raw() { - return fmt ("0 %1", text); +str LDComment::raw() +{ return fmt ("0 %1", text); } // ============================================================================= // ----------------------------------------------------------------------------- -str LDSubfile::raw() { - str val = fmt ("1 %1 %2 ", color(), position()); +str LDSubfile::raw() +{ str val = fmt ("1 %1 %2 ", color(), position()); val += transform().stringRep(); val += ' '; val += fileInfo()->name(); @@ -112,71 +114,71 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDLine::raw() { - str val = fmt ("2 %1", color()); - - for (ushort i = 0; i < 2; ++i) +str LDLine::raw() +{ str val = fmt ("2 %1", color()); + + for (int i = 0; i < 2; ++i) val += fmt (" %1", getVertex (i)); - + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDTriangle::raw() { - str val = fmt ("3 %1", color()); - - for (ushort i = 0; i < 3; ++i) +str LDTriangle::raw() +{ str val = fmt ("3 %1", color()); + + for (int i = 0; i < 3; ++i) val += fmt (" %1", getVertex (i)); - + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDQuad::raw() { - str val = fmt ("4 %1", color()); - - for (ushort i = 0; i < 4; ++i) +str LDQuad::raw() +{ str val = fmt ("4 %1", color()); + + for (int i = 0; i < 4; ++i) val += fmt (" %1", getVertex (i)); - + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDCndLine::raw() { - str val = fmt ("5 %1", color()); - +str LDCndLine::raw() +{ str val = fmt ("5 %1", color()); + // Add the coordinates - for (ushort i = 0; i < 4; ++i) + for (int i = 0; i < 4; ++i) val += fmt (" %1", getVertex (i)); - + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDError::raw() { - return contents; +str LDError::raw() +{ return contents; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDVertex::raw() { - return fmt ("0 !LDFORGE VERTEX %1 %2", color(), pos); +str LDVertex::raw() +{ return fmt ("0 !LDFORGE VERTEX %1 %2", color(), pos); } // ============================================================================= // ----------------------------------------------------------------------------- -str LDEmpty::raw() { - return ""; +str LDEmpty::raw() +{ return ""; } // ============================================================================= // ----------------------------------------------------------------------------- -const char* LDBFC::statements[] = { - "CERTIFY CCW", +const char* LDBFC::statements[] = +{ "CERTIFY CCW", "CCW", "CERTIFY CW", "CW", @@ -188,14 +190,14 @@ "NOCLIP", }; -str LDBFC::raw() { - return fmt ("0 BFC %1", LDBFC::statements[type]); +str LDBFC::raw() +{ return fmt ("0 BFC %1", LDBFC::statements[type]); } // ============================================================================= // ----------------------------------------------------------------------------- -List<LDTriangle*> LDQuad::splitToTriangles() { - // Create the two triangles based on this quadrilateral: +QList<LDTriangle*> LDQuad::splitToTriangles() +{ // Create the two triangles based on this quadrilateral: // 0---3 0---3 3 // | | | / /| // | | ==> | / / | @@ -203,12 +205,12 @@ // 1---2 1 1---2 LDTriangle* tri1 = new LDTriangle (getVertex (0), getVertex (1), getVertex (3)); LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3)); - + // The triangles also inherit the quad's color tri1->setColor (color()); tri2->setColor (color()); - - List<LDTriangle*> triangles; + + QList<LDTriangle*> triangles; triangles << tri1; triangles << tri2; return triangles; @@ -216,27 +218,28 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::replace (LDObject* other) { - long idx = getIndex(); +void LDObject::replace (LDObject* other) +{ long idx = getIndex(); assert (idx != -1); - + // Replace the instance of the old object with the new object file()->setObject (idx, other); - + // Remove the old object delete this; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::swap (LDObject* other) { - int i = 0; - for (LDObject* obj : file()->objects()) { - if (obj == this) +void LDObject::swap (LDObject* other) +{ int i = 0; + + for (LDObject* obj : file()->objects()) + { if (obj == this) file()->setObject (i, other); elif (obj == other) file()->setObject (i, this); - + ++i; } @@ -245,131 +248,139 @@ // ============================================================================= // ----------------------------------------------------------------------------- -LDLine::LDLine (vertex v1, vertex v2) { - setVertex (0, v1); +LDLine::LDLine (vertex v1, vertex v2) +{ setVertex (0, v1); setVertex (1, v2); } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject::~LDObject() { - // Remove this object from the selection array if it is there. - for (ulong i = 0; i < g_win->sel().size(); ++i) - if (g_win->sel() [i] == this) - g_win->sel().erase (i); - - // Delete the GL lists - GL::deleteLists (this); - - // Remove this object from the list of LDObjects - ulong pos = g_LDObjects.find (this); - - if (pos < g_LDObjects.size()) - g_LDObjects.erase (pos); - - g_vertexCompiler.forgetObject (this); +LDQuad::LDQuad (const vertex& v0, const vertex& v1, const vertex& v2, const vertex& v3) +{ setVertex (0, v0); + setVertex (1, v1); + setVertex (2, v2); + setVertex (3, v3); } // ============================================================================= // ----------------------------------------------------------------------------- -static void transformObject (LDObject* obj, matrix transform, vertex pos, short parentcolor) { - switch (obj->getType()) { - case LDObject::Line: - case LDObject::CndLine: - case LDObject::Triangle: - case LDObject::Quad: - for (short i = 0; i < obj->vertices(); ++i) { - vertex v = obj->getVertex (i); - v.transform (transform, pos); - obj->setVertex (i, v); - } +LDObject::~LDObject() +{ // If this object was selected, unselect it now + if (selected()) + unselect(); + + // If this object was associated to a file, remove it off it now + if (file()) + file()->forgetObject (this); + + // Delete the GL lists + GL::deleteLists (this); + + // Remove this object from the list of LDObjects + g_LDObjects.removeOne (this); +} - break; +// ============================================================================= +// ----------------------------------------------------------------------------- +static void transformObject (LDObject* obj, matrix transform, vertex pos, short parentcolor) +{ switch (obj->getType()) + { case LDObject::Line: + case LDObject::CndLine: + case LDObject::Triangle: + case LDObject::Quad: - case LDObject::Subfile: - { - LDSubfile* ref = static_cast<LDSubfile*> (obj); + for (short i = 0; i < obj->vertices(); ++i) + { vertex v = obj->getVertex (i); + v.transform (transform, pos); + obj->setVertex (i, v); + } + + break; + + case LDObject::Subfile: + { LDSubfile* ref = static_cast<LDSubfile*> (obj); matrix newMatrix = transform * ref->transform(); vertex newpos = ref->position(); - + newpos.transform (transform, pos); ref->setPosition (newpos); ref->setTransform (newMatrix); } break; - default: - break; + default: + break; } - + if (obj->color() == maincolor) obj->setColor (parentcolor); } // ============================================================================= // ----------------------------------------------------------------------------- -List<LDObject*> LDSubfile::inlineContents (InlineFlags flags) { - List<LDObject*> objs = fileInfo()->inlineContents (flags); - +QList<LDObject*> LDSubfile::inlineContents (InlineFlags flags) +{ QList<LDObject*> objs = fileInfo()->inlineContents (flags); + // Transform the objects - for (LDObject* obj : objs) { - // Set the parent now so we know what inlined this. +for (LDObject * obj : objs) + { // Set the parent now so we know what inlined this. obj->setParent (this); transformObject (obj, transform(), position(), color()); } - + return objs; } // ============================================================================= // ----------------------------------------------------------------------------- -long LDObject::getIndex() const { +long LDObject::getIndex() const +{ #ifndef RELEASE assert (file() != null); #endif - - for (ulong i = 0; i < file()->numObjs(); ++i) + + for (int i = 0; i < file()->numObjs(); ++i) if (file()->obj (i) == this) return i; - + return -1; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::moveObjects (List<LDObject*> objs, const bool up) { - if (objs.size() == 0) +void LDObject::moveObjects (QList<LDObject*> objs, const bool up) +{ if (objs.isEmpty()) return; - + // If we move down, we need to iterate the array in reverse order. const long start = up ? 0 : (objs.size() - 1); const long end = up ? objs.size() : -1; const long incr = up ? 1 : -1; - List<LDObject*> objsToCompile; + QList<LDObject*> objsToCompile; LDFile* file = objs[0]->file(); - - for (long i = start; i != end; i += incr) { - LDObject* obj = objs[i]; - + + for (long i = start; i != end; i += incr) + { LDObject* obj = objs[i]; + const long idx = obj->getIndex(), - target = idx + (up ? -1 : 1); - - if ((up && idx == 0) || (!up && idx == (long) (file->objects().size() - 1))) { - // One of the objects hit the extrema. If this happens, this should be the first + target = idx + (up ? -1 : 1); + + if ( (up && idx == 0) || (!up && idx == (long) (file->objects().size() - 1))) + { // One of the objects hit the extrema. If this happens, this should be the first // object to be iterated on. Thus, nothing has changed yet and it's safe to just // abort the entire operation. assert (i == start); return; } - + objsToCompile << obj; objsToCompile << file->obj (target); - + obj->swap (file->obj (target)); } - - objsToCompile.makeUnique(); - + + removeDuplicates (objsToCompile); + // The objects need to be recompiled, otherwise their pick lists are left with // the wrong index colors which messes up selection. for (LDObject* obj : objsToCompile) @@ -378,8 +389,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDObject::typeName (LDObject::Type type) { - LDObject* obj = LDObject::getDefault (type); +str LDObject::typeName (LDObject::Type type) +{ LDObject* obj = LDObject::getDefault (type); str name = obj->typeName(); delete obj; return name; @@ -387,48 +398,49 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDObject::objectListContents (const List<LDObject*>& objs) { - bool firstDetails = true; +str LDObject::objectListContents (const QList<LDObject*>& objs) +{ bool firstDetails = true; str text = ""; - - if (objs.size() == 0) + + if (objs.isEmpty()) return "nothing"; // :) - - for (long i = 0; i < LDObject::NumTypes; ++i) { - LDObject::Type objType = (LDObject::Type) i; - ulong objCount = 0; - - for (LDObject* obj : objs) + + for (long i = 0; i < LDObject::NumTypes; ++i) + { LDObject::Type objType = (LDObject::Type) i; + int count = 0; + + for (LDObject * obj : objs) if (obj->getType() == objType) - objCount++; - - if (objCount == 0) + count++; + + if (count == 0) continue; - + if (!firstDetails) text += ", "; - - str noun = fmt ("%1%2", typeName (objType), plural (objCount)); + + str noun = fmt ("%1%2", typeName (objType), plural (count)); + + // Plural of "vertex" is "vertices", correct that - // Plural of "vertex" is "vertices". Stupid English. - if (objType == LDObject::Vertex && objCount != 1) + if (objType == LDObject::Vertex && count != 1) noun = "vertices"; - - text += fmt ("%1 %2", objCount, noun); + + text += fmt ("%1 %2", count, noun); firstDetails = false; } - + return text; } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDObject::topLevelParent() { - if (!parent()) +LDObject* LDObject::topLevelParent() +{ if (!parent()) return this; - + LDObject* it = this; - + while (it->parent()) it = it->parent(); @@ -437,73 +449,83 @@ // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDObject::next() const { - long idx = getIndex(); +LDObject* LDObject::next() const +{ long idx = getIndex(); assert (idx != -1); - + if (idx == (long) file()->numObjs() - 1) return null; - + return file()->obj (idx + 1); } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDObject::prev() const { - long idx = getIndex(); +LDObject* LDObject::prev() const +{ long idx = getIndex(); assert (idx != -1); - + if (idx == 0) return null; - + return file()->obj (idx - 1); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::move (vertex vect) { (void) vect; } -void LDEmpty::move (vertex vect) { (void) vect; } -void LDBFC::move (vertex vect) { (void) vect; } -void LDComment::move (vertex vect) { (void) vect; } -void LDError::move (vertex vect) { (void) vect; } - -// ============================================================================= -// ----------------------------------------------------------------------------- -void LDVertex::move (vertex vect) { - pos += vect; +void LDObject::move (vertex vect) +{ (void) vect; +} +void LDEmpty::move (vertex vect) +{ (void) vect; +} +void LDBFC::move (vertex vect) +{ (void) vect; +} +void LDComment::move (vertex vect) +{ (void) vect; +} +void LDError::move (vertex vect) +{ (void) vect; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDSubfile::move (vertex vect) { - setPosition (position() + vect); +void LDVertex::move (vertex vect) +{ pos += vect; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDLine::move (vertex vect) { - for (short i = 0; i < 2; ++i) +void LDSubfile::move (vertex vect) +{ setPosition (position() + vect); +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +void LDLine::move (vertex vect) +{ for (short i = 0; i < 2; ++i) setVertex (i, getVertex (i) + vect); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDTriangle::move (vertex vect) { - for (short i = 0; i < 3; ++i) +void LDTriangle::move (vertex vect) +{ for (short i = 0; i < 3; ++i) setVertex (i, getVertex (i) + vect); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDQuad::move (vertex vect) { - for (short i = 0; i < 4; ++i) +void LDQuad::move (vertex vect) +{ for (short i = 0; i < 4; ++i) setVertex (i, getVertex (i) + vect); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDCndLine::move (vertex vect) { - for (short i = 0; i < 4; ++i) +void LDCndLine::move (vertex vect) +{ for (short i = 0; i < 4; ++i) setVertex (i, getVertex (i) + vect); } @@ -513,8 +535,8 @@ if (type == LDObject::N) \ return new LD##N; -LDObject* LDObject::getDefault (const LDObject::Type type) { - CHECK_FOR_OBJ (Comment) +LDObject* LDObject::getDefault (const LDObject::Type type) +{ CHECK_FOR_OBJ (Comment) CHECK_FOR_OBJ (BFC) CHECK_FOR_OBJ (Line) CHECK_FOR_OBJ (CndLine) @@ -539,8 +561,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void LDTriangle::invert() { - // Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1. +void LDTriangle::invert() +{ // Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1. // Thus, we swap 1 and 2. vertex tmp = getVertex (1); setVertex (1, getVertex (2)); @@ -551,8 +573,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void LDQuad::invert() { - // Quad: 0 -> 1 -> 2 -> 3 +void LDQuad::invert() +{ // Quad: 0 -> 1 -> 2 -> 3 // rev: 0 -> 3 -> 2 -> 1 // Thus, we swap 1 and 3. vertex tmp = getVertex (1); @@ -562,26 +584,26 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void LDSubfile::invert() { - // Subfiles are inverted when they're prefixed with +void LDSubfile::invert() +{ // Subfiles are inverted when they're prefixed with // a BFC INVERTNEXT statement. Thus we need to toggle this status. // For flat primitives it's sufficient that the determinant is // flipped but I don't have a method for checking flatness yet. // Food for thought... - - ulong idx = getIndex(); - - if (idx > 0) { - LDBFC* bfc = dynamic_cast<LDBFC*> (prev()); - - if (bfc && bfc->type == LDBFC::InvertNext) { - // This is prefixed with an invertnext, thus remove it. + + int idx = getIndex(); + + if (idx > 0) + { LDBFC* bfc = dynamic_cast<LDBFC*> (prev()); + + if (bfc && bfc->type == LDBFC::InvertNext) + { // This is prefixed with an invertnext, thus remove it. file()->forgetObject (bfc); delete bfc; return; } } - + // Not inverted, thus prefix it with a new invertnext. LDBFC* bfc = new LDBFC (LDBFC::InvertNext); file()->insertObj (idx, bfc); @@ -589,57 +611,57 @@ // ============================================================================= // ----------------------------------------------------------------------------- -static void invertLine (LDObject* line) { - // For lines, we swap the vertices. I don't think that a +static void invertLine (LDObject* line) +{ // For lines, we swap the vertices. I don't think that a // cond-line's control points need to be swapped, do they? vertex tmp = line->getVertex (0); line->setVertex (0, line->getVertex (1)); line->setVertex (1, tmp); } -void LDLine::invert() { - invertLine (this); +void LDLine::invert() +{ invertLine (this); } -void LDCndLine::invert() { - invertLine (this); +void LDCndLine::invert() +{ invertLine (this); } void LDVertex::invert() {} // ============================================================================= // ----------------------------------------------------------------------------- -LDLine* LDCndLine::demote() { - LDLine* repl = new LDLine; - +LDLine* LDCndLine::demote() +{ LDLine* repl = new LDLine; + for (int i = 0; i < repl->vertices(); ++i) repl->setVertex (i, getVertex (i)); - + repl->setColor (color()); - + replace (repl); return repl; } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDObject::fromID (int id) { - for (LDObject* obj : g_LDObjects) +LDObject* LDObject::fromID (int id) +{ for (LDObject * obj : g_LDObjects) if (obj->id() == id) return obj; - + return null; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDOverlay::raw() { - return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", - filename(), camera(), x(), y(), width(), height()); +str LDOverlay::raw() +{ return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", + filename(), camera(), x(), y(), width(), height()); } -void LDOverlay::move (vertex vect) { - Q_UNUSED (vect) +void LDOverlay::move (vertex vect) +{ Q_UNUSED (vect) } void LDOverlay::invert() {} @@ -649,55 +671,108 @@ // It takes care of history management so we can capture low-level changes, this // makes history stuff work out of the box. // ----------------------------------------------------------------------------- -template<class T> void changeProperty (LDObject* obj, T* ptr, const T& val) { - long idx; - - if (obj->file() && (idx = obj->getIndex()) != -1) { - str before = obj->raw(); +template<class T> static void changeProperty (LDObject* obj, T* ptr, const T& val) +{ long idx; + + if (*ptr == val) + return; + + if (obj->file() && (idx = obj->getIndex()) != -1) + { str before = obj->raw(); *ptr = val; str after = obj->raw(); - + obj->file()->addToHistory (new EditHistory (idx, before, after)); - } else + } + else *ptr = val; } // ============================================================================= // ----------------------------------------------------------------------------- -READ_ACCESSOR (short, LDObject::color) { - return m_color; +READ_ACCESSOR (short, LDObject::color) +{ return m_color; +} + +SET_ACCESSOR (short, LDObject::setColor) +{ changeProperty (this, &m_color, val); +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +const vertex& LDObject::getVertex (int i) const +{ return m_coords[i]->data(); } -SET_ACCESSOR (short, LDObject::setColor) { - changeProperty (this, &m_color, val); +void LDObject::setVertex (int i, const vertex& vert) +{ changeProperty (this, &m_coords[i], LDSharedVertex::getSharedVertex (vert)); +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +void LDMatrixObject::setPosition (const vertex& a) +{ changeProperty (linkPointer(), &m_position, LDSharedVertex::getSharedVertex (a)); +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +READ_ACCESSOR (matrix, LDMatrixObject::transform) +{ return m_transform; +} + +SET_ACCESSOR (matrix, LDMatrixObject::setTransform) +{ changeProperty (linkPointer(), &m_transform, val); } // ============================================================================= // ----------------------------------------------------------------------------- -const vertex& LDObject::getVertex (int i) const { - return m_coords[i]; +static QMap<vertex, LDSharedVertex*> g_sharedVerts; + +LDSharedVertex* LDSharedVertex::getSharedVertex (const vertex& a) +{ auto it = g_sharedVerts.find (a); + + if (it == g_sharedVerts.end()) + { LDSharedVertex* v = new LDSharedVertex (a); + g_sharedVerts[a] = v; + return v; + } + + return *it; } -void LDObject::setVertex (int i, const vertex& vert) { - changeProperty (this, &m_coords[i], vert); +// ============================================================================= +// ----------------------------------------------------------------------------- +void LDSharedVertex::addRef (LDObject* a) +{ m_refs << a; } // ============================================================================= // ----------------------------------------------------------------------------- -READ_ACCESSOR (vertex, LDMatrixObject::position) { - return m_position; -} +void LDSharedVertex::delRef (LDObject* a) +{ m_refs.removeOne (a); -SET_ACCESSOR (vertex, LDMatrixObject::setPosition) { - changeProperty (linkPointer(), &m_position, val); + if (m_refs.empty()) + { g_sharedVerts.remove (m_data); + delete this; + } } // ============================================================================= // ----------------------------------------------------------------------------- -READ_ACCESSOR (matrix, LDMatrixObject::transform) { - return m_transform; +void LDObject::select() +{ if (!file()) + { log ("Warning: Object #%1 cannot be selected as it is not assigned a file!\n", id()); + return; + } + + file()->addToSelection (this); } -SET_ACCESSOR (matrix, LDMatrixObject::setTransform) { - changeProperty (linkPointer(), &m_transform, val); +void LDObject::unselect() +{ if (!file()) + { log ("Warning: Object #%1 cannot be unselected as it is not assigned a file!\n", id()); + return; + } + + file()->removeFromSelection (this); } \ No newline at end of file