Merge branch 'master' of github.com:daid/Cura
This commit is contained in:
commit
7a6b9f367a
22 changed files with 185 additions and 108 deletions
|
@ -30,6 +30,6 @@ def readHex(filename):
|
||||||
elif recType == 2: #Extended Segment Address Record
|
elif recType == 2: #Extended Segment Address Record
|
||||||
extraAddr = int(line[9:13], 16) * 16
|
extraAddr = int(line[9:13], 16) * 16
|
||||||
else:
|
else:
|
||||||
print recType, recLen, addr, checkSum, line
|
print(recType, recLen, addr, checkSum, line)
|
||||||
f.close()
|
f.close()
|
||||||
return data
|
return data
|
|
@ -12,9 +12,9 @@ class IspBase():
|
||||||
raise IspError("Chip with signature: " + str(self.getSignature()) + "not found")
|
raise IspError("Chip with signature: " + str(self.getSignature()) + "not found")
|
||||||
self.chipErase()
|
self.chipErase()
|
||||||
|
|
||||||
print "Flashing %i bytes" % len(flashData)
|
print("Flashing %i bytes" % len(flashData))
|
||||||
self.writeFlash(flashData)
|
self.writeFlash(flashData)
|
||||||
print "Verifying %i bytes" % len(flashData)
|
print("Verifying %i bytes" % len(flashData))
|
||||||
self.verifyFlash(flashData)
|
self.verifyFlash(flashData)
|
||||||
|
|
||||||
#low level ISP commands
|
#low level ISP commands
|
||||||
|
|
|
@ -101,7 +101,7 @@ class Stk500v2(ispBase.IspBase):
|
||||||
raise ispBase.IspError("Timeout")
|
raise ispBase.IspError("Timeout")
|
||||||
b = struct.unpack(">B", s)[0]
|
b = struct.unpack(">B", s)[0]
|
||||||
checksum ^= b
|
checksum ^= b
|
||||||
#print hex(b)
|
#print(hex(b))
|
||||||
if state == 'Start':
|
if state == 'Start':
|
||||||
if b == 0x1B:
|
if b == 0x1B:
|
||||||
state = 'GetSeq'
|
state = 'GetSeq'
|
||||||
|
|
|
@ -115,7 +115,7 @@ def getFilePathsByDirectory(directoryName):
|
||||||
if os.path.dirname(name) == subpath:
|
if os.path.dirname(name) == subpath:
|
||||||
filePaths.append(os.path.join(zipfilename, name))
|
filePaths.append(os.path.join(zipfilename, name))
|
||||||
z.close()
|
z.close()
|
||||||
print directoryName, filePaths
|
print(directoryName, filePaths)
|
||||||
return filePaths
|
return filePaths
|
||||||
|
|
||||||
def getFilePathsRecursively(fileInDirectory=''):
|
def getFilePathsRecursively(fileInDirectory=''):
|
||||||
|
|
|
@ -32,10 +32,15 @@ import __init__
|
||||||
|
|
||||||
from fabmetheus_utilities.vector3 import Vector3
|
from fabmetheus_utilities.vector3 import Vector3
|
||||||
from fabmetheus_utilities import xml_simple_writer
|
from fabmetheus_utilities import xml_simple_writer
|
||||||
import cStringIO
|
|
||||||
|
import sys
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
if sys.version_info.major < 3:
|
||||||
|
import cStringIO
|
||||||
|
else:
|
||||||
|
import io as cStringIO
|
||||||
|
|
||||||
__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
|
__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
|
||||||
__date__ = '$Date: 2008/21/04 $'
|
__date__ = '$Date: 2008/21/04 $'
|
||||||
|
|
|
@ -23,12 +23,16 @@ import __init__
|
||||||
from fabmetheus_utilities.vector3 import Vector3
|
from fabmetheus_utilities.vector3 import Vector3
|
||||||
from fabmetheus_utilities import archive
|
from fabmetheus_utilities import archive
|
||||||
from fabmetheus_utilities import euclidean
|
from fabmetheus_utilities import euclidean
|
||||||
import cStringIO
|
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
if sys.version_info.major < 3:
|
||||||
|
import cStringIO
|
||||||
|
else:
|
||||||
|
import io as cStringIO
|
||||||
|
|
||||||
__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
|
__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
|
||||||
__date__ = '$Date: 2008/21/04 $'
|
__date__ = '$Date: 2008/21/04 $'
|
||||||
|
|
|
@ -25,6 +25,8 @@ def storedSettingInt(name):
|
||||||
return lambda setting: int(profile.getProfileSettingFloat(name))
|
return lambda setting: int(profile.getProfileSettingFloat(name))
|
||||||
def storedPreference(name):
|
def storedPreference(name):
|
||||||
return lambda setting: profile.getPreference(name)
|
return lambda setting: profile.getPreference(name)
|
||||||
|
def storedSettingInvertBoolean(name):
|
||||||
|
return lambda setting: profile.getProfileSetting(name) == "False"
|
||||||
|
|
||||||
def ifSettingAboveZero(name):
|
def ifSettingAboveZero(name):
|
||||||
return lambda setting: profile.getProfileSettingFloat(name) > 0
|
return lambda setting: profile.getProfileSettingFloat(name) > 0
|
||||||
|
@ -376,10 +378,9 @@ def getProfileInformation():
|
||||||
'Filament_Packing_Density_ratio': storedSettingFloat("filament_density"),
|
'Filament_Packing_Density_ratio': storedSettingFloat("filament_density"),
|
||||||
'Maximum_E_Value_before_Reset_float': DEFSET,
|
'Maximum_E_Value_before_Reset_float': DEFSET,
|
||||||
'Minimum_Travel_for_Retraction_millimeters': storedSettingFloat("retraction_min_travel"),
|
'Minimum_Travel_for_Retraction_millimeters': storedSettingFloat("retraction_min_travel"),
|
||||||
'Retract_Within_Island': DEFSET,
|
'Retract_Within_Island': storedSettingInvertBoolean("retract_on_jumps_only"),
|
||||||
'Retraction_Distance_millimeters': storedSettingFloat('retraction_amount'),
|
'Retraction_Distance_millimeters': storedSettingFloat('retraction_amount'),
|
||||||
'Restart_Extra_Distance_millimeters': storedSettingFloat('retraction_extra'),
|
'Restart_Extra_Distance_millimeters': storedSettingFloat('retraction_extra'),
|
||||||
'Only_Retract_On_Jumps': storedSetting("retract_on_jumps_only"),
|
|
||||||
},'alteration': {
|
},'alteration': {
|
||||||
'Activate_Alteration': storedSetting('add_start_end_gcode'),
|
'Activate_Alteration': storedSetting('add_start_end_gcode'),
|
||||||
'Name_of_End_File': "end.gcode",
|
'Name_of_End_File': "end.gcode",
|
||||||
|
@ -414,7 +415,7 @@ def getReadRepository(repository):
|
||||||
|
|
||||||
info = getProfileInformation()
|
info = getProfileInformation()
|
||||||
if not info.has_key(repository.name):
|
if not info.has_key(repository.name):
|
||||||
print "Warning: Plugin: " + repository.name + " missing from Cura info"
|
print("Warning: Plugin: " + repository.name + " missing from Cura info")
|
||||||
return repository
|
return repository
|
||||||
info = info[repository.name]
|
info = info[repository.name]
|
||||||
|
|
||||||
|
@ -422,7 +423,7 @@ def getReadRepository(repository):
|
||||||
for p in repository.preferences:
|
for p in repository.preferences:
|
||||||
name = safeConfigName(p.name)
|
name = safeConfigName(p.name)
|
||||||
if not info.has_key(name):
|
if not info.has_key(name):
|
||||||
print "Setting: " + repository.name + ":" + name + " missing from Cura info"
|
print("Setting: " + repository.name + ":" + name + " missing from Cura info")
|
||||||
continue
|
continue
|
||||||
if isinstance(info[name], types.FunctionType):
|
if isinstance(info[name], types.FunctionType):
|
||||||
p.setValueToString(str(info[name](p)))
|
p.setValueToString(str(info[name](p)))
|
||||||
|
@ -432,11 +433,11 @@ def getReadRepository(repository):
|
||||||
return repository
|
return repository
|
||||||
|
|
||||||
def printProgress(layerIndex, procedureName):
|
def printProgress(layerIndex, procedureName):
|
||||||
print ("Progress[" + procedureName + ":" + str(layerIndex+1) + "]")
|
print("Progress[" + procedureName + ":" + str(layerIndex+1) + "]")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
|
def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
|
||||||
print ("Progress[" + procedureName + ":" + str(layerIndex+1) + ":" + str(numberOfLayers) + "]")
|
print("Progress[" + procedureName + ":" + str(layerIndex+1) + ":" + str(numberOfLayers) + "]")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
def getAlterationFileLines(fileName):
|
def getAlterationFileLines(fileName):
|
||||||
|
|
|
@ -198,7 +198,7 @@ class SVGWriter:
|
||||||
self.setMetadataNoscriptElement('minZ', 'Z: ', self.cornerMinimum.z)
|
self.setMetadataNoscriptElement('minZ', 'Z: ', self.cornerMinimum.z)
|
||||||
self.textHeight = float( self.sliceDictionary['textHeight'] )
|
self.textHeight = float( self.sliceDictionary['textHeight'] )
|
||||||
controlTop = len(loopLayers) * (self.margin + self.extent.y * self.unitScale + self.textHeight) + self.marginTop + self.textHeight
|
controlTop = len(loopLayers) * (self.margin + self.extent.y * self.unitScale + self.textHeight) + self.marginTop + self.textHeight
|
||||||
self.svgElement.getFirstChildByLocalName('title').setTextContent(os.path.basename(fileName) + ' - Slice Layers')
|
self.svgElement.getFirstChildByLocalName('title').setTextContent(os.path.basename(fileName).encode("utf-8") + ' - Slice Layers')
|
||||||
svgElementDictionary['height'] = '%spx' % self.getRounded(max(controlTop, self.controlBoxHeightMargin))
|
svgElementDictionary['height'] = '%spx' % self.getRounded(max(controlTop, self.controlBoxHeightMargin))
|
||||||
width = max(self.extent.x * self.unitScale, svgMinWidth)
|
width = max(self.extent.x * self.unitScale, svgMinWidth)
|
||||||
svgElementDictionary['width'] = '%spx' % self.getRounded( width )
|
svgElementDictionary['width'] = '%spx' % self.getRounded( width )
|
||||||
|
|
|
@ -8,7 +8,12 @@ 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.
|
#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__
|
import __init__
|
||||||
|
|
||||||
import cStringIO
|
import sys
|
||||||
|
|
||||||
|
if sys.version_info.major < 3:
|
||||||
|
import cStringIO
|
||||||
|
else:
|
||||||
|
import io as cStringIO
|
||||||
|
|
||||||
|
|
||||||
__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
|
__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
|
||||||
|
|
|
@ -165,7 +165,6 @@ class DimensionRepository:
|
||||||
self.retractionDistance = settings.FloatSpin().getFromValue( 0.0, 'Retraction Distance (millimeters):', self, 100.0, 0.0 )
|
self.retractionDistance = settings.FloatSpin().getFromValue( 0.0, 'Retraction Distance (millimeters):', self, 100.0, 0.0 )
|
||||||
self.restartExtraDistance = settings.FloatSpin().getFromValue( 0.0, 'Restart Extra Distance (millimeters):', self, 100.0, 0.0 )
|
self.restartExtraDistance = settings.FloatSpin().getFromValue( 0.0, 'Restart Extra Distance (millimeters):', self, 100.0, 0.0 )
|
||||||
self.executeTitle = 'Dimension'
|
self.executeTitle = 'Dimension'
|
||||||
self.onlyRetractOnJumps = settings.BooleanSetting().getFromValue('Only Retract On Jumps', self, True )
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
'Dimension button has been clicked.'
|
'Dimension button has been clicked.'
|
||||||
|
@ -194,7 +193,6 @@ class DimensionSkein:
|
||||||
self.zDistanceRatio = 5.0
|
self.zDistanceRatio = 5.0
|
||||||
self.addRetraction = True
|
self.addRetraction = True
|
||||||
self.reverseRetraction = False
|
self.reverseRetraction = False
|
||||||
self.onlyRetractOnJumps = True
|
|
||||||
|
|
||||||
def addLinearMoveExtrusionDistanceLine(self, extrusionDistance):
|
def addLinearMoveExtrusionDistanceLine(self, extrusionDistance):
|
||||||
'Get the extrusion distance string from the extrusion distance.'
|
'Get the extrusion distance string from the extrusion distance.'
|
||||||
|
@ -206,7 +204,6 @@ class DimensionSkein:
|
||||||
def getCraftedGcode(self, gcodeText, repository):
|
def getCraftedGcode(self, gcodeText, repository):
|
||||||
'Parse gcode text and store the dimension gcode.'
|
'Parse gcode text and store the dimension gcode.'
|
||||||
self.repository = repository
|
self.repository = repository
|
||||||
self.onlyRetractOnJumps = repository.onlyRetractOnJumps.value
|
|
||||||
filamentRadius = 0.5 * repository.filamentDiameter.value
|
filamentRadius = 0.5 * repository.filamentDiameter.value
|
||||||
filamentPackingArea = math.pi * filamentRadius * filamentRadius * repository.filamentPackingDensity.value
|
filamentPackingArea = math.pi * filamentRadius * filamentRadius * repository.filamentPackingDensity.value
|
||||||
self.minimumTravelForRetraction = self.repository.minimumTravelForRetraction.value
|
self.minimumTravelForRetraction = self.repository.minimumTravelForRetraction.value
|
||||||
|
@ -264,7 +261,7 @@ class DimensionSkein:
|
||||||
if isActive:
|
if isActive:
|
||||||
if not self.repository.retractWithinIsland.value:
|
if not self.repository.retractWithinIsland.value:
|
||||||
locationEnclosureIndex = self.getSmallestEnclosureIndex(location.dropAxis())
|
locationEnclosureIndex = self.getSmallestEnclosureIndex(location.dropAxis())
|
||||||
if locationEnclosureIndex != self.getSmallestEnclosureIndex(self.oldLocation.dropAxis()):
|
if locationEnclosureIndex == self.getSmallestEnclosureIndex(self.oldLocation.dropAxis()):
|
||||||
return None
|
return None
|
||||||
locationMinusOld = location - self.oldLocation
|
locationMinusOld = location - self.oldLocation
|
||||||
xyTravel = abs(locationMinusOld.dropAxis())
|
xyTravel = abs(locationMinusOld.dropAxis())
|
||||||
|
@ -306,7 +303,7 @@ class DimensionSkein:
|
||||||
'Get the retraction ratio.'
|
'Get the retraction ratio.'
|
||||||
distanceToNextThread = self.getDistanceToNextThread(lineIndex)
|
distanceToNextThread = self.getDistanceToNextThread(lineIndex)
|
||||||
if distanceToNextThread == None:
|
if distanceToNextThread == None:
|
||||||
return 1.0
|
return 0.0
|
||||||
if distanceToNextThread >= self.doubleMinimumTravelForRetraction:
|
if distanceToNextThread >= self.doubleMinimumTravelForRetraction:
|
||||||
return 1.0
|
return 1.0
|
||||||
if distanceToNextThread <= self.minimumTravelForRetraction:
|
if distanceToNextThread <= self.minimumTravelForRetraction:
|
||||||
|
@ -384,15 +381,6 @@ class DimensionSkein:
|
||||||
self.absoluteDistanceMode = True
|
self.absoluteDistanceMode = True
|
||||||
elif firstWord == 'G91':
|
elif firstWord == 'G91':
|
||||||
self.absoluteDistanceMode = False
|
self.absoluteDistanceMode = False
|
||||||
elif firstWord == '(<nestedRing>)':
|
|
||||||
if self.onlyRetractOnJumps:
|
|
||||||
self.addRetraction = False
|
|
||||||
elif firstWord == '(</nestedRing>)':
|
|
||||||
if self.onlyRetractOnJumps:
|
|
||||||
self.addRetraction = True
|
|
||||||
self.retractionRatio = self.getRetractionRatio(lineIndex)
|
|
||||||
self.addLinearMoveExtrusionDistanceLine(-self.repository.retractionDistance.value * self.retractionRatio)
|
|
||||||
self.reverseRetraction = True
|
|
||||||
elif firstWord == '(<layer>':
|
elif firstWord == '(<layer>':
|
||||||
self.layerIndex += 1
|
self.layerIndex += 1
|
||||||
settings.printProgress(self.layerIndex, 'dimension')
|
settings.printProgress(self.layerIndex, 'dimension')
|
||||||
|
@ -401,9 +389,8 @@ class DimensionSkein:
|
||||||
self.distanceFeedRate.addLine('G92 E0')
|
self.distanceFeedRate.addLine('G92 E0')
|
||||||
self.totalExtrusionDistance = 0.0
|
self.totalExtrusionDistance = 0.0
|
||||||
elif firstWord == 'M101':
|
elif firstWord == 'M101':
|
||||||
if self.reverseRetraction:
|
if self.retractionRatio > 0.0:
|
||||||
self.addLinearMoveExtrusionDistanceLine(self.restartDistance * self.retractionRatio)
|
self.addLinearMoveExtrusionDistanceLine(self.restartDistance * self.retractionRatio)
|
||||||
self.reverseRetraction = False
|
|
||||||
if self.totalExtrusionDistance > self.repository.maximumEValueBeforeReset.value:
|
if self.totalExtrusionDistance > self.repository.maximumEValueBeforeReset.value:
|
||||||
if not self.repository.relativeExtrusionDistance.value:
|
if not self.repository.relativeExtrusionDistance.value:
|
||||||
self.distanceFeedRate.addLine('G92 E0')
|
self.distanceFeedRate.addLine('G92 E0')
|
||||||
|
@ -411,9 +398,8 @@ class DimensionSkein:
|
||||||
self.isExtruderActive = True
|
self.isExtruderActive = True
|
||||||
elif firstWord == 'M103':
|
elif firstWord == 'M103':
|
||||||
self.retractionRatio = self.getRetractionRatio(lineIndex)
|
self.retractionRatio = self.getRetractionRatio(lineIndex)
|
||||||
if self.addRetraction:
|
if self.retractionRatio > 0.0:
|
||||||
self.addLinearMoveExtrusionDistanceLine(-self.repository.retractionDistance.value * self.retractionRatio)
|
self.addLinearMoveExtrusionDistanceLine(-self.repository.retractionDistance.value * self.retractionRatio)
|
||||||
self.reverseRetraction = True
|
|
||||||
self.isExtruderActive = False
|
self.isExtruderActive = False
|
||||||
elif firstWord == 'M108':
|
elif firstWord == 'M108':
|
||||||
self.flowRate = float( splitLine[1][1 :] )
|
self.flowRate = float( splitLine[1][1 :] )
|
||||||
|
|
|
@ -68,7 +68,9 @@ class expertConfigWindow(configBase.configWindowBase):
|
||||||
configBase.TitleRow(right, "Dwindle")
|
configBase.TitleRow(right, "Dwindle")
|
||||||
c = configBase.SettingRow(right, "Enable dwindle", 'enable_dwindle', False, 'Dwindle is used to slow down near the end of a printed line, and reducing the amount of filament printed near the end. This to release the preasure on the printer head.')
|
c = configBase.SettingRow(right, "Enable dwindle", 'enable_dwindle', False, 'Dwindle is used to slow down near the end of a printed line, and reducing the amount of filament printed near the end. This to release the preasure on the printer head.')
|
||||||
c = configBase.SettingRow(right, "Pent up volume (mm3)", 'dwindle_pent_up_volume', '0.4', 'Amount of plastic inside the nozzle under pressure. This normally comes out as ooze after printing.')
|
c = configBase.SettingRow(right, "Pent up volume (mm3)", 'dwindle_pent_up_volume', '0.4', 'Amount of plastic inside the nozzle under pressure. This normally comes out as ooze after printing.')
|
||||||
|
validators.validFloat(c, 0.0001)
|
||||||
c = configBase.SettingRow(right, "Slow down volume (mm3)", 'dwindle_slowdown_volume', '5.0', 'Amount of printing volume that is used to slow down to release the pressure.')
|
c = configBase.SettingRow(right, "Slow down volume (mm3)", 'dwindle_slowdown_volume', '5.0', 'Amount of printing volume that is used to slow down to release the pressure.')
|
||||||
|
validators.validFloat(c, 0.0001)
|
||||||
|
|
||||||
main.Fit()
|
main.Fit()
|
||||||
self.Fit()
|
self.Fit()
|
||||||
|
|
|
@ -234,6 +234,7 @@ class previewPanel(wx.Panel):
|
||||||
obj.dirty = False
|
obj.dirty = False
|
||||||
obj.mesh = mesh
|
obj.mesh = mesh
|
||||||
self.updateModelTransform()
|
self.updateModelTransform()
|
||||||
|
self.errorList = []
|
||||||
wx.CallAfter(self.updateToolbar)
|
wx.CallAfter(self.updateToolbar)
|
||||||
wx.CallAfter(self.glCanvas.Refresh)
|
wx.CallAfter(self.glCanvas.Refresh)
|
||||||
|
|
||||||
|
@ -243,7 +244,6 @@ class previewPanel(wx.Panel):
|
||||||
gcode.progressCallback = self.loadProgress
|
gcode.progressCallback = self.loadProgress
|
||||||
gcode.load(self.gcodeFilename)
|
gcode.load(self.gcodeFilename)
|
||||||
self.gcodeDirty = False
|
self.gcodeDirty = False
|
||||||
self.errorList = []
|
|
||||||
self.gcode = gcode
|
self.gcode = gcode
|
||||||
self.gcodeDirty = True
|
self.gcodeDirty = True
|
||||||
wx.CallAfter(self.updateToolbar)
|
wx.CallAfter(self.updateToolbar)
|
||||||
|
@ -455,6 +455,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0]);
|
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0]);
|
||||||
|
|
||||||
glColor3f(1.0,1.0,1.0)
|
glColor3f(1.0,1.0,1.0)
|
||||||
|
glPushMatrix()
|
||||||
glTranslate(self.parent.machineCenter.x, self.parent.machineCenter.y, 0)
|
glTranslate(self.parent.machineCenter.x, self.parent.machineCenter.y, 0)
|
||||||
for obj in self.parent.objectList:
|
for obj in self.parent.objectList:
|
||||||
if obj.mesh == None:
|
if obj.mesh == None:
|
||||||
|
@ -530,6 +531,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||||
glEnable(GL_LIGHTING)
|
glEnable(GL_LIGHTING)
|
||||||
self.drawModel(obj)
|
self.drawModel(obj)
|
||||||
|
|
||||||
|
glPopMatrix()
|
||||||
if self.viewMode == "Normal" or self.viewMode == "Transparent" or self.viewMode == "X-Ray":
|
if self.viewMode == "Normal" or self.viewMode == "Transparent" or self.viewMode == "X-Ray":
|
||||||
glDisable(GL_LIGHTING)
|
glDisable(GL_LIGHTING)
|
||||||
glDisable(GL_DEPTH_TEST)
|
glDisable(GL_DEPTH_TEST)
|
||||||
|
|
|
@ -25,6 +25,7 @@ from gui import printWindow
|
||||||
from util import profile
|
from util import profile
|
||||||
from util import util3d
|
from util import util3d
|
||||||
from util import stl
|
from util import stl
|
||||||
|
from util import mesh
|
||||||
from util import sliceRun
|
from util import sliceRun
|
||||||
from util import gcodeInterpreter
|
from util import gcodeInterpreter
|
||||||
from util import exporer
|
from util import exporer
|
||||||
|
@ -137,6 +138,7 @@ class projectPlanner(wx.Frame):
|
||||||
|
|
||||||
self.list = []
|
self.list = []
|
||||||
self.selection = None
|
self.selection = None
|
||||||
|
self.printMode = 0
|
||||||
|
|
||||||
self.machineSize = util3d.Vector3(profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height'))
|
self.machineSize = util3d.Vector3(profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height'))
|
||||||
self.headSizeMin = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0)
|
self.headSizeMin = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0)
|
||||||
|
@ -160,6 +162,11 @@ class projectPlanner(wx.Frame):
|
||||||
toolbarUtil.NormalButton(self.toolbar, self.OnPreferences, 'preferences.png', 'Project planner preferences')
|
toolbarUtil.NormalButton(self.toolbar, self.OnPreferences, 'preferences.png', 'Project planner preferences')
|
||||||
self.toolbar.AddSeparator()
|
self.toolbar.AddSeparator()
|
||||||
toolbarUtil.NormalButton(self.toolbar, self.OnCutMesh, 'cut-mesh.png', 'Cut a plate STL into multiple STL files, and add those files to the project.\nNote: Splitting up plates sometimes takes a few minutes.')
|
toolbarUtil.NormalButton(self.toolbar, self.OnCutMesh, 'cut-mesh.png', 'Cut a plate STL into multiple STL files, and add those files to the project.\nNote: Splitting up plates sometimes takes a few minutes.')
|
||||||
|
toolbarUtil.NormalButton(self.toolbar, self.OnSaveCombinedSTL, 'save-combination.png', 'Save all the combined STL files into a single STL file as a plate.')
|
||||||
|
self.toolbar.AddSeparator()
|
||||||
|
group = []
|
||||||
|
self.printOneAtATime = toolbarUtil.RadioButton(self.toolbar, group, 'view-normal-on.png', 'view-normal-off.png', 'Print one object at a time', callback=self.OnPrintTypeChange)
|
||||||
|
self.printAllAtOnce = toolbarUtil.RadioButton(self.toolbar, group, 'all-at-once-on.png', 'all-at-once-off.png', 'Print all the objects at once', callback=self.OnPrintTypeChange)
|
||||||
self.toolbar.AddSeparator()
|
self.toolbar.AddSeparator()
|
||||||
toolbarUtil.NormalButton(self.toolbar, self.OnQuit, 'exit.png', 'Close project planner')
|
toolbarUtil.NormalButton(self.toolbar, self.OnQuit, 'exit.png', 'Close project planner')
|
||||||
|
|
||||||
|
@ -271,6 +278,27 @@ class projectPlanner(wx.Frame):
|
||||||
self.preview.Refresh()
|
self.preview.Refresh()
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def OnPrintTypeChange(self):
|
||||||
|
self.printMode = 0
|
||||||
|
if self.printAllAtOnce.GetValue():
|
||||||
|
self.printMode = 1
|
||||||
|
self.preview.Refresh()
|
||||||
|
|
||||||
|
def OnSaveCombinedSTL(self, e):
|
||||||
|
dlg=wx.FileDialog(self, "Save as STL", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
|
||||||
|
dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
self._saveCombinedSTL(dlg.GetPath())
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def _saveCombinedSTL(filename):
|
||||||
|
output = mesh.mesh()
|
||||||
|
for item in self.list:
|
||||||
|
offset = util3d.Vector3(item.centerX, item.centerY, 0)
|
||||||
|
for f in item.faces:
|
||||||
|
output.addFace(f.v[0] * item.scale + offset, f.v[1] * item.scale + offset, f.v[2] * item.scale + offset)
|
||||||
|
stl.saveAsSTL(output, filename)
|
||||||
|
|
||||||
def OnSaveProject(self, e):
|
def OnSaveProject(self, e):
|
||||||
dlg=wx.FileDialog(self, "Save project file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
|
dlg=wx.FileDialog(self, "Save project file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
|
||||||
dlg.SetWildcard("Project files (*.curaproject)|*.curaproject")
|
dlg.SetWildcard("Project files (*.curaproject)|*.curaproject")
|
||||||
|
@ -472,6 +500,10 @@ class projectPlanner(wx.Frame):
|
||||||
extraSizeMin = extraSizeMin + util3d.Vector3(3.0, 0, 0)
|
extraSizeMin = extraSizeMin + util3d.Vector3(3.0, 0, 0)
|
||||||
extraSizeMax = extraSizeMax + util3d.Vector3(3.0, 0, 0)
|
extraSizeMax = extraSizeMax + util3d.Vector3(3.0, 0, 0)
|
||||||
|
|
||||||
|
if self.printMode == 1:
|
||||||
|
extraSizeMin = util3d.Vector3(6.0, 6.0, 0)
|
||||||
|
extraSizeMax = util3d.Vector3(6.0, 6.0, 0)
|
||||||
|
|
||||||
if extraSizeMin.x > extraSizeMax.x:
|
if extraSizeMin.x > extraSizeMax.x:
|
||||||
posX = self.machineSize.x
|
posX = self.machineSize.x
|
||||||
dirX = -1
|
dirX = -1
|
||||||
|
@ -515,14 +547,21 @@ class projectPlanner(wx.Frame):
|
||||||
return (maxX - minX) + (maxY - minY)
|
return (maxX - minX) + (maxY - minY)
|
||||||
|
|
||||||
def OnSlice(self, e):
|
def OnSlice(self, e):
|
||||||
|
dlg=wx.FileDialog(self, "Save project gcode file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
|
||||||
|
dlg.SetWildcard("GCode file (*.gcode)|*.gcode")
|
||||||
|
if dlg.ShowModal() != wx.ID_OK:
|
||||||
|
dlg.Destroy()
|
||||||
|
return
|
||||||
|
resultFilename = dlg.GetPath()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
put = profile.setTempOverride
|
put = profile.setTempOverride
|
||||||
oldProfile = profile.getGlobalProfileString()
|
oldProfile = profile.getGlobalProfileString()
|
||||||
|
|
||||||
put('model_multiply_x', '1')
|
|
||||||
put('model_multiply_y', '1')
|
|
||||||
put('enable_raft', 'False')
|
|
||||||
put('add_start_end_gcode', 'False')
|
put('add_start_end_gcode', 'False')
|
||||||
put('gcode_extension', 'project_tmp')
|
put('gcode_extension', 'project_tmp')
|
||||||
|
if self.printMode == 0:
|
||||||
|
put('enable_raft', 'False')
|
||||||
|
|
||||||
clearZ = 0
|
clearZ = 0
|
||||||
actionList = []
|
actionList = []
|
||||||
|
@ -558,17 +597,31 @@ class projectPlanner(wx.Frame):
|
||||||
if item.profile != None:
|
if item.profile != None:
|
||||||
profile.loadGlobalProfileFromString(oldProfile)
|
profile.loadGlobalProfileFromString(oldProfile)
|
||||||
|
|
||||||
|
else:
|
||||||
|
self._saveCombinedSTL(resultFilename + "_temp_.stl")
|
||||||
|
put('model_scale', 1.0)
|
||||||
|
put('flip_x', False)
|
||||||
|
put('flip_y', False)
|
||||||
|
put('flip_z', False)
|
||||||
|
put('model_rotate_base', 0)
|
||||||
|
put('swap_xz', False)
|
||||||
|
put('swap_yz', False)
|
||||||
|
actionList = []
|
||||||
|
|
||||||
|
action = Action()
|
||||||
|
action.sliceCmd = sliceRun.getSliceCommand(resultFilename + "_temp_.stl")
|
||||||
|
action.centerX = profile.getProfileSettingFloat('machine_center_x')
|
||||||
|
action.centerY = profile.getProfileSettingFloat('machine_center_y')
|
||||||
|
action.extruder = 0
|
||||||
|
action.filename = resultFilename + "_temp_.stl"
|
||||||
|
action.clearZ = 0
|
||||||
|
action.leaveResultForNextSlice = False
|
||||||
|
action.usePreviousSlice = False
|
||||||
|
actionList.append(action)
|
||||||
|
|
||||||
#Restore the old profile.
|
#Restore the old profile.
|
||||||
profile.resetTempOverride()
|
profile.resetTempOverride()
|
||||||
|
|
||||||
dlg=wx.FileDialog(self, "Save project gcode file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
|
|
||||||
dlg.SetWildcard("GCode file (*.gcode)|*.gcode")
|
|
||||||
if dlg.ShowModal() != wx.ID_OK:
|
|
||||||
dlg.Destroy()
|
|
||||||
return
|
|
||||||
resultFilename = dlg.GetPath()
|
|
||||||
dlg.Destroy()
|
|
||||||
|
|
||||||
pspw = ProjectSliceProgressWindow(actionList, resultFilename)
|
pspw = ProjectSliceProgressWindow(actionList, resultFilename)
|
||||||
pspw.extruderOffset = self.extruderOffset
|
pspw.extruderOffset = self.extruderOffset
|
||||||
pspw.Centre()
|
pspw.Centre()
|
||||||
|
@ -702,6 +755,13 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||||
skirtSize = profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')
|
skirtSize = profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')
|
||||||
extraSizeMin = extraSizeMin + util3d.Vector3(skirtSize, skirtSize, 0)
|
extraSizeMin = extraSizeMin + util3d.Vector3(skirtSize, skirtSize, 0)
|
||||||
extraSizeMax = extraSizeMax + util3d.Vector3(skirtSize, skirtSize, 0)
|
extraSizeMax = extraSizeMax + util3d.Vector3(skirtSize, skirtSize, 0)
|
||||||
|
if profile.getProfileSetting('support') != 'None':
|
||||||
|
extraSizeMin = extraSizeMin + util3d.Vector3(3.0, 0, 0)
|
||||||
|
extraSizeMax = extraSizeMax + util3d.Vector3(3.0, 0, 0)
|
||||||
|
|
||||||
|
if self.parent.printMode == 1:
|
||||||
|
extraSizeMin = util3d.Vector3(6.0, 6.0, 0)
|
||||||
|
extraSizeMax = util3d.Vector3(6.0, 6.0, 0)
|
||||||
|
|
||||||
for item in self.parent.list:
|
for item in self.parent.list:
|
||||||
item.validPlacement = True
|
item.validPlacement = True
|
||||||
|
|
|
@ -192,7 +192,7 @@ class simpleModeWindow(configBase.configWindowBase):
|
||||||
put('bottom_layer_speed', '25')
|
put('bottom_layer_speed', '25')
|
||||||
put('cool_min_layer_time', '10')
|
put('cool_min_layer_time', '10')
|
||||||
put('fan_enabled', 'True')
|
put('fan_enabled', 'True')
|
||||||
put('fan_layer', '0')
|
put('fan_layer', '1')
|
||||||
put('fan_speed', '100')
|
put('fan_speed', '100')
|
||||||
#put('model_scale', '1.0')
|
#put('model_scale', '1.0')
|
||||||
#put('flip_x', 'False')
|
#put('flip_x', 'False')
|
||||||
|
|
|
@ -40,7 +40,7 @@ class sliceProgessPanel(wx.Panel):
|
||||||
cmdList = []
|
cmdList = []
|
||||||
for filename in self.filelist:
|
for filename in self.filelist:
|
||||||
idx = self.filelist.index(filename)
|
idx = self.filelist.index(filename)
|
||||||
print filename, idx
|
#print filename, idx
|
||||||
if idx > 0:
|
if idx > 0:
|
||||||
profile.setTempOverride('fan_enabled', 'False')
|
profile.setTempOverride('fan_enabled', 'False')
|
||||||
profile.setTempOverride('skirt_line_count', '0')
|
profile.setTempOverride('skirt_line_count', '0')
|
||||||
|
|
BIN
Cura/images/save-combination.png
Normal file
BIN
Cura/images/save-combination.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 865 B |
|
@ -3,7 +3,11 @@ from __future__ import division
|
||||||
#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.
|
#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__
|
import __init__
|
||||||
|
|
||||||
import ConfigParser, os, traceback, math, re, zlib, base64, time, sys
|
import os, traceback, math, re, zlib, base64, time, sys
|
||||||
|
if sys.version_info.major < 3:
|
||||||
|
import ConfigParser
|
||||||
|
else:
|
||||||
|
import configparser as ConfigParser
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
## Default settings when none are found.
|
## Default settings when none are found.
|
||||||
|
@ -247,13 +251,13 @@ def getProfileSetting(name):
|
||||||
if name in profileDefaultSettings:
|
if name in profileDefaultSettings:
|
||||||
default = profileDefaultSettings[name]
|
default = profileDefaultSettings[name]
|
||||||
else:
|
else:
|
||||||
print "Missing default setting for: '" + name + "'"
|
print("Missing default setting for: '" + name + "'")
|
||||||
profileDefaultSettings[name] = ''
|
profileDefaultSettings[name] = ''
|
||||||
default = ''
|
default = ''
|
||||||
if not globalProfileParser.has_section('profile'):
|
if not globalProfileParser.has_section('profile'):
|
||||||
globalProfileParser.add_section('profile')
|
globalProfileParser.add_section('profile')
|
||||||
globalProfileParser.set('profile', name, str(default))
|
globalProfileParser.set('profile', name, str(default))
|
||||||
#print name + " not found in profile, so using default: " + str(default)
|
#print(name + " not found in profile, so using default: " + str(default))
|
||||||
return default
|
return default
|
||||||
return globalProfileParser.get('profile', name)
|
return globalProfileParser.get('profile', name)
|
||||||
|
|
||||||
|
@ -304,13 +308,13 @@ def getPreference(name):
|
||||||
if name in preferencesDefaultSettings:
|
if name in preferencesDefaultSettings:
|
||||||
default = preferencesDefaultSettings[name]
|
default = preferencesDefaultSettings[name]
|
||||||
else:
|
else:
|
||||||
print "Missing default setting for: '" + name + "'"
|
print("Missing default setting for: '" + name + "'")
|
||||||
preferencesDefaultSettings[name] = ''
|
preferencesDefaultSettings[name] = ''
|
||||||
default = ''
|
default = ''
|
||||||
if not globalPreferenceParser.has_section('preference'):
|
if not globalPreferenceParser.has_section('preference'):
|
||||||
globalPreferenceParser.add_section('preference')
|
globalPreferenceParser.add_section('preference')
|
||||||
globalPreferenceParser.set('preference', name, str(default))
|
globalPreferenceParser.set('preference', name, str(default))
|
||||||
#print name + " not found in preferences, so using default: " + str(default)
|
#print(name + " not found in preferences, so using default: " + str(default))
|
||||||
return default
|
return default
|
||||||
return unicode(globalPreferenceParser.get('preference', name), "utf-8")
|
return unicode(globalPreferenceParser.get('preference', name), "utf-8")
|
||||||
|
|
||||||
|
@ -406,12 +410,12 @@ def getAlterationFile(filename):
|
||||||
if filename in alterationDefault:
|
if filename in alterationDefault:
|
||||||
default = alterationDefault[filename]
|
default = alterationDefault[filename]
|
||||||
else:
|
else:
|
||||||
print "Missing default alteration for: '" + filename + "'"
|
print("Missing default alteration for: '" + filename + "'")
|
||||||
alterationDefault[filename] = ''
|
alterationDefault[filename] = ''
|
||||||
default = ''
|
default = ''
|
||||||
if not globalProfileParser.has_section('alterations'):
|
if not globalProfileParser.has_section('alterations'):
|
||||||
globalProfileParser.add_section('alterations')
|
globalProfileParser.add_section('alterations')
|
||||||
#print "Using default for: %s" % (filename)
|
#print("Using default for: %s" % (filename))
|
||||||
globalProfileParser.set('alterations', filename, default)
|
globalProfileParser.set('alterations', filename, default)
|
||||||
return unicode(globalProfileParser.get('alterations', filename), "utf-8")
|
return unicode(globalProfileParser.get('alterations', filename), "utf-8")
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ sliceStepTimeFactor = {
|
||||||
}
|
}
|
||||||
|
|
||||||
totalRunTimeFactor = 0
|
totalRunTimeFactor = 0
|
||||||
for v in sliceStepTimeFactor.itervalues():
|
for v in sliceStepTimeFactor.values():
|
||||||
totalRunTimeFactor += v
|
totalRunTimeFactor += v
|
||||||
|
|
||||||
def getPyPyExe():
|
def getPyPyExe():
|
||||||
|
@ -75,22 +75,24 @@ def runSlice(fileNames):
|
||||||
"Run the slicer on the files. If we are running with PyPy then just do the slicing action. If we are running as Python, try to find pypy."
|
"Run the slicer on the files. If we are running with PyPy then just do the slicing action. If we are running as Python, try to find pypy."
|
||||||
pypyExe = getPyPyExe()
|
pypyExe = getPyPyExe()
|
||||||
for fileName in fileNames:
|
for fileName in fileNames:
|
||||||
|
if fileName.startswith("#UTF8#"):
|
||||||
|
fileName = unicode(fileName[6:], "utf-8")
|
||||||
if platform.python_implementation() == "PyPy":
|
if platform.python_implementation() == "PyPy":
|
||||||
skeinforge_craft.writeOutput(fileName)
|
skeinforge_craft.writeOutput(fileName)
|
||||||
elif pypyExe == False:
|
elif pypyExe == False:
|
||||||
if not hasattr(sys, 'frozen'):
|
if not hasattr(sys, 'frozen'):
|
||||||
print "************************************************"
|
print("************************************************")
|
||||||
print "* Failed to find pypy, so slicing with python! *"
|
print("* Failed to find pypy, so slicing with python! *")
|
||||||
print "************************************************"
|
print("************************************************")
|
||||||
skeinforge_craft.writeOutput(fileName)
|
skeinforge_craft.writeOutput(fileName)
|
||||||
print "************************************************"
|
print("************************************************")
|
||||||
print "* Failed to find pypy, so sliced with python! *"
|
print("* Failed to find pypy, so sliced with python! *")
|
||||||
print "************************************************"
|
print("************************************************")
|
||||||
else:
|
else:
|
||||||
print "******************************************************************"
|
print("******************************************************************")
|
||||||
print "* Failed to find pypy, we need pypy to slice with a frozen build *"
|
print("* Failed to find pypy, we need pypy to slice with a frozen build *")
|
||||||
print "* Place pypy in the same directory as Cura so Cura can find it. *"
|
print("* Place pypy in the same directory as Cura so Cura can find it. *")
|
||||||
print "******************************************************************"
|
print("******************************************************************")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
subprocess.call(getSliceCommand(fileName))
|
subprocess.call(getSliceCommand(fileName))
|
||||||
|
@ -161,6 +163,12 @@ def getSliceCommand(filename):
|
||||||
else:
|
else:
|
||||||
mainScriptFile = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", os.path.split(sys.argv[0])[1]))
|
mainScriptFile = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", os.path.split(sys.argv[0])[1]))
|
||||||
cmd = [pypyExe, mainScriptFile, '-p', profile.getGlobalProfileString()]
|
cmd = [pypyExe, mainScriptFile, '-p', profile.getGlobalProfileString()]
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
try:
|
||||||
|
cmd.append(str(filename))
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
cmd.append("#UTF8#" + filename.encode("utf-8"))
|
||||||
|
else:
|
||||||
cmd.append(filename)
|
cmd.append(filename)
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ def saveAsSTL(mesh, filename):
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
for filename in sys.argv[1:]:
|
for filename in sys.argv[1:]:
|
||||||
m = stlModel().load(filename)
|
m = stlModel().load(filename)
|
||||||
print "Loaded %d faces" % (len(m.faces))
|
print("Loaded %d faces" % (len(m.faces)))
|
||||||
parts = m.splitToParts()
|
parts = m.splitToParts()
|
||||||
for p in parts:
|
for p in parts:
|
||||||
saveAsSTL(p, "export_%i.stl" % parts.index(p))
|
saveAsSTL(p, "export_%i.stl" % parts.index(p))
|
||||||
|
|
|
@ -92,7 +92,7 @@ def processPath(e):
|
||||||
curPath = [p]
|
curPath = [p]
|
||||||
paths.append(curPath)
|
paths.append(curPath)
|
||||||
i = 0
|
i = 0
|
||||||
print param
|
print(param)
|
||||||
while i < len(param):
|
while i < len(param):
|
||||||
endPoint = p + complex(param[i+5], -param[i+6])
|
endPoint = p + complex(param[i+5], -param[i+6])
|
||||||
addArc(curPath, p, endPoint, complex(param[i], param[i+1]), param[i+2], param[i+3], param[i+4])
|
addArc(curPath, p, endPoint, complex(param[i], param[i+1]), param[i+2], param[i+3], param[i+4])
|
||||||
|
@ -102,7 +102,7 @@ def processPath(e):
|
||||||
elif cmd == 'Z' or cmd == 'z':
|
elif cmd == 'Z' or cmd == 'z':
|
||||||
curPath.append(curPath[0])
|
curPath.append(curPath[0])
|
||||||
elif cmd != None:
|
elif cmd != None:
|
||||||
print cmd
|
print(cmd)
|
||||||
cmd = c
|
cmd = c
|
||||||
param = []
|
param = []
|
||||||
return paths
|
return paths
|
||||||
|
|
|
@ -311,6 +311,6 @@ if __name__ == '__main__':
|
||||||
tree.insert(AABB(Vector3(0,0,0), Vector3(0,0,0)))
|
tree.insert(AABB(Vector3(0,0,0), Vector3(0,0,0)))
|
||||||
tree.insert(AABB(Vector3(1,1,1), Vector3(1,1,1)))
|
tree.insert(AABB(Vector3(1,1,1), Vector3(1,1,1)))
|
||||||
tree.insert(AABB(Vector3(0.5,0.5,0.5), Vector3(0.5,0.5,0.5)))
|
tree.insert(AABB(Vector3(0.5,0.5,0.5), Vector3(0.5,0.5,0.5)))
|
||||||
print tree
|
print(tree)
|
||||||
print tree.query(AABB(Vector3(0,0,0), Vector3(0,0,0)))
|
print(tree.query(AABB(Vector3(0,0,0), Vector3(0,0,0))))
|
||||||
|
|
||||||
|
|
|
@ -16,5 +16,5 @@ def getVersion():
|
||||||
return "?"
|
return "?"
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print getVersion()
|
print(getVersion())
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue