30
30
********************************************************************
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) $
36
36
********************************************************************/
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;
123
123
//static qint64 seedNextTime = 0;
232
232
static inline GridEntry * TiGetGridEntry(Tile * tile) { return dynamic_cast<GridEntry *>(TiGetClient(tile)); }
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());
245
inline qreal tileToReal(int x) {
246
return x / ((qreal) TILEFACTOR);
245
inline double tileToReal(int x) {
246
return x / ((double) TILEFACTOR);
249
249
void tileRectToQRect(TileRect & tileRect, QRectF & rect) {
1240
1240
// TODO: only bother with connectors that might be electrically relevant, since parts are all we need for obstacles
1242
foreach (QGraphicsItem * childItem, itemBase->childItems()) {
1243
ConnectorItem * connectorItem = dynamic_cast<ConnectorItem *>(childItem);
1244
if (connectorItem == NULL) continue;
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);
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);
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);
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();
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;
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;
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));
2606
2603
addWireToUndo(wire, parentCommand);
2607
2604
wires.append(wire);
2764
2761
void CMRouter::updateProgress(int num, int denom)
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);
2769
2766
Tile * CMRouter::addTile(NonConnectorItem * nci, Tile::TileType type, Plane * thePlane, QList<Tile *> & alreadyTiled, CMRouter::OverlapType overlapType)
3689
3686
QPointF v2 = check - vertex;
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);
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;
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;
3716
3713
void CMRouter::listCompletePath(CompletePath & completePath, QList<PathUnit *> & fullPath) {
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);
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);
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())
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;
4286
void CMRouter::setUpWidths(qreal width)
4283
void CMRouter::setUpWidths(double width)
4288
4285
StandardWireWidth = width;
4289
4286
TileStandardWireWidth = fasterRealToTile(StandardWireWidth);
4290
4287
HalfStandardWireWidth = StandardWireWidth / 2;
4291
4288
TileHalfStandardWireWidth = fasterRealToTile(HalfStandardWireWidth);
4293
void CMRouter::setKeepout(qreal keepout)
4290
void CMRouter::setKeepout(double keepout)
4295
4292
m_keepout = keepout;
4301
4298
if (!m_sketchWidget->autorouteTypePCB()) return;
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;