summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/GUI/xasyBezierInterface.py
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/GUI/xasyBezierInterface.py')
-rw-r--r--Build/source/utils/asymptote/GUI/xasyBezierInterface.py375
1 files changed, 0 insertions, 375 deletions
diff --git a/Build/source/utils/asymptote/GUI/xasyBezierInterface.py b/Build/source/utils/asymptote/GUI/xasyBezierInterface.py
deleted file mode 100644
index 0a5c689bffe..00000000000
--- a/Build/source/utils/asymptote/GUI/xasyBezierInterface.py
+++ /dev/null
@@ -1,375 +0,0 @@
-#!/usr/bin/env python3
-
-import xasy2asy as x2a
-import xasyUtils as xu
-
-import PyQt5.QtCore as Qc
-import PyQt5.QtGui as Qg
-import PyQt5.QtWidgets as Qw
-
-import Widg_editBezier as Web
-
-import InplaceAddObj
-
-import math
-
-class CurrentlySelctedType:
- none = -1
- node = 0
- ctrlPoint = 1
-
-class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
- editAccepted = Qc.pyqtSignal()
- editRejected = Qc.pyqtSignal()
-
- def __init__(self, parent: Qc.QObject, obj: x2a.xasyDrawnItem, info: dict={}):
- super().__init__(parent)
- self.info = info
- self.asyPathBackup = x2a.asyPath.fromPath(obj.path)
- self.asyPath = obj.path
- self.curveMode = self.asyPath.containsCurve
- assert isinstance(self.asyPath, x2a.asyPath)
- self.transf = obj.transfKeymap[obj.transfKey][0]
- self._active = True
-
- self.currentSelMode = None
- # (Node index, Node subindex for )
- self.currentSelIndex = (None, 0)
-
- self.nodeSelRects = []
- self.ctrlSelRects = []
-
- self.setSelectionBoundaries()
-
- self.lastSelPoint = None
- self.preCtrlOffset = None
- self.postCtrlOffset = None
- self.inTransformMode = False
-
- self.opt = None
-
- self.prosectiveNodes = []
- self.prospectiveCtrlPts = []
-
- def setSelectionBoundaries(self):
- self.nodeSelRects = self.handleNodeSelectionBounds()
-
- if self.curveMode:
- self.ctrlSelRects = self.handleCtrlSelectionBoundaries()
-
- def handleNodeSelectionBounds(self):
- nodeSelectionBoundaries = []
-
- for node in self.asyPath.nodeSet:
- if node == 'cycle':
- nodeSelectionBoundaries.append(None)
- continue
-
- selEpsilon = 6/self.info['magnification']
- newRect = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
- x, y = self.transf * node
- x = int(round(x))
- y = int(round(y))
- newRect.moveCenter(Qc.QPoint(x, y))
-
- nodeSelectionBoundaries.append(newRect)
-
- return nodeSelectionBoundaries
-
- def handleCtrlSelectionBoundaries(self):
- ctrlPointSelBoundaries = []
-
- for nodes in self.asyPath.controlSet:
- nodea, nodeb = nodes
-
- selEpsilon = 6/self.info['magnification']
-
- newRect = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
- newRectb = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
-
- x, y = self.transf * nodea
- x2, y2 = self.transf * nodeb
-
- x = int(round(x))
- y = int(round(y))
-
- x2 = int(round(x2))
- y2 = int(round(y2))
-
- newRect.moveCenter(Qc.QPoint(x, y))
- newRectb.moveCenter(Qc.QPoint(x2, y2))
-
- ctrlPointSelBoundaries.append((newRect, newRectb))
-
- return ctrlPointSelBoundaries
-
- def postDrawPreview(self, canvas: Qg.QPainter):
- assert canvas.isActive()
-
- dashedPen = Qg.QPen(Qc.Qt.DashLine)
- dashedPen.setWidthF(1/self.info['magnification'])
- # draw the base points
- canvas.save()
- canvas.setWorldTransform(self.transf.toQTransform(), True)
-
- epsilonSize = 6/self.info['magnification']
-
- if self.info['autoRecompute'] or not self.curveMode:
- ctrlPtsColor = 'gray'
- else:
- ctrlPtsColor = 'red'
-
- canvas.setPen(dashedPen)
-
- canvas.drawPath(self.asyPath.toQPainterPath())
-
- nodePen = Qg.QPen(Qg.QColor('blue'))
- nodePen.setWidthF(1/self.info['magnification'])
-
- ctlPtsPen = Qg.QPen(Qg.QColor(ctrlPtsColor))
- ctlPtsPen.setWidthF(1/self.info['magnification'])
-
- for index in range(len(self.asyPath.nodeSet)):
- point = self.asyPath.nodeSet[index]
-
- if point != 'cycle':
- basePoint = Qc.QPointF(point[0], point[1])
- canvas.setPen(nodePen)
- canvas.drawEllipse(basePoint, epsilonSize, epsilonSize)
- else:
- point = self.asyPath.nodeSet[0]
- basePoint = Qc.QPointF(point[0], point[1])
- if self.curveMode:
- if index != 0:
- canvas.setPen(ctlPtsPen)
- postCtrolSet = self.asyPath.controlSet[index - 1][1]
- postCtrlPoint = Qc.QPointF(postCtrolSet[0], postCtrolSet[1])
- canvas.drawEllipse(postCtrlPoint, epsilonSize, epsilonSize)
-
- canvas.setPen(dashedPen)
- canvas.drawLine(basePoint, postCtrlPoint)
-
- if index != len(self.asyPath.nodeSet) - 1:
- canvas.setPen(ctlPtsPen)
- preCtrlSet = self.asyPath.controlSet[index][0]
- preCtrlPoint = Qc.QPointF(preCtrlSet[0], preCtrlSet[1])
- canvas.drawEllipse(preCtrlPoint, epsilonSize, epsilonSize)
-
- canvas.setPen(dashedPen)
- canvas.drawLine(basePoint, preCtrlPoint)
-
- canvas.restore()
-
- def getPreAndPostCtrlPts(self, index):
- isCycle = self.asyPath.nodeSet[-1] == 'cycle'
-
- if index == 0 and not isCycle:
- preCtrl = None
- else:
- preCtrl = self.asyPath.controlSet[index - 1][1]
-
- if index == len(self.asyPath.nodeSet) - 1 and not isCycle:
- postCtrl = None
- else:
- postCtrl = self.asyPath.controlSet[index % (len(self.asyPath.nodeSet) - 1)][0]
-
- return preCtrl, postCtrl
-
- def findLinkingNode(self, index, subindex):
- """index and subindex are of the control points list."""
- if subindex == 0:
- return index
- else:
- if self.asyPath.nodeSet[index + 1] == 'cycle':
- return 0
- else:
- return index + 1
-
- def resetObj(self):
- self.asyPath.setInfo(self.asyPathBackup)
- self.setSelectionBoundaries()
-
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
- self.lastSelPoint = pos
- if self.inTransformMode:
- return
-
- if self.prosectiveNodes and not self.inTransformMode:
- self.currentSelMode = CurrentlySelctedType.node
- self.currentSelIndex = (self.prosectiveNodes[0], 0)
- self.inTransformMode = True
- self.parentNodeIndex = self.currentSelIndex[0]
- elif self.prospectiveCtrlPts and not self.inTransformMode:
- self.currentSelMode = CurrentlySelctedType.ctrlPoint
- self.currentSelIndex = self.prospectiveCtrlPts[0]
- self.inTransformMode = True
- self.parentNodeIndex = self.findLinkingNode(*self.currentSelIndex)
-
- if self.inTransformMode:
- parentNode = self.asyPath.nodeSet[self.parentNodeIndex]
-
- # find the offset of each control point to the node
- if not self.curveMode:
- return
-
- preCtrl, postCtrl = self.getPreAndPostCtrlPts(self.parentNodeIndex)
-
- if parentNode == 'cycle':
- parentNode = self.asyPath.nodeSet[0]
- self.parentNodeIndex = 0
-
- if preCtrl is not None:
- self.preCtrlOffset = xu.funcOnList(
- preCtrl, parentNode, lambda a, b: a - b)
- else:
- self.preCtrlOffset = None
-
- if postCtrl is not None:
- self.postCtrlOffset = xu.funcOnList(
- postCtrl, parentNode, lambda a, b: a - b)
- else:
- self.postCtrlOffset = None
-
- def mouseMove(self, pos, event: Qg.QMouseEvent):
- if self.currentSelMode is None and not self.inTransformMode:
- # in this case, search for prosective nodes.
- prospectiveNodes = []
- prospectiveCtrlpts = []
-
- for i in range(len(self.nodeSelRects)):
- rect = self.nodeSelRects[i]
- if rect is None:
- continue
- if rect.contains(pos):
- prospectiveNodes.append(i)
-
- self.prosectiveNodes = prospectiveNodes
-
- if not self.info['autoRecompute'] and self.curveMode:
- for i in range(len(self.ctrlSelRects)):
- recta, rectb = self.ctrlSelRects[i]
-
- if recta.contains(pos):
- prospectiveCtrlpts.append((i, 0))
-
- if rectb.contains(pos):
- prospectiveCtrlpts.append((i, 1))
-
- self.prospectiveCtrlPts = prospectiveCtrlpts
- else:
- self.prospectiveCtrlPts = []
-
-
- if self.inTransformMode:
- index, subindex = self.currentSelIndex
- deltaPos = pos - self.lastSelPoint
- newNode = (pos.x(), pos.y())
- if self.currentSelMode == CurrentlySelctedType.node:
- # static throughout the moving
- if self.asyPath.nodeSet[index] == 'cycle':
- return
-
- self.asyPath.setNode(index, newNode)
- # if also move node:
-
- if self.curveMode:
- checkPre, checkPost = self.getPreAndPostCtrlPts(index)
-
- if 1 == 1: # TODO: Replace this with an option to also move control pts.
- if checkPre is not None:
- self.asyPath.controlSet[index - 1][1] = xu.funcOnList(
- newNode, self.preCtrlOffset, lambda a, b: a + b
- )
- if checkPost is not None:
- self.asyPath.controlSet[index][0] = xu.funcOnList(
- newNode, self.postCtrlOffset, lambda a, b: a + b
- )
-
- if self.info['autoRecompute']:
- self.quickRecalculateCtrls()
-
-
- elif self.currentSelMode == CurrentlySelctedType.ctrlPoint and self.curveMode:
- self.asyPath.controlSet[index][subindex] = newNode
- parentNode = self.asyPath.nodeSet[self.parentNodeIndex]
-
- if parentNode == 'cycle':
- parentNode = self.asyPath.nodeSet[0]
- isCycle = True
- else:
- isCycle = False
-
- if self.parentNodeIndex == 0 and self.asyPath.nodeSet[-1] == 'cycle':
- isCycle = True
-
- rawNewNode = xu.funcOnList(newNode, parentNode, lambda a, b: a - b)
- rawAngle = math.atan2(rawNewNode[1], rawNewNode[0])
- newNorm = xu.twonorm(rawNewNode)
-
-
- if self.info['editBezierlockMode'] >= Web.LockMode.angleLock:
- otherIndex = 1 - subindex # 1 if 0, 0 otherwise.
- if otherIndex == 0:
- if index < (len(self.asyPath.controlSet) - 1) or isCycle:
- newIndex = 0 if isCycle else index + 1
-
- oldOtherCtrlPnt = xu.funcOnList(
- self.asyPath.controlSet[newIndex][0], parentNode, lambda a, b: a - b)
-
- if self.info['editBezierlockMode'] >= Web.LockMode.angleAndScaleLock:
- rawNorm = newNorm
- else:
- rawNorm = xu.twonorm(oldOtherCtrlPnt)
-
- newPnt = (rawNorm * math.cos(rawAngle + math.pi),
- rawNorm * math.sin(rawAngle + math.pi))
-
- self.asyPath.controlSet[newIndex][0] = xu.funcOnList(
- newPnt, parentNode, lambda a, b: a + b)
- else:
- if index > 0 or isCycle:
- newIndex = -1 if isCycle else index - 1
- oldOtherCtrlPnt = xu.funcOnList(
- self.asyPath.controlSet[newIndex][1], parentNode, lambda a, b: a - b)
-
- if self.info['editBezierlockMode'] >= Web.LockMode.angleAndScaleLock:
- rawNorm = newNorm
- else:
- rawNorm = xu.twonorm(oldOtherCtrlPnt)
-
- newPnt = (rawNorm * math.cos(rawAngle + math.pi),
- rawNorm * math.sin(rawAngle + math.pi))
- self.asyPath.controlSet[newIndex][1] = xu.funcOnList(
- newPnt, parentNode, lambda a, b: a + b)
-
- def recalculateCtrls(self):
- self.quickRecalculateCtrls()
- self.setSelectionBoundaries()
-
- def quickRecalculateCtrls(self):
- self.asyPath.controlSet.clear()
- self.asyPath.computeControls()
-
- def mouseRelease(self):
- if self.inTransformMode:
- self.inTransformMode = False
- self.currentSelMode = None
-
- self.setSelectionBoundaries()
-
- def forceFinalize(self):
- self.objectUpdated.emit()
-
- def createOptWidget(self, info):
- self.opt = Web.Widg_editBezier(self.info, self.curveMode)
- self.opt.ui.btnOk.clicked.connect(self.editAccepted)
- self.opt.ui.btnCancel.clicked.connect(self.editRejected)
- self.opt.ui.btnForceRecompute.clicked.connect(self.recalculateCtrls)
-
- return self.opt
-
- def getObject(self):
- pass
-
- def getXasyObject(self):
- pass