def __init__(self): self.pos1 = QVector3D() self.pos2 = QVector3D() #self.rawPos = QVector3D() self.startTime = sNaN self.endTime = sNaN self.command = sNaN
def getAngle(cls, start: QVector3D, end: QVector3D) -> float: ''' Return the angle in radians when going from start to end. ''' deltaX = end.x() - start.x() deltaY = end.y() - start.y() angle = 0.0 if deltaX != 0: # prevent div by 0 # it helps to know what quadrant you are in if deltaX > 0 and deltaY >= 0: # 0 - 90 angle = math.atan(deltaY / deltaX) elif deltaX < 0 and deltaY >= 0: # 90 to 180 angle = cls.M_PI - math.fabs(math.atan(deltaY / deltaX)) elif deltaX < 0 and deltaY < 0: # 180 - 270 angle = cls.M_PI + math.fabs(math.atan(deltaY / deltaX)) elif deltaX > 0 and deltaY < 0: # 270 - 360 angle = cls.M_PI * 2 - math.fabs(math.atan(deltaY / deltaX)) else: # 90 deg if deltaY > 0: angle = cls.M_PI / 2.0 #270 deg else: angle = cls.M_PI * 3.0 / 2.0 return angle
def createCircle(self, center: QVector3D, radius: float, arcs: int, color: QVector3D) -> List[VertexData]: # Vertices circle: List[VertexData] = [] # Prepare vertex vertex = VertexData() vertex.color = color vertex.start = QVector3D(sNaN, sNaN, sNaN) # Create line loop for i in range(self.arcs + 1): angle = 2 * M_PI * i / self.arcs x = center.x() + radius * math.cos(angle) y = center.y() + radius * math.sin(angle) if i > 1: circle.append(VertexData.clone(circle[-1])) elif i == self.arcs: circle.append(VertexData.clone(circle[0])) vertex.position = QVector3D(x, y, center.z()) circle.append(VertexData.clone(vertex)) return circle
def addLinearPointSegment(self, nextPoint: QVector3D, fastTraverse: bool) -> PointSegment: ps = PointSegment.PointSegment_FromQVector3D(nextPoint, self.m_commandNumber) self.m_commandNumber += 1 zOnly = False # Check for z-only if (self.m_currentPoint.x() == nextPoint.x()) and \ (self.m_currentPoint.y() == nextPoint.y()) and \ (self.m_currentPoint.z() != nextPoint.z()) : \ zOnly = True ps.setIsMetric(self.m_isMetric) ps.setIsZMovement(zOnly) ps.setIsFastTraverse(fastTraverse) ps.setIsAbsolute(self.m_inAbsoluteMode) ps.setSpeed(self.m_traverseSpeed if fastTraverse else self.m_lastSpeed) ps.setSpindleSpeed(self.m_lastSpindleSpeed) self.m_points.append(ps) # Save off the endpoint. self.m_currentPoint = nextPoint return ps
def reset(self): self.m_lines = [] self.m_lineIndexes = [] self.currentLine = 0 self.m_min = QVector3D(qQNaN(), qQNaN(), qQNaN()) self.m_max = QVector3D(qQNaN(), qQNaN(), qQNaN()) self.m_minLength = qQNaN()
def __init__(self): super(SelectionDrawer, self).__init__() self.m_points = [] self.m_startPosition = QVector3D(0, 0, 0) self.m_endPosition = QVector3D(0, 0, 0) self.m_color = QColor(120, 200, 200)
def getSizes(self) -> QVector3D : xs = [item[0] for item in self.path] ys = [item[1] for item in self.path] zs = [item[2] for item in self.path] xmin = QVector3D(min(xs), min(ys), min(zs)) xmax = QVector3D(max(xs), max(ys), max(zs)) return QVector3D(xmax.x() - xmin.x(), xmax.y() - xmin.y(), xmax.z() - xmin.z())
def generatePointsAlongArcBDring_Arc( cls, plane: PointSegment.Plane, start: QVector3D, end: QVector3D, center: QVector3D, clockwise: bool, R: float, minArcLength: float, arcPrecision: float, arcDegreeMode: bool) -> List[QVector3D]: ''' Generates the points along an arc including the start and end points. ''' radius = R # Rotate vectors according to plane m = QMatrix4x4() m.setToIdentity() if plane == PointSegment.Plane.XY: pass elif plane == PointSegment.Plane.ZX: m.rotate(90, 1.0, 0.0, 0.0) elif plane == PointSegment.Plane.YZ: m.rotate(-90, 0.0, 1.0, 0.0) start = m * start end = m * end center = m * center # Check center if qIsNaN(center.length()): return [] # Calculate radius if necessary. if radius == 0: radius = math.sqrt( math.pow((start.x() - center.x(), 2.0) + math.pow(end.y() - center.y(), 2.0))) startAngle = cls.getAngle(center, start) endAngle = cls.getAngle(center, end) sweep = cls.calculateSweep(startAngle, endAngle, clockwise) # Convert units. arcLength = sweep * radius numPoints = 0 if arcDegreeMode and arcPrecision > 0: numPoints = max(1.0, sweep / (cls.M_PI * arcPrecision / 180)) else: if arcPrecision <= 0 and minArcLength > 0: arcPrecision = minArcLength numPoints = math.ceil(arcLength / arcPrecision) return cls.generatePointsAlongArcBDring_Num(plane, start, end, center, clockwise, radius, startAngle, sweep, numPoints)
def PointSegment_FromVectorQVector3DQVector3D(cls, point: QVector3D, num: int, center: QVector3D, radius: float, clockwise: bool): this = PointSegment(point, num) this.m_isArc = True this.m_arcProperties = ArcProperties() this.m_arcProperties.center = QVector3D(center.x(), center.y(), center.z()) this.m_arcProperties.radius = radius this.m_arcProperties.isClockwise = clockwise
def prepareDraw(self, context: QOpenGLFunctions): ''' jscut work with the pathBuffer directly ... here we work with the vertexData List so we do not use the "self.m_gcodedrawer.pathBufferContent", but rather the self.m_gcodedrawer.m_triangles list ''' self.m_shader_program.bind() idx = ToolDrawer.lowerBound(self.m_gcodedrawer.m_triangles, self.m_gcodedrawer.stopAtTime) if idx < self.m_gcodedrawer.pathNumPoints: beginTime = self.m_gcodedrawer.m_triangles[idx].startTime endTime = self.m_gcodedrawer.m_triangles[idx].endTime if endTime == beginTime: ratio = 0 else: ratio = (self.m_gcodedrawer.stopAtTime - beginTime) / (endTime - beginTime) x = ToolDrawer.mix(self.m_gcodedrawer.m_triangles[idx].pos1.x(), self.m_gcodedrawer.m_triangles[idx].pos2.x(), ratio) y = ToolDrawer.mix(self.m_gcodedrawer.m_triangles[idx].pos1.y(), self.m_gcodedrawer.m_triangles[idx].pos2.y(), ratio) z = ToolDrawer.mix(self.m_gcodedrawer.m_triangles[idx].pos1.z(), self.m_gcodedrawer.m_triangles[idx].pos2.z(), ratio) else: x = self.m_gcodedrawer.m_triangles[idx - 1].pos2.x() y = self.m_gcodedrawer.m_triangles[idx - 1].pos2.y() z = self.m_gcodedrawer.m_triangles[idx - 2].pos2.z() self.m_shader_program.setUniformValue( "scale", QVector3D(self.m_gcodedrawer.cutterDia, self.m_gcodedrawer.cutterDia, self.m_gcodedrawer.cutterH) * self.m_gcodedrawer.pathScale) self.m_shader_program.setUniformValue( "translate", QVector3D((x + self.m_gcodedrawer.pathXOffset), (y + self.m_gcodedrawer.pathYOffset), (z - self.m_gcodedrawer.pathTopZ)) * self.m_gcodedrawer.pathScale) self.m_shader_program.setUniformValue("rotate", self.rotate)
def f(command, rawX, rawY, rawZ, rotCos, rotSin, zOffset=None): if zOffset is None: zOffset = 0 vertex = VertexData() vertex.pos1 = QVector3D(prevX, prevY, prevZ + zOffset) vertex.pos2 = QVector3D(x, y, z + zOffset) vertex.startTime = beginTime vertex.endTime = total_time vertex.command = command vertex.rawPos = QVector3D(rawX * rotCos - rawY * rotSin, rawY * rotCos + rawX * rotSin, rawZ) self.m_triangles.append(vertex)
def extrude(self, x1, y1, x2, y2): n = QVector3D.normal(QVector3D(0, 0, -0.1), QVector3D(x2 - x1, y2 - y1, 0)) self.add(QVector3D(x1, y1, 0.05), n) self.add(QVector3D(x1, y1, -0.05), n) self.add(QVector3D(x2, y2, 0.05), n) self.add(QVector3D(x2, y2, -0.05), n) self.add(QVector3D(x2, y2, 0.05), n) self.add(QVector3D(x1, y1, -0.05), n)
def __init__(self, parent = None): ''' ''' # Current state self.m_isMetric = True self.m_inAbsoluteMode = True self.m_inAbsoluteIJKMode = False self.m_lastGcodeCommand = -1 self.m_commandNumber = 0 self.m_currentPoint = QVector3D(0, 0, 0) self.m_currentPlane = PointSegment.Plane.XY # Settings self.m_speedOverride = -1 self.m_truncateDecimalLength = 40 self.m_removeAllWhitespace = True self.m_convertArcsToLines = False self.m_smallArcThreshold = 1.0 # Not configurable outside, but maybe it should be. self.m_smallArcSegmentLength = 0.3 self.m_lastSpeed = 0 self.m_traverseSpeed = 300 self.m_lastSpindleSpeed = 0 # The gcode. self.m_points : List[PointSegment] = [] self.reset()
def __init__(self): super(Window, self).__init__() # Camera self.camera().lens().setPerspectiveProjection(45, 16 / 9, 0.1, 1000) self.camera().setPosition(QVector3D(0, 0, 40)) self.camera().setViewCenter(QVector3D(0, 0, 0)) # For camera controls self.createScene() self.camController = Qt3DExtras.QOrbitCameraController(self.rootEntity) self.camController.setLinearSpeed(50) self.camController.setLookSpeed(180) self.camController.setCamera(self.camera()) self.setRootEntity(self.rootEntity)
def createScene(self): # Root entity self.rootEntity = Qt3DCore.QEntity() # Material self.material = Qt3DExtras.QPhongMaterial(self.rootEntity) # Torus self.torusEntity = Qt3DCore.QEntity(self.rootEntity) self.torusMesh = Qt3DExtras.QTorusMesh() self.torusMesh.setRadius(5) self.torusMesh.setMinorRadius(1) self.torusMesh.setRings(100) self.torusMesh.setSlices(20) self.torusTransform = Qt3DCore.QTransform() self.torusTransform.setScale3D(QVector3D(1.5, 1, 0.5)) self.torusTransform.setRotation( QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 45)) self.torusEntity.addComponent(self.torusMesh) self.torusEntity.addComponent(self.torusTransform) self.torusEntity.addComponent(self.material) # Sphere self.sphereEntity = Qt3DCore.QEntity(self.rootEntity) self.sphereMesh = Qt3DExtras.QSphereMesh() self.sphereMesh.setRadius(3) self.sphereTransform = Qt3DCore.QTransform() self.controller = OrbitTransformController(self.sphereTransform) self.controller.setTarget(self.sphereTransform) self.controller.setRadius(20) self.sphereRotateTransformAnimation = QPropertyAnimation( self.sphereTransform) self.sphereRotateTransformAnimation.setTargetObject(self.controller) self.sphereRotateTransformAnimation.setPropertyName(b"angle") self.sphereRotateTransformAnimation.setStartValue(0) self.sphereRotateTransformAnimation.setEndValue(360) self.sphereRotateTransformAnimation.setDuration(10000) self.sphereRotateTransformAnimation.setLoopCount(-1) self.sphereRotateTransformAnimation.start() self.sphereEntity.addComponent(self.sphereMesh) self.sphereEntity.addComponent(self.sphereTransform) self.sphereEntity.addComponent(self.material)
def convertRToCenter(cls, start: QVector3D, end: QVector3D, radius: float, absoluteIJK: bool, clockwise: bool) -> QVector3D: R = radius center = QVector3D() x = end.x() - start.x() y = end.y() - start.y() h_x2_div_d = 4 * R * R - x * x - y * y if h_x2_div_d < 0: print("Error computing arc radius.") h_x2_div_d = (-math.sqrt(h_x2_div_d)) / math.hypot(x, y) if not clockwise: h_x2_div_d = -h_x2_div_d # Special message from gcoder to software for which radius # should be used. if R < 0: h_x2_div_d = -h_x2_div_d # TODO: Places that use this need to run ABS on radius. radius = -radius offsetX = 0.5 * (x - (y * h_x2_div_d)) offsetY = 0.5 * (y + (x * h_x2_div_d)) if not absoluteIJK: center.setX(start.x() + offsetX) center.setY(start.y() + offsetY) else: center.setX(offsetX) center.setY(offsetY) return center
def updatePointWithCommand_FromVector3D(cls, initial: QVector3D, x: float, y: float, z: float, absoluteMode: bool) -> QVector3D: ''' Update a point given the new coordinates. ''' newPoint = QVector3D(initial.x(), initial.y(), initial.z()) if absoluteMode: if not qIsNaN(x): newPoint.setX(x) if not qIsNaN(y): newPoint.setY(y) if not qIsNaN(z): newPoint.setZ(z) else: if not qIsNaN(x): newPoint.setX(newPoint.x() + x) if not qIsNaN(y): newPoint.setY(newPoint.y() + y) if not qIsNaN(z): newPoint.setZ(newPoint.z() + z) return newPoint
def __init__(self, parent=None): self.absoluteMode = True self.absoluteIJK = False # Parsed object self.m_min = QVector3D(qQNaN(), qQNaN(), qQNaN()) self.m_max = QVector3D(qQNaN(), qQNaN(), qQNaN()) self.m_minLength = qQNaN() self.m_lines: List[LineSegment] = [] self.m_lineIndexes: List[List[int]] = [[]] # Parsing state. self.lastPoint: QVector3D = None self.currentLine = 0 # for assigning line numbers to segments. # Debug self.debug = True
def __init__(self): super(ToolDrawer, self).__init__() self.m_toolDiameter = 3.0 self.m_toolLength = 15.0 self.m_endLength = 3.0 self.m_toolPosition = QVector3D(0, 0, 0) self.m_rotationAngle = 0.0 self.m_toolAngle = 0.0 self.m_color = QColor(1.0, 0.6, 4.0)
def getMaximumExtremes(self) -> QVector3D : xs = [item[0] for item in self.path] ys = [item[1] for item in self.path] zs = [item[2] for item in self.path] xmax = QVector3D(max(xs), max(ys), max(zs)) if self.m_ignoreZ: xmax.setZ(0) return xmax
def getMinimumExtremes(self) -> QVector3D : xs = [item[0] for item in self.path] ys = [item[1] for item in self.path] zs = [item[2] for item in self.path] xmin = QVector3D(min(xs), min(ys), min(zs)) if self.m_ignoreZ: xmin.setZ(0) return xmin
def updateData(self) -> bool: self.m_points = [] vertex = VertexData() vertex.color = Util.colorToVector(self.m_color) vertex.position = self.m_endPosition vertex.start = QVector3D(sNaN, sNaN, self.m_pointSize) self.m_points.append(vertex) return True
def reset(self, initialPoint : QVector3D = None): print("reseting gp %s" % initialPoint) if initialPoint is None: #initialPoint = QVector3D(qQNaN(), qQNaN(), qQNaN()) # CANDLE: this line! initialPoint = QVector3D(0.0, 0.0, 0.0) self.m_points = [] # The unspoken home location. self.m_currentPoint = initialPoint self.m_currentPlane = PointSegment.Plane.XY self.m_points.append(PointSegment.PointSegment_FromQVector3D(self.m_currentPoint, -1))
def test_2(): data: List[QVector3D] = [] for k in range(NB): v = QVector3D() v.setX(3 * k) v.setY(3 * k + 1) v.setZ(3 * k + 2) data.append(v) np_array = np.empty(3 * len(data), dtype=ctypes.c_float) for k, vdata in enumerate(data): np_array[3 * k + 0] = vdata.x() np_array[3 * k + 1] = vdata.y() np_array[3 * k + 2] = vdata.z() return np_array
def initializeGL(self): self.context().aboutToBeDestroyed.connect(self.cleanup) self.initializeOpenGLFunctions() self.glClearColor(0, 0, 0, 1) self.program = QOpenGLShaderProgram() if self.core: self.vertexShader = self.vertexShaderSourceCore() self.fragmentShader = self.fragmentShaderSourceCore() else: self.vertexShader = self.vertexShaderSource() self.fragmentShader = self.fragmentShaderSource() self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, self.vertexShader) self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, self.fragmentShader) self.program.bindAttributeLocation("vertex", 0) self.program.bindAttributeLocation("normal", 1) self.program.link() self.program.bind() self.projMatrixLoc = self.program.uniformLocation("projMatrix") self.mvMatrixLoc = self.program.uniformLocation("mvMatrix") self.normalMatrixLoc = self.program.uniformLocation("normalMatrix") self.lightPosLoc = self.program.uniformLocation("lightPos") self.vao.create() vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao) self.logoVbo.create() self.logoVbo.bind() float_size = ctypes.sizeof(ctypes.c_float) self.logoVbo.allocate(self.logo.constData(), self.logo.count() * float_size) self.setupVertexAttribs() self.camera.setToIdentity() self.camera.translate(0, 0, -1) self.program.setUniformValue(self.lightPosLoc, QVector3D(0, 0, 70)) self.program.release() vaoBinder = None
def generatePointsAlongArcBDring_Num(cls, plane: PointSegment.Plane, p1: QVector3D, p2: QVector3D, center: QVector3D, isCw: bool, radius: float, startAngle: float, sweep: float, numPoints: int) -> List[QVector3D]: ''' Generates the points along an arc including the start and end points. ''' # Prepare rotation matrix to restore plane m = QMatrix4x4() m.setToIdentity() if plane == PointSegment.plane.XY: pass elif plane == PointSegment.plane.ZX: m.rotate(-90, 1.0, 0.0, 0.0) elif plane == PointSegment.plane.YZ: m.rotate(90, 0.0, 1.0, 0.0) lineEnd = QVector3D(p2.x(), p2.y(), p1.z()) segments = [] angle = 0.0 # Calculate radius if necessary. if radius == 0: radius = math.sqrt( math.pow((p1.x() - center.x()), 2.0) + math.pow((p1.y() - center.y()), 2.0)) zIncrement = (p2.z() - p1.z()) / numPoints for i in range(numPoints): if isCw: angle = (startAngle - i * sweep / numPoints) else: angle = (startAngle + i * sweep / numPoints) if angle >= cls.M_PI * 2: angle = angle - cls.M_PI * 2 lineEnd.setX(math.cos(angle) * radius + center.x()) lineEnd.setY(math.sin(angle) * radius + center.y()) lineEnd.setZ(lineEnd.z() + zIncrement) segments.append(m * lineEnd) segments.append(m * p2) return segments
def quad(self, x1, y1, x2, y2, x3, y3, x4, y4): n = QVector3D.normal(QVector3D(x4 - x1, y4 - y1, 0), QVector3D(x2 - x1, y2 - y1, 0)) self.add(QVector3D(x1, y1, -0.05), n) self.add(QVector3D(x4, y4, -0.05), n) self.add(QVector3D(x2, y2, -0.05), n) self.add(QVector3D(x3, y3, -0.05), n) self.add(QVector3D(x2, y2, -0.05), n) self.add(QVector3D(x4, y4, -0.05), n) n = QVector3D.normal(QVector3D(x1 - x4, y1 - y4, 0), QVector3D(x2 - x4, y2 - y4, 0)) self.add(QVector3D(x4, y4, 0.05), n) self.add(QVector3D(x1, y1, 0.05), n) self.add(QVector3D(x2, y2, 0.05), n) self.add(QVector3D(x2, y2, 0.05), n) self.add(QVector3D(x3, y3, 0.05), n) self.add(QVector3D(x4, y4, 0.05), n)
def calculateVolume(self, size: QtGui.QVector3D) -> float: return size.x() * size.y() * size.z()
def generateG1FromPoints(cls, start: QVector3D, end: QVector3D, absoluteMode: bool, precision: int) -> str: sb = "G1" if absoluteMode: if not qIsNaN(end.x()): sb.append("X" + "%.*f" % (precision, end.x())) if not qIsNaN(end.y()): sb.append("Y" + "%.*f" % (precision, end.y())) if not qIsNaN(end.z()): sb.append("Z" + "%.*f" % (precision, end.z())) else: if not qIsNaN(end.x()): sb.append("X" + "%.*f" % (precision, end.x() - start.x())) if not qIsNaN(end.y()): sb.append("Y" + "%.*f" % (precision, end.y() - start.y())) if not qIsNaN(end.z()): sb.append("Z" + "%.*f" % (precision, end.z() - start.z())) return sb
def prepareVectors(self) -> bool: print("preparing vectors : %s" % self) self.m_miniParser.parse_gcode(self.gcode) self.path = path = self.m_miniParser.path # Clear all vertex data self.m_lines = [] self.m_points = [] self.m_triangles = [] # Delete texture on mode change if self.m_texture: self.m_texture.destroy() self.m_texture = None self.needToCreatePathTexture = True #self.requestFrame() self.pathNumPoints = len(path) numHalfCircleSegments = 5 if self.isVBit: self.pathStride = 12 pathVertexesPerLine = 12 + numHalfCircleSegments * 6 else: self.pathStride = 9 pathVertexesPerLine = 18 self.pathNumVertexes = len(path) * pathVertexesPerLine minX = path[0][0] maxX = path[0][0] minY = path[0][1] maxY = path[0][1] minZ = path[0][2] total_time = 0 for idx, point in enumerate(path): prevIdx = max(idx - 1, 0) prevPoint = self.path[prevIdx] x = point[0] y = point[1] z = point[2] f = point[3] prevX = prevPoint[0] prevY = prevPoint[1] prevZ = prevPoint[2] dist = math.sqrt((x - prevX) * (x - prevX) + (y - prevY) * (y - prevY) + (z - prevZ) * (z - prevZ)) beginTime = total_time total_time = total_time + dist / f * 60 minX = min(minX, x) maxX = max(maxX, x) minY = min(minY, y) maxY = max(maxY, y) minZ = min(minZ, z) if self.isVBit: coneHeight = -min(z, prevZ, 0) + 0.1 coneDia = coneHeight * 2 * math.sin(self.cutterAngleRad / 2) / math.cos(self.cutterAngleRad / 2) if x == prevX and y == prevY: rotAngle = 0 else: rotAngle = math.atan2(y - prevY, x - prevX) xyDist = math.sqrt((x - prevX) * (x - prevX) + (y - prevY) * (y - prevY)) # -------------------------------------------------------------------------------------------------- def f(command, rawX, rawY, rawZ, rotCos, rotSin, zOffset=None): if zOffset is None: zOffset = 0 vertex = VertexData() vertex.pos1 = QVector3D(prevX, prevY, prevZ + zOffset) vertex.pos2 = QVector3D(x, y, z + zOffset) vertex.startTime = beginTime vertex.endTime = total_time vertex.command = command vertex.rawPos = QVector3D(rawX * rotCos - rawY * rotSin, rawY * rotCos + rawX * rotSin, rawZ) self.m_triangles.append(vertex) # -------------------------------------------------------------------------------------------------- if math.abs(z - prevZ) >= xyDist * M_PI / 2 * math.cos(self.cutterAngleRad / 2) / math.sin(self.cutterAngleRad / 2): #console.log("plunge or retract") #plunge or retract index = 0 command = 100 if prevZ < z else 101 for circleIndex in range(1, numHalfCircleSegments*2): a1 = 2 * M_PI * circleIndex / numHalfCircleSegments/2 a2 = 2 * M_PI * (circleIndex + 1) / numHalfCircleSegments/2 f(command, coneDia / 2 * math.cos(a2), coneDia / 2 * math.sin(a2), coneHeight, 1, 0) index += 1 f(command, 0, 0, 0, 1, 0) index += 1 f(command, coneDia / 2 * math.cos(a1), coneDia / 2 * math.sin(a1), coneHeight, 1, 0) index += 1 while index < pathVertexesPerLine: f(200, 0, 0, 0, 1, 0) index += 1 else: # cut planeContactAngle = math.asin((prevZ - z) / xyDist * math.sin(self.cutterAngleRad / 2) / math.cos(self.cutterAngleRad / 2)) index = 0 if True: f(100, 0, -coneDia / 2, coneHeight, math.cos(rotAngle - planeContactAngle), math.sin(rotAngle - planeContactAngle)) f(101, 0, -coneDia / 2, coneHeight, math.cos(rotAngle - planeContactAngle), math.sin(rotAngle - planeContactAngle)) f(100, 0, 0, 0, 1, 0) f(100, 0, 0, 0, 1, 0) f(101, 0, -coneDia / 2, coneHeight, math.cos(rotAngle - planeContactAngle), math.sin(rotAngle - planeContactAngle)) f(101, 0, 0, 0, 1, 0) f(100, 0, 0, 0, 1, 0) f(101, 0, 0, 0, 1, 0) f(100, 0, coneDia / 2, coneHeight, math.cos(rotAngle + planeContactAngle), math.sin(rotAngle + planeContactAngle)) f(100, 0, coneDia / 2, coneHeight, math.cos(rotAngle + planeContactAngle), math.sin(rotAngle + planeContactAngle)) f(101, 0, 0, 0, 1, 0) f(101, 0, coneDia / 2, coneHeight, math.cos(rotAngle + planeContactAngle), math.sin(rotAngle + planeContactAngle)) index += 12 startAngle = rotAngle + math.PI / 2 - planeContactAngle endAngle = rotAngle + 3 * math.PI / 2 + planeContactAngle for circleIndex in range(1,numHalfCircleSegments): a1 = startAngle + circleIndex / numHalfCircleSegments * (endAngle - startAngle) a2 = startAngle + (circleIndex + 1) / numHalfCircleSegments * (endAngle - startAngle) #console.log("a1,a2: " + (a1 * 180 / math.PI) + ", " + (a2 * 180 / math.PI)) f(100, coneDia / 2 * math.cos(a2), coneDia / 2 * math.sin(a2), coneHeight, 1, 0) f(100, 0, 0, 0, 1, 0) f(100, coneDia / 2 * math.cos(a1), coneDia / 2 * math.sin(a1), coneHeight, 1, 0) f(101, coneDia / 2 * math.cos(a2 + math.PI), coneDia / 2 * math.sin(a2 + math.PI), coneHeight, 1, 0) f(101, 0, 0, 0, 1, 0) f(101, coneDia / 2 * math.cos(a1 + math.PI), coneDia / 2 * math.sin(a1 + math.PI), coneHeight, 1, 0) index += 16 else : # recall: pathVertexesPerLine = 18 for virtex in range(pathVertexesPerLine): vertex = VertexData() vertex.pos1 = QVector3D(prevX, prevY, prevZ) vertex.pos2 = QVector3D(x, y, z) vertex.startTime = beginTime vertex.endTime = total_time vertex.command = virtex self.m_triangles.append(vertex) self.totalTime = total_time self.pathXOffset = -(minX + maxX) / 2 self.pathYOffset = -(minY + maxY) / 2 size = max(maxX - minX + 4 * self.cutterDia, maxY - minY + 4 * self.cutterDia) self.pathScale = 2 / size self.pathMinZ = minZ self.stopAtTime = total_time self.update() return True