~ubuntu-branches/ubuntu/precise/fritzing/precise

« back to all changes in this revision

Viewing changes to src/autoroute/cmrouter/cmrouter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Georges Khaznadar
  • Date: 2011-08-26 10:11:05 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110826101105-w5hmn7zcf93ig5v6
Tags: 0.6.3b-1
* upgrapded to the newer upstream version
* parameters of the function GraphicsUtils::distanceFromLine in 
  src/svg/groundplanegenerator.cpp:767 are now declared as doubles,
  which Closes: #636441
* the new version fixes src/utils/folderutils.cpp, which
  Closes: #636061

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
********************************************************************
31
31
 
32
 
$Revision: 5178 $:
 
32
$Revision: 5375 $:
33
33
$Author: cohen@irascible.com $:
34
 
$Date: 2011-07-05 14:46:13 +0200 (Tue, 05 Jul 2011) $
 
34
$Date: 2011-08-08 21:38:25 +0200 (Mon, 08 Aug 2011) $
35
35
 
36
36
********************************************************************/
37
37
 
107
107
#include <limits>
108
108
#include <QApplication>
109
109
#include <QMessageBox> 
110
 
#include <QElapsedTimer>
 
110
//#include <QElapsedTimer>                      // forces a dependency on qt 4.7
111
111
#include <QSettings>
112
112
#include <QCryptographicHash>
113
113
 
115
115
static const int TILEFACTOR = 1000;
116
116
static int TileStandardWireWidth = 0;
117
117
static int TileHalfStandardWireWidth = 0;
118
 
static qreal StandardWireWidth = 0;
119
 
static qreal HalfStandardWireWidth = 0;
120
 
static const qreal CloseEnough = 0.5;
 
118
static double StandardWireWidth = 0;
 
119
static double HalfStandardWireWidth = 0;
 
120
static const double CloseEnough = 0.5;
121
121
static const int GridEntryAlpha = 128;
122
122
 
123
123
//static qint64 seedNextTime = 0;
127
127
 
128
128
const int Segment::NotSet = std::numeric_limits<int>::min();
129
129
 
130
 
static inline qreal dot(const QPointF & p1, const QPointF & p2)
 
130
static inline double dot(const QPointF & p1, const QPointF & p2)
131
131
{
132
132
        return (p1.x() * p2.x()) + (p1.y() * p2.y());
133
133
}
188
188
        );
189
189
}
190
190
 
191
 
inline int fasterRealToTile(qreal x) {
 
191
inline int fasterRealToTile(double x) {
192
192
        return qRound(x * TILEFACTOR);
193
193
}
194
194
 
231
231
 
232
232
static inline GridEntry * TiGetGridEntry(Tile * tile) { return dynamic_cast<GridEntry *>(TiGetClient(tile)); }
233
233
 
234
 
void realsToTile(TileRect & tileRect, qreal l, qreal t, qreal r, qreal b) {
 
234
void realsToTile(TileRect & tileRect, double l, double t, double r, double b) {
235
235
        tileRect.xmini = fasterRealToTile(l);
236
236
        tileRect.ymini = fasterRealToTile(t);
237
237
        tileRect.xmaxi = fasterRealToTile(r);
242
242
        realsToTile(tileRect, rect.left(), rect.top(), rect.right(), rect.bottom());
243
243
}
244
244
 
245
 
inline qreal tileToReal(int x) {
246
 
        return x / ((qreal) TILEFACTOR);
 
245
inline double tileToReal(int x) {
 
246
        return x / ((double) TILEFACTOR);
247
247
}
248
248
 
249
249
void tileRectToQRect(TileRect & tileRect, QRectF & rect) {
1239
1239
                        
1240
1240
                        // TODO: only bother with connectors that might be electrically relevant, since parts are all we need for obstacles
1241
1241
 
1242
 
                        foreach (QGraphicsItem * childItem, itemBase->childItems()) {
1243
 
                                ConnectorItem * connectorItem = dynamic_cast<ConnectorItem *>(childItem);
1244
 
                                if (connectorItem == NULL) continue;
1245
 
 
 
1242
                        foreach (ConnectorItem * connectorItem, itemBase->cachedConnectorItems()) {
1246
1243
                                QRectF r = itemBase->mapRectToScene(connectorItem->rect());
1247
1244
                                TileRect tileRect;
1248
1245
                                realsToTile(tileRect, r.left() - m_keepout, r.top() - m_keepout, r.right() + m_keepout, r.bottom() + m_keepout);
1610
1607
        foreach (Wire * wire, wires) {
1611
1608
                QPointF p1 = wire->pos();
1612
1609
                QPointF p2 = wire->line().p2() + p1;
1613
 
                qreal dx = qAbs(p1.x() - p2.x());
1614
 
                qreal dy = qAbs(p1.y() - p2.y());
 
1610
                double dx = qAbs(p1.x() - p2.x());
 
1611
                double dy = qAbs(p1.y() - p2.y());
1615
1612
                if (dx < CloseEnough) {
1616
1613
                        // vertical line
1617
 
                        qreal x = qMin(p1.x(), p2.x()) - (wire->width() / 2) - m_keepout;
1618
 
                        qreal y = qMin(p1.y(), p2.y()) - m_keepout;                     
 
1614
                        double x = qMin(p1.x(), p2.x()) - (wire->width() / 2) - m_keepout;
 
1615
                        double y = qMin(p1.y(), p2.y()) - m_keepout;                    
1619
1616
                        wireRects.insert(wire, QRectF(x, y, wire->width() + dx + m_keepout + m_keepout, dy + m_keepout + m_keepout));
1620
1617
                        qobject_cast<TraceWire *>(wire)->setWireDirection(TraceWire::Vertical);
1621
1618
                }
1622
1619
                else if (dy < CloseEnough) {
1623
1620
                        // horizontal line
1624
 
                        qreal y = qMin(p1.y(), p2.y()) - (wire->width() / 2) - m_keepout;
1625
 
                        qreal x = qMin(p1.x(), p2.x()) - m_keepout;
 
1621
                        double y = qMin(p1.y(), p2.y()) - (wire->width() / 2) - m_keepout;
 
1622
                        double x = qMin(p1.x(), p2.x()) - m_keepout;
1626
1623
                        wireRects.insert(wire, QRectF(x, y, qMax(p1.x(), p2.x()) - x + m_keepout + m_keepout, wire->width() + dy + m_keepout + m_keepout));
1627
1624
                        qobject_cast<TraceWire *>(wire)->setWireDirection(TraceWire::Horizontal);
1628
1625
                }
1629
1626
                else {
1630
 
                        qreal factor = (eliminateThin ? StandardWireWidth : 1);
1631
 
                        qreal w = (dx + m_keepout + m_keepout) / factor;
1632
 
                        qreal h = (dy + m_keepout + m_keepout) / factor;
 
1627
                        double factor = (eliminateThin ? StandardWireWidth : 1);
 
1628
                        double w = (dx + m_keepout + m_keepout) / factor;
 
1629
                        double h = (dy + m_keepout + m_keepout) / factor;
1633
1630
                        QImage image(w, h, QImage::Format_RGB32);
1634
1631
                        image.fill(0xff000000);
1635
1632
                        QPainter painter(&image);
1636
1633
                        painter.setRenderHint(QPainter::Antialiasing);
1637
1634
                        painter.scale(1 / factor, 1 / factor);
1638
 
                        qreal tx = m_keepout;
1639
 
                        qreal ty = m_keepout;
 
1635
                        double tx = m_keepout;
 
1636
                        double ty = m_keepout;
1640
1637
                        if (p2.x() < p1.x()) tx += dx;
1641
1638
                        if (p2.y() < p1.y()) ty += dy;
1642
1639
                        painter.translate(tx, ty);
1742
1739
 
1743
1740
        QList<Tile *> alreadyTiled;
1744
1741
        tileWires(wires, alreadyTiled, m_sketchWidget->autorouteTypePCB() ? Tile::OBSTACLE : Tile::SCHEMATICWIRESPACE, CMRouter::ClipAllOverlaps, true);
1745
 
        qreal l = std::numeric_limits<int>::max();
1746
 
        qreal t = std::numeric_limits<int>::max();
1747
 
        qreal r = std::numeric_limits<int>::min();
1748
 
        qreal b = std::numeric_limits<int>::min();
 
1742
        double l = std::numeric_limits<int>::max();
 
1743
        double t = std::numeric_limits<int>::max();
 
1744
        double r = std::numeric_limits<int>::min();
 
1745
        double b = std::numeric_limits<int>::min();
1749
1746
        foreach (Wire * w, wires) {
1750
1747
                viewLayerIDs.insert(w->viewLayerID());
1751
1748
                QPointF p1 = w->pos();
1851
1848
        }
1852
1849
 
1853
1850
        bool success = false;
1854
 
        qreal result;
 
1851
        double result;
1855
1852
        if (targetGreater) {
1856
1853
                result = std::numeric_limits<int>::min();
1857
1854
        }
2075
2072
 
2076
2073
        QList<Tile *> alreadyTiled;
2077
2074
        TileRect tileRect;
2078
 
        qreal x = proposed.x() - HalfStandardWireWidth;
 
2075
        double x = proposed.x() - HalfStandardWireWidth;
2079
2076
        realsToTile(tileRect, x, qMin(p1.y(), p3.y()), x + StandardWireWidth, qMax(p1.y(), p3.y()));
2080
2077
        TiSrArea(NULL, thePlane, &tileRect, simpleList, &alreadyTiled);
2081
 
        qreal y = proposed.y() - HalfStandardWireWidth;
 
2078
        double y = proposed.y() - HalfStandardWireWidth;
2082
2079
        realsToTile(tileRect, qMin(p1.x(), p3.x()), y, qMax(p1.x(), p3.x()), y + StandardWireWidth);
2083
2080
        TiSrArea(NULL, thePlane, &tileRect, simpleList, &alreadyTiled);
2084
2081
        foreach (Tile * tile, alreadyTiled) {
2489
2486
                        foreach (ConnectorItem * ci, jumperItem->connector0()->connectedToItems()) both.append(ci);
2490
2487
                        foreach (ConnectorItem * ci, jumperItem->connector1()->connectedToItems()) both.append(ci);
2491
2488
                        foreach (ConnectorItem * connectorItem, both) {
2492
 
                                TraceWire * w = dynamic_cast<TraceWire *>(connectorItem->attachedTo());
 
2489
                                TraceWire * w = qobject_cast<TraceWire *>(connectorItem->attachedTo());
2493
2490
                                if (w == NULL) continue;
2494
2491
 
2495
2492
                                QList<Wire *> wires;
2516
2513
                        foreach (ConnectorItem * ci, via->connectorItem()->connectedToItems()) both.append(ci);
2517
2514
                        foreach (ConnectorItem * ci, via->connectorItem()->getCrossLayerConnectorItem()->connectedToItems()) both.append(ci);
2518
2515
                        foreach (ConnectorItem * connectorItem, both) {
2519
 
                                TraceWire * w = dynamic_cast<TraceWire *>(connectorItem->attachedTo());
 
2516
                                TraceWire * w = qobject_cast<TraceWire *>(connectorItem->attachedTo());
2520
2517
                                if (w == NULL) continue;
2521
2518
 
2522
2519
                                QList<Wire *> wires;
2601
2598
                        m_sketchWidget->setClipEnds(wire, true);
2602
2599
                        wire->update();
2603
2600
                        if (wire->getAutoroutable()) {
2604
 
                                wire->setWireWidth(StandardWireWidth, m_sketchWidget);
 
2601
                                wire->setWireWidth(StandardWireWidth, m_sketchWidget, m_sketchWidget->getWireStrokeWidth(wire, StandardWireWidth));
2605
2602
                        }
2606
2603
                        addWireToUndo(wire, parentCommand);
2607
2604
                        wires.append(wire);
2763
2760
 
2764
2761
void CMRouter::updateProgress(int num, int denom) 
2765
2762
{
2766
 
        emit setProgressValue((int) MaximumProgress * (m_currentProgressPart + (num / (qreal) denom)) / (qreal) m_maximumProgressPart);
 
2763
        emit setProgressValue((int) MaximumProgress * (m_currentProgressPart + (num / (double) denom)) / (double) m_maximumProgressPart);
2767
2764
}
2768
2765
 
2769
2766
Tile * CMRouter::addTile(NonConnectorItem * nci, Tile::TileType type, Plane * thePlane, QList<Tile *> & alreadyTiled, CMRouter::OverlapType overlapType) 
3689
3686
        QPointF v2 = check - vertex;
3690
3687
 
3691
3688
        // Compute dot products
3692
 
        qreal dot00 = dot(v0, v0);
3693
 
        qreal dot01 = dot(v0, v1);
3694
 
        qreal dot02 = dot(v0, v2);
3695
 
        qreal dot11 = dot(v1, v1);
3696
 
        qreal dot12 = dot(v1, v2);
 
3689
        double dot00 = dot(v0, v0);
 
3690
        double dot01 = dot(v0, v1);
 
3691
        double dot02 = dot(v0, v2);
 
3692
        double dot11 = dot(v1, v1);
 
3693
        double dot12 = dot(v1, v2);
3697
3694
 
3698
3695
        // Compute barycentric coordinates
3699
 
        qreal invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
3700
 
        qreal u = (dot11 * dot02 - dot01 * dot12) * invDenom;
3701
 
        qreal v = (dot00 * dot12 - dot01 * dot02) * invDenom;
 
3696
        double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
 
3697
        double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
 
3698
        double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
3702
3699
 
3703
3700
        // Check if point is in or on triangle
3704
3701
        return (u >= 0) && (v >= 0) && (u + v <= 1);
3710
3707
        for ( ; sourcePathUnit->parent; sourcePathUnit = sourcePathUnit->parent) ;
3711
3708
        for ( ; destPathUnit->parent; destPathUnit = destPathUnit->parent) ;
3712
3709
        int bestCost = manhattan(sourcePathUnit->minCostRect, destPathUnit->minCostRect);
3713
 
        return completePath.sourceCost < ((qreal) bestCost) * 1.05;
 
3710
        return completePath.sourceCost < ((double) bestCost) * 1.05;
3714
3711
}
3715
3712
 
3716
3713
void CMRouter::listCompletePath(CompletePath & completePath, QList<PathUnit *> & fullPath) {
3810
3807
 
3811
3808
        cleanPoints(allPoints, first->plane);
3812
3809
 
3813
 
        qreal wireWidth = minWireWidth(completePath);
 
3810
        double wireWidth = minWireWidth(completePath);
3814
3811
                 
3815
3812
        QList<Wire *> wires;
3816
3813
        for (int i = 0; i < allPoints.count() - 1; i++) {
4200
4197
        return m_tileMaxRect;
4201
4198
}
4202
4199
 
4203
 
int CMRouter::realToTile(qreal x) {
 
4200
int CMRouter::realToTile(double x) {
4204
4201
        return qRound(x * TILEFACTOR);
4205
4202
}
4206
4203
 
4211
4208
}
4212
4209
 
4213
4210
void CMRouter::getViaSize(int & tWidthNeeded, int & tHeightNeeded) {
4214
 
        qreal ringThickness, holeSize;
 
4211
        double ringThickness, holeSize;
4215
4212
        m_sketchWidget->getViaSize(ringThickness, holeSize);
4216
4213
        tHeightNeeded = tWidthNeeded = fasterRealToTile(ringThickness + ringThickness + holeSize + m_keepout + m_keepout);
4217
4214
}
4220
4217
        TileRect nearestSpace = m_nearestSpaces.value(pathUnit);
4221
4218
        int tWidthNeeded, tHeightNeeded;
4222
4219
        getViaSize(tWidthNeeded, tHeightNeeded);
4223
 
        qreal tHalfWidth = tWidthNeeded / 2.0;
4224
 
        qreal tHalfHeight = tHeightNeeded / 2.0;
4225
 
        qreal cx = (pathUnit->minCostRect.xmaxi + pathUnit->minCostRect.xmini) / 2.0; 
4226
 
        qreal cy = (pathUnit->minCostRect.ymaxi + pathUnit->minCostRect.ymini) / 2.0; 
 
4220
        double tHalfWidth = tWidthNeeded / 2.0;
 
4221
        double tHalfHeight = tHeightNeeded / 2.0;
 
4222
        double cx = (pathUnit->minCostRect.xmaxi + pathUnit->minCostRect.xmini) / 2.0; 
 
4223
        double cy = (pathUnit->minCostRect.ymaxi + pathUnit->minCostRect.ymini) / 2.0; 
4227
4224
        if (cx < nearestSpace.xmini + tHalfWidth) cx = nearestSpace.xmini + tHalfWidth;
4228
4225
        if (cx > nearestSpace.xmaxi - tHalfWidth) cx = nearestSpace.xmaxi - tHalfWidth;
4229
4226
        if (cy < nearestSpace.ymini + tHalfHeight) cy = nearestSpace.ymini + tHalfHeight;
4237
4234
                                                                                m_specHash.value(pathUnit->plane), BaseCommand::CrossView, viewGeometry, newID, -1, NULL, NULL);
4238
4235
 
4239
4236
        //DebugDialog::debug(QString("back from adding via %1").arg((long) itemBase, 0, 16));
4240
 
        Via * via = dynamic_cast<Via *>(itemBase);
 
4237
        Via * via = qobject_cast<Via *>(itemBase);
4241
4238
        via->setAutoroutable(true);
4242
 
        qreal ringThickness, holeSize;
 
4239
        double ringThickness, holeSize;
4243
4240
        m_sketchWidget->getViaSize(ringThickness, holeSize);
4244
4241
        via->setHoleSize(QString("%1in,%2in")
4245
4242
                                                .arg(holeSize / FSvgRenderer::printerScale())
4253
4250
        return via;
4254
4251
}
4255
4252
 
4256
 
qreal CMRouter::minWireWidth(CompletePath & completePath) {
4257
 
        qreal wireWidth = StandardWireWidth;
 
4253
double CMRouter::minWireWidth(CompletePath & completePath) {
 
4254
        double wireWidth = StandardWireWidth;
4258
4255
        if (completePath.source) {
4259
4256
                if (completePath.source->connectorItem) {
4260
4257
                        if (completePath.source->connectorItem->minDimension() < wireWidth) {
4283
4280
        return wireWidth;
4284
4281
}
4285
4282
 
4286
 
void CMRouter::setUpWidths(qreal width)
 
4283
void CMRouter::setUpWidths(double width)
4287
4284
{
4288
4285
        StandardWireWidth = width;
4289
4286
    TileStandardWireWidth = fasterRealToTile(StandardWireWidth);                                                
4290
4287
        HalfStandardWireWidth = StandardWireWidth / 2;                                                                          
4291
4288
    TileHalfStandardWireWidth = fasterRealToTile(HalfStandardWireWidth);
4292
4289
}
4293
 
void CMRouter::setKeepout(qreal keepout)
 
4290
void CMRouter::setKeepout(double keepout)
4294
4291
{
4295
4292
        m_keepout = keepout;
4296
4293
}
4300
4297
{
4301
4298
        if (!m_sketchWidget->autorouteTypePCB()) return;
4302
4299
 
4303
 
        qreal minDim = std::numeric_limits<int>::max();
 
4300
        double minDim = std::numeric_limits<int>::max();
4304
4301
        foreach (QList<ConnectorItem *> * list, m_allPartConnectorItems) {
4305
4302
                foreach (ConnectorItem * connectorItem, *list) {
4306
 
                        qreal md = connectorItem->minDimension();
 
4303
                        double md = connectorItem->minDimension();
4307
4304
                        if (md < minDim) minDim = md;
4308
4305
                }
4309
4306
        }