def parse_color(json_color: str): """ Parse color in one of these supported formats: - #fff or #ffffff - hsl(30, 19%, 90%) or hsla(30, 19%, 90%, 0.4) - rgb(10, 20, 30) or rgba(10, 20, 30, 0.5) """ if not isinstance(json_color, str): print(f"Could not parse non-string color {json_color}, skipping.") return QColor(0,0,0,0) if json_color[0] == '#': return QColor(json_color) elif json_color.startswith('hsla'): x = json_color[5:-1] lst = x.split(',') assert len(lst) == 4 and lst[1].endswith('%') and lst[2].endswith('%') hue = int(lst[0]) sat = float(lst[1][:-1]) / 100. * 255 lig = float(lst[2][:-1]) / 100. * 255 alpha = float(lst[3]) * 255 # print(hue,sat,lig,alpha) return QColor.fromHsl(hue, sat, lig, alpha) elif json_color.startswith('hsl'): x = json_color[4:-1] lst = x.split(',') assert len(lst) == 3 and lst[1].endswith('%') and lst[2].endswith('%') hue = int(lst[0]) sat = float(lst[1][:-1]) / 100. * 255 lig = float(lst[2][:-1]) / 100. * 255 # print(hue,sat,lig) return QColor.fromHsl(hue, sat, lig) elif json_color.startswith('rgba'): x = json_color[5:-1] lst = x.split(',') assert len(lst) == 4 return QColor(int(lst[0]), int(lst[1]), int(lst[2]), float(lst[3]) * 255) elif json_color.startswith('rgb'): x = json_color[4:-1] lst = x.split(',') assert len(lst) == 3 return QColor(int(lst[0]), int(lst[1]), int(lst[2])) else: try: from PIL import ImageColor image_color = ImageColor.getrgb(json_color) return QColor(int(image_color[0]), int(image_color[1]), int(image_color[2])) except ImportError: import_error_message = "You do not have PIL/Pillow library installed on your system. " \ "Proper color name parsing might not be supported.\n" \ "MacOS users: To install Pillow library, run following code in terminal:\n" \ "/Applications/QGIS.app/Contents/MacOS/bin/pip3 install pillow -U" QMessageBox.warning(None, 'Missing PIL/Pillow library', import_error_message) except ValueError as e: print(e("unknown color syntax", json_color))
def draw(self, qp, x, y, w, h): # TODO: change this so it sets color, not albedo if self.obj is None: qp.setBrush(QColor(0,100,0)) else: # convert albedo from "darkness" to lightness color = 255-255*self.obj.albedo qp.setBrush(QColor(min(max(color+(self.obj.optTemp-22.5)*5,0),255), color, min(max(color+(22.5-self.obj.optTemp)*5,0),255))) # draw in the albedo qp.drawRect(x,y,w,h) # overlay temp rect over the top # qp.setBrush(QColor(min(max((self.temp-22.5)*50-255,0),255), # min(max(255-abs((self.temp-22.5)*50),0),255), # min(max(128-(self.temp-22.5)*50,0),255),25)) # qp.drawRect(x,y,w,h) qp.setPen(QColor.fromHsl(max(min(int(100+25*(22.5-self.temp)),255),0),255,100)); # Write the temperature on the tile qp.drawText(QRectF(QPointF(x,y+h), QPointF(x+w,y)), Qt.AlignCenter, str(round(self.temp,1))) qp.setPen(Qt.black);
def parse_color(json_color: str): """ Parse color in one of these supported formats: - #fff or #ffffff - hsl(30, 19%, 90%) or hsla(30, 19%, 90%, 0.4) - rgb(10, 20, 30) or rgba(10, 20, 30, 0.5) """ if not isinstance(json_color, str): print(f"Could not parse non-string color {json_color}, skipping.") return QColor(0, 0, 0, 0) if json_color[0] == '#': return QColor(json_color) elif json_color.startswith('hsla'): x = json_color[5:-1] lst = x.split(',') assert len(lst) == 4 and lst[1].endswith('%') and lst[2].endswith('%') hue = int(lst[0]) sat = float(lst[1][:-1]) / 100. * 255 lig = float(lst[2][:-1]) / 100. * 255 alpha = float(lst[3]) * 255 # print(hue,sat,lig,alpha) return QColor.fromHsl(hue, sat, lig, alpha) elif json_color.startswith('hsl'): x = json_color[4:-1] lst = x.split(',') assert len(lst) == 3 and lst[1].endswith('%') and lst[2].endswith('%') hue = int(lst[0]) sat = float(lst[1][:-1]) / 100. * 255 lig = float(lst[2][:-1]) / 100. * 255 # print(hue,sat,lig) return QColor.fromHsl(hue, sat, lig) elif json_color.startswith('rgba'): x = json_color[5:-1] lst = x.split(',') assert len(lst) == 4 return QColor(int(lst[0]), int(lst[1]), int(lst[2]), float(lst[3]) * 255) elif json_color.startswith('rgb'): x = json_color[4:-1] lst = x.split(',') assert len(lst) == 3 return QColor(int(lst[0]), int(lst[1]), int(lst[2])) else: raise ValueError("unknown color syntax", json_color)
def get(idx): if idx >= len(Color._idx2clr): while len(Color._idx2clr) <= idx: h = 360 * random() s = 80 + 20 * random() l = 95 + 5 * random() Color._idx2clr.append(QColor.fromHsl(h, s, l)) if not Settings.colors_on: return Settings.default_brush return Color._idx2clr[idx]
def set_colorcoding(self, colorlist): amounts = {} for name in colorlist: amounts[name] = max(1, sum(x[0] == name for x in self._items)) for item in self._items.items(): if item[0][0] in colorlist: effect = QGraphicsColorizeEffect() effect.setColor( QColor.fromHsl( max(0, item[0][1] - 1) * 256 / max(1, amounts[item[0][0]] - 1), 255, 128, 255)) item[1].setGraphicsEffect(effect) for item in self._paths.items(): if item[0][0] in colorlist: effect = QGraphicsColorizeEffect() effect.setColor( QColor.fromHsl( max(0, item[0][1] - 1) * 256 / max(1, amounts[item[0][0]] - 1), 255, 128, 255)) item[1].setGraphicsEffect(effect)
def choose_target_hue(self, event, source_object=None, index=None): self.target_hue_idx = index if self.source_hue_idx is not None: q = self.mid_hue_layout.itemAt(self.source_hue_idx).widget() p = q.palette() p.setColor( q.backgroundRole(), QColor.fromHsl(int((self.target_hue_idx + 0.5) * self.binsz), 255, 128, alpha=255)) q.setPalette(p) qc = QColor.fromHsl(int((self.target_hue_idx + 0.5) * self.binsz), 255, 128, alpha=255) q.setStyleSheet("background-color: %s" % (qc.name(QColor.HexArgb))) self.src_tar_mp[self.source_hue_idx] = self.target_hue_idx #更新目标颜色 并刷新结果 self.parent_win.update_target_colors(self.src_tar_mp, self.binsz) pass
def naloga9_razdalja(): from PyQt5.QtGui import QColor from collections import defaultdict na_razdalji = defaultdict(set) for kraj, _, _ in TestBase.kraji: na_razdalji[razdalja("Vrhnika", kraj, Test09.povezave5)].add(kraj) oznake = naloga6_povezave(False, True) for r, kraji in na_razdalji.items(): barva = QColor.fromHsl(r * 36, 255, 128) for kraj in kraji: oznake[kraj].setDefaultTextColor(barva) oznake[kraj].setPlainText(f"{kraj}: {r}") risar.stoj()
def run(self) -> None: ''' Run the thread. (internal function) ''' api = self._window.api try: matter_list = api.get_matter_list() self.gotMatterCount.emit(len(matter_list)) # Generate distinct colors associated with matters colors = [QColor.fromHsl( 360 * i // (len(matter_list) + 1), 128, randint(96, 192) ) for i in range(len(matter_list) + 1)] shuffle(colors) for index, matter in enumerate(matter_list): self.gotMatter.emit(index, matter, colors[index]) self.succeeded.emit() except Exception as exc: self.failed.emit(exc)
class GLWidget(CanvasBase): CAM_LEFT_X = -0.5 CAM_RIGHT_X = 0.5 CAM_BOTTOM_Y = 0.5 CAM_TOP_Y = -0.5 CAM_NEAR_Z = -14.0 CAM_FAR_Z = 14.0 COLOR_BACKGROUND = QColor.fromHsl(160, 0, 255, 255) COLOR_NORMAL = QColor.fromCmykF(1.0, 0.5, 0.0, 0.0, 1.0) COLOR_SELECT = QColor.fromCmykF(0.0, 1.0, 0.9, 0.0, 1.0) COLOR_NORMAL_DISABLED = QColor.fromCmykF(1.0, 0.5, 0.0, 0.0, 0.25) COLOR_SELECT_DISABLED = QColor.fromCmykF(0.0, 1.0, 0.9, 0.0, 0.25) COLOR_ENTRY_ARROW = QColor.fromRgbF(0.0, 0.0, 1.0, 1.0) COLOR_EXIT_ARROW = QColor.fromRgbF(0.0, 1.0, 0.0, 1.0) COLOR_ROUTE = QColor.fromRgbF(0.5, 0.0, 0.0, 1.0) COLOR_STMOVE = QColor.fromRgbF(0.5, 0.0, 0.25, 1.0) COLOR_BREAK = QColor.fromRgbF(1.0, 0.0, 1.0, 0.7) COLOR_LEFT = QColor.fromHsl(134, 240, 130, 255) COLOR_RIGHT = QColor.fromHsl(186, 240, 130, 255) def __init__(self, parent=None): super(GLWidget, self).__init__(parent) self.shapes = Shapes([]) self.orientation = 0 self.wpZero = 0 self.routearrows = [] self.expprv = None self.isPanning = False self.isRotating = False self.isMultiSelect = False self._lastPos = QPoint() self.posX = 0.0 self.posY = 0.0 self.posZ = 0.0 self.rotX = 0.0 self.rotY = 0.0 self.rotZ = 0.0 self.scale = 1.0 self.scaleCorr = 1.0 self.showPathDirections = False self.showDisabledPaths = False self.topLeft = Point() self.bottomRight = Point() self.tol = 0 def tr(self, string_to_translate): """ Translate a string using the QCoreApplication translation framework @param string_to_translate: a unicode string @return: the translated unicode string if it was possible to translate """ return text_type( QCoreApplication.translate('GLWidget', string_to_translate)) def resetAll(self): # the wpzero is currently generated "last" if self.wpZero > 0: GL.glDeleteLists(self.orientation + 1, self.wpZero - self.orientation) self.shapes = Shapes([]) self.wpZero = 0 self.delete_opt_paths() self.posX = 0.0 self.posY = 0.0 self.posZ = 0.0 self.rotX = 0.0 self.rotY = 0.0 self.rotZ = 0.0 self.scale = 1.0 self.topLeft = Point() self.bottomRight = Point() self.update() def delete_opt_paths(self): if len(self.routearrows) > 0: GL.glDeleteLists(self.routearrows[0][2], len(self.routearrows)) self.routearrows = [] def addexproutest(self): self.expprv = Point3D( g.config.vars.Plane_Coordinates['axis1_start_end'], g.config.vars.Plane_Coordinates['axis2_start_end'], 0) def addexproute(self, exp_order, layer_nr): """ This function initialises the Arrows of the export route order and its numbers. """ for shape_nr in range(len(exp_order)): shape = self.shapes[exp_order[shape_nr]] st = self.expprv en, self.expprv = shape.get_start_end_points_physical() en = en.to3D(shape.axis3_start_mill_depth) self.expprv = self.expprv.to3D(shape.axis3_mill_depth) self.routearrows.append([st, en, 0]) # TODO self.routetext.append(RouteText(text=("%s,%s" % (layer_nr, shape_nr+1)), startp=en)) def addexprouteen(self): st = self.expprv en = Point3D(g.config.vars.Plane_Coordinates['axis1_start_end'], g.config.vars.Plane_Coordinates['axis2_start_end'], 0) self.routearrows.append([st, en, 0]) for route in self.routearrows: route[2] = self.makeRouteArrowHead(route[0], route[1]) def contextMenuEvent(self, event): if not self.isRotating: clicked, offset, _ = self.getClickedDetails(event) MyDropDownMenu(self, event.globalPos(), clicked, offset) def setXRotation(self, angle): self.rotX = self.normalizeAngle(angle) def setYRotation(self, angle): self.rotY = self.normalizeAngle(angle) def setZRotation(self, angle): self.rotZ = self.normalizeAngle(angle) def normalizeAngle(self, angle): return (angle - 180) % -360 + 180 def mousePressEvent(self, event): if self.isPanning or self.isRotating: self.setCursor(Qt.ClosedHandCursor) elif event.button() == Qt.LeftButton: clicked, offset, tol = self.getClickedDetails(event) xyForZ = {} for shape in self.shapes: hit = False z = shape.axis3_start_mill_depth if z not in xyForZ: xyForZ[z] = self.determineSelectedPosition( clicked, z, offset) hit |= shape.isHit(xyForZ[z], tol) if not hit: z = shape.axis3_mill_depth if z not in xyForZ: xyForZ[z] = self.determineSelectedPosition( clicked, z, offset) hit |= shape.isHit(xyForZ[z], tol) if self.isMultiSelect and shape.selected: hit = not hit if hit != shape.selected: g.window.TreeHandler.updateShapeSelection(shape, hit) shape.selected = hit self.update() self._lastPos = event.pos() def getClickedDetails(self, event): min_side = min(self.frameSize().width(), self.frameSize().height()) clicked = Point( (event.pos().x() - self.frameSize().width() / 2), (event.pos().y() - self.frameSize().height() / 2)) / min_side / self.scale offset = Point3D(-self.posX, -self.posY, -self.posZ) / self.scale tol = 4 * self.scaleCorr / min_side / self.scale return clicked, offset, tol def determineSelectedPosition(self, clicked, forZ, offset): angleX = -radians(self.rotX) angleY = -radians(self.rotY) zv = forZ - offset.z clickedZ = ((zv + clicked.x * sin(angleY)) / cos(angleY) - clicked.y * sin(angleX)) / cos(angleX) sx, sy, sz = self.deRotate(clicked.x, clicked.y, clickedZ) return Point(sx + offset.x, -sy - offset.y) #, sz + offset.z def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton or event.button() == Qt.RightButton: if self.isPanning: self.setCursor(Qt.OpenHandCursor) elif self.isRotating: self.setCursor(Qt.PointingHandCursor) def mouseMoveEvent(self, event): dx = event.pos().x() - self._lastPos.x() dy = event.pos().y() - self._lastPos.y() if self.isRotating: if event.buttons() == Qt.LeftButton: self.setXRotation(self.rotX - dy / 2) self.setYRotation(self.rotY + dx / 2) elif event.buttons() == Qt.RightButton: self.setXRotation(self.rotX - dy / 2) self.setZRotation(self.rotZ + dx / 2) elif self.isPanning: if event.buttons() == Qt.LeftButton: min_side = min(self.frameSize().width(), self.frameSize().height()) dx, dy, dz = self.deRotate(dx, dy, 0) self.posX += dx / min_side self.posY += dy / min_side self.posZ += dz / min_side self._lastPos = event.pos() self.update() def wheelEvent(self, event): min_side = min(self.frameSize().width(), self.frameSize().height()) x = (event.pos().x() - self.frameSize().width() / 2) / min_side y = (event.pos().y() - self.frameSize().height() / 2) / min_side s = 1.001**event.angleDelta().y() x, y, z = self.deRotate(x, y, 0) self.posX = (self.posX - x) * s + x self.posY = (self.posY - y) * s + y self.posZ = (self.posZ - z) * s + z self.scale *= s self.update() def rotate(self, x, y, z): angleZ = radians(self.rotZ) x, y, z = x * cos(angleZ) - y * sin(angleZ), x * sin(angleZ) + y * cos( angleZ), z angleY = radians(self.rotY) x, y, z = x * cos(angleY) + z * sin(angleY), y, -x * sin( angleY) + z * cos(angleY) angleX = radians(self.rotX) return x, y * cos(angleX) - z * sin(angleX), y * sin(angleX) + z * cos( angleX) def deRotate(self, x, y, z): angleX = -radians(self.rotX) x, y, z = x, y * cos(angleX) - z * sin(angleX), y * sin( angleX) + z * cos(angleX) angleY = -radians(self.rotY) x, y, z = x * cos(angleY) + z * sin(angleY), y, -x * sin( angleY) + z * cos(angleY) angleZ = -radians(self.rotZ) return x * cos(angleZ) - y * sin(angleZ), x * sin(angleZ) + y * cos( angleZ), z def getRotationVectors(self, orgRefVector, toRefVector): """ Generate a rotation matrix such that toRefVector = matrix * orgRefVector @param orgRefVector: A 3D unit vector @param toRefVector: A 3D unit vector @return: 3 vectors such that matrix = [vx; vy; vz] """ # based on: # http://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d if orgRefVector == toRefVector: return Point3D(1, 0, 0), Point3D(0, 1, 0), Point3D(0, 0, 1) v = orgRefVector.cross_product(toRefVector) mn = (1 - orgRefVector * toRefVector) / v.length_squared() vx = Point3D( 1, -v.z, v.y) + mn * Point3D(-v.y**2 - v.z**2, v.x * v.y, v.x * v.z) vy = Point3D( v.z, 1, -v.x) + mn * Point3D(v.x * v.y, -v.x**2 - v.z**2, v.y * v.z) vz = Point3D(-v.y, v.x, 1) + mn * Point3D(v.x * v.z, v.y * v.z, -v.x**2 - v.y**2) return vx, vy, vz def initializeGL(self): logger.debug( self.tr("Using OpenGL version: %s") % GL.glGetString(GL.GL_VERSION).decode("utf-8")) self.setClearColor(GLWidget.COLOR_BACKGROUND) GL.glEnable(GL.GL_MULTISAMPLE) GL.glEnable(GL.GL_POLYGON_SMOOTH) GL.glHint(GL.GL_POLYGON_SMOOTH_HINT, GL.GL_NICEST) # GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE) GL.glShadeModel(GL.GL_SMOOTH) GL.glEnable(GL.GL_DEPTH_TEST) GL.glEnable(GL.GL_CULL_FACE) # GL.glEnable(GL.GL_LIGHTING) # GL.glEnable(GL.GL_LIGHT0) GL.glEnable(GL.GL_BLEND) GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) # GL.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, (0.5, 5.0, 7.0, 1.0)) # GL.glEnable(GL.GL_NORMALIZE) self.drawOrientationArrows() def paintGL(self): # The last transformation you specify takes place first. GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) GL.glLoadIdentity() GL.glRotatef(self.rotX, 1.0, 0.0, 0.0) GL.glRotatef(self.rotY, 0.0, 1.0, 0.0) GL.glRotatef(self.rotZ, 0.0, 0.0, 1.0) GL.glTranslatef(self.posX, self.posY, self.posZ) GL.glScalef(self.scale, self.scale, self.scale) for shape in self.shapes.selected_iter(): if not shape.disabled: self.setColor(GLWidget.COLOR_STMOVE) GL.glCallList(shape.drawStMove) self.setColor(GLWidget.COLOR_SELECT) GL.glCallList(shape.drawObject) elif self.showDisabledPaths: self.setColor(GLWidget.COLOR_SELECT_DISABLED) GL.glCallList(shape.drawObject) for shape in self.shapes.not_selected_iter(): if not shape.disabled: if shape.parentLayer.isBreakLayer(): self.setColor(GLWidget.COLOR_BREAK) elif shape.cut_cor == 41: self.setColor(GLWidget.COLOR_LEFT) elif shape.cut_cor == 42: self.setColor(GLWidget.COLOR_RIGHT) else: self.setColor(GLWidget.COLOR_NORMAL) GL.glCallList(shape.drawObject) if self.showPathDirections: self.setColor(GLWidget.COLOR_STMOVE) GL.glCallList(shape.drawStMove) elif self.showDisabledPaths: self.setColor(GLWidget.COLOR_NORMAL_DISABLED) GL.glCallList(shape.drawObject) # optimization route arrows self.setColor(GLWidget.COLOR_ROUTE) GL.glBegin(GL.GL_LINES) for route in self.routearrows: start = route[0] end = route[1] GL.glVertex3f(start.x, -start.y, start.z) GL.glVertex3f(end.x, -end.y, end.z) GL.glEnd() GL.glScalef(self.scaleCorr / self.scale, self.scaleCorr / self.scale, self.scaleCorr / self.scale) scaleArrow = self.scale / self.scaleCorr for route in self.routearrows: end = scaleArrow * route[1] GL.glTranslatef(end.x, -end.y, end.z) GL.glCallList(route[2]) GL.glTranslatef(-end.x, end.y, -end.z) # direction arrows for shape in self.shapes: if shape.selected and (not shape.disabled or self.showDisabledPaths) or\ self.showPathDirections and not shape.disabled: start, end = shape.get_start_end_points_physical() start = scaleArrow * start.to3D(shape.axis3_start_mill_depth) end = scaleArrow * end.to3D(shape.axis3_mill_depth) GL.glTranslatef(start.x, -start.y, start.z) GL.glCallList(shape.drawArrowsDirection[0]) GL.glTranslatef(-start.x, start.y, -start.z) GL.glTranslatef(end.x, -end.y, end.z) GL.glCallList(shape.drawArrowsDirection[1]) GL.glTranslatef(-end.x, end.y, -end.z) if self.wpZero > 0: GL.glCallList(self.wpZero) GL.glTranslatef(-self.posX / self.scaleCorr, -self.posY / self.scaleCorr, -self.posZ / self.scaleCorr) GL.glCallList(self.orientation) def resizeGL(self, width, height): GL.glViewport(0, 0, width, height) side = min(width, height) GL.glMatrixMode(GL.GL_PROJECTION) GL.glLoadIdentity() if width >= height: scale_x = width / height GL.glOrtho(GLWidget.CAM_LEFT_X * scale_x, GLWidget.CAM_RIGHT_X * scale_x, GLWidget.CAM_BOTTOM_Y, GLWidget.CAM_TOP_Y, GLWidget.CAM_NEAR_Z, GLWidget.CAM_FAR_Z) else: scale_y = height / width GL.glOrtho(GLWidget.CAM_LEFT_X, GLWidget.CAM_RIGHT_X, GLWidget.CAM_BOTTOM_Y * scale_y, GLWidget.CAM_TOP_Y * scale_y, GLWidget.CAM_NEAR_Z, GLWidget.CAM_FAR_Z) self.scaleCorr = 400 / side GL.glMatrixMode(GL.GL_MODELVIEW) def setClearColor(self, c): GL.glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()) def setColor(self, c): self.setColorRGBA(c.redF(), c.greenF(), c.blueF(), c.alphaF()) def setColorRGBA(self, r, g, b, a): # GL.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, (r, g, b, a)) GL.glColor4f(r, g, b, a) def plotAll(self, shapes): for shape in shapes: self.paint_shape(shape) self.shapes.append(shape) self.drawWpZero() def repaint_shape(self, shape): GL.glDeleteLists(shape.drawObject, 4) self.paint_shape(shape) def paint_shape(self, shape): shape.drawObject = self.makeShape(shape) # 1 object shape.stmove = StMove(shape) shape.drawStMove = self.makeStMove(shape.stmove) # 1 object shape.drawArrowsDirection = self.makeDirArrows(shape) # 2 objects def makeShape(self, shape): genList = GL.glGenLists(1) GL.glNewList(genList, GL.GL_COMPILE) GL.glBegin(GL.GL_LINES) shape.make_path(self.drawHorLine, self.drawVerLine) GL.glEnd() GL.glEndList() self.topLeft.detTopLeft(shape.topLeft) self.bottomRight.detBottomRight(shape.bottomRight) return genList def makeStMove(self, stmove): genList = GL.glGenLists(1) GL.glNewList(genList, GL.GL_COMPILE) GL.glBegin(GL.GL_LINES) stmove.make_path(self.drawHorLine, self.drawVerLine) GL.glEnd() GL.glEndList() return genList def drawHorLine(self, caller, Ps, Pe): GL.glVertex3f(Ps.x, -Ps.y, caller.axis3_start_mill_depth) GL.glVertex3f(Pe.x, -Pe.y, caller.axis3_start_mill_depth) GL.glVertex3f(Ps.x, -Ps.y, caller.axis3_mill_depth) GL.glVertex3f(Pe.x, -Pe.y, caller.axis3_mill_depth) def drawVerLine(self, caller, Ps): GL.glVertex3f(Ps.x, -Ps.y, caller.axis3_start_mill_depth) GL.glVertex3f(Ps.x, -Ps.y, caller.axis3_mill_depth) def drawOrientationArrows(self): rCone = 0.01 rCylinder = 0.004 zTop = 0.05 zMiddle = 0.02 zBottom = -0.03 segments = 20 arrow = GL.glGenLists(1) GL.glNewList(arrow, GL.GL_COMPILE) self.drawCone(Point(), rCone, zTop, zMiddle, segments) self.drawSolidCircle(Point(), rCone, zMiddle, segments) self.drawCylinder(Point(), rCylinder, zMiddle, zBottom, segments) self.drawSolidCircle(Point(), rCylinder, zBottom, segments) GL.glEndList() self.orientation = GL.glGenLists(1) GL.glNewList(self.orientation, GL.GL_COMPILE) self.setColorRGBA(0.0, 0.0, 1.0, 0.5) GL.glCallList(arrow) GL.glRotatef(90, 0, 1, 0) self.setColorRGBA(1.0, 0.0, 0.0, 0.5) GL.glCallList(arrow) GL.glRotatef(90, 1, 0, 0) self.setColorRGBA(0.0, 1.0, 0.0, 0.5) GL.glCallList(arrow) GL.glEndList() def drawWpZero(self): r = 0.02 segments = 20 # must be a multiple of 4 self.wpZero = GL.glGenLists(1) GL.glNewList(self.wpZero, GL.GL_COMPILE) self.setColorRGBA(0.2, 0.2, 0.2, 0.7) self.drawSphere(r, segments, segments // 4, segments, segments // 4) GL.glBegin(GL.GL_TRIANGLE_FAN) GL.glVertex3f(0, 0, 0) for i in range(segments // 4 + 1): ang = -i * 2 * pi / segments xy2 = Point().get_arc_point(ang, r) # GL.glNormal3f(0, -1, 0) GL.glVertex3f(xy2.x, 0, xy2.y) for i in range(segments // 4 + 1): ang = -i * 2 * pi / segments xy2 = Point().get_arc_point(ang, r) # GL.glNormal3f(-1, 0, 0) GL.glVertex3f(0, -xy2.y, -xy2.x) for i in range(segments // 4 + 1): ang = -i * 2 * pi / segments xy2 = Point().get_arc_point(ang, r) # GL.glNormal3f(0, 0, 1) GL.glVertex3f(-xy2.y, xy2.x, 0) GL.glEnd() self.setColorRGBA(0.6, 0.6, 0.6, 0.5) self.drawSphere(r * 1.25, segments, segments, segments, segments) GL.glEndList() def drawSphere(self, r, lats, mlats, longs, mlongs): lats //= 2 # based on http://www.cburch.com/cs/490/sched/feb8/index.html for i in range(mlats): lat0 = pi * (-0.5 + i / lats) z0 = r * sin(lat0) zr0 = r * cos(lat0) lat1 = pi * (-0.5 + (i + 1) / lats) z1 = r * sin(lat1) zr1 = r * cos(lat1) GL.glBegin(GL.GL_QUAD_STRIP) for j in range(mlongs + 1): lng = 2 * pi * j / longs x = cos(lng) y = sin(lng) GL.glNormal3f(x * zr0, y * zr0, z0) GL.glVertex3f(x * zr0, y * zr0, z0) GL.glNormal3f(x * zr1, y * zr1, z1) GL.glVertex3f(x * zr1, y * zr1, z1) GL.glEnd() def drawSolidCircle(self, origin, r, z, segments): GL.glBegin(GL.GL_TRIANGLE_FAN) # GL.glNormal3f(0, 0, -1) GL.glVertex3f(origin.x, -origin.y, z) for i in range(segments + 1): ang = -i * 2 * pi / segments xy2 = origin.get_arc_point(ang, r) GL.glVertex3f(xy2.x, -xy2.y, z) GL.glEnd() def drawCone(self, origin, r, zTop, zBottom, segments): GL.glBegin(GL.GL_TRIANGLE_FAN) GL.glVertex3f(origin.x, -origin.y, zTop) for i in range(segments + 1): ang = i * 2 * pi / segments xy2 = origin.get_arc_point(ang, r) # GL.glNormal3f(xy2.x, -xy2.y, zBottom) GL.glVertex3f(xy2.x, -xy2.y, zBottom) GL.glEnd() def drawCylinder(self, origin, r, zTop, zBottom, segments): GL.glBegin(GL.GL_QUAD_STRIP) for i in range(segments + 1): ang = i * 2 * pi / segments xy = origin.get_arc_point(ang, r) # GL.glNormal3f(xy.x, -xy.y, 0) GL.glVertex3f(xy.x, -xy.y, zTop) GL.glVertex3f(xy.x, -xy.y, zBottom) GL.glEnd() def makeDirArrows(self, shape): (start, start_dir), (end, end_dir) = shape.get_start_end_points_physical( None, False) startArrow = GL.glGenLists(1) GL.glNewList(startArrow, GL.GL_COMPILE) self.setColor(GLWidget.COLOR_ENTRY_ARROW) self.drawDirArrow(Point3D(), start_dir.to3D(), True) GL.glEndList() endArrow = GL.glGenLists(1) GL.glNewList(endArrow, GL.GL_COMPILE) self.setColor(GLWidget.COLOR_EXIT_ARROW) self.drawDirArrow(Point3D(), end_dir.to3D(), False) GL.glEndList() return startArrow, endArrow def drawDirArrow(self, origin, direction, startError): offset = 0.0 if startError else 0.05 zMiddle = -0.02 + offset zBottom = -0.05 + offset rx, ry, rz = self.getRotationVectors(Point3D(0, 0, 1), direction) self.drawArrowHead(origin, rx, ry, rz, offset) GL.glBegin(GL.GL_LINES) zeroMiddle = Point3D(0, 0, zMiddle) GL.glVertex3f(zeroMiddle * rx + origin.x, -zeroMiddle * ry - origin.y, zeroMiddle * rz + origin.z) zeroBottom = Point3D(0, 0, zBottom) GL.glVertex3f(zeroBottom * rx + origin.x, -zeroBottom * ry - origin.y, zeroBottom * rz + origin.z) GL.glEnd() def makeRouteArrowHead(self, start, end): if end == start: direction = Point3D(0, 0, 1) else: direction = (end - start).unit_vector() rx, ry, rz = self.getRotationVectors(Point3D(0, 0, 1), direction) head = GL.glGenLists(1) GL.glNewList(head, GL.GL_COMPILE) self.drawArrowHead(Point3D(), rx, ry, rz, 0) GL.glEndList() return head def drawArrowHead(self, origin, rx, ry, rz, offset): r = 0.01 segments = 10 zTop = 0 + offset zBottom = -0.02 + offset GL.glBegin(GL.GL_TRIANGLE_FAN) zeroTop = Point3D(0, 0, zTop) GL.glVertex3f(zeroTop * rx + origin.x, -zeroTop * ry - origin.y, zeroTop * rz + origin.z) for i in range(segments + 1): ang = i * 2 * pi / segments xy2 = Point().get_arc_point(ang, r).to3D(zBottom) GL.glVertex3f(xy2 * rx + origin.x, -xy2 * ry - origin.y, xy2 * rz + origin.z) GL.glEnd() GL.glBegin(GL.GL_TRIANGLE_FAN) zeroBottom = Point3D(0, 0, zBottom) GL.glVertex3f(zeroBottom * rx + origin.x, -zeroBottom * ry - origin.y, zeroBottom * rz + origin.z) for i in range(segments + 1): ang = -i * 2 * pi / segments xy2 = Point().get_arc_point(ang, r).to3D(zBottom) GL.glVertex3f(xy2 * rx + origin.x, -xy2 * ry - origin.y, xy2 * rz + origin.z) GL.glEnd() def setShowPathDirections(self, flag): self.showPathDirections = flag def setShowDisabledPaths(self, flag=True): self.showDisabledPaths = flag def autoscale(self): # TODO currently only works correctly when object is not rotated if self.frameSize().width() >= self.frameSize().height(): aspect_scale_x = self.frameSize().width() / self.frameSize( ).height() aspect_scale_y = 1 else: aspect_scale_x = 1 aspect_scale_y = self.frameSize().height() / self.frameSize( ).width() scaleX = (GLWidget.CAM_RIGHT_X - GLWidget.CAM_LEFT_X ) * aspect_scale_x / (self.bottomRight.x - self.topLeft.x) scaleY = (GLWidget.CAM_BOTTOM_Y - GLWidget.CAM_TOP_Y ) * aspect_scale_y / (self.topLeft.y - self.bottomRight.y) self.scale = min(scaleX, scaleY) * 0.95 self.posX = ((GLWidget.CAM_LEFT_X + GLWidget.CAM_RIGHT_X) * 0.95 * aspect_scale_x - (self.topLeft.x + self.bottomRight.x) * self.scale) / 2 self.posY = -((GLWidget.CAM_TOP_Y + GLWidget.CAM_BOTTOM_Y) * 0.95 * aspect_scale_y - (self.topLeft.y + self.bottomRight.y) * self.scale) / 2 self.posZ = 0 self.update() def topView(self): self.rotX = 0 self.rotY = 0 self.rotZ = 0 self.update() def isometricView(self): self.rotX = -22 self.rotY = -22 self.rotZ = 0 self.update()
def add_hue_matchings(self): self.top_hue_layout = QHBoxLayout() self.mid_hue_layout = QHBoxLayout() self.bottom_hue_layout = QHBoxLayout() self.mainlayout.addLayout(self.top_hue_layout) self.mainlayout.addLayout(self.mid_hue_layout) self.mainlayout.addLayout(self.bottom_hue_layout) bin_size = 10 self.binsz = bin_size for idx, w in enumerate(range(0, 360, bin_size)): mid_h = int((idx + 0.5) * bin_size) if mid_h >= 360: break q = QLabel() q.setAutoFillBackground(True) q.setText(" ") q.setMargin(5) p = q.palette() ss = False for hu_range in range(int(mid_h - bin_size * 0.5), int(mid_h + bin_size * 0.5)): if hu_range in self.h_dom_colors: ss = True if ss: # p.setColor(q.backgroundRole(),QColor.fromHsl(mid_h,255,128)) q.setStyleSheet("background-color: %s" % (QColor.fromHsl(mid_h, 255, 128).name())) else: # p.setColor(q.backgroundRole(), QColor.fromHsl(mid_h, 255, 128,alpha=0)) q.setStyleSheet("background-color: %s" % (QColor.fromHsl( mid_h, 255, 128, alpha=0).name(QColor.HexArgb))) q.setPalette(p) q.mousePressEvent = functools.partial(self.choose_source_hue, source_object=q, index=idx) self.top_hue_layout.addWidget(q) for idx, w in enumerate(range(0, 360, bin_size)): if int((idx + 0.5) * bin_size) >= 360: break q = QLabel() q.setAutoFillBackground(True) q.setText(" ") q.setMargin(5) p = q.palette() # p.setColor(q.backgroundRole(),QColor.fromHsl(int((idx+0.5)*bin_size), 255, 128, alpha=0)) q.setPalette(p) qc = QColor.fromHsl(int((idx + 0.5) * bin_size), 255, 128, alpha=0) q.setStyleSheet("background-color: %s" % (qc.name(QColor.HexArgb))) self.mid_hue_layout.addWidget(q) for idx, w in enumerate(range(0, 360, bin_size)): if int((idx + 0.5) * bin_size) >= 360: break q = QLabel() q.setAutoFillBackground(True) q.setMargin(5) p = q.palette() p.setColor(q.backgroundRole(), QColor.fromHsl(int((idx + 0.5) * bin_size), 255, 128)) q.setPalette(p) q.setStyleSheet("background-color: %s" % (QColor.fromHsl(int( (idx + 0.5) * bin_size), 255, 128).name())) q.mousePressEvent = functools.partial(self.choose_target_hue, source_object=q, index=idx) self.bottom_hue_layout.addWidget(q)
def fromHSL(h, l, s): color = QColor.fromHsl(h, l, s) return Color(color.red(), color.green(), color.blue())
def AfToColor(self, af): """0 <= af <= 1""" h = 240 - (af * 240) return QColor.fromHsl(h, 200, 182, self.beamTransparancy)