Updated build script to create win32/linux/macos versions. Fixed the defaults to they work with PLA. Fixed the temperature plugin default "ON" problem. Removed all profiles except for PLA.
166 lines
6.8 KiB
Python
166 lines
6.8 KiB
Python
"""
|
|
Add material to support overhang or remove material at the overhang angle.
|
|
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
#Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
|
|
import __init__
|
|
|
|
from fabmetheus_utilities.geometry.creation import lineation
|
|
from fabmetheus_utilities.geometry.geometry_utilities import evaluate
|
|
from fabmetheus_utilities.vector3 import Vector3
|
|
from fabmetheus_utilities import euclidean
|
|
|
|
__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
|
|
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
|
|
__date__ = '$Date: 2008/02/05 $'
|
|
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
|
|
|
|
|
globalExecutionOrder = 60
|
|
|
|
|
|
def getManipulatedPaths(close, elementNode, loop, prefix, sideLength):
|
|
"Get segment loop."
|
|
if len(loop) < 3:
|
|
return [loop]
|
|
derivation = SegmentDerivation(elementNode, prefix)
|
|
if derivation.path == getSegmentPathDefault():
|
|
return [loop]
|
|
path = getXNormalizedVector3Path(derivation.path)
|
|
if euclidean.getIsWiddershinsByVector3(loop):
|
|
path = path[: : -1]
|
|
for point in path:
|
|
point.x = 1.0 - point.x
|
|
if derivation.center == None:
|
|
point.y = - point.y
|
|
segmentLoop = []
|
|
startEnd = StartEnd(elementNode, len(loop), prefix)
|
|
for pointIndex in xrange(len(loop)):
|
|
if pointIndex >= startEnd.start and pointIndex < startEnd.end:
|
|
segmentLoop += getSegmentPath(derivation.center, loop, path, pointIndex)
|
|
else:
|
|
segmentLoop.append(loop[pointIndex])
|
|
return [euclidean.getLoopWithoutCloseSequentialPoints( close, segmentLoop)]
|
|
|
|
def getNewDerivation(elementNode, prefix, sideLength):
|
|
'Get new derivation.'
|
|
return SegmentDerivation(elementNode, prefix)
|
|
|
|
def getRadialPath(begin, center, end, path):
|
|
"Get radial path."
|
|
beginComplex = begin.dropAxis()
|
|
endComplex = end.dropAxis()
|
|
centerComplex = center.dropAxis()
|
|
beginMinusCenterComplex = beginComplex - centerComplex
|
|
endMinusCenterComplex = endComplex - centerComplex
|
|
beginMinusCenterComplexRadius = abs( beginMinusCenterComplex )
|
|
endMinusCenterComplexRadius = abs( endMinusCenterComplex )
|
|
if beginMinusCenterComplexRadius == 0.0 or endMinusCenterComplexRadius == 0.0:
|
|
return [ begin ]
|
|
beginMinusCenterComplex /= beginMinusCenterComplexRadius
|
|
endMinusCenterComplex /= endMinusCenterComplexRadius
|
|
angleDifference = euclidean.getAngleDifferenceByComplex( endMinusCenterComplex, beginMinusCenterComplex )
|
|
radialPath = []
|
|
for point in path:
|
|
weightEnd = point.x
|
|
weightBegin = 1.0 - weightEnd
|
|
weightedRadius = beginMinusCenterComplexRadius * weightBegin + endMinusCenterComplexRadius * weightEnd * ( 1.0 + point.y )
|
|
radialComplex = weightedRadius * euclidean.getWiddershinsUnitPolar( angleDifference * point.x ) * beginMinusCenterComplex
|
|
polygonPoint = center + Vector3( radialComplex.real, radialComplex.imag, point.z )
|
|
radialPath.append( polygonPoint )
|
|
return radialPath
|
|
|
|
def getSegmentPath(center, loop, path, pointIndex):
|
|
"Get segment path."
|
|
centerBegin = loop[pointIndex]
|
|
centerEnd = loop[(pointIndex + 1) % len(loop)]
|
|
centerEndMinusBegin = centerEnd - centerBegin
|
|
if abs( centerEndMinusBegin ) <= 0.0:
|
|
return [ centerBegin ]
|
|
if center != None:
|
|
return getRadialPath(centerBegin, center, centerEnd, path)
|
|
begin = loop[(pointIndex + len(loop) - 1) % len(loop)]
|
|
end = loop[(pointIndex + 2) % len(loop)]
|
|
return getWedgePath(begin, centerBegin, centerEnd, centerEndMinusBegin, end, path)
|
|
|
|
def getSegmentPathDefault():
|
|
"Get segment path default."
|
|
return [Vector3(), Vector3(0.0, 1.0)]
|
|
|
|
def getWedgePath( begin, centerBegin, centerEnd, centerEndMinusBegin, end, path ):
|
|
"Get segment path."
|
|
beginComplex = begin.dropAxis()
|
|
centerBeginComplex = centerBegin.dropAxis()
|
|
centerEndComplex = centerEnd.dropAxis()
|
|
endComplex = end.dropAxis()
|
|
wedgePath = []
|
|
centerBeginMinusBeginComplex = euclidean.getNormalized( centerBeginComplex - beginComplex )
|
|
centerEndMinusCenterBeginComplexOriginal = centerEndComplex - centerBeginComplex
|
|
centerEndMinusCenterBeginComplexLength = abs( centerEndMinusCenterBeginComplexOriginal )
|
|
if centerEndMinusCenterBeginComplexLength <= 0.0:
|
|
return [ centerBegin ]
|
|
centerEndMinusCenterBeginComplex = centerEndMinusCenterBeginComplexOriginal / centerEndMinusCenterBeginComplexLength
|
|
endMinusCenterEndComplex = euclidean.getNormalized( endComplex - centerEndComplex )
|
|
widdershinsBegin = getWiddershinsAverageByVector3( centerBeginMinusBeginComplex, centerEndMinusCenterBeginComplex )
|
|
widdershinsEnd = getWiddershinsAverageByVector3( centerEndMinusCenterBeginComplex, endMinusCenterEndComplex )
|
|
for point in path:
|
|
weightEnd = point.x
|
|
weightBegin = 1.0 - weightEnd
|
|
polygonPoint = centerBegin + centerEndMinusBegin * point.x
|
|
weightedWiddershins = widdershinsBegin * weightBegin + widdershinsEnd * weightEnd
|
|
polygonPoint += weightedWiddershins * point.y * centerEndMinusCenterBeginComplexLength
|
|
polygonPoint.z += point.z
|
|
wedgePath.append( polygonPoint )
|
|
return wedgePath
|
|
|
|
def getWiddershinsAverageByVector3( centerMinusBeginComplex, endMinusCenterComplex ):
|
|
"Get the normalized average of the widdershins vectors."
|
|
centerMinusBeginWiddershins = Vector3( - centerMinusBeginComplex.imag, centerMinusBeginComplex.real )
|
|
endMinusCenterWiddershins = Vector3( - endMinusCenterComplex.imag, endMinusCenterComplex.real )
|
|
return ( centerMinusBeginWiddershins + endMinusCenterWiddershins ).getNormalized()
|
|
|
|
def getXNormalizedVector3Path(path):
|
|
"Get path where the x ranges from 0 to 1."
|
|
if len(path) < 1:
|
|
return path
|
|
minimumX = path[0].x
|
|
for point in path[1 :]:
|
|
minimumX = min( minimumX, point.x )
|
|
for point in path:
|
|
point.x -= minimumX
|
|
maximumX = path[0].x
|
|
for point in path[1 :]:
|
|
maximumX = max( maximumX, point.x )
|
|
for point in path:
|
|
point.x /= maximumX
|
|
return path
|
|
|
|
def processElementNode(elementNode):
|
|
"Process the xml element."
|
|
lineation.processElementNodeByFunction(elementNode, getManipulatedPaths)
|
|
|
|
|
|
class SegmentDerivation:
|
|
"Class to hold segment variables."
|
|
def __init__(self, elementNode, prefix):
|
|
'Set defaults.'
|
|
self.center = evaluate.getVector3ByPrefix(None, elementNode, prefix + 'center')
|
|
self.path = evaluate.getPathByPrefix(elementNode, getSegmentPathDefault(), prefix)
|
|
|
|
|
|
class StartEnd:
|
|
'Class to get a start through end range.'
|
|
def __init__(self, elementNode, modulo, prefix):
|
|
"Initialize."
|
|
self.start = evaluate.getEvaluatedInt(0, elementNode, prefix + 'start')
|
|
self.extent = evaluate.getEvaluatedInt(modulo - self.start, elementNode, prefix + 'extent')
|
|
self.end = evaluate.getEvaluatedInt(self.start + self.extent, elementNode, prefix + 'end')
|
|
self.revolutions = evaluate.getEvaluatedInt(1, elementNode, prefix + 'revolutions')
|
|
if self.revolutions > 1:
|
|
self.end += modulo * (self.revolutions - 1)
|
|
|
|
def __repr__(self):
|
|
"Get the string representation of this StartEnd."
|
|
return '%s, %s, %s' % (self.start, self.end, self.revolutions)
|