
- Added RigidConstraint. - Depricated some methods (get_result, get_constrainedness) and added some new methods (get_solution, get_cluster, get_status). Removed old SelectionConstraint and renamed FunctionConstraint to SelectionConstraint Depricated ClusterSolver2D Small bugfixes in cluster ClusterSolver3D Renamed solvergui directory to workbench Renamed solvertest directory to test
602 lines
24 KiB
Python
602 lines
24 KiB
Python
from includes import *
|
|
from tree import Node
|
|
from geosolver import GeometricCluster
|
|
from parameters import Settings
|
|
|
|
class CVCluster(QtGui.QGraphicsItem, Node):
|
|
""" Visualisation of the clusters (nodes) in the decompositionView """
|
|
def __init__(self, compView, parentNode, id, parent=None):
|
|
QtGui.QGraphicsItem.__init__(self, parent)
|
|
Node.__init__(self, parentNode)
|
|
|
|
self.compositionView = compView
|
|
self.setFlags(QtGui.QGraphicsItem.ItemIsSelectable)
|
|
self.setAcceptsHoverEvents(True)
|
|
self.startAngle = 0
|
|
self.spanAngle = 0
|
|
self.paintRect = QtCore.QRectF(0, 0, self.width, self.height)
|
|
self.boundary = QtCore.QRectF(0.0, 0.0, 0.0, 0.0)
|
|
self.fixGraphic = QtGui.QGraphicsSimpleTextItem("F", self)
|
|
|
|
self.identifier = id
|
|
|
|
self.bezierCurve = None
|
|
self.initAngles()
|
|
self.bound = QtCore.QRectF()
|
|
self.updateBound()
|
|
self.flag = None
|
|
self.clusterHighlight = None
|
|
self.permCluster = None
|
|
self.clusterActive = False
|
|
self.fixGraphic.hide()
|
|
|
|
def initAngles(self):
|
|
""" Initialize the angles for the visual representation of the nodes, these are dependent on the orientation of the tree """
|
|
self.startAngle = 60 * 16
|
|
self.spanAngle = 60 * 16
|
|
|
|
if self.compositionView.tree.orientation == TreeOrientation.BOTTOM:
|
|
self.startAngle = -self.startAngle
|
|
self.spanAngle = -self.spanAngle
|
|
elif self.compositionView.tree.orientation == TreeOrientation.LEFT:
|
|
self.startAngle = self.startAngle + 90 * 16
|
|
elif self.compositionView.tree.orientation == TreeOrientation.RIGHT:
|
|
self.startAngle = self.startAngle - 90 * 16
|
|
|
|
def updateBound(self):
|
|
""" The bound where the user can click in to do a certain action, is set here. This bound is tightly set around the object """
|
|
pointBegin = QtCore.QPointF(0.0, 0.0)
|
|
pointBegin.setX((self.paintRect.width()/2.0) * math.cos(math.radians(self.startAngle/16.0)))
|
|
pointBegin.setY((self.paintRect.height()/2.0) * math.sin(math.radians(self.startAngle/16.0)))
|
|
|
|
pointEnd = QtCore.QPointF(0.0, 0.0)
|
|
pointEnd.setX((self.paintRect.width()/2.0) * math.cos(math.radians((self.startAngle+self.spanAngle)/16.0)))
|
|
pointEnd.setY((self.paintRect.height()/2.0) * math.sin(math.radians((self.startAngle+self.spanAngle)/16.0)))
|
|
|
|
pointMiddle = QtCore.QPointF(0.0, 0.0)
|
|
halfDegree = (self.startAngle+(self.spanAngle/2.0))/16.0
|
|
pointMiddle.setX((self.paintRect.width()/2.0) * math.cos(math.radians(halfDegree)))
|
|
pointMiddle.setY((self.paintRect.height()/2.0) * math.sin(math.radians(halfDegree)))
|
|
|
|
if pointBegin.x() < pointMiddle.x() and pointBegin.x() < pointEnd.x():
|
|
self.boundary.setLeft(pointBegin.x())
|
|
elif pointMiddle.x() < pointEnd.x():
|
|
self.boundary.setLeft(pointMiddle.x())
|
|
else:
|
|
self.boundary.setLeft(pointEnd.x())
|
|
|
|
if self.boundary.left() > 0.0:
|
|
self.boundary.setLeft(0.0)
|
|
|
|
if pointBegin.x() > pointMiddle.x() and pointBegin.x() > pointEnd.x():
|
|
self.boundary.setRight(pointBegin.x())
|
|
elif pointMiddle.x() > pointEnd.x():
|
|
self.boundary.setRight(pointMiddle.x())
|
|
else:
|
|
self.boundary.setRight(pointEnd.x())
|
|
|
|
if self.boundary.right() < 0.0:
|
|
self.boundary.setRight(0.0)
|
|
|
|
if pointBegin.y() < pointMiddle.y() and pointBegin.y() < pointEnd.y():
|
|
self.boundary.setBottom(pointBegin.y())
|
|
elif pointMiddle.y() < pointEnd.y():
|
|
self.boundary.setBottom(pointMiddle.y())
|
|
else:
|
|
self.boundary.setBottom(pointEnd.y())
|
|
|
|
if self.boundary.bottom() > 0.0:
|
|
self.boundary.setBottom(0.0)
|
|
|
|
if pointBegin.y() > pointMiddle.y() and pointBegin.y() > pointEnd.y():
|
|
self.boundary.setTop(pointBegin.y())
|
|
elif pointMiddle.y() > pointEnd.y():
|
|
self.boundary.setTop(pointMiddle.y())
|
|
else:
|
|
self.boundary.setTop(pointEnd.y())
|
|
|
|
if self.boundary.top() < 0.0:
|
|
self.boundary.setTop(0.0)
|
|
|
|
self.__translateBound()
|
|
|
|
|
|
def __translateBound(self):
|
|
""" Translation of the boundary, so that it fits exactly around the figure"""
|
|
self.boundary.setLeft(self.boundary.left()+self.paintRect.center().x())
|
|
self.boundary.setRight(self.boundary.right()+self.paintRect.center().x())
|
|
self.boundary.setTop(-self.boundary.top()+self.paintRect.center().y())
|
|
self.boundary.setBottom(-self.boundary.bottom()+self.paintRect.center().y())
|
|
|
|
def shape(self):
|
|
""" Overridden function to set the boundary wherein the user can perform an action """
|
|
path = QtGui.QPainterPath()
|
|
path.addRect(self.boundary)
|
|
return path
|
|
|
|
def boundingRect(self):
|
|
""" Overridden function where a update area is determined for painting and returned """
|
|
return self.paintRect
|
|
|
|
def paint(self, painter, option, widget):
|
|
""" Visualisation of a clusteritem """
|
|
painter.setPen(QtGui.QColor(0,155,50))
|
|
|
|
if self.flag != None:
|
|
if self.flag == GeometricCluster.OK:
|
|
painter.setBrush(QtGui.QBrush(self.compositionView.wellConstrainedColor))
|
|
elif self.flag == GeometricCluster.I_UNDER or self.flag == GeometricCluster.S_UNDER:
|
|
painter.setBrush(QtGui.QBrush(self.compositionView.underConstrainedColor))
|
|
elif self.flag == GeometricCluster.I_OVER or self.flag == GeometricCluster.S_OVER:
|
|
painter.setBrush(QtGui.QBrush(self.compositionView.overConstrainedColor))
|
|
elif self.flag == GeometricCluster.UNSOLVED:
|
|
painter.setBrush(QtGui.QBrush(self.compositionView.unsolvedColor))
|
|
painter.drawPie(self.paintRect, self.startAngle, self.spanAngle)
|
|
|
|
def setInfoOverlay(self):
|
|
constrInfo = QtCore.QString("")
|
|
if self.flag == GeometricCluster.OK:
|
|
constrInfo = QtCore.QString("Well-Constrained\n")
|
|
elif self.flag == GeometricCluster.I_UNDER:
|
|
constrInfo = QtCore.QString("Inc. Underconstrained\n")
|
|
elif self.flag == GeometricCluster.S_UNDER:
|
|
constrInfo = QtCore.QString("Struct. Underconstrained\n")
|
|
elif self.flag == GeometricCluster.I_OVER:
|
|
constrInfo = QtCore.QString("Inc. Overconstrained\n")
|
|
elif self.flag == GeometricCluster.S_OVER:
|
|
constrInfo = QtCore.QString("Struct. Overconstrained\n")
|
|
elif self.flag == GeometricCluster.UNSOLVED:
|
|
constrInfo = QtCore.QString("Unsolved\n")
|
|
constrInfo.append("Points: ")
|
|
|
|
for point in self.variables:
|
|
pointObject = self.compositionView.prototypeManager.getObjectByKey(point)
|
|
if pointObject != None:
|
|
constrInfo.append(pointObject.name)
|
|
if point != self.variables[-1]:
|
|
constrInfo.append(", ")
|
|
|
|
self.compositionView.infoOverlay.infoText = constrInfo
|
|
|
|
#painter.setBrush(QtCore.Qt.NoBrush)
|
|
#painter.drawRect(self.bound)
|
|
|
|
def mousePressEvent(self, event):
|
|
""" Handling the mouse press, where the cluster (visualisation) and tree can be updated
|
|
|
|
Parameters:
|
|
event - pressed mousebutton
|
|
"""
|
|
if event.button() == QtCore.Qt.LeftButton:
|
|
self.updateCluster()
|
|
self.updateBound()
|
|
self.compositionView.updateTree()
|
|
elif event.button() == QtCore.Qt.RightButton:
|
|
if not self.clusterActive:
|
|
self.permanentCluster()
|
|
self.clusterActive = True
|
|
self.fixGraphic.show()
|
|
self.compositionView.stateChange(self.identifier, True)
|
|
else:
|
|
self.compositionView.prototypeManager.removeClusterObjects([self.permCluster], True, True)
|
|
self.clusterActive = False
|
|
self.fixGraphic.hide()
|
|
self.compositionView.stateChange(self.identifier, False)
|
|
self.permCluster = None
|
|
self.compositionView.prototypeManager.setObjectVisibilityByClusters()
|
|
self.compositionView.updateViewports()
|
|
|
|
def hoverEnterEvent(self, event):
|
|
self.setZValue(2)
|
|
self.setInfoOverlay()
|
|
self.compositionView.infoOverlay.setPosition(event.scenePos())
|
|
self.compositionView.infoOverlay.show()
|
|
if not self.clusterActive:
|
|
self.compositionView.prototypeManager.selectObjectsByKeys(self.variables)
|
|
self.highlightCluster()
|
|
self.compositionView.update()
|
|
self.compositionView.updateViewports()
|
|
|
|
def hoverMoveEvent(self, event):
|
|
self.overlayPosition = self.compositionView.ui.graphicsView.mapFromScene(event.scenePos())
|
|
self.compositionView.infoOverlay.setPosition(event.scenePos())
|
|
|
|
self.compositionView.updateConnections()
|
|
self.compositionView.update()
|
|
|
|
def hoverLeaveEvent(self, event):
|
|
self.setZValue(0)
|
|
self.compositionView.infoOverlay.infoText = ""
|
|
self.compositionView.infoOverlay.hide()
|
|
self.compositionView.infoOverlay.update()
|
|
if not self.clusterActive:
|
|
self.compositionView.prototypeManager.deselectAllObjects()
|
|
self.compositionView.prototypeManager.removeClusterObjects([self.clusterHighlight], True, False)
|
|
self.compositionView.updateViewports()
|
|
|
|
def updateCluster(self):
|
|
""" Cluster update, where the cluster is (un-)collapsed depending on the state of the cluster, to visualise a certain part of the tree """
|
|
if self.canCollapse:
|
|
if self.isCollapsed:
|
|
self.isCollapsed = False
|
|
self.showChildren()
|
|
height = self.paintRect.height()*0.5
|
|
width = self.paintRect.width()*0.5
|
|
height2 = self.paintRect.height()
|
|
if self.compositionView.tree.orientation == TreeOrientation.TOP:
|
|
self.paintRect.setTop(self.paintRect.top() + height )
|
|
self.paintRect.setBottom(self.paintRect.bottom() + height)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.BOTTOM:
|
|
self.paintRect.setTop(self.paintRect.top()- height )
|
|
self.paintRect.setBottom(self.paintRect.bottom() - height)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.LEFT:
|
|
self.paintRect.setLeft(self.paintRect.left() + width)
|
|
self.paintRect.setRight(self.paintRect.right() + width)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.RIGHT:
|
|
self.paintRect.setLeft(self.paintRect.left() - width)
|
|
self.paintRect.setRight(self.paintRect.right() - width)
|
|
else:
|
|
self.isCollapsed = True
|
|
self.showChildren()
|
|
height = self.paintRect.height()*0.5
|
|
width = self.paintRect.width()*0.5
|
|
height2 = self.paintRect.height()
|
|
if self.compositionView.tree.orientation == TreeOrientation.TOP:
|
|
self.paintRect.setTop(self.paintRect.top() - height)
|
|
self.paintRect.setBottom(self.paintRect.bottom() - height)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.BOTTOM:
|
|
self.paintRect.setTop(self.paintRect.top() + height)
|
|
self.paintRect.setBottom(self.paintRect.bottom() + height)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.LEFT:
|
|
self.paintRect.setLeft(self.paintRect.left() - width)
|
|
self.paintRect.setRight(self.paintRect.right() - width)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.RIGHT:
|
|
self.paintRect.setLeft(self.paintRect.left() + width)
|
|
self.paintRect.setRight(self.paintRect.right() + width)
|
|
|
|
if self.compositionView.tree.orientation == TreeOrientation.LEFT or self.compositionView.tree.orientation == TreeOrientation.RIGHT:
|
|
self.startAngle = self.startAngle + 180 * 16
|
|
else:
|
|
self.startAngle = -self.startAngle
|
|
self.spanAngle = -self.spanAngle
|
|
|
|
def highlightCluster(self):
|
|
if self.clusterHighlight != None:
|
|
if self.clusterHighlight.temporary:
|
|
self.compositionView.prototypeManager.addClusterObject(self.clusterHighlight)
|
|
self.clusterHighlight.selected = True
|
|
else:
|
|
self.clusterHighlight = self.compositionView.prototypeManager.selectClusterObjectByKeys(self.variables)
|
|
if self.clusterHighlight == None:
|
|
self.clusterHighlight = self.compositionView.prototypeManager.createCluster(self.variables)
|
|
if self.clusterHighlight != None:
|
|
self.clusterHighlight.temporary = True
|
|
if self.clusterHighlight != None:
|
|
self.clusterHighlight.selected = True
|
|
|
|
def permanentCluster(self):
|
|
if self.permCluster == None:
|
|
self.permCluster = self.compositionView.prototypeManager.createCluster(self.variables, self.flag)
|
|
self.permCluster.temporary = True
|
|
self.permCluster.fixed = True
|
|
self.compositionView.prototypeManager.setObjectVisibilityByClusters()
|
|
else:
|
|
self.compositionView.prototypeManager.addClusterObject(self.permCluster)
|
|
self.permCluster.selected = False
|
|
|
|
def showChildren(self):
|
|
""" Show the children of this node """
|
|
if self.isCollapsed or (self.isVisible()==False):
|
|
for child in self.children:
|
|
child.hide()
|
|
child.showChildren()
|
|
if child.clusterActive:
|
|
child.fixGraphic.hide()
|
|
else:
|
|
for child in self.children:
|
|
child.show()
|
|
child.showChildren()
|
|
if child.clusterActive:
|
|
child.fixGraphic.show()
|
|
else:
|
|
child.fixGraphic.hide()
|
|
|
|
def collapseFromResult(self):
|
|
if self.flag == GeometricCluster.I_UNDER or self.flag == GeometricCluster.S_UNDER or self.flag == GeometricCluster.I_OVER or self.flag == GeometricCluster.S_OVER or self.flag == GeometricCluster.UNSOLVED:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def collapse(self):
|
|
if not self.isCollapsed:
|
|
self.updateCluster()
|
|
self.updateBound()
|
|
|
|
def expand(self):
|
|
if self.isCollapsed:
|
|
self.updateCluster()
|
|
self.updateBound()
|
|
|
|
class CVPoint(QtGui.QGraphicsItem, Node):
|
|
""" Visualisation of the leaves of the 'leaf' clusters in the tree """
|
|
def __init__(self, compView, parentNode, id, parent=None):
|
|
QtGui.QGraphicsItem.__init__(self, parent)
|
|
Node.__init__(self, parentNode)
|
|
|
|
self.compositionView = compView
|
|
self.setFlags(QtGui.QGraphicsItem.ItemIsSelectable)
|
|
self.setAcceptsHoverEvents(True)
|
|
self.startAngle = 0
|
|
self.spanAngle = 0
|
|
self.paintRect = QtCore.QRectF(0, 0, self.width/2, self.height/2)
|
|
self.fixGraphic = QtGui.QGraphicsSimpleTextItem("F", self)
|
|
self.fixGraphic.hide()
|
|
self.bezierCurve = None
|
|
self.flag = None
|
|
self.prtRef = None
|
|
self.boundary = self.paintRect
|
|
self.clusterHighlight = None
|
|
self.permCluster = None
|
|
self.clusterActive = False
|
|
self.identifier = id
|
|
|
|
def paint(self, painter, option, widget):
|
|
painter.setPen(QtGui.QColor(0,155,50))
|
|
painter.setBrush(QtGui.QBrush(QtGui.QColor(0,155,50)))
|
|
painter.drawEllipse(self.paintRect)
|
|
|
|
def setInfoOverlay(self):
|
|
constrInfo = QtCore.QString("Points \n")
|
|
if self.prtRef != None:
|
|
constrInfo += "Name: " + self.prtRef.name + "\n"
|
|
constrInfo += "Position: (" + str(round(self.prtRef.position[0],2)) + " , " + str(round(self.prtRef.position[1])) + " , " + str(round(self.prtRef.position[2])) + ")"
|
|
self.compositionView.infoOverlay.infoText = constrInfo
|
|
|
|
def mousePressEvent(self, event):
|
|
""" Handling the mouse press, where the cluster (visualisation) is handled
|
|
|
|
Parameters:
|
|
event - pressed mousebutton
|
|
"""
|
|
if event.button() == QtCore.Qt.RightButton:
|
|
if not self.clusterActive:
|
|
self.permanentCluster()
|
|
self.clusterActive = True
|
|
self.fixGraphic.show()
|
|
self.compositionView.stateChange(self.identifier, True)
|
|
else:
|
|
self.compositionView.prototypeManager.removeClusterObjects([self.permCluster], True, True)
|
|
self.clusterActive = False
|
|
self.permCluster = None
|
|
self.fixGraphic.hide()
|
|
self.compositionView.stateChange(self.identifier, False)
|
|
self.compositionView.prototypeManager.setObjectVisibilityByClusters()
|
|
self.compositionView.updateViewports()
|
|
|
|
def hoverEnterEvent(self, event):
|
|
self.setZValue(2)
|
|
self.setInfoOverlay()
|
|
self.compositionView.infoOverlay.setPosition(event.scenePos())
|
|
self.compositionView.infoOverlay.show()
|
|
|
|
if not self.clusterActive:
|
|
self.compositionView.prototypeManager.selectObject(self.prtRef)
|
|
self.highlightCluster()
|
|
self.compositionView.update()
|
|
self.compositionView.updateViewports()
|
|
|
|
def hoverMoveEvent(self, event):
|
|
self.compositionView.infoOverlay.setPosition(event.scenePos())
|
|
self.compositionView.update()
|
|
|
|
def hoverLeaveEvent(self, event):
|
|
self.setZValue(0)
|
|
self.compositionView.infoOverlay.infoText = ""
|
|
self.compositionView.infoOverlay.hide()
|
|
self.compositionView.infoOverlay.update()
|
|
if not self.clusterActive:
|
|
self.compositionView.prototypeManager.deselectAllObjects()
|
|
self.compositionView.prototypeManager.removeClusterObjects([self.clusterHighlight], True)
|
|
self.compositionView.updateViewports()
|
|
|
|
def highlightCluster(self):
|
|
if self.clusterHighlight != None:
|
|
if self.clusterHighlight.temporary:
|
|
self.compositionView.prototypeManager.addClusterObject(self.clusterHighlight)
|
|
self.clusterHighlight.selected = True
|
|
else:
|
|
self.clusterHighlight = self.compositionView.prototypeManager.selectClusterObjectByKeys([self.prtRef.key])
|
|
if self.clusterHighlight == None:
|
|
self.clusterHighlight = self.compositionView.prototypeManager.createCluster([self.prtRef.key])
|
|
if self.clusterHighlight != None:
|
|
self.clusterHighlight.temporary = True
|
|
if self.clusterHighlight != None:
|
|
self.clusterHighlight.selected = True
|
|
|
|
def permanentCluster(self):
|
|
if self.permCluster == None:
|
|
self.permCluster = self.compositionView.prototypeManager.createCluster([self.prtRef.key])
|
|
self.permCluster.temporary = True
|
|
self.permCluster.fixed = True
|
|
self.compositionView.prototypeManager.setObjectVisibilityByClusters()
|
|
else:
|
|
self.compositionView.prototypeManager.addClusterObject(self.permCluster)
|
|
self.permCluster.selected = False
|
|
|
|
def boundingRect(self):
|
|
return self.paintRect
|
|
|
|
def setWidthAndHeight(self, width, height):
|
|
self.width = width
|
|
self.height = height
|
|
self.paintRect.setWidth(width)
|
|
self.paintRect.setHeight(height)
|
|
|
|
def showChildren(self):
|
|
""" Show the children of this node """
|
|
if self.isCollapsed or (self.isVisible()==False):
|
|
for child in self.children:
|
|
child.hide()
|
|
child.showChildren()
|
|
else:
|
|
for child in self.children:
|
|
child.show()
|
|
child.showChildren()
|
|
|
|
def collapse(self):
|
|
self.isCollapsed = True
|
|
|
|
def expand(self):
|
|
self.isCollapsed = False
|
|
|
|
class CVInfoOverlay(QtGui.QGraphicsItem):
|
|
def __init__(self, compView, parent=None):
|
|
QtGui.QGraphicsItem.__init__(self, parent)
|
|
self.node = None
|
|
self.compositionView = compView
|
|
self.infoText = QtCore.QString("")
|
|
self.setZValue(3)
|
|
self.infoOverlay = QtCore.QRectF(0, 0, 140, 50)
|
|
self.overlayPosition = QtCore.QPointF()
|
|
self.scenePosition = QtCore.QPointF()
|
|
|
|
self.overlayBGColor = QtGui.QColor(204, 251, 255, 200)
|
|
self.overlayLineColor = QtGui.QColor(33, 116, 154)
|
|
self.overlayTextColor = QtGui.QColor(0, 0, 0)
|
|
|
|
def paint(self, painter, option, widget):
|
|
painter.save()
|
|
painter.resetMatrix()
|
|
painter.translate(self.overlayPosition)
|
|
painter.translate(10.0, 10.0)
|
|
painter.setPen(self.overlayLineColor)
|
|
painter.setBrush(self.overlayBGColor)
|
|
painter.drawRect(self.infoOverlay)
|
|
|
|
infoFont = QtGui.QFont("Arial", 7)
|
|
infoFont.setStyleStrategy(QtGui.QFont.ForceOutline)
|
|
painter.setFont(infoFont)
|
|
painter.setRenderHint(QtGui.QPainter.TextAntialiasing, False)
|
|
painter.setPen(self.overlayTextColor)
|
|
textRect = QtCore.QRect(self.infoOverlay.left()+4, self.infoOverlay.top(), self.infoOverlay.width()-3, self.infoOverlay.height()-3)
|
|
|
|
painter.drawText(textRect, QtCore.Qt.AlignLeft|QtCore.Qt.TextWordWrap, self.infoText)
|
|
painter.restore()
|
|
|
|
def setPosition(self, position):
|
|
self.scenePosition = position
|
|
self.overlayPosition = self.compositionView.ui.graphicsView.mapFromScene(position)
|
|
|
|
def boundingRect(self):
|
|
check = QtCore.QRectF(self.infoOverlay)
|
|
return check
|
|
|
|
class CVConnection(QtGui.QGraphicsItem):
|
|
""" Visualisation of the connections between the clusters, where two types of visualisation can be chosen: Bezier(default) and Lines """
|
|
def __init__(self, compView, nodeFrom , nodeTo, parent=None):
|
|
QtGui.QGraphicsItem.__init__(self, parent)
|
|
self.settings = Settings()
|
|
self.compositionView = compView
|
|
self.nodeFrom = nodeFrom
|
|
self.nodeTo = nodeTo
|
|
self.connectType = self.settings.dvData.treeConnection
|
|
#self.boundRect = QtCore.QRectF(0.0, 0.0, 0.0, 0.0)
|
|
self.beziercurve = None
|
|
self.paintRect = QtCore.QRectF(0, 0, 0, 0)
|
|
self.setZValue(1)
|
|
|
|
def paint(self, painter, option, widget):
|
|
""" Visualisation of the connection between two nodes """
|
|
if self.nodeFrom != None and self.nodeTo != None:
|
|
painter.setPen(QtGui.QColor(0,0,0))
|
|
|
|
diffPosExt = self.paintRect
|
|
endPoint = self.determineEndpoint(diffPosExt)
|
|
|
|
if self.connectType == ConnectionType.BEZIER:
|
|
""" display a bezier curve as connection """
|
|
self.beziercurve = QtGui.QPainterPath()
|
|
|
|
if self.compositionView.tree.orientation == TreeOrientation.TOP:
|
|
self.beziercurve.moveTo(diffPosExt.x(), diffPosExt.y())
|
|
firstPoint = QtCore.QPointF(diffPosExt.x(), diffPosExt.height()*0.5)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.BOTTOM:
|
|
self.beziercurve.moveTo(diffPosExt.x(), diffPosExt.bottom())
|
|
firstPoint = QtCore.QPointF(diffPosExt.x(), -diffPosExt.height()*0.5 + self.nodeTo.paintRect.height())
|
|
elif self.compositionView.tree.orientation == TreeOrientation.LEFT:
|
|
self.beziercurve.moveTo(diffPosExt.x(), diffPosExt.y())
|
|
firstPoint = QtCore.QPointF(diffPosExt.width()*0.5, diffPosExt.y())
|
|
elif self.compositionView.tree.orientation == TreeOrientation.RIGHT:
|
|
self.beziercurve.moveTo(diffPosExt.x(), diffPosExt.y())
|
|
firstPoint = QtCore.QPointF(self.nodeTo.paintRect.width() + diffPosExt.width()*0.5,diffPosExt.y())
|
|
|
|
if self.compositionView.tree.orientation == TreeOrientation.TOP:
|
|
secondPoint = QtCore.QPointF(diffPosExt.right(),diffPosExt.height()*0.5)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.BOTTOM:
|
|
secondPoint = QtCore.QPointF(diffPosExt.right(), self.nodeTo.paintRect.height() - diffPosExt.height()*0.5)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.LEFT:
|
|
secondPoint = QtCore.QPointF(diffPosExt.width()*0.5, diffPosExt.bottom())
|
|
elif self.compositionView.tree.orientation == TreeOrientation.RIGHT:
|
|
secondPoint = QtCore.QPointF(self.nodeTo.paintRect.width() + diffPosExt.width()*0.5, diffPosExt.bottom())
|
|
|
|
self.beziercurve.cubicTo(firstPoint, secondPoint, endPoint)
|
|
painter.drawPath(self.beziercurve)
|
|
|
|
elif self.connectType == ConnectionType.LINES:
|
|
""" draw a straight line """
|
|
if self.compositionView.tree.orientation == TreeOrientation.TOP:
|
|
painter.drawLine(QtCore.QPointF(self.nodeTo.paintRect.width()*0.5, 0.0), QtCore.QPointF(endPoint.x(), endPoint.y()))
|
|
elif self.compositionView.tree.orientation == TreeOrientation.BOTTOM:
|
|
painter.drawLine(QtCore.QPointF(self.nodeTo.paintRect.width()*0.5, self.nodeTo.paintRect.height()), QtCore.QPointF(endPoint.x(), endPoint.y()))
|
|
elif self.compositionView.tree.orientation == TreeOrientation.LEFT:
|
|
painter.drawLine(QtCore.QPointF(0.0, self.nodeTo.paintRect.height()*0.5), QtCore.QPointF(endPoint.x(), endPoint.y()))
|
|
elif self.compositionView.tree.orientation == TreeOrientation.RIGHT:
|
|
painter.drawLine(QtCore.QPointF(self.nodeTo.paintRect.width(), self.nodeTo.paintRect.height()*0.5), QtCore.QPointF(endPoint.x(), endPoint.y()))
|
|
|
|
def areaBetweenNodes(self):
|
|
diffPos = self.nodeTo.position - self.nodeFrom.position
|
|
area = QtCore.QRectF(0.0, 0.0, 0.0 , 0.0)
|
|
if self.compositionView.tree.orientation == TreeOrientation.TOP:
|
|
area.setX(self.nodeTo.paintRect.width()*0.5)
|
|
area.setY(0.0)
|
|
area.setRight(self.nodeFrom.paintRect.width()*0.5 - diffPos.x())
|
|
area.setBottom(self.nodeTo.boundary.height()-diffPos.y())
|
|
elif self.compositionView.tree.orientation == TreeOrientation.BOTTOM:
|
|
area.setX(self.nodeTo.paintRect.width()*0.5)
|
|
area.setY(-diffPos.y()+self.nodeFrom.boundary.height())
|
|
area.setRight(-diffPos.x()+self.nodeFrom.paintRect.width()*0.5)
|
|
area.setBottom(self.nodeTo.paintRect.height())
|
|
elif self.compositionView.tree.orientation == TreeOrientation.LEFT:
|
|
area.setX(0.0)
|
|
area.setY(self.nodeTo.paintRect.height()*0.5)
|
|
area.setRight(-diffPos.x()+self.nodeFrom.boundary.width())
|
|
area.setBottom(-diffPos.y() + self.nodeFrom.paintRect.height()*0.5)
|
|
elif self.compositionView.tree.orientation == TreeOrientation.RIGHT:
|
|
area.setX(self.nodeTo.paintRect.width())
|
|
area.setY(self.nodeTo.paintRect.height()*0.5)
|
|
area.setRight(-diffPos.x() + self.nodeFrom.paintRect.width()*0.5)
|
|
area.setBottom(-diffPos.y() + self.nodeFrom.paintRect.height()*0.5)
|
|
return area
|
|
|
|
def determineEndpoint(self, area):
|
|
endPoint = QtCore.QPointF(0.0, 0.0)
|
|
|
|
if self.compositionView.tree.orientation == TreeOrientation.TOP:
|
|
endPoint.setX(area.right())
|
|
endPoint.setY(area.height())
|
|
elif self.compositionView.tree.orientation == TreeOrientation.BOTTOM:
|
|
endPoint.setX(area.right())
|
|
endPoint.setY(area.y())
|
|
elif self.compositionView.tree.orientation == TreeOrientation.LEFT:
|
|
endPoint.setX(area.right())
|
|
endPoint.setY(area.bottom())
|
|
elif self.compositionView.tree.orientation == TreeOrientation.RIGHT:
|
|
endPoint.setX(area.right())
|
|
endPoint.setY(area.bottom())
|
|
return endPoint
|
|
|
|
def boundingRect(self):
|
|
""" Overridden function where a update area is determined for painting and returned """
|
|
self.paintRect = self.areaBetweenNodes()
|
|
return self.paintRect
|