Merge pull request #474 from mlampert/logging

Path: minor fix in dogbones and introduction of PathLog module (with initial use).
This commit is contained in:
Yorik van Havre
2017-01-26 21:23:41 -02:00
committed by GitHub
7 changed files with 487 additions and 129 deletions

View File

@@ -39,6 +39,7 @@ SET(PathScripts_SRCS
PathScripts/PathJob.py
PathScripts/PathKurveUtils.py
PathScripts/PathLoadTool.py
PathScripts/PathLog.py
PathScripts/PathMillFace.py
PathScripts/PathPlane.py
PathScripts/PathPocket.py
@@ -79,6 +80,7 @@ SET(PathScripts_SRCS
PathTests/TestPathDepthParams.py
PathTests/TestPathDressupHoldingTags.py
PathTests/TestPathGeom.py
PathTests/TestPathLog.py
PathTests/TestPathPost.py
PathTests/__init__.py
PathTests/test_linuxcnc_00.ngc

View File

@@ -21,31 +21,26 @@
# * USA *
# * *
# ***************************************************************************
import DraftGeomUtils
import FreeCAD
import FreeCADGui
import Path
from PathScripts import PathUtils
from PathScripts.PathGeom import *
from PySide import QtCore, QtGui
import math
import Part
import DraftGeomUtils
import Path
import PathScripts.PathLog as PathLog
from PathScripts import PathUtils
from PathScripts.PathGeom import PathGeom
from PySide import QtCore, QtGui
"""Dogbone Dressup object and FreeCAD command"""
debugDressup = False
LOG_MODULE = 'PathDressupDogbone'
#PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
# Qt tanslation handling
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def translate(context, text, disambig=None):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def translate(context, text, disambig=None):
return QtGui.QApplication.translate(context, text, disambig)
def translate(text, context = "PathDressup_Dogbone", disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
movecommands = ['G0', 'G00', 'G1', 'G01', 'G2', 'G02', 'G3', 'G03']
movestraight = ['G1', 'G01']
@@ -53,12 +48,8 @@ movecw = ['G2', 'G02']
moveccw = ['G3', 'G03']
movearc = movecw + moveccw
def debugPrint(msg):
if debugDressup:
print(msg)
def debugMarker(vector, label, color = None, radius = 0.5):
if debugDressup:
if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Sphere", label)
obj.Label = label
obj.Radius = radius
@@ -67,7 +58,7 @@ def debugMarker(vector, label, color = None, radius = 0.5):
obj.ViewObject.ShapeColor = color
def debugCircle(vector, r, label, color = None):
if debugDressup:
if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Cylinder", label)
obj.Label = label
obj.Radius = r
@@ -285,6 +276,7 @@ class Bone:
self.inChord = inChord
self.outChord = outChord
self.smooth = smooth
self.smooth = Smooth.Neither
def angle(self):
if not hasattr(self, 'cAngle'):
@@ -318,9 +310,9 @@ class Bone:
# for some reason pi/2 is not equal to pi/2
if math.fabs(angle - boneAngle) < 0.00001:
# moving directly towards the corner
debugPrint("adaptive - on target: %.2f - %.2f" % (distance, toolRadius))
PathLog.debug("adaptive - on target: %.2f - %.2f" % (distance, toolRadius))
return distance - toolRadius
debugPrint("adaptive - angles: corner=%.2f bone=%.2f diff=%.12f" % (angle/math.pi, boneAngle/math.pi, angle - boneAngle))
PathLog.debug("adaptive - angles: corner=%.2f bone=%.2f diff=%.12f" % (angle/math.pi, boneAngle/math.pi, angle - boneAngle))
# The bones root and end point form a triangle with the intersection of the tool path
# with the toolRadius circle around the bone end point.
@@ -331,7 +323,7 @@ class Bone:
beta = math.fabs(addAngle(boneAngle, -angle))
D = (distance / toolRadius) * math.sin(beta)
if D > 1: # no intersection
debugPrint("adaptive - no intersection - no bone")
PathLog.debug("adaptive - no intersection - no bone")
return 0
gamma = math.asin(D)
alpha = math.pi - beta - gamma
@@ -343,7 +335,7 @@ class Bone:
length2 = toolRadius * math.sin(alpha2) / math.sin(beta2)
length = min(length, length2)
debugPrint("adaptive corner=%.2f * %.2f˚ -> bone=%.2f * %.2f˚" % (distance, angle, length, boneAngle))
PathLog.debug("adaptive corner=%.2f * %.2f˚ -> bone=%.2f * %.2f˚" % (distance, angle, length, boneAngle))
return length
def edges(self):
@@ -390,26 +382,26 @@ class ObjectDressup:
return outChord.foldsBackOrTurns(inChord, self.theOtherSideOf(obj.Side))
def findPivotIntersection(self, pivot, pivotEdge, edge, refPt, d, color):
debugPrint("Intersection (%.2f, %.2f)^%.2f - [(%.2f, %.2f), (%.2f, %.2f)]" % (pivotEdge.Curve.Center.x, pivotEdge.Curve.Center.y, pivotEdge.Curve.Radius, edge.Vertexes[0].Point.x, edge.Vertexes[0].Point.y, edge.Vertexes[1].Point.x, edge.Vertexes[1].Point.y))
PathLog.track("(%.2f, %.2f)^%.2f - [(%.2f, %.2f), (%.2f, %.2f)]" % (pivotEdge.Curve.Center.x, pivotEdge.Curve.Center.y, pivotEdge.Curve.Radius, edge.Vertexes[0].Point.x, edge.Vertexes[0].Point.y, edge.Vertexes[1].Point.x, edge.Vertexes[1].Point.y))
ppt = None
pptDistance = 0
for pt in DraftGeomUtils.findIntersection(edge, pivotEdge, dts=False):
#debugMarker(pt, "pti.%d-%s.in" % (self.boneId, d), color, 0.2)
distance = (pt - refPt).Length
debugPrint(" --> (%.2f, %.2f): %.2f" % (pt.x, pt.y, distance))
PathLog.debug(" --> (%.2f, %.2f): %.2f" % (pt.x, pt.y, distance))
if not ppt or pptDistance < distance:
ppt = pt
pptDistance = distance
if not ppt:
tangent = DraftGeomUtils.findDistance(pivot, edge)
if tangent:
debugPrint("Taking tangent as intersect %s" % tangent)
PathLog.debug("Taking tangent as intersect %s" % tangent)
ppt = pivot + tangent
else:
debugPrint("Taking chord start as intersect %s" % inChordStart)
PathLog.debug("Taking chord start as intersect %s" % inChordStart)
ppt = inChord.Start
#debugMarker(ppt, "ptt.%d-%s.in" % (self.boneId, d), color, 0.2)
debugPrint(" --> (%.2f, %.2f)" % (ppt.x, ppt.y))
PathLog.debug(" --> (%.2f, %.2f)" % (ppt.x, ppt.y))
return ppt
def pointIsOnEdge(self, point, edge):
@@ -418,7 +410,7 @@ class ObjectDressup:
def smoothChordCommands(self, bone, inChord, outChord, edge, wire, corner, smooth, color = None):
if smooth == 0:
debugPrint(" No smoothing requested")
PathLog.info(" No smoothing requested")
return [ bone.lastCommand, outChord.g1Command() ]
d = 'in'
@@ -428,32 +420,32 @@ class ObjectDressup:
refPoint = outChord.End
if DraftGeomUtils.areColinear(inChord.asEdge(), outChord.asEdge()):
debugPrint(" straight edge %s" % d)
PathLog.info(" straight edge %s" % d)
return [ outChord.g1Command() ]
pivot = None
pivotDistance = 0
debugPrint("smooth: (%.2f, %.2f)-(%.2f, %.2f)" % (edge.Vertexes[0].Point.x, edge.Vertexes[0].Point.y, edge.Vertexes[1].Point.x, edge.Vertexes[1].Point.y))
PathLog.info("smooth: (%.2f, %.2f)-(%.2f, %.2f)" % (edge.Vertexes[0].Point.x, edge.Vertexes[0].Point.y, edge.Vertexes[1].Point.x, edge.Vertexes[1].Point.y))
for e in wire.Edges:
self.dbg.append(e)
if type(e.Curve) == Part.LineSegment or type(e.Curve) == Part.Line:
debugPrint(" (%.2f, %.2f)-(%.2f, %.2f)" % (e.Vertexes[0].Point.x, e.Vertexes[0].Point.y, e.Vertexes[1].Point.x, e.Vertexes[1].Point.y))
PathLog.debug(" (%.2f, %.2f)-(%.2f, %.2f)" % (e.Vertexes[0].Point.x, e.Vertexes[0].Point.y, e.Vertexes[1].Point.x, e.Vertexes[1].Point.y))
else:
debugPrint(" (%.2f, %.2f)^%.2f" % (e.Curve.Center.x, e.Curve.Center.y, e.Curve.Radius))
PathLog.debug(" (%.2f, %.2f)^%.2f" % (e.Curve.Center.x, e.Curve.Center.y, e.Curve.Radius))
for pt in DraftGeomUtils.findIntersection(edge, e, True, findAll=True):
if not PathGeom.pointsCoincide(pt, corner) and self.pointIsOnEdge(pt, e):
debugMarker(pt, "candidate-%d-%s" % (self.boneId, d), color, 0.05)
debugPrint(" -> candidate")
#debugMarker(pt, "candidate-%d-%s" % (self.boneId, d), color, 0.05)
PathLog.debug(" -> candidate")
distance = (pt - refPoint).Length
if not pivot or pivotDistance > distance:
pivot = pt
pivotDistance = distance
else:
debugPrint(" -> corner intersect")
PathLog.debug(" -> corner intersect")
if pivot:
debugCircle(pivot, self.toolRadius, "pivot.%d-%s" % (self.boneId, d), color)
#debugCircle(pivot, self.toolRadius, "pivot.%d-%s" % (self.boneId, d), color)
pivotEdge = Part.Edge(Part.Circle(pivot, FreeCAD.Vector(0,0,1), self.toolRadius))
t1 = self.findPivotIntersection(pivot, pivotEdge, inChord.asEdge(), inChord.End, d, color)
@@ -461,16 +453,16 @@ class ObjectDressup:
commands = []
if not PathGeom.pointsCoincide(t1, inChord.Start):
debugPrint(" add lead in")
PathLog.debug(" add lead in")
commands.append(Chord(inChord.Start, t1).g1Command())
if bone.obj.Side == Side.Left:
debugPrint(" add g3 command")
PathLog.debug(" add g3 command")
commands.append(Chord(t1, t2).g3Command(pivot))
else:
debugPrint(" add g2 command center=(%.2f, %.2f) -> from (%2f, %.2f) to (%.2f, %.2f" % (pivot.x, pivot.y, t1.x, t1.y, t2.x, t2.y))
PathLog.debug(" add g2 command center=(%.2f, %.2f) -> from (%2f, %.2f) to (%.2f, %.2f" % (pivot.x, pivot.y, t1.x, t1.y, t2.x, t2.y))
commands.append(Chord(t1, t2).g2Command(pivot))
if not PathGeom.pointsCoincide(t2, outChord.End):
debugPrint(" add lead out")
PathLog.debug(" add lead out")
commands.append(Chord(t2, outChord.End).g1Command())
#debugMarker(pivot, "pivot.%d-%s" % (self.boneId, d), color, 0.2)
@@ -479,7 +471,7 @@ class ObjectDressup:
return commands
debugPrint(" no pivot found - straight command")
PathLog.info(" no pivot found - straight command")
return [ inChord.g1Command(), outChord.g1Command() ]
def inOutBoneCommands(self, bone, boneAngle, fixedLength):
@@ -487,8 +479,8 @@ class ObjectDressup:
bone.tip = bone.inChord.End # in case there is no bone
debugPrint("corner = (%.2f, %.2f)" % (corner.x, corner.y))
debugMarker(corner, 'corner', (1., 0., 1.), self.toolRadius)
PathLog.debug("corner = (%.2f, %.2f)" % (corner.x, corner.y))
#debugMarker(corner, 'corner', (1., 0., 1.), self.toolRadius)
length = fixedLength
if bone.obj.Incision == Incision.Custom:
@@ -497,7 +489,7 @@ class ObjectDressup:
length = bone.adaptiveLength(boneAngle, self.toolRadius)
if length == 0:
# no bone after all ..
PathLog.info("no bone after all ..")
return [ bone.lastCommand, bone.outChord.g1Command() ]
boneInChord = bone.inChord.move(length, boneAngle)
@@ -576,7 +568,7 @@ class ObjectDressup:
onInString = 'out'
if onIn:
onInString = 'in'
debugPrint("tboneEdge boneAngle[%s]=%.2f (in=%.2f, out=%.2f)" % (onInString, boneAngle/math.pi, bone.inChord.getAngleXY()/math.pi, bone.outChord.getAngleXY()/math.pi))
PathLog.debug("tboneEdge boneAngle[%s]=%.2f (in=%.2f, out=%.2f)" % (onInString, boneAngle/math.pi, bone.inChord.getAngleXY()/math.pi, bone.outChord.getAngleXY()/math.pi))
return self.inOutBoneCommands(bone, boneAngle, self.toolRadius)
def tboneLongEdge(self, bone):
@@ -619,21 +611,21 @@ class ObjectDressup:
return [ bone.lastCommand, bone.outChord.g1Command() ]
def insertBone(self, bone):
debugPrint(">----------------------------------- %d --------------------------------------" % bone.boneId)
PathLog.debug(">----------------------------------- %d --------------------------------------" % bone.boneId)
self.boneShapes = []
blacklisted, inaccessible = self.boneIsBlacklisted(bone)
enabled = not blacklisted
self.bones.append((bone.boneId, bone.location(), enabled, inaccessible))
self.boneId = bone.boneId
if debugDressup and bone.boneId > 2:
if False and PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG and bone.boneId > 2:
commands = self.boneCommands(bone, False)
else:
commands = self.boneCommands(bone, enabled)
bone.commands = commands
self.shapes[bone.boneId] = self.boneShapes
debugPrint("<----------------------------------- %d --------------------------------------" % bone.boneId)
PathLog.debug("<----------------------------------- %d --------------------------------------" % bone.boneId)
return commands
def removePathCrossing(self, commands, bone1, bone2):
@@ -652,7 +644,7 @@ class ObjectDressup:
#debugCircle(e2.Curve.Center, e2.Curve.Radius, "bone.%d-2" % (self.boneId), (0.,1.,0.))
if PathGeom.pointsCoincide(pt, e1.valueAt(e1.LastParameter)) or PathGeom.pointsCoincide(pt, e2.valueAt(e2.FirstParameter)):
continue
debugMarker(pt, "it", (0.0, 1.0, 1.0))
#debugMarker(pt, "it", (0.0, 1.0, 1.0))
# 1. remove all redundant commands
commands = commands[:-(len(inEdges) - i)]
# 2., correct where c1 ends
@@ -702,40 +694,52 @@ class ObjectDressup:
boneIserted = False
for thisCommand in obj.Base.Path.Commands:
PathLog.info("Command: %s" % thisCommand)
if thisCommand.Name in movecommands:
thisChord = lastChord.moveToParameters(thisCommand.Parameters)
thisIsACandidate = self.canAttachDogbone(thisCommand, thisChord)
if thisIsACandidate and lastCommand and self.shouldInsertDogbone(obj, lastChord, thisChord):
PathLog.info(" Found bone corner")
bone = Bone(boneId, obj, lastCommand, lastChord, thisChord, Smooth.InAndOut)
bones = self.insertBone(bone)
boneId += 1
if lastBone:
PathLog.info(" removing potential path crossing")
#debugMarker(thisChord.Start, "it", (1.0, 0.0, 1.0))
commands, bones = self.removePathCrossing(commands, lastBone, bone)
commands.extend(bones[:-1])
lastCommand = bones[-1]
lastBone = bone
elif lastCommand and thisChord.isAPlungeMove():
PathLog.info(" Looking for connection in odds and ends")
haveNewLastCommand = False
for chord in (chord for chord in oddsAndEnds if lastChord.connectsTo(chord)):
if self.shouldInsertDogbone(obj, lastChord, chord):
PathLog.info(" and there is one")
bone = Bone(boneId, obj, lastCommand, lastChord, chord, Smooth.In)
bones = self.insertBone(bone)
boneId += 1
if lastBone:
PathLog.info(" removing potential path crossing")
#debugMarker(chord.Start, "it", (0.0, 1.0, 1.0))
commands, bones = self.removePathCrossing(commands, lastBone, bone)
commands.extend(bones[:-1])
lastCommand = bones[-1]
haveNewLastCommand = True
if not haveNewLastCommand:
commands.append(lastCommand)
lastCommand = None
commands.append(thisCommand)
lastBone = None
elif thisIsACandidate:
PathLog.info(" is a candidate, keeping for later")
if lastCommand:
commands.append(lastCommand)
lastCommand = thisCommand
lastBone = None
else:
PathLog.info(" nope")
if lastCommand:
commands.append(lastCommand)
lastCommand = None
@@ -743,21 +747,24 @@ class ObjectDressup:
lastBone = None
if lastChord.isAPlungeMove() and thisIsACandidate:
PathLog.info(" adding to odds and ends")
oddsAndEnds.append(thisChord)
lastChord = thisChord
else:
PathLog.info(" Clean slate")
if lastCommand:
commands.append(lastCommand)
lastCommand = None
commands.append(thisCommand)
lastBone = None
#for cmd in commands:
# debugPrint("cmd = '%s'" % cmd)
# PathLog.debug("cmd = '%s'" % cmd)
path = Path.Path(commands)
obj.Path = path
def setup(self, obj):
debugPrint("Here we go ... ")
PathLog.info("Here we go ... ")
if hasattr(obj.Base, "BoneBlacklist"):
# dressing up a bone dressup
obj.Side = obj.Base.Side
@@ -861,18 +868,18 @@ class TaskPanel:
self.form.customLabel.setEnabled(customSelected)
self.updateBoneList()
if debugDressup:
if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
for obj in FreeCAD.ActiveDocument.Objects:
if obj.Name.startswith('Shape'):
FreeCAD.ActiveDocument.removeObject(obj.Name)
print('object name %s' % self.obj.Name)
if hasattr(self.obj.Proxy, "shapes"):
debugPrint("showing shapes attribute")
PathLog.info("showing shapes attribute")
for shapes in self.obj.Proxy.shapes.itervalues():
for shape in shapes:
Part.show(shape)
else:
debugPrint("no shapes attribute found")
PathLog.info("no shapes attribute found")
def updateModel(self):

View File

@@ -27,18 +27,16 @@ import Draft
import DraftGeomUtils
import DraftGui
import Path
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferencesPathDressup as PathPreferencesPathDressup
import Part
import copy
import math
import cProfile
import time
from DraftGui import todo
from PathScripts import PathUtils
from PathScripts.PathGeom import *
from PathScripts.PathPreferences import *
from PathScripts.PathGeom import PathGeom
from PathScripts.PathPreferences import PathPreferences
from PySide import QtCore, QtGui
from pivy import coin
@@ -48,16 +46,14 @@ from pivy import coin
def translate(text, context = "PathDressup_HoldingTags", disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
debugDressup = False
def debugPrint(msg):
if debugDressup:
print(msg)
LOG_MODULE = 'PathDressupHoldingTags'
#PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE)
def debugEdge(edge, prefix, force = False):
pf = edge.valueAt(edge.FirstParameter)
pl = edge.valueAt(edge.LastParameter)
if force or debugDressup:
if force or PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
pf = edge.valueAt(edge.FirstParameter)
pl = edge.valueAt(edge.LastParameter)
if type(edge.Curve) == Part.Line or type(edge.Curve) == Part.LineSegment:
print("%s %s((%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f))" % (prefix, type(edge.Curve), pf.x, pf.y, pf.z, pl.x, pl.y, pl.z))
else:
@@ -65,7 +61,7 @@ def debugEdge(edge, prefix, force = False):
print("%s %s((%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f))" % (prefix, type(edge.Curve), pf.x, pf.y, pf.z, pm.x, pm.y, pm.z, pl.x, pl.y, pl.z))
def debugMarker(vector, label, color = None, radius = 0.5):
if debugDressup:
if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Sphere", label)
obj.Label = label
obj.Radius = radius
@@ -74,7 +70,7 @@ def debugMarker(vector, label, color = None, radius = 0.5):
obj.ViewObject.ShapeColor = color
def debugCylinder(vector, r, height, label, color = None):
if debugDressup:
if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Cylinder", label)
obj.Label = label
obj.Radius = r
@@ -85,7 +81,7 @@ def debugCylinder(vector, r, height, label, color = None):
obj.ViewObject.ShapeColor = color
def debugCone(vector, r1, r2, height, label, color = None):
if debugDressup:
if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
obj = FreeCAD.ActiveDocument.addObject("Part::Cone", label)
obj.Label = label
obj.Radius1 = r1
@@ -162,7 +158,7 @@ class HoldingTagsPreferences:
class Tag:
def __init__(self, x, y, width, height, angle, radius, enabled=True):
debugPrint("Tag(%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d)" % (x, y, width, height, angle, radius, enabled))
PathLog.track("%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d" % (x, y, width, height, angle, radius, enabled))
self.x = x
self.y = y
self.width = math.fabs(width)
@@ -198,7 +194,7 @@ class Tag:
self.isSquare = True
self.solid = Part.makeCylinder(r1, height)
radius = min(min(self.radius, r1), self.height)
debugPrint("Part.makeCone(%f, %f)" % (r1, height))
PathLog.debug("Part.makeCone(%f, %f)" % (r1, height))
elif self.angle > 0.0 and height > 0.0:
# cone
rad = math.radians(self.angle)
@@ -215,29 +211,29 @@ class Tag:
height = r1 * tangens * 1.01
self.actualHeight = height
self.r2 = r2
debugPrint("Part.makeCone(%f, %f, %f)" % (r1, r2, height))
PathLog.debug("Part.makeCone(%f, %f, %f)" % (r1, r2, height))
self.solid = Part.makeCone(r1, r2, height)
else:
# degenerated case - no tag
debugPrint("Part.makeSphere(%f / 10000)" % (r1))
PathLog.debug("Part.makeSphere(%f / 10000)" % (r1))
self.solid = Part.makeSphere(r1 / 10000)
if not R == 0: # testing is easier if the solid is not rotated
angle = -PathGeom.getAngle(self.originAt(0)) * 180 / math.pi
debugPrint("solid.rotate(%f)" % angle)
PathLog.debug("solid.rotate(%f)" % angle)
self.solid.rotate(FreeCAD.Vector(0,0,0), FreeCAD.Vector(0,0,1), angle)
debugPrint("solid.translate(%s)" % self.originAt(z))
PathLog.debug("solid.translate(%s)" % self.originAt(z))
self.solid.translate(self.originAt(z - 0.01 * self.actualHeight))
self.realRadius = radius
if radius != 0:
debugPrint("makeFillet(%.4f)" % radius)
PathLog.debug("makeFillet(%.4f)" % radius)
self.solid = self.solid.makeFillet(radius, [self.solid.Edges[0]])
def filterIntersections(self, pts, face):
if type(face.Surface) == Part.Cone or type(face.Surface) == Part.Cylinder or type(face.Surface) == Part.Toroid:
#print("it's a cone/cylinder, checking z")
PathLog.track("it's a cone/cylinder, checking z")
return filter(lambda pt: pt.z >= self.bottom() and pt.z <= self.top(), pts)
if type(face.Surface) == Part.Plane:
#print("it's a plane, checking R")
PathLog.track("it's a plane, checking R")
c = face.Edges[0].Curve
if (type(c) == Part.Circle):
return filter(lambda pt: (pt - c.Center).Length <= c.Radius or PathGeom.isRoughly((pt - c.Center).Length, c.Radius), pts)
@@ -312,9 +308,9 @@ class MapWireToTag:
self.edges = []
self.entry = i
if tail:
debugPrint("MapWireToTag(%s - %s)" % (i, tail.valueAt(tail.FirstParameter)))
PathLog.debug("MapWireToTag(%s - %s)" % (i, tail.valueAt(tail.FirstParameter)))
else:
debugPrint("MapWireToTag(%s - )" % i)
PathLog.debug("MapWireToTag(%s - )" % i)
self.complete = False
self.haveProblem = False
@@ -342,11 +338,11 @@ class MapWireToTag:
def cleanupEdges(self, edges):
# want to remove all edges from the wire itself, and all internal struts
#print("+cleanupEdges")
#print(" edges:")
PathLog.track("+cleanupEdges")
PathLog.debug(" edges:")
for e in edges:
debugEdge(e, ' ')
#print(":")
PathLog.debug(":")
self.edgesCleanup = [copy.copy(edges)]
# remove any edge that has a point inside the tag solid
@@ -413,7 +409,7 @@ class MapWireToTag:
return edges
def orderAndFlipEdges(self, edges):
#print("entry(%.2f, %.2f, %.2f), exit(%.2f, %.2f, %.2f)" % (self.entry.x, self.entry.y, self.entry.z, self.exit.x, self.exit.y, self.exit.z))
PathLog.track("entry(%.2f, %.2f, %.2f), exit(%.2f, %.2f, %.2f)" % (self.entry.x, self.entry.y, self.entry.z, self.exit.x, self.exit.y, self.exit.z))
self.edgesOrder = []
outputEdges = []
p0 = self.entry
@@ -450,11 +446,11 @@ class MapWireToTag:
debugEdge(e, ' ', False)
raise ValueError("No connection to %s" % (p0))
elif lastP:
debugPrint("xxxxxx (%.2f, %.2f, %.2f) (%.2f, %.2f, %.2f)" % (p0.x, p0.y, p0.z, lastP.x, lastP.y, lastP.z))
PathLog.debug("xxxxxx (%.2f, %.2f, %.2f) (%.2f, %.2f, %.2f)" % (p0.x, p0.y, p0.z, lastP.x, lastP.y, lastP.z))
else:
debugPrint("xxxxxx (%.2f, %.2f, %.2f) -" % (p0.x, p0.y, p0.z))
PathLog.debug("xxxxxx (%.2f, %.2f, %.2f) -" % (p0.x, p0.y, p0.z))
lastP = p0
#print("-cleanupEdges")
PathLog.track("-")
return outputEdges
def isStrut(self, edge):
@@ -546,14 +542,9 @@ class _RapidEdges:
return True
return False
def debugPrint(self):
debugPrint('rapid:')
for r in self.rapid:
debugEdge(r, ' ')
class PathData:
def __init__(self, obj):
debugPrint("PathData(%s)" % obj.Base.Name)
PathLog.track(obj.Base.Name)
self.obj = obj
self.wire, rapid = PathGeom.wireForPath(obj.Base.Path)
self.rapid = _RapidEdges(rapid)
@@ -593,7 +584,7 @@ class PathData:
return (edges[0], edges[-1])
def generateTags(self, obj, count, width=None, height=None, angle=None, radius=None, spacing=None):
debugPrint("generateTags(%s, %s, %s, %s, %s)" % (count, width, height, angle, spacing))
PathLog.track(count, width, height, angle, spacing)
#for e in self.base.Edges:
# debugMarker(e.Vertexes[0].Point, 'base', (0.0, 1.0, 1.0), 0.2)
@@ -613,7 +604,7 @@ class PathData:
startIndex = 0
for i in range(0, len(self.base.Edges)):
edge = self.base.Edges[i]
debugPrint(' %d: %.2f' % (i, edge.Length))
PathLog.debug(' %d: %.2f' % (i, edge.Length))
if edge.Length == longestEdge.Length:
startIndex = i
break
@@ -628,10 +619,10 @@ class PathData:
minLength = min(2. * W, longestEdge.Length)
debugPrint("length=%.2f shortestEdge=%.2f(%.2f) longestEdge=%.2f(%.2f) minLength=%.2f" % (self.base.Length, shortestEdge.Length, shortestEdge.Length/self.base.Length, longestEdge.Length, longestEdge.Length / self.base.Length, minLength))
debugPrint(" start: index=%-2d count=%d (length=%.2f, distance=%.2f)" % (startIndex, startCount, startEdge.Length, tagDistance))
debugPrint(" -> lastTagLength=%.2f)" % lastTagLength)
debugPrint(" -> currentLength=%.2f)" % currentLength)
PathLog.debug("length=%.2f shortestEdge=%.2f(%.2f) longestEdge=%.2f(%.2f) minLength=%.2f" % (self.base.Length, shortestEdge.Length, shortestEdge.Length/self.base.Length, longestEdge.Length, longestEdge.Length / self.base.Length, minLength))
PathLog.debug(" start: index=%-2d count=%d (length=%.2f, distance=%.2f)" % (startIndex, startCount, startEdge.Length, tagDistance))
PathLog.debug(" -> lastTagLength=%.2f)" % lastTagLength)
PathLog.debug(" -> currentLength=%.2f)" % currentLength)
edgeDict = { startIndex: startCount }
@@ -646,7 +637,7 @@ class PathData:
for (i, count) in edgeDict.iteritems():
edge = self.base.Edges[i]
debugPrint(" %d: %d" % (i, count))
PathLog.debug(" %d: %d" % (i, count))
#debugMarker(edge.Vertexes[0].Point, 'base', (1.0, 0.0, 0.0), 0.2)
#debugMarker(edge.Vertexes[1].Point, 'base', (0.0, 1.0, 0.0), 0.2)
if 0 != count:
@@ -665,10 +656,10 @@ class PathData:
tagCount += 1
lastTagLength += tagDistance
if tagCount > 0:
debugPrint(" index=%d -> count=%d" % (index, tagCount))
PathLog.debug(" index=%d -> count=%d" % (index, tagCount))
edgeDict[index] = tagCount
else:
debugPrint(" skipping=%-2d (%.2f)" % (index, edge.Length))
PathLog.debug(" skipping=%-2d (%.2f)" % (index, edge.Length))
return (currentLength, lastTagLength)
@@ -701,7 +692,7 @@ class PathData:
ordered.append(t)
# disable all tags that are not on the base wire.
for tag in tags:
FreeCAD.Console.PrintMessage("Tag #%d not on base wire - disabling\n" % len(ordered))
PathLog.notice("Tag #%d not on base wire - disabling\n" % len(ordered))
tag.enabled = False
ordered.append(tag)
return ordered
@@ -756,7 +747,7 @@ class ObjectDressup:
return True
def createPath(self, obj, pathData, tags):
#print("createPath")
PathLog.track()
commands = []
lastEdge = 0
lastTag = 0
@@ -776,7 +767,7 @@ class ObjectDressup:
mapper = None
while edge or lastEdge < len(pathData.edges):
debugPrint("------- lastEdge = %d/%d.%d/%d" % (lastEdge, lastTag, t, len(tags)))
PathLog.debug("------- lastEdge = %d/%d.%d/%d" % (lastEdge, lastTag, t, len(tags)))
if not edge:
edge = pathData.edges[lastEdge]
debugEdge(edge, "======= new edge: %d/%d" % (lastEdge, len(pathData.edges)))
@@ -836,19 +827,19 @@ class ObjectDressup:
if tag.enabled:
if prev:
if prev.solid.common(tag.solid).Faces:
FreeCAD.Console.PrintMessage("Tag #%d intersects with previous tag - disabling\n" % i)
debugPrint("this tag = %d [%s]" % (i, tag.solid.BoundBox))
PathLog.notice("Tag #%d intersects with previous tag - disabling\n" % i)
PathLog.debug("this tag = %d [%s]" % (i, tag.solid.BoundBox))
tag.enabled = False
elif self.pathData.edges:
e = self.pathData.edges[0]
p0 = e.valueAt(e.FirstParameter)
p1 = e.valueAt(e.LastParameter)
if tag.solid.isInside(p0, PathGeom.Tolerance, True) or tag.solid.isInside(p1, PathGeom.Tolerance, True):
FreeCAD.Console.PrintMessage("Tag #%d intersects with starting point - disabling\n" % i)
PathLog.notice("Tag #%d intersects with starting point - disabling\n" % i)
tag.enabled = False
if tag.enabled:
prev = tag
debugPrint("previousTag = %d [%s]" % (i, prev))
PathLog.debug("previousTag = %d [%s]" % (i, prev))
else:
disabled.append(i)
tags.append(tag)
@@ -856,6 +847,7 @@ class ObjectDressup:
return (tags, positions, disabled)
def execute(self, obj):
#import cProfile
#pr = cProfile.Profile()
#pr.enable()
self.doExecute(obj)
@@ -881,7 +873,7 @@ class ObjectDressup:
if hasattr(obj, "Positions"):
self.tags, positions, disabled = self.createTagsPositionDisabled(obj, obj.Positions, obj.Disabled)
if obj.Disabled != disabled:
debugPrint("Updating properties.... %s vs. %s" % (obj.Disabled, disabled))
PathLog.debug("Updating properties.... %s vs. %s" % (obj.Disabled, disabled))
obj.Positions = positions
obj.Disabled = disabled
@@ -894,11 +886,11 @@ class ObjectDressup:
def processTags(self, obj):
tagID = 0
if debugDressup:
if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
for tag in self.tags:
tagID += 1
if tag.enabled:
debugPrint("x=%s, y=%s, z=%s" % (tag.x, tag.y, self.pathData.minZ))
PathLog.debug("x=%s, y=%s, z=%s" % (tag.x, tag.y, self.pathData.minZ))
#debugMarker(FreeCAD.Vector(tag.x, tag.y, self.pathData.minZ), "tag-%02d" % tagID , (1.0, 0.0, 1.0), 0.5)
#if tag.angle != 90:
# debugCone(tag.originAt(self.pathData.minZ), tag.r1, tag.r2, tag.actualHeight, "tag-%02d" % tagID)
@@ -906,15 +898,14 @@ class ObjectDressup:
# debugCylinder(tag.originAt(self.pathData.minZ), tag.fullWidth()/2, tag.actualHeight, "tag-%02d" % tagID)
obj.Path = self.createPath(obj, self.pathData, self.tags)
#print("execute - done")
def setup(self, obj, generate=False):
debugPrint("setup")
PathLog.debug("setup")
self.obj = obj
try:
pathData = PathData(obj)
except ValueError:
FreeCAD.Console.PrintError(translate("Cannot insert holding tags for this path - please select a Profile path\n"))
PathLog.error(translate("Cannot insert holding tags for this path - please select a Profile path\n"))
return None
self.toolRadius = 5
@@ -938,7 +929,7 @@ class ObjectDressup:
return self.pathData
def setXyEnabled(self, triples):
debugPrint("setXyEnabled")
PathLog.track()
if not hasattr(self, 'pathData'):
self.setup(self.obj)
positions = []
@@ -1038,7 +1029,7 @@ class TaskPanel:
self.obj.Proxy.setXyEnabled(tags)
def updateTagsView(self):
#print("updateTagsView")
PathLog.track()
self.formTags.lwTags.blockSignals(True)
self.formTags.lwTags.clear()
for i, pos in enumerate(self.obj.Positions):
@@ -1066,7 +1057,7 @@ class TaskPanel:
self.obj.Proxy.execute(self.obj)
self.updateTagsView()
#if debugDressup:
#if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
# # this causes a big of an echo and a double click on the spin buttons, don't know why though
# FreeCAD.ActiveDocument.recompute()
@@ -1359,7 +1350,7 @@ class ViewProviderDressup:
self.tags = tags
def selectTag(self, index):
#print("selectTag(%s)" % index)
PathLog.track(index)
for i, tag in enumerate(self.tags):
tag.setSelected(i == index)
@@ -1401,14 +1392,14 @@ class CommandPathDressupHoldingTags:
# check that the selection contains exactly what we want
selection = FreeCADGui.Selection.getSelection()
if len(selection) != 1:
FreeCAD.Console.PrintError(translate("Please select one path object\n"))
PathLog.error(translate("Please select one path object\n"))
return
baseObject = selection[0]
if not baseObject.isDerivedFrom("Path::Feature"):
FreeCAD.Console.PrintError(translate("The selected object is not a path\n"))
PathLog.error(translate("The selected object is not a path\n"))
return
if baseObject.isDerivedFrom("Path::FeatureCompoundPython"):
FreeCAD.Console.PrintError(translate("Please select a Profile object"))
PathLog.error(translate("Please select a Profile object"))
return
# everything ok!
@@ -1430,4 +1421,4 @@ if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand('PathDressup_HoldingTags', CommandPathDressupHoldingTags())
FreeCAD.Console.PrintLog("Loading PathDressupHoldingTags... done\n")
PathLog.notice("Loading PathDressupHoldingTags... done\n")

View File

@@ -0,0 +1,163 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * *
# * Copyright (c) 2016 sliptonic <shopinthewoods@gmail.com> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
import FreeCAD
import os
import traceback
class Level:
"""Enumeration of log levels, used for setLevel and getLevel."""
RESET = -1
ERROR = 0
WARNING = 1
NOTICE = 2
INFO = 3
DEBUG = 4
_names = { ERROR: 'ERROR', WARNING: 'WARNING', NOTICE: 'NOTICE', INFO: 'INFO', DEBUG: 'DEBUG' }
@classmethod
def toString(cls, level):
return cls._names.get(level, 'UNKNOWN')
_defaultLogLevel = Level.NOTICE
_moduleLogLevel = { }
_useConsole = True
_trackModule = { }
_trackAll = False
def logToConsole(yes):
"""(boolean) - if set to True (default behaviour) log messages are printed to the console. Otherwise they are printed to stdout."""
global _useConsole
_useConsole = yes
def setLevel(level, module = None):
"""(level, module = None)
if no module is specified the default log level is set.
Otherwise the module specific log level is changed (use RESET to clear)."""
global _defaultLogLevel
global _moduleLogLevel
if module:
if level == Level.RESET:
if _moduleLogLevel.get(module, -1) != -1:
del _moduleLogLevel[module]
else:
_moduleLogLevel[module] = level
else:
if level == Level.RESET:
_defaultLogLevel = Level.NOTICE
_moduleLogLevel = { }
else:
_defaultLogLevel = level
def getLevel(module = None):
"""(module = None) - return the global (None) or module specific log level."""
if module:
return _moduleLogLevel.get(module, _defaultLogLevel)
return _defaultLogLevel
def _caller():
"""internal function to determine the calling module."""
file, line, func, text = traceback.extract_stack(limit=3)[0]
return os.path.splitext(os.path.basename(file))[0], line, func
def _log(level, (module, line, func), msg):
"""internal function to do the logging"""
if getLevel(module) >= level:
message = "%s.%s: %s" % (module, Level.toString(level), msg)
if _useConsole:
message += "\n"
if level == Level.NOTICE:
FreeCAD.Console.PrintLog(message)
elif level == Level.WARNING:
FreeCAD.Console.PrintWarning(message)
elif level == Level.ERROR:
FreeCAD.Console.PrintError(message)
else:
FreeCAD.Console.PrintMessage(message)
else:
print(message)
return message
return None
def debug(msg):
"""(message)"""
return _log(Level.DEBUG, _caller(), msg)
def info(msg):
"""(message)"""
return _log(Level.INFO, _caller(), msg)
def notice(msg):
"""(message)"""
return _log(Level.NOTICE, _caller(), msg)
def warning(msg):
"""(message)"""
return _log(Level.WARNING, _caller(), msg)
def error(msg):
"""(message)"""
return _log(Level.ERROR, _caller(), msg)
def trackAllModules(boolean):
"""(boolean) - if True all modules will be tracked, otherwise tracking is up to the module setting."""
global _trackAll
_trackAll = boolean
def untrackAllModules():
"""In addition to stop tracking all modules it also clears the tracking flag for all individual modules."""
global _trackAll
global _trackModule
_trackAll = False
_trackModule = { }
def trackModule(module = None):
"""(module = None) - start tracking given module, current module if not set."""
global _trackModule
if module:
_trackModule[module] = True
else:
mod, line, func = _caller()
_trackModule[mod] = True
def untrackModule(module = None):
"""(module = None) - stop tracking given module, current module if not set."""
global _trackModule
if module and _trackModule.get(module, None):
del _trackModule[module]
elif not module:
mod, line, func = _caller()
if _trackModule.get(mod, None):
del _trackModule[mod]
def track(*args):
"""(....) - call with arguments of current function you want logged if tracking is enabled."""
module, line, func = _caller()
if _trackAll or _trackModule.get(module, None):
message = "%s(%d).%s(%s)" % (module, line, func, ', '.join([str(arg) for arg in args]))
if _useConsole:
FreeCAD.Console.PrintMessage(message + "\n")
else:
print(message)
return message
return None

View File

@@ -0,0 +1,195 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * *
# * Copyright (c) 2016 sliptonic <shopinthewoods@gmail.com> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
import PathScripts.PathLog as PathLog
import unittest
class TestPathLog(unittest.TestCase):
"""Some basic tests for the logging framework."""
MODULE = 'TestPathLog' # file name without extension
def setUp(self):
PathLog.setLevel(PathLog.Level.RESET)
PathLog.untrackAllModules()
def callerFile(self):
return PathLog._caller()[0]
def callerLine(self):
return PathLog._caller()[1]
def callerFunc(self):
return PathLog._caller()[2]
def test00(self):
"""Check for proper module extraction."""
self.assertEqual(self.callerFile(), self.MODULE)
def test01(self):
"""Check for proper function extraction."""
self.assertEqual(self.callerFunc(), 'test01')
def test10(self):
"""Verify default log levels is NOTICE."""
self.assertEqual(PathLog.getLevel(), PathLog.Level.NOTICE)
self.assertEqual(PathLog.getLevel(self.MODULE), PathLog.Level.NOTICE)
def test11(self):
"""Verify setting global log level."""
PathLog.setLevel(PathLog.Level.DEBUG)
self.assertEqual(PathLog.getLevel(), PathLog.Level.DEBUG)
self.assertEqual(PathLog.getLevel(self.MODULE), PathLog.Level.DEBUG)
def test12(self):
"""Verify setting module log level."""
PathLog.setLevel(PathLog.Level.DEBUG, self.MODULE)
self.assertEqual(PathLog.getLevel(), PathLog.Level.NOTICE)
self.assertEqual(PathLog.getLevel(self.MODULE), PathLog.Level.DEBUG)
def test13(self):
"""Verify setting other modul's log level doesn't change this one's."""
# if this test fails then most likely the global RESET is broken
PathLog.setLevel(PathLog.Level.DEBUG, 'SomeOtherModule')
self.assertEqual(PathLog.getLevel(), PathLog.Level.NOTICE)
self.assertEqual(PathLog.getLevel(self.MODULE), PathLog.Level.NOTICE)
def test14(self):
"""Verify resetting log level for module falls back to global level."""
PathLog.setLevel(PathLog.Level.DEBUG, self.MODULE)
self.assertEqual(PathLog.getLevel(self.MODULE), PathLog.Level.DEBUG)
# changing global log level does not affect module
PathLog.setLevel(PathLog.Level.ERROR)
self.assertEqual(PathLog.getLevel(self.MODULE), PathLog.Level.DEBUG)
# resetting module log level restores global log level for module
PathLog.setLevel(PathLog.Level.RESET, self.MODULE)
self.assertEqual(PathLog.getLevel(self.MODULE), PathLog.Level.ERROR)
# changing the global log level will also change the module log level
PathLog.setLevel(PathLog.Level.DEBUG)
self.assertEqual(PathLog.getLevel(self.MODULE), PathLog.Level.DEBUG)
def test20(self):
"""Verify debug logs aren't logged by default."""
self.assertIsNone(PathLog.debug("this"))
def test21(self):
"""Verify debug logs are logged if log level is set to DEBUG."""
PathLog.setLevel(PathLog.Level.DEBUG)
self.assertIsNotNone(PathLog.debug("this"))
def test30(self):
"""Verify log level ERROR."""
PathLog.setLevel(PathLog.Level.ERROR)
self.assertIsNone(PathLog.debug('something'))
self.assertIsNone(PathLog.info('something'))
self.assertIsNone(PathLog.notice('something'))
self.assertIsNone(PathLog.warning('something'))
self.assertIsNotNone(PathLog.error('something'))
def test31(self):
"""Verify log level WARNING."""
PathLog.setLevel(PathLog.Level.WARNING)
self.assertIsNone(PathLog.debug('something'))
self.assertIsNone(PathLog.info('something'))
self.assertIsNone(PathLog.notice('something'))
self.assertIsNotNone(PathLog.warning('something'))
self.assertIsNotNone(PathLog.error('something'))
def test32(self):
"""Verify log level NOTICE."""
PathLog.setLevel(PathLog.Level.NOTICE)
self.assertIsNone(PathLog.debug('something'))
self.assertIsNone(PathLog.info('something'))
self.assertIsNotNone(PathLog.notice('something'))
self.assertIsNotNone(PathLog.warning('something'))
self.assertIsNotNone(PathLog.error('something'))
def test33(self):
"""Verify log level INFO."""
PathLog.setLevel(PathLog.Level.INFO)
self.assertIsNone(PathLog.debug('something'))
self.assertIsNotNone(PathLog.info('something'))
self.assertIsNotNone(PathLog.notice('something'))
self.assertIsNotNone(PathLog.warning('something'))
self.assertIsNotNone(PathLog.error('something'))
def test34(self):
"""Verify log level DEBUG."""
PathLog.setLevel(PathLog.Level.DEBUG)
self.assertIsNotNone(PathLog.debug('something'))
self.assertIsNotNone(PathLog.info('something'))
self.assertIsNotNone(PathLog.notice('something'))
self.assertIsNotNone(PathLog.warning('something'))
self.assertIsNotNone(PathLog.error('something'))
def test50(self):
"""Verify no tracking by default."""
self.assertIsNone(PathLog.track('this', 'and', 'that'))
def test51(self):
"""Verify enabling tracking for module results in tracking."""
PathLog.trackModule()
# Don't want to rely on the line number matching - still want some
# indication that track does the right thing ....
msg = PathLog.track('this', 'and', 'that')
self.assertTrue(msg.startswith(self.MODULE))
self.assertTrue(msg.endswith('test51(this, and, that)'))
def test52(self):
"""Verify untracking stops tracking."""
PathLog.trackModule()
self.assertIsNotNone(PathLog.track('this', 'and', 'that'))
PathLog.untrackModule()
self.assertIsNone(PathLog.track('this', 'and', 'that'))
def test53(self):
"""Verify trackAllModules works correctly."""
PathLog.trackAllModules(True)
self.assertIsNotNone(PathLog.track('this', 'and', 'that'))
PathLog.trackAllModules(False)
self.assertIsNone(PathLog.track('this', 'and', 'that'))
PathLog.trackAllModules(True)
PathLog.trackModule()
self.assertIsNotNone(PathLog.track('this', 'and', 'that'))
PathLog.trackAllModules(False)
self.assertIsNotNone(PathLog.track('this', 'and', 'that'))
def test60(self):
"""Verify track handles no argument."""
PathLog.trackModule()
msg = PathLog.track()
self.assertTrue(msg.startswith(self.MODULE))
self.assertTrue(msg.endswith('test60()'))
def test61(self):
"""Verify track handles arbitrary argument types correctly."""
PathLog.trackModule()
msg = PathLog.track('this', None, 1, 18.25)
self.assertTrue(msg.startswith(self.MODULE))
self.assertTrue(msg.endswith('test61(this, None, 1, 18.25)'))
def testzz(self):
"""Restoring environment after tests."""
PathLog.setLevel(PathLog.Level.RESET)

View File

@@ -74,7 +74,6 @@ class PathPostTestCases(unittest.TestCase):
contour.OffsetExtra = 0.0
contour.Direction = 'CW'
contour.UseComp = True
contour.PlungeAngle = 90.0
PathScripts.PathUtils.addToJob(contour)
PathScripts.PathContour.ObjectContour.setDepths(contour.Proxy, contour)
self.doc.recompute()

View File

@@ -24,10 +24,11 @@
import TestApp
from PathTests.TestPathLog import TestPathLog
from PathTests.TestPathCore import TestPathCore
from PathTests.TestPathPost import PathPostTestCases
from PathTests.TestPathGeom import TestPathGeom
from PathTests.TestPathDepthParams import depthTestCases
from PathTests.TestPathDressupHoldingTags import TestHoldingTags
#from PathTests.TestPathDressupHoldingTags import TestHoldingTags