X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fbase%2Frs_entitycontainer.cpp;h=e3c409193fa6b0c36cf51510d44c49c173e3f0d6;hb=bd2b29c8735d83ab48df13c3efee53f63570473e;hp=85a38b5e8d629104fd6b0c06cec2dfec52771fdb;hpb=16ce54abf01ca3032e42a5bb11a4afcf9014dcca;p=architektonas diff --git a/src/base/rs_entitycontainer.cpp b/src/base/rs_entitycontainer.cpp index 85a38b5..e3c4091 100644 --- a/src/base/rs_entitycontainer.cpp +++ b/src/base/rs_entitycontainer.cpp @@ -3,7 +3,9 @@ // Part of the Architektonas Project // Originally part of QCad Community Edition by Andrew Mustun // Extensively rewritten and refactored by James L. Hammons -// (C) 2010 Underground Software +// Portions copyright (C) 2001-2003 RibbonSoft +// Copyright (C) 2010 Underground Software +// See the README and GPLv2 files for licensing and warranty information // // JLH = James L. Hammons // @@ -24,8 +26,8 @@ #include "rs_insert.h" #include "rs_spline.h" #include "rs_information.h" -#include "rs_graphicview.h" -#include "paintintf.h" +#include "graphicview.h" +#include "paintinterface.h" bool RS_EntityContainer::autoUpdateBorders = true; @@ -348,7 +350,7 @@ void RS_EntityContainer::addEntity(RS_Entity * entity) */ //printf("RS_EntityContainer::addEntity(): entity=%08X\n", entity); - if (entity == NULL) + if (!entity) return; if (entity->rtti() == RS2::EntityImage || entity->rtti() == RS2::EntityHatch) @@ -1191,284 +1193,221 @@ Vector RS_EntityContainer::getNearestEndpoint(const Vector & coord, double * dis return closestPoint; } +Vector RS_EntityContainer::getNearestPointOnEntity(const Vector & coord, + bool onEntity, double * dist, RS_Entity ** entity) +{ + Vector point(false); + RS_Entity * e = getNearestEntity(coord, dist, RS2::ResolveNone); -Vector RS_EntityContainer::getNearestPointOnEntity(const Vector& coord, - bool onEntity, double* dist, RS_Entity** entity) { - - Vector point(false); - - RS_Entity* e = getNearestEntity(coord, dist, RS2::ResolveNone); - - if (e!=NULL && e->isVisible()) { - point = e->getNearestPointOnEntity(coord, onEntity, dist, entity); - } + if (e && e->isVisible()) + point = e->getNearestPointOnEntity(coord, onEntity, dist, entity); - return point; + return point; } +Vector RS_EntityContainer::getNearestCenter(const Vector & coord, double * dist) +{ + Vector point(false); + RS_Entity * closestEntity = getNearestEntity(coord, NULL, RS2::ResolveNone); + if (closestEntity) + point = closestEntity->getNearestCenter(coord, dist); -Vector RS_EntityContainer::getNearestCenter(const Vector& coord, - double* dist) { - - Vector point(false); - RS_Entity* closestEntity; - - //closestEntity = getNearestEntity(coord, NULL, RS2::ResolveAll); - closestEntity = getNearestEntity(coord, NULL, RS2::ResolveNone); - - if (closestEntity!=NULL) { - point = closestEntity->getNearestCenter(coord, dist); - } - - return point; + return point; } +Vector RS_EntityContainer::getNearestMiddle(const Vector & coord, double * dist) +{ + Vector point(false); + RS_Entity * closestEntity = getNearestEntity(coord, NULL, RS2::ResolveNone); + if (closestEntity) + point = closestEntity->getNearestMiddle(coord, dist); -Vector RS_EntityContainer::getNearestMiddle(const Vector& coord, - double* dist) { - - Vector point(false); - RS_Entity* closestEntity; - - closestEntity = getNearestEntity(coord, NULL, RS2::ResolveNone); - - if (closestEntity!=NULL) { - point = closestEntity->getNearestMiddle(coord, dist); - } - - return point; - - - /* - double minDist = RS_MAXDOUBLE; // minimum measured distance - double curDist; // currently measured distance - Vector closestPoint; // closest found endpoint - Vector point; // endpoint found - - for (RS_Entity* en = firstEntity(); - en != NULL; - en = nextEntity()) { - - if (en->isVisible()) { - point = en->getNearestMiddle(coord, &curDist); - if (curDistgetNearestDist(distance, coord, dist); -Vector RS_EntityContainer::getNearestDist(double distance, - const Vector& coord, - double* dist) { - - Vector point(false); - RS_Entity* closestEntity; - - closestEntity = getNearestEntity(coord, NULL, RS2::ResolveNone); - - if (closestEntity!=NULL) { - point = closestEntity->getNearestDist(distance, coord, dist); - } - - return point; + return point; } - - /** * @return The intersection which is closest to 'coord' */ -Vector RS_EntityContainer::getNearestIntersection(const Vector& coord, - double* dist) { - - double minDist = RS_MAXDOUBLE; // minimum measured distance - double curDist; // currently measured distance - Vector closestPoint(false); // closest found endpoint - Vector point; // endpoint found - VectorSolutions sol; - RS_Entity* closestEntity; - - closestEntity = getNearestEntity(coord, NULL, RS2::ResolveAll); - - if (closestEntity!=NULL) { - for (RS_Entity* en = firstEntity(RS2::ResolveAll); - en != NULL; - en = nextEntity(RS2::ResolveAll)) { - - if (en->isVisible() && en!=closestEntity) { - sol = RS_Information::getIntersection(closestEntity, - en, - true); - - for (int i=0; i<4; i++) { - point = sol.get(i); - if (point.valid) { - curDist = coord.distanceTo(point); - - if (curDistisVisible() && en!=closestEntity) + { + sol = RS_Information::getIntersection(closestEntity, en, true); -Vector RS_EntityContainer::getNearestRef(const Vector& coord, - double* dist) { + for(int i=0; i<4; i++) + { + point = sol.get(i); - double minDist = RS_MAXDOUBLE; // minimum measured distance - double curDist; // currently measured distance - Vector closestPoint(false); // closest found endpoint - Vector point; // endpoint found + if (point.valid) + { + curDist = coord.distanceTo(point); - for (RS_Entity* en = firstEntity(); - en != NULL; - en = nextEntity()) { + if (curDist < minDist) + { + closestPoint = point; + minDist = curDist; - if (en->isVisible()) { - point = en->getNearestRef(coord, &curDist); - if (point.valid && curDistisVisible()) + { + point = en->getNearestRef(coord, &curDist); - for (RS_Entity* en = firstEntity(); - en != NULL; - en = nextEntity()) { + if (point.valid && curDist < minDist) + { + closestPoint = point; + minDist = curDist; - if (en->isVisible() && en->isSelected() && !en->isParentSelected()) { - point = en->getNearestSelectedRef(coord, &curDist); - if (point.valid && curDistisVisible() && en->isSelected() && !en->isParentSelected()) + { + point = en->getNearestSelectedRef(coord, &curDist); - RS_DEBUG->print("RS_EntityContainer::getDistanceToPoint"); + if (point.valid && curDist < minDist) + { + closestPoint = point; + minDist = curDist; - double minDist = RS_MAXDOUBLE; // minimum measured distance - double curDist; // currently measured distance - RS_Entity* closestEntity = NULL; // closest entity found - RS_Entity* subEntity = NULL; + if (dist) + *dist = curDist; + } + } + } - //int k=0; - for (RS_Entity* e = firstEntity(level); - e != NULL; - e = nextEntity(level)) { + return closestPoint; +} - if (e->isVisible()) { - RS_DEBUG->print("entity: getDistanceToPoint"); - RS_DEBUG->print("entity: %d", e->rtti()); - curDist = e->getDistanceToPoint(coord, &subEntity, level, solidDist); +double RS_EntityContainer::getDistanceToPoint(const Vector & coord, + RS_Entity ** entity, RS2::ResolveLevel level, double solidDist) +{ + RS_DEBUG->print("RS_EntityContainer::getDistanceToPoint"); - RS_DEBUG->print("entity: getDistanceToPoint: OK"); + double minDist = RS_MAXDOUBLE; // minimum measured distance + double curDist; // currently measured distance + RS_Entity * closestEntity = NULL; // closest entity found + RS_Entity * subEntity = NULL; - if (curDistisVisible()) + { + RS_DEBUG->print("entity: getDistanceToPoint"); + RS_DEBUG->print("entity: %d", e->rtti()); + curDist = e->getDistanceToPoint(coord, &subEntity, level, solidDist); + RS_DEBUG->print("entity: getDistanceToPoint: OK"); - if (entity!=NULL) { - *entity = closestEntity; - } - RS_DEBUG->print("RS_EntityContainer::getDistanceToPoint: OK"); + if (curDistprint("RS_EntityContainer::getDistanceToPoint: OK"); + return minDist; +} -RS_Entity* RS_EntityContainer::getNearestEntity(const Vector& coord, - double* dist, - RS2::ResolveLevel level) { +RS_Entity * RS_EntityContainer::getNearestEntity(const Vector & coord, + double * dist, RS2::ResolveLevel level) +{ + RS_DEBUG->print("RS_EntityContainer::getNearestEntity"); + RS_Entity * e = NULL; - RS_DEBUG->print("RS_EntityContainer::getNearestEntity"); + // distance for points inside solids: + double solidDist = RS_MAXDOUBLE; - RS_Entity* e = NULL; + if (dist) + solidDist = *dist; - // distance for points inside solids: - double solidDist = RS_MAXDOUBLE; - if (dist!=NULL) { - solidDist = *dist; - } + double d = getDistanceToPoint(coord, &e, level, solidDist); - double d = getDistanceToPoint(coord, &e, level, solidDist); - - if (e!=NULL && e->isVisible()==false) { - e = NULL; - } + if (e && e->isVisible() == false) + e = NULL; - // if d is negative, use the default distance (used for points inside solids) - if (dist!=NULL) { - *dist = d; - } - RS_DEBUG->print("RS_EntityContainer::getNearestEntity: OK"); + // if d is negative, use the default distance (used for points inside solids) + if (dist) + *dist = d; - return e; + RS_DEBUG->print("RS_EntityContainer::getNearestEntity: OK"); + return e; } - - /** * Rearranges the atomic entities in this container in a way that connected * entities are stored in the right order and direction. @@ -1477,217 +1416,217 @@ RS_Entity* RS_EntityContainer::getNearestEntity(const Vector& coord, * @retval true all contours were closed * @retval false at least one contour is not closed */ -bool RS_EntityContainer::optimizeContours() { - - RS_DEBUG->print("RS_EntityContainer::optimizeContours"); - - Vector current(false); - Vector start(false); - RS_EntityContainer tmp; - - bool changed = false; - bool closed = true; +bool RS_EntityContainer::optimizeContours() +{ + RS_DEBUG->print("RS_EntityContainer::optimizeContours"); - for (uint ci=0; ciisEdge() && !e1->isContainer() && - !e1->isProcessed()) { + bool changed = false; + bool closed = true; - RS_AtomicEntity* ce = (RS_AtomicEntity*)e1; + for(uint ci=0; cisetProcessed(true); - tmp.addEntity(ce->clone()); - current = ce->getEndpoint(); - start = ce->getStartpoint(); + if (e1 && e1->isEdge() && !e1->isContainer() && !e1->isProcessed()) + { + RS_AtomicEntity * ce = (RS_AtomicEntity *)e1; - // find all connected entities: - bool done; - do { - done = true; - for (uint ei=0; eisetProcessed(true); + tmp.addEntity(ce->clone()); + current = ce->getEndpoint(); + start = ce->getStartpoint(); - if (e2!=NULL && e2->isEdge() && !e2->isContainer() && - !e2->isProcessed()) { + // find all connected entities: + bool done; - RS_AtomicEntity* e = (RS_AtomicEntity*)e2; + do + { + done = true; + for(uint ei=0; eigetStartpoint().distanceTo(current) < - 1.0e-4) { + if (e2 != NULL && e2->isEdge() && !e2->isContainer() && + !e2->isProcessed()) + { + RS_AtomicEntity * e = (RS_AtomicEntity *)e2; - e->setProcessed(true); - tmp.addEntity(e->clone()); - current = e->getEndpoint(); + if (e->getStartpoint().distanceTo(current) < 1.0e-4) + { + e->setProcessed(true); + tmp.addEntity(e->clone()); + current = e->getEndpoint(); + done = false; + } + else if (e->getEndpoint().distanceTo(current) < 1.0e-4) + { + e->setProcessed(true); + RS_AtomicEntity * cl = (RS_AtomicEntity *)e->clone(); + cl->reverse(); + tmp.addEntity(cl); + current = cl->getEndpoint(); + changed = true; + done = false; + } + } + } - done=false; - } else if (e->getEndpoint().distanceTo(current) < - 1.0e-4) { + if (!done) + changed = true; + } + while (!done); - e->setProcessed(true); - RS_AtomicEntity* cl = (RS_AtomicEntity*)e->clone(); - cl->reverse(); - tmp.addEntity(cl); - current = cl->getEndpoint(); + if (current.distanceTo(start) > 1.0e-4) + closed = false; + } + } - changed = true; - done=false; - } - } - } - if (!done) { - changed = true; - } - } while (!done); + // remove all atomic entities: + bool done; - if (current.distanceTo(start)>1.0e-4) { - closed = false; - } - } - } + do + { + done = true; - // remove all atomic entities: - bool done; - do { - done = true; - for (RS_Entity* en=firstEntity(); en!=NULL; en=nextEntity()) { - if (!en->isContainer()) { - removeEntity(en); - done = false; - break; - } - } - } while (!done); + for(RS_Entity * en=firstEntity(); en!=NULL; en=nextEntity()) + { + if (!en->isContainer()) + { + removeEntity(en); + done = false; + break; + } + } + } + while (!done); - // add new sorted entities: - for (RS_Entity* en=tmp.firstEntity(); en!=NULL; en=tmp.nextEntity()) { - en->setProcessed(false); - addEntity(en->clone()); - } + // add new sorted entities: + for(RS_Entity * en=tmp.firstEntity(); en!=NULL; en=tmp.nextEntity()) + { + en->setProcessed(false); + addEntity(en->clone()); + } - RS_DEBUG->print("RS_EntityContainer::optimizeContours: OK"); - return closed; + RS_DEBUG->print("RS_EntityContainer::optimizeContours: OK"); + return closed; } +bool RS_EntityContainer::hasEndpointsWithinWindow(Vector v1, Vector v2) +{ + for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) + { + if (e->hasEndpointsWithinWindow(v1, v2)) + return true; + } -bool RS_EntityContainer::hasEndpointsWithinWindow(Vector v1, Vector v2) { - for (RS_Entity* e=firstEntity(RS2::ResolveNone); - e!=NULL; - e=nextEntity(RS2::ResolveNone)) { - if (e->hasEndpointsWithinWindow(v1, v2)) { - return true; - } - } - - return false; + return false; } +void RS_EntityContainer::move(Vector offset) +{ + for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) + e->move(offset); -void RS_EntityContainer::move(Vector offset) { - for (RS_Entity* e=firstEntity(RS2::ResolveNone); - e!=NULL; - e=nextEntity(RS2::ResolveNone)) { - e->move(offset); - } - if (autoUpdateBorders) { - calculateBorders(); - } + if (autoUpdateBorders) + calculateBorders(); } +void RS_EntityContainer::rotate(Vector center, double angle) +{ + for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) + e->rotate(center, angle); - -void RS_EntityContainer::rotate(Vector center, double angle) { - for (RS_Entity* e=firstEntity(RS2::ResolveNone); - e!=NULL; - e=nextEntity(RS2::ResolveNone)) { - e->rotate(center, angle); - } - if (autoUpdateBorders) { - calculateBorders(); - } + if (autoUpdateBorders) + calculateBorders(); } +void RS_EntityContainer::scale(Vector center, Vector factor) +{ + if (fabs(factor.x) > RS_TOLERANCE && fabs(factor.y) > RS_TOLERANCE) + { + for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) + e->scale(center, factor); + } - -void RS_EntityContainer::scale(Vector center, Vector factor) { - if (fabs(factor.x)>RS_TOLERANCE && fabs(factor.y)>RS_TOLERANCE) { - for (RS_Entity* e=firstEntity(RS2::ResolveNone); - e!=NULL; - e=nextEntity(RS2::ResolveNone)) { - e->scale(center, factor); - } - } - if (autoUpdateBorders) { - calculateBorders(); - } + if (autoUpdateBorders) + calculateBorders(); } - - -void RS_EntityContainer::mirror(Vector axisPoint1, Vector axisPoint2) { - if (axisPoint1.distanceTo(axisPoint2)>1.0e-6) { - for (RS_Entity* e=firstEntity(RS2::ResolveNone); - e!=NULL; - e=nextEntity(RS2::ResolveNone)) { - e->mirror(axisPoint1, axisPoint2); - } - } +void RS_EntityContainer::mirror(Vector axisPoint1, Vector axisPoint2) +{ + if (axisPoint1.distanceTo(axisPoint2) > 1.0e-6) + { + for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) + e->mirror(axisPoint1, axisPoint2); + } } +void RS_EntityContainer::stretch(Vector firstCorner, Vector secondCorner, + Vector offset) +{ + if (getMin().isInWindow(firstCorner, secondCorner) && + getMax().isInWindow(firstCorner, secondCorner)) + { + move(offset); + } + else + { + for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) + e->stretch(firstCorner, secondCorner, offset); + } -void RS_EntityContainer::stretch(Vector firstCorner, - Vector secondCorner, - Vector offset) { - - if (getMin().isInWindow(firstCorner, secondCorner) && - getMax().isInWindow(firstCorner, secondCorner)) { - - move(offset); - } else { - for (RS_Entity* e=firstEntity(RS2::ResolveNone); - e!=NULL; - e=nextEntity(RS2::ResolveNone)) { - e->stretch(firstCorner, secondCorner, offset); - } - } - - // some entitiycontainers might need an update (e.g. RS_Leader): - update(); + // some entitiycontainers might need an update (e.g. RS_Leader): + update(); } +void RS_EntityContainer::moveRef(const Vector & ref, const Vector & offset) +{ + for(RS_Entity* e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) + e->moveRef(ref, offset); - -void RS_EntityContainer::moveRef(const Vector& ref, - const Vector& offset) { - - for (RS_Entity* e=firstEntity(RS2::ResolveNone); - e!=NULL; - e=nextEntity(RS2::ResolveNone)) { - e->moveRef(ref, offset); - } - if (autoUpdateBorders) { - calculateBorders(); - } + if (autoUpdateBorders) + calculateBorders(); } void RS_EntityContainer::moveSelectedRef(const Vector & ref, const Vector & offset) { - for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) - e->moveSelectedRef(ref, offset); + for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) + e->moveSelectedRef(ref, offset); if (autoUpdateBorders) - calculateBorders(); + calculateBorders(); } -//void RS_EntityContainer::draw(RS_Painter* painter, RS_GraphicView* view, -void RS_EntityContainer::draw(PaintInterface * painter, RS_GraphicView * view, double /*patternOffset*/) +void RS_EntityContainer::draw(PaintInterface * painter, GraphicView * view, double /*patternOffset*/) { - if (painter == NULL || view == NULL) + if (!painter || !view) return; - for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e = nextEntity(RS2::ResolveNone)) + for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone)) +#if 0 +{ +if (e->rtti() == RS2::EntityText) +{ + std::cout << "About to draw TEXT entity... " + << "TEXT=\"" << ((RS_Text *)e)->getText().toAscii().data() << "\"" << std::endl; +} +//OK, we have text, but no insert entities at least none that are drawn... +//Ah! But with a standard text entity, it DOES have them! +else if (e->rtti() == RS2::EntityInsert) +{ + std::cout << "About to draw INSERT entity... " + << "INSERT=\"" << ((RS_Insert *)e)->getData().name.toAscii().data() << "\"" << std::endl; +} +#endif view->drawEntity(e); +#if 0 +} +#endif } /** @@ -1696,16 +1635,13 @@ void RS_EntityContainer::draw(PaintInterface * painter, RS_GraphicView * view, d std::ostream & operator<<(std::ostream & os, RS_EntityContainer & ec) { static int indent = 0; - char * tab = new char[indent * 2 + 1]; - for(int i=0; igetName().toLatin1().data() << "\n"; + << ec.getLayer()->getName().toLatin1().data() << "\n"; } else { @@ -1763,9 +1699,8 @@ os << s.toAscii().data(); } os << tab << "\n\n"; - --indent; + indent--; delete[] tab; return os; } -