geosolver/workbench/tree.py
kwikrick 22e159a5ad Changes to GeometricSolver:
- 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
2009-10-09 12:23:02 +00:00

253 lines
7.4 KiB
Python

from includes import *
from parameters import Settings
class Tree:
def __init__(self, root):
self.settings = Settings()
self.orientation = self.settings.dvData.treeAlignment
self.maxDepth = 100
self.siblingSeperation = 5
self.subtreeSeperation = 5
self.levelSeperation = 40
self.maxLevelHeight = []
self.maxLevelWidth = []
self.previousLevelNode = []
self.root = None
self.topXAdjustment = 0
self.topYAdjustment = 0
self.rootOffset = QtCore.QPoint()
def firstWalk(self, tree, node, level):
leftSibbling = None
node.position.setX(0.0)
node.position.setY(0.0)
node.leftNeighbour = None
node.rightNeighbour = None
tree.setLevelHeight(node, level)
tree.setLevelWidth(node, level)
tree.setNeighbours(node, level)
if (node.getChildrenCount() == 0) or (level == tree.maxDepth):
leftSibling = node.getLeftSibling()
if leftSibling != None:
node.prelim = leftSibling.prelim + tree.getNodeSize(leftSibling) + tree.siblingSeperation
else:
node.prelim = 0.0
else:
for chldNode in node.children:
self.firstWalk(tree, chldNode, level+1)
midPoint = node.getChildrenCenter(tree)
midPoint -= tree.getNodeSize(node)/2.0
leftSibling = node.getLeftSibling()
if leftSibling != None:
node.prelim = leftSibling.prelim + tree.getNodeSize(leftSibling) + tree.siblingSeperation
node.modifier = node.prelim - midPoint
self.apportion(tree, node, level)
else:
node.prelim = midPoint
def apportion(self, tree, node, level):
k = tree.maxDepth - level
j = 1
if node.getChildrenCount() != 0:
firstChild = node.children[0]
firstChildLeftNeighbour = node.children[0].leftNeighbour
else:
firstChild = None
firstChildLeftNeighbour = None
while firstChild != None and firstChildLeftNeighbour != None and j <= k:
modifierSumRight = 0.0
modifierSumLeft = 0.0
rightAncestor = firstChild
leftAncestor = firstChildLeftNeighbour
for i in range(j):
rightAncestor = rightAncestor.parentNode
leftAncestor = leftAncestor.parentNode
modifierSumRight += rightAncestor.modifier
modifierSumLeft += leftAncestor.modifier
totalGap = (firstChildLeftNeighbour.prelim + modifierSumLeft + tree.getNodeSize(firstChildLeftNeighbour) + tree.subtreeSeperation) - (firstChild.prelim + modifierSumRight)
if totalGap > 0:
subtreeAux = node
numSubtrees = 0
while subtreeAux != None and subtreeAux != leftAncestor:
numSubtrees +=1
subtreeAux = subtreeAux.getLeftSibling()
if subtreeAux != None:
subtreeMoveAux = node
singleGap = totalGap / numSubtrees
while subtreeMoveAux != None and subtreeMoveAux != leftAncestor:
subtreeMoveAux.prelim += totalGap
subtreeMoveAux.modifier += totalGap
totalGap -= singleGap
subtreeMoveAux = subtreeMoveAux.getLeftSibling()
j += 1
if firstChild.getChildrenCount() == 0:
firstChild = tree.getLeftMost(node, 0, j)
else:
firstChild = firstChild.children[0]
if firstChild != None:
firstChildLeftNeighbour = firstChild.leftNeighbour
def secondWalk(self, tree, node, level, posX, posY):
if level <= tree.maxDepth:
xTmp = tree.rootOffset.x() + node.prelim + posX
yTmp = tree.rootOffset.y() + posY
maxSizeTmp = 0
nodeSizeTmp = 0
flag = False
if self.orientation == TreeOrientation.TOP or self.orientation == TreeOrientation.BOTTOM:
maxSizeTmp = tree.maxLevelHeight[level]
nodeSizeTmp = node.height
elif self.orientation == TreeOrientation.LEFT or self.orientation == TreeOrientation.RIGHT:
maxSizeTmp = tree.maxLevelWidth[level]
nodeSizeTmp = node.width
flag = True
node.position.setX(xTmp)
node.position.setY(yTmp)
if flag:
swapTmp = node.position.x()
node.position.setX(node.position.y())
node.position.setY(swapTmp)
if self.orientation == TreeOrientation.BOTTOM:
node.position.setY(-node.position.y() - nodeSizeTmp)
elif self.orientation == TreeOrientation.RIGHT:
node.position.setX(-node.position.x() - nodeSizeTmp)
if node.getChildrenCount() != 0:
self.secondWalk(tree, node.children[0], level+1, posX + node.modifier, posY + maxSizeTmp + tree.levelSeperation)
rightSibling = node.getRightSibling()
if rightSibling != None:
self.secondWalk(tree, rightSibling, level, posX, posY)
def positionTree(self):
self.maxLevelWidth = []
self.maxLevelHeight = []
self.previousLevelNode = []
self.firstWalk(self, self.root, 0)
self.rootOffset.setX( self.topXAdjustment + self.root.position.x())
self.rootOffset.setY( self.topYAdjustment + self.root.position.y())
self.secondWalk(self, self.root, 0, 0, 0)
def updateTree(self):
self.positionTree()
def setLevelHeight(self, node, level):
if len(self.maxLevelHeight) <= level:
for i in range(level-len(self.maxLevelHeight)+1):
self.maxLevelHeight += [None]
if self.maxLevelHeight[level]< node.height:
self.maxLevelHeight[level] = node.height
def setLevelWidth(self, node, level):
if len(self.maxLevelWidth) <= level:
for i in range(level-len(self.maxLevelWidth)+1):
self.maxLevelWidth += [None]
if self.maxLevelWidth[level]< node.width:
self.maxLevelWidth[level] = node.width
def setNeighbours(self, node, level):
if len(self.previousLevelNode) > level:
node.leftNeighbour = self.previousLevelNode[level]
else:
for i in range(level - len(self.previousLevelNode)+1):
self.previousLevelNode += [None]
if node.leftNeighbour != None:
node.leftNeighbour.rightNeighbour = node
self.previousLevelNode[level] = node
def getLeftMost(self, node, level, maxLevel):
if level >= maxLevel:
return node
if node.getChildrenCount() == 0:
return None
for chldNode in node.children:
leftMostDescendant = self.getLeftMost(chldNode, level+1, maxLevel)
if leftMostDescendant != None:
return leftMostDescendant
def getNodeSize(self, node):
if self.orientation == TreeOrientation.TOP or self.orientation == TreeOrientation.BOTTOM:
return node.width
elif self.orientation == TreeOrientation.LEFT or self.orientation == TreeOrientation.RIGHT:
return node.height
def clear(self, node):
node.clear()
for childNode in node.children:
self.clear(childNode)
def __str__(self):
pass
def __str_recursive_(self):
pass
class Node:
def __init__(self, parentNode):
self.prelim = 0
self.position = QtCore.QPointF()
self.modifier = 0.0
self.width = 50.0
self.height = 40.0
self.isCollapsed = False
self.canCollapse = True
self.parentNode = parentNode
self.leftNeighbour = None
self.rightNeighbour = None
self.children = []
self.variables = []
def collapse(self):
pass
def expand(self):
pass
def getLeftSibling(self):
if self.leftNeighbour != None and self.leftNeighbour.parentNode == self.parentNode:
return self.leftNeighbour
else:
return None
def getRightSibling(self):
if self.rightNeighbour != None and self.rightNeighbour.parentNode == self.parentNode:
return self.rightNeighbour
else:
return None
def getChildrenCenter(self, tree):
if len(self.children) > 0:
return self.children[0].prelim + ((self.children[-1].prelim - self.children[0].prelim) + tree.getNodeSize(self.children[-1]))/2.0
else:
return 0.0
def getChildrenCount(self):
if self.isCollapsed:
return 0
else:
return len(self.children)
def clear(self):
self.position.setX(0.0)
self.position.setY(0.0)
self.prelim = 0.0
self.modifier = 0.0