diff --git a/samples/qt/FuncDemo/custom.bat b/samples/qt/FuncDemo/custom.bat index 115ac2c09..38728c3ad 100644 --- a/samples/qt/FuncDemo/custom.bat +++ b/samples/qt/FuncDemo/custom.bat @@ -1,3 +1,3 @@ @echo off rem Define QTDIR variable -set QTDIR= +set QTDIR=%PRODUCTS_PATH%/qt486-vc10-32 diff --git a/samples/qt/FuncDemo/src/BaseDriver.cpp b/samples/qt/FuncDemo/src/BaseDriver.cpp index f42552e01..2d34a6973 100644 --- a/samples/qt/FuncDemo/src/BaseDriver.cpp +++ b/samples/qt/FuncDemo/src/BaseDriver.cpp @@ -36,7 +36,6 @@ void BaseDriver::Arguments(TDF_LabelList& args) const } } - // Returns the results of the function void BaseDriver::Results(TDF_LabelList& res) const { @@ -50,6 +49,12 @@ void BaseDriver::Results(TDF_LabelList& res) const } } +// Sets a mutex for execution of the driver. +void BaseDriver::SetMutex(Standard_Mutex* pmutex) +{ + myMutex = pmutex; +} + // Execution. Standard_Integer BaseDriver::Execute(Handle(TFunction_Logbook)& ) const { diff --git a/samples/qt/FuncDemo/src/BaseDriver.h b/samples/qt/FuncDemo/src/BaseDriver.h index ab23adb85..c5c669c42 100644 --- a/samples/qt/FuncDemo/src/BaseDriver.h +++ b/samples/qt/FuncDemo/src/BaseDriver.h @@ -5,14 +5,11 @@ #if !defined(_BASEDRIVER_H_) #define _BASEDRIVER_H_ -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - #include #include #include #include +#include DEFINE_STANDARD_HANDLE(BaseDriver, TFunction_Driver) @@ -30,10 +27,16 @@ class BaseDriver : public TFunction_Driver // Returns the results of the function virtual void Results(TDF_LabelList& res) const; + // Sets a mutex for execution of the driver. + void SetMutex(Standard_Mutex* pmutex); + // Execution. virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const; DEFINE_STANDARD_RTTIEXT(BaseDriver, TFunction_Driver) + +protected: + Standard_Mutex* myMutex; }; #endif // !defined(_BASEDRIVER_H_) diff --git a/samples/qt/FuncDemo/src/CircleDriver.h b/samples/qt/FuncDemo/src/CircleDriver.h index 11d55c274..eb2c38565 100644 --- a/samples/qt/FuncDemo/src/CircleDriver.h +++ b/samples/qt/FuncDemo/src/CircleDriver.h @@ -5,10 +5,6 @@ #if !defined(_CIRCLEDRIVER_H_) #define _CIRCLEDRIVER_H_ -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - #include "BaseDriver.h" #include diff --git a/samples/qt/FuncDemo/src/ConeDriver.h b/samples/qt/FuncDemo/src/ConeDriver.h index a7f9439f4..be225b1e1 100644 --- a/samples/qt/FuncDemo/src/ConeDriver.h +++ b/samples/qt/FuncDemo/src/ConeDriver.h @@ -5,10 +5,6 @@ #if !defined(_CONEDRIVER_H_) #define _CONEDRIVER_H_ -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - #include "BaseDriver.h" #include diff --git a/samples/qt/FuncDemo/src/CylinderDriver.h b/samples/qt/FuncDemo/src/CylinderDriver.h index bfa8ee66d..287ce87a9 100644 --- a/samples/qt/FuncDemo/src/CylinderDriver.h +++ b/samples/qt/FuncDemo/src/CylinderDriver.h @@ -5,10 +5,6 @@ #if !defined(_CYLINDERDRIVER_H_) #define _CYLINDERDRIVER_H_ -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - #include "BaseDriver.h" #include diff --git a/samples/qt/FuncDemo/src/FThread.cpp b/samples/qt/FuncDemo/src/FThread.cpp index c18b7c4fb..d66d14a4a 100644 --- a/samples/qt/FuncDemo/src/FThread.cpp +++ b/samples/qt/FuncDemo/src/FThread.cpp @@ -1,5 +1,6 @@ #include "FThread.h" #include "graphwidget.h" +#include "BaseDriver.h" #include #include @@ -39,6 +40,11 @@ void FThread::setThreadIndex(const int theIndex) this->thread_index = theIndex; } +void FThread::setMutex(Standard_Mutex* pmutex) +{ + this->pmutex = pmutex; +} + // Returns any free (not executed yet) function TDF_Label FThread::getFreeFunction() { @@ -94,12 +100,16 @@ void FThread::run() const bool must = D->MustExecute(log); if (must) { - // Usage of mutex for execution of Open CASCADE code is the most stupid thing!!! - // But it makes the execution more reliable... + // Usage of mutex for execution of Open CASCADE code. + // It makes the execution more reliable... + if (!Handle(BaseDriver)::DownCast(D).IsNull()) + Handle(BaseDriver)::DownCast(D)->SetMutex(pmutex); + + // Execute the driver. const int ret = D->Execute(log); if (ret == 0) { - // Successfully executed! + // Successfuly executed! itr.SetStatus(L, TFunction_ES_Succeeded); TDF_LabelList res; diff --git a/samples/qt/FuncDemo/src/FThread.h b/samples/qt/FuncDemo/src/FThread.h index e7ab7ac07..e494b797c 100644 --- a/samples/qt/FuncDemo/src/FThread.h +++ b/samples/qt/FuncDemo/src/FThread.h @@ -8,6 +8,7 @@ #include #include #include +#include class GraphWidget; // shows graphically execution of functions @@ -25,6 +26,7 @@ class FThread : public QThread void setLogbook(const Handle(TFunction_Logbook)& ); // to set logbook with modifications void setGraph(GraphWidget* ); // to change color of a graph circle void setThreadIndex(const int ); // to set the index of the thread + void setMutex(Standard_Mutex* ); protected: @@ -35,6 +37,7 @@ class FThread : public QThread TFunction_Iterator itr; Handle(TFunction_Logbook) log; + Standard_Mutex* pmutex; int thread_index; GraphWidget* graph; diff --git a/samples/qt/FuncDemo/src/PointDriver.cpp b/samples/qt/FuncDemo/src/PointDriver.cpp index 3f1041273..03aa733ce 100644 --- a/samples/qt/FuncDemo/src/PointDriver.cpp +++ b/samples/qt/FuncDemo/src/PointDriver.cpp @@ -47,9 +47,15 @@ Standard_Integer PointDriver::Execute(Handle(TFunction_Logbook)& log) const // Make the result TopoDS_Vertex V = BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, z)); + if (myMutex) + myMutex->Lock(); + // Set the result TNaming_Builder B(Label()); B.Generated(V); + if (myMutex) + myMutex->Unlock(); + return BaseDriver::Execute(log); } \ No newline at end of file diff --git a/samples/qt/FuncDemo/src/PointDriver.h b/samples/qt/FuncDemo/src/PointDriver.h index 015923746..4d6cd1ccb 100644 --- a/samples/qt/FuncDemo/src/PointDriver.h +++ b/samples/qt/FuncDemo/src/PointDriver.h @@ -5,10 +5,6 @@ #if !defined(_PointDRIVER_H_) #define _PointDRIVER_H_ -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - #include "BaseDriver.h" #include diff --git a/samples/qt/FuncDemo/src/PrismDriver.h b/samples/qt/FuncDemo/src/PrismDriver.h index 778b1cd92..4c2894e5e 100644 --- a/samples/qt/FuncDemo/src/PrismDriver.h +++ b/samples/qt/FuncDemo/src/PrismDriver.h @@ -5,10 +5,6 @@ #if !defined(_PRISMDRIVER_H_) #define _PRISMDRIVER_H_ -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - #include "BaseDriver.h" #include diff --git a/samples/qt/FuncDemo/src/ShapeSaverDriver.cpp b/samples/qt/FuncDemo/src/ShapeSaverDriver.cpp index 1f14881b5..15a39f927 100644 --- a/samples/qt/FuncDemo/src/ShapeSaverDriver.cpp +++ b/samples/qt/FuncDemo/src/ShapeSaverDriver.cpp @@ -56,10 +56,14 @@ Standard_Integer ShapeSaverDriver::Execute(Handle(TFunction_Logbook)& log) const } } - //BRepTools::Write(C, "result.brep"); + if (myMutex) + myMutex->Lock(); TNaming_Builder Bui(Label()); Bui.Generated(C); + if (myMutex) + myMutex->Unlock(); + return BaseDriver::Execute(log); } \ No newline at end of file diff --git a/samples/qt/FuncDemo/src/ShapeSaverDriver.h b/samples/qt/FuncDemo/src/ShapeSaverDriver.h index 5247949b7..ddc6b1338 100644 --- a/samples/qt/FuncDemo/src/ShapeSaverDriver.h +++ b/samples/qt/FuncDemo/src/ShapeSaverDriver.h @@ -5,10 +5,6 @@ #if !defined(_SHAPESAVERDRIVER_H_) #define _SHAPESAVERDRIVER_H_ -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - #include "BaseDriver.h" #include diff --git a/samples/qt/FuncDemo/src/SimpleDriver.h b/samples/qt/FuncDemo/src/SimpleDriver.h index a78a065b5..92b646a04 100644 --- a/samples/qt/FuncDemo/src/SimpleDriver.h +++ b/samples/qt/FuncDemo/src/SimpleDriver.h @@ -5,10 +5,6 @@ #if !defined(_SIMPLEDRIVER_H_) #define _SIMPLEDRIVER_H_ -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - #include #include #include diff --git a/samples/qt/FuncDemo/src/edge.cpp b/samples/qt/FuncDemo/src/edge.cpp index 983b64a21..93a3b029a 100644 --- a/samples/qt/FuncDemo/src/edge.cpp +++ b/samples/qt/FuncDemo/src/edge.cpp @@ -50,6 +50,7 @@ static const double Pi = 3.14159265358979323846264338327950288419717; static double TwoPi = 2.0 * Pi; +//! [0] Edge::Edge(Node *sourceNode, Node *destNode) : arrowSize(10) { @@ -60,7 +61,9 @@ Edge::Edge(Node *sourceNode, Node *destNode) dest->addEdge(this); adjust(); } +//! [0] +//! [1] Node *Edge::sourceNode() const { return source; @@ -70,7 +73,9 @@ Node *Edge::destNode() const { return dest; } +//! [1] +//! [2] void Edge::adjust() { if (!source || !dest) @@ -89,7 +94,9 @@ void Edge::adjust() sourcePoint = destPoint = line.p1(); } } +//! [2] +//! [3] QRectF Edge::boundingRect() const { if (!source || !dest) @@ -103,7 +110,9 @@ QRectF Edge::boundingRect() const .normalized() .adjusted(-extra, -extra, extra, extra); } +//! [3] +//! [4] void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { if (!source || !dest) @@ -112,11 +121,15 @@ void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) QLineF line(sourcePoint, destPoint); if (qFuzzyCompare(line.length(), qreal(0.))) return; +//! [4] +//! [5] // Draw the line itself painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawLine(line); +//! [5] +//! [6] // Draw the arrows double angle = ::acos(line.dx() / line.length()); if (line.dy() >= 0) @@ -135,3 +148,4 @@ void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) painter->drawPolygon(QPolygonF() << line.p1() << sourceArrowP1 << sourceArrowP2); painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2); } +//! [6] diff --git a/samples/qt/FuncDemo/src/edge.h b/samples/qt/FuncDemo/src/edge.h index 5662ef00a..21bdec02e 100644 --- a/samples/qt/FuncDemo/src/edge.h +++ b/samples/qt/FuncDemo/src/edge.h @@ -47,13 +47,13 @@ class Node; +//! [0] class Edge : public QGraphicsItem { public: Edge(Node *sourceNode, Node *destNode); Node *sourceNode() const; - Node *destNode() const; void adjust(); @@ -72,5 +72,6 @@ class Edge : public QGraphicsItem QPointF destPoint; qreal arrowSize; }; +//! [0] #endif diff --git a/samples/qt/FuncDemo/src/graphwidget.cpp b/samples/qt/FuncDemo/src/graphwidget.cpp index 1ee3a6609..5c6992f22 100644 --- a/samples/qt/FuncDemo/src/graphwidget.cpp +++ b/samples/qt/FuncDemo/src/graphwidget.cpp @@ -43,10 +43,7 @@ #include "node.h" #include -#include -#include -#include -#include +#include #include #include @@ -73,24 +70,73 @@ #include "ShapeSaverDriver.h" #include "SimpleDriver.h" -GraphWidget::GraphWidget(QWidget* parent):QGraphicsView(parent), - myThread1(0),myThread2(0),myThread3(0),myThread4(0) +//! [0] +GraphWidget::GraphWidget(QWidget *parent) + : QGraphicsView(parent), timerId(0), + myThread1(0),myThread2(0),myThread3(0),myThread4(0) { QGraphicsScene *scene = new QGraphicsScene(this); scene->setItemIndexMethod(QGraphicsScene::NoIndex); - scene->setSceneRect(1, 1, parent->width(), parent->height()); + scene->setSceneRect(-200, -200, 400, 400); setScene(scene); setCacheMode(CacheBackground); + setViewportUpdateMode(BoundingRectViewportUpdate); setRenderHint(QPainter::Antialiasing); setTransformationAnchor(AnchorUnderMouse); - setResizeAnchor(AnchorViewCenter); - scale(0.7, 0.81); + scale(qreal(0.8), qreal(0.8)); setMinimumSize(400, 400); setWindowTitle(tr("Function Mechanism")); - setNbThreads(1); +//! [0] + +//! [1] +/* + Node *node1 = new Node(this); + Node *node2 = new Node(this); + Node *node3 = new Node(this); + Node *node4 = new Node(this); + centerNode = new Node(this); + Node *node6 = new Node(this); + Node *node7 = new Node(this); + Node *node8 = new Node(this); + Node *node9 = new Node(this); + scene->addItem(node1); + scene->addItem(node2); + scene->addItem(node3); + scene->addItem(node4); + scene->addItem(centerNode); + scene->addItem(node6); + scene->addItem(node7); + scene->addItem(node8); + scene->addItem(node9); + scene->addItem(new Edge(node1, node2)); + scene->addItem(new Edge(node2, node3)); + scene->addItem(new Edge(node2, centerNode)); + scene->addItem(new Edge(node3, node6)); + scene->addItem(new Edge(node4, node1)); + scene->addItem(new Edge(node4, centerNode)); + scene->addItem(new Edge(centerNode, node6)); + scene->addItem(new Edge(centerNode, node8)); + scene->addItem(new Edge(node6, node9)); + scene->addItem(new Edge(node7, node4)); + scene->addItem(new Edge(node8, node7)); + scene->addItem(new Edge(node9, node8)); + + node1->setPos(-50, -50); + node2->setPos(0, -50); + node3->setPos(50, -50); + node4->setPos(-50, 0); + centerNode->setPos(0, 0); + node6->setPos(50, 0); + node7->setPos(-50, 50); + node8->setPos(0, 50); + node9->setPos(50, 50); +*/ + + setNbThreads(4); } +//! [1] GraphWidget::~GraphWidget() { @@ -138,8 +184,8 @@ bool GraphWidget::createModel(const Handle(TDocStd_Document)& doc) return false; // Grid of functions - int dx = width() / nbx, dy = height() / nby; - int x0 = dx / 2, y0 = dy / 2; // start position + int dx = width() / nbx / 2, dy = height() / nby; + int x0 = int(-double(width()) / 1.5) + dx, y0 = int(-double(height()) / 1.5) + dy; // start position // Draw functions double x = x0, y = y0; @@ -163,6 +209,7 @@ bool GraphWidget::createModel(const Handle(TDocStd_Document)& doc) if (y > height()) y = y0; fIterator.Next(); + x = x0 + dx; } // Draw dependencies @@ -199,41 +246,151 @@ bool GraphWidget::createModel(const Handle(TDocStd_Document)& doc) return !myDocument.IsNull(); } +//! [2] +void GraphWidget::itemMoved() +{ + if (!timerId) + timerId = startTimer(1000 / 25); +} +//! [2] + +//! [3] +void GraphWidget::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Up: + centerNode->moveBy(0, -20); + break; + case Qt::Key_Down: + centerNode->moveBy(0, 20); + break; + case Qt::Key_Left: + centerNode->moveBy(-20, 0); + break; + case Qt::Key_Right: + centerNode->moveBy(20, 0); + break; + case Qt::Key_Plus: + zoomIn(); + break; + case Qt::Key_Minus: + zoomOut(); + break; + case Qt::Key_Space: + case Qt::Key_Enter: + shuffle(); + break; + default: + QGraphicsView::keyPressEvent(event); + } +} +//! [3] + +//! [4] +void GraphWidget::timerEvent(QTimerEvent *event) +{ + Q_UNUSED(event); + + QList nodes; + foreach (QGraphicsItem *item, scene()->items()) { + if (Node *node = qgraphicsitem_cast(item)) + nodes << node; + } + + foreach (Node *node, nodes) + node->calculateForces(); + + bool itemsMoved = false; + foreach (Node *node, nodes) { + if (node->advance()) + itemsMoved = true; + } + + if (!itemsMoved) { + killTimer(timerId); + timerId = 0; + } +} +//! [4] + +//! [5] void GraphWidget::wheelEvent(QWheelEvent *event) { scaleView(pow((double)2, -event->delta() / 240.0)); } +//! [5] -void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect) +//! [6] +void GraphWidget::drawBackground(QPainter* painter, const QRectF &rect) { Q_UNUSED(rect); - - // Shadow - QRectF sceneRect = this->sceneRect(); - QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height()); - QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5); - if (rightShadow.intersects(rect) || rightShadow.contains(rect)) - painter->fillRect(rightShadow, Qt::darkGray); - if (bottomShadow.intersects(rect) || bottomShadow.contains(rect)) - painter->fillRect(bottomShadow, Qt::darkGray); - - // Fill - QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight()); - gradient.setColorAt(0, Qt::white); - gradient.setColorAt(1, Qt::lightGray); - painter->fillRect(rect.intersected(sceneRect), gradient); - painter->setBrush(Qt::NoBrush); - painter->drawRect(sceneRect); + Q_UNUSED(painter); + +// // Shadow +// QRectF sceneRect = this->sceneRect(); +// QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height()); +// QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5); +// if (rightShadow.intersects(rect) || rightShadow.contains(rect)) +// painter->fillRect(rightShadow, Qt::darkGray); +// if (bottomShadow.intersects(rect) || bottomShadow.contains(rect)) +// painter->fillRect(bottomShadow, Qt::darkGray); +// +// // Fill +// QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight()); +// gradient.setColorAt(0, Qt::white); +// gradient.setColorAt(1, Qt::lightGray); +// painter->fillRect(rect.intersect(sceneRect), gradient); +// painter->setBrush(Qt::NoBrush); +// painter->drawRect(sceneRect); +// +//#if !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5) +// // Text +// QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4, +// sceneRect.width() - 4, sceneRect.height() - 4); +// QString message(tr("Click and drag the nodes around, and zoom with the mouse " +// "wheel or the '+' and '-' keys")); +// +// QFont font = painter->font(); +// font.setBold(true); +// font.setPointSize(14); +// painter->setFont(font); +// painter->setPen(Qt::lightGray); +// painter->drawText(textRect.translated(2, 2), message); +// painter->setPen(Qt::black); +// painter->drawText(textRect, message); +//#endif } +//! [6] +//! [7] void GraphWidget::scaleView(qreal scaleFactor) { - qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); + qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); if (factor < 0.07 || factor > 100) return; scale(scaleFactor, scaleFactor); } +//! [7] + +void GraphWidget::shuffle() +{ + foreach (QGraphicsItem *item, scene()->items()) { + if (qgraphicsitem_cast(item)) + item->setPos(-150 + qrand() % 300, -150 + qrand() % 300); + } +} + +void GraphWidget::zoomIn() +{ + scaleView(qreal(1.2)); +} + +void GraphWidget::zoomOut() +{ + scaleView(1 / qreal(1.2)); +} + // Find node of the function Node* GraphWidget::findNode(const TDF_Label& L) @@ -300,6 +457,14 @@ void GraphWidget::compute() if (myNbThreads > 3) myThread4->setThreadIndex(4); + myThread1->setMutex(&myMutex); + if (myNbThreads > 1) + myThread2->setMutex(&myMutex); + if (myNbThreads > 2) + myThread3->setMutex(&myMutex); + if (myNbThreads > 3) + myThread4->setMutex(&myMutex); + QThread::Priority priority = QThread::LowestPriority; if (!myThread1->isRunning()) myThread1->start(priority); @@ -410,4 +575,4 @@ void GraphWidget::slowDownThread(const int thread_index) myThread4->setPriority(priority); break; } -} \ No newline at end of file +} diff --git a/samples/qt/FuncDemo/src/graphwidget.h b/samples/qt/FuncDemo/src/graphwidget.h index d4205e6bc..7459b337f 100644 --- a/samples/qt/FuncDemo/src/graphwidget.h +++ b/samples/qt/FuncDemo/src/graphwidget.h @@ -52,13 +52,16 @@ class Node; +//! [0] class GraphWidget : public QGraphicsView { Q_OBJECT public: - GraphWidget(QWidget* parent); - ~GraphWidget(); + GraphWidget(QWidget *parent = 0); + ~GraphWidget(); + + void itemMoved(); bool createModel(const Handle(TDocStd_Document)& doc); Handle(TDocStd_Document) getDocument() { return myDocument; } @@ -73,12 +76,25 @@ class GraphWidget : public QGraphicsView void setFinished(); bool isFinished(); +public slots: + void shuffle(); + void zoomIn(); + void zoomOut(); + protected: + void keyPressEvent(QKeyEvent *event); + void timerEvent(QTimerEvent *event); void wheelEvent(QWheelEvent *event); void drawBackground(QPainter *painter, const QRectF &rect); + void scaleView(qreal scaleFactor); private: + int timerId; + Node *centerNode; + +private: + Standard_Mutex myMutex; Handle(TDocStd_Document) myDocument; int myNbThreads; FThread* myThread1; @@ -87,5 +103,6 @@ class GraphWidget : public QGraphicsView FThread* myThread4; int myNbFinishedThreads; }; +//! [0] #endif diff --git a/samples/qt/FuncDemo/src/mainwindow.cpp b/samples/qt/FuncDemo/src/mainwindow.cpp index f7f5694ce..c86003ad8 100644 --- a/samples/qt/FuncDemo/src/mainwindow.cpp +++ b/samples/qt/FuncDemo/src/mainwindow.cpp @@ -101,6 +101,7 @@ MainWindow::MainWindow() // Create a new document createDefaultModel1(); + graph->setNbThreads(4); } Handle(AppStd_Application) MainWindow::getApplication() @@ -224,7 +225,7 @@ void MainWindow::nbThreads() { bool ok; int nb = QInputDialog::getInt(this, tr("Number of threads"), tr("(1 - 4): "), - graph->getNbThreads(), 1, 4, 1, &ok); + graph->getNbThreads(), 1, 4, 1, &ok); if (ok) graph->setNbThreads(nb); } @@ -335,6 +336,7 @@ void MainWindow::createDefaultModel1() Handle(TDocStd_Document) doc; app->NewDocument("XmlOcaf", doc); TDF_Label mainLabel = doc->Main(); + mainLabel.ForgetAllAttributes(true); // Initialize function drivers TFunction_DriverTable::Get()->AddDriver(SimpleDriver::GetID(), new SimpleDriver()); @@ -423,8 +425,8 @@ void MainWindow::createDefaultModel2() Handle(AppStd_Application) app = MainWindow::getApplication(); Handle(TDocStd_Document) doc; app->NewDocument("BinOcaf", doc); - //app->Open("W:\\TestFM\\model2.cbf", doc); TDF_Label mainLabel = doc->Main(); + mainLabel.ForgetAllAttributes(true); // Initialize function drivers TFunction_DriverTable::Get()->AddDriver(PointDriver::GetID(), new PointDriver()); diff --git a/samples/qt/FuncDemo/src/node.cpp b/samples/qt/FuncDemo/src/node.cpp index 9271222fb..5afd1f022 100644 --- a/samples/qt/FuncDemo/src/node.cpp +++ b/samples/qt/FuncDemo/src/node.cpp @@ -54,12 +54,16 @@ #include #include +//! [0] Node::Node(GraphWidget *graphWidget) : graph(graphWidget) { setFlag(ItemIsMovable); - setZValue(1); + setFlag(ItemSendsGeometryChanges); + setCacheMode(DeviceCoordinateCache); + setZValue(-1); } +//! [0] void Node::setFunction(const TDF_Label& func) { @@ -71,6 +75,7 @@ const TDF_Label& Node::getFunction() const return myFunction; } +//! [1] void Node::addEdge(Edge *edge) { edgeList << edge; @@ -81,26 +86,111 @@ QList Node::edges() const { return edgeList; } +//! [1] +//! [2] +void Node::calculateForces() +{ + if (!scene() || scene()->mouseGrabberItem() == this) { + newPos = pos(); + return; + } +//! [2] + +//! [3] + // Sum up all forces pushing this item away + qreal xvel = 0; + qreal yvel = 0; + foreach (QGraphicsItem *item, scene()->items()) { + Node *node = qgraphicsitem_cast(item); + if (!node) + continue; + + QPointF vec = mapToItem(node, 0, 0); + qreal dx = vec.x(); + qreal dy = vec.y(); + double l = 2.0 * (dx * dx + dy * dy); + if (l > 0) { + xvel += (dx * 150.0) / l; + yvel += (dy * 150.0) / l; + } + } +//! [3] + +//! [4] + // Now subtract all forces pulling items together + double weight = (edgeList.size() + 1) * 10; + foreach (Edge *edge, edgeList) { + QPointF vec; + if (edge->sourceNode() == this) + vec = mapToItem(edge->destNode(), 0, 0); + else + vec = mapToItem(edge->sourceNode(), 0, 0); + xvel -= vec.x() / weight; + yvel -= vec.y() / weight; + } +//! [4] + +//! [5] + if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1) + xvel = yvel = 0; +//! [5] + +//! [6] + QRectF sceneRect = scene()->sceneRect(); + newPos = pos() + QPointF(xvel, yvel); + newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)); + newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10)); +} +//! [6] + +//! [7] +bool Node::advance() +{ + if (newPos == pos()) + return false; + + setPos(newPos); + return true; +} +//! [7] + +//! [8] QRectF Node::boundingRect() const { +#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) + // Add some extra space around the circle for easier touching with finger + qreal adjust = 30; + return QRectF( -10 - adjust, -10 - adjust, + 20 + adjust * 2, 20 + adjust * 2); +#else qreal adjust = 2; - return QRectF(-15 - adjust, -15 - adjust, - 33 + adjust, 33 + adjust); + return QRectF( -10 - adjust, -10 - adjust, + 23 + adjust, 23 + adjust); +#endif } +//! [8] +//! [9] QPainterPath Node::shape() const { QPainterPath path; - path.addEllipse(-15, -15, 30, 30); +#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) + // Add some extra space around the circle for easier touching with finger + path.addEllipse( -40, -40, 80, 80); +#else + path.addEllipse(-10, -10, 20, 20); +#endif return path; } +//! [9] +//! [10] void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { painter->setPen(Qt::NoPen); painter->setBrush(Qt::darkGray); - painter->drawEllipse(-12, -12, 30, 30); + painter->drawEllipse(-7, -7, 20, 20); QColor light_color(Qt::yellow); TFunction_IFunction iFunc(myFunction); @@ -137,8 +227,9 @@ void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid gradient.setColorAt(1, dark_color); } painter->setBrush(gradient); + painter->setPen(QPen(Qt::black, 0)); - painter->drawEllipse(-15, -15, 30, 30); + painter->drawEllipse(-10, -10, 20, 20); QString s; Handle(TDataStd_Name) n; @@ -146,13 +237,16 @@ void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid s = TCollection_AsciiString(n->Get()).ToCString(); painter->drawText(-7, 3, s); } +//! [10] +//! [11] QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) { switch (change) { - case ItemPositionChange: + case ItemPositionHasChanged: foreach (Edge *edge, edgeList) edge->adjust(); + //graph->itemMoved(); break; default: break; @@ -160,7 +254,9 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) return QGraphicsItem::itemChange(change, value); } +//! [11] +//! [12] void Node::mousePressEvent(QGraphicsSceneMouseEvent *event) { update(); @@ -172,3 +268,4 @@ void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) update(); QGraphicsItem::mouseReleaseEvent(event); } +//! [12] diff --git a/samples/qt/FuncDemo/src/node.h b/samples/qt/FuncDemo/src/node.h index 393cc1f09..ab56201e6 100644 --- a/samples/qt/FuncDemo/src/node.h +++ b/samples/qt/FuncDemo/src/node.h @@ -50,8 +50,11 @@ class Edge; class GraphWidget; +QT_BEGIN_NAMESPACE class QGraphicsSceneMouseEvent; +QT_END_NAMESPACE +//! [0] class Node : public QGraphicsItem { public: @@ -66,12 +69,16 @@ class Node : public QGraphicsItem enum { Type = UserType + 1 }; int type() const { return Type; } + void calculateForces(); + bool advance(); + QRectF boundingRect() const; QPainterPath shape() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); protected: QVariant itemChange(GraphicsItemChange change, const QVariant &value); + void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); @@ -81,5 +88,6 @@ class Node : public QGraphicsItem GraphWidget *graph; TDF_Label myFunction; }; +//! [0] #endif