Skip to content

Commit

Permalink
Fixed adaptive length calculation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mlampert committed Nov 13, 2016
1 parent e0a0aa7 commit c58852a
Showing 1 changed file with 44 additions and 26 deletions.
70 changes: 44 additions & 26 deletions src/Mod/Path/PathScripts/DogboneDressup.py
Expand Up @@ -294,23 +294,44 @@ def canAttachDogbone(self, cmd, chord):
def shouldInsertDogbone(self, obj, inChord, outChord):
return outChord.foldsBackOrTurns(inChord, self.theOtherSideOf(obj.Side))

def adaptiveBoneLength(self, obj, inChord, outChord, boneAngle):
inAngle = inChord.getAngleXY()
outAngle = outChord.getAngleXY()
# if the bone is on any of the edges - the corner is tangential
if anglesAreParallel(boneAngle, inAngle) or anglesAreParallel(boneAngle, outAngle):
return self.toolRadius
debugPrint("angle=%.2f in=%.2f out=%.2f" % (boneAngle/math.pi, inAngle/math.pi, outAngle/math.pi))

# TODO: need to figure out if there even is an intersection ...
def cornerDistanceAndAngle(self, obj, inChord, outChord):
baseAngle = inChord.getAngleXY()
turnAngle = outChord.getAngle(inChord)
boneAngle = addAngle(baseAngle, (turnAngle - math.pi)/2)
if obj.Side == Side.Left:
boneAngle = addAngle(boneAngle, math.pi)
#debugPrint("base=%+3.2f turn=%+3.2f bone=%+3.2f" % (baseAngle/math.pi, turnAngle/math.pi, boneAngle/math.pi))
distance = self.toolRadius / math.cos(turnAngle/2)
return (distance, boneAngle)

cornerRelAngle = inChord.getAngle(outChord) / 2
cornerDistance = self.toolRadius / math.cos(cornerRelAngle)
boneRelAngle = addAngle(inAngle, -boneAngle)
# only works if there is an intersection, but if there is no intersection, the bone is screwed up anyway
distance = cornerDistance - self.toolRadius * math.fabs(math.cos(addAngle(cornerRelAngle, boneRelAngle)))
debugPrint("corner=%.2f * %.2f -> bone=%.2f * %.2f" % (cornerDistance, cornerRelAngle, distance, boneRelAngle))
return distance
def adaptiveBoneLength(self, obj, inChord, outChord, boneAngle):
cornerDistance, cornerAngle = self.cornerDistanceAndAngle(obj, inChord, outChord)
if cornerAngle == boneAngle:
# moving directly towards the corner
return cornerDistance - self.toolRadius

# 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.
# In case the math looks questionable, look for "triangle ssa"
# c = cornerDistance
# b = self.toolRadius
# beta = fabs(boneAngle - cornerAngle)
beta = math.fabs(addAngle(boneAngle, -cornerAngle))
D = (cornerDistance / self.toolRadius) * math.sin(beta)
if D > 1: # no intersection
return 0
gamma = math.asin(D)
alpha = math.pi - beta - gamma
boneDistance = self.toolRadius * math.sin(alpha) / math.sin(beta)
if D < 1 and self.toolRadius < cornerDistance: # there exists a second solution
beta2 = beta
gamma2 = math.pi - gamma
alpha2 = math.pi - beta2 - gamma2
boneDistance2 = self.toolRadius * math.sin(alpha2) / math.sin(beta2)
boneDistance = min(boneDistance, boneDistance2)

debugPrint("corner=%.2f * %.2f -> bone=%.2f * %.2f" % (cornerDistance, cornerAngle, boneDistance, boneAngle))
return boneDistance

def smoothChordCommands(self, inChord, outChord, side, smooth):
if smooth == 0:
Expand Down Expand Up @@ -358,6 +379,10 @@ def inOutBoneCommands(self, obj, inChord, outChord, angle, fixedLength, smooth):
if obj.Incision == Incision.Adaptive:
length = self.adaptiveBoneLength(obj, inChord, outChord, angle)

if length == 0:
# no bone after all ..
return [ inChord.g1Command(), outChord.g1Command() ]

x = length * math.cos(angle);
y = length * math.sin(angle);
boneInChord = inChord.moveBy(x, y, 0)
Expand All @@ -372,13 +397,8 @@ def inOutBoneCommands(self, obj, inChord, outChord, angle, fixedLength, smooth):
return bones

def dogboneAngle(self, obj, inChord, outChord):
baseAngle = inChord.getAngleXY()
turnAngle = outChord.getAngle(inChord)
boneAngle = addAngle(baseAngle, (turnAngle - math.pi)/2)
if obj.Side == Side.Left:
boneAngle = addAngle(boneAngle, math.pi)
#debugPrint("base=%+3.2f turn=%+3.2f bone=%+3.2f" % (baseAngle/math.pi, turnAngle/math.pi, boneAngle/math.pi))
return boneAngle
distance, angle = self.cornerDistanceAndAngle(obj, inChord, outChord)
return angle

def dogbone(self, obj, inChord, outChord, smooth):
boneAngle = self.dogboneAngle(obj, inChord, outChord)
Expand Down Expand Up @@ -454,7 +474,7 @@ def insertBone(self, boneId, obj, inChord, outChord, commands, smooth):
enabled = not blacklisted
self.bones.append((boneId, loc, enabled, inaccessible))

if False and debugDogbone and boneId > 5:
if debugDogbone and boneId != 2:
bones = self.boneCommands(obj, False, inChord, outChord, smooth)
else:
bones = self.boneCommands(obj, enabled, inChord, outChord, smooth)
Expand Down Expand Up @@ -649,8 +669,6 @@ def open(self):
# install the function mode resident
FreeCADGui.Selection.addObserver(self.s)

# def getStandardButtons(self):
# return int(QtGui.QDialogButtonBox.OkCancel)

def setupUi(self):
self.setFields()
Expand Down

0 comments on commit c58852a

Please sign in to comment.