Merge branch 'master' of github.com:daid/SkeinPyPy

Conflicts:
	SkeinPyPy_NewUI/skeinforge_application/alterations/end.gcode
	SkeinPyPy_NewUI/skeinforge_application/alterations/start.gcode
master
Daid 2012-02-28 19:37:17 +01:00
commit 92dcb02e4b
13 changed files with 716 additions and 446 deletions

View File

@ -13,7 +13,7 @@ import types, math
from fabmetheus_utilities import archive
def defaultSetting(setting):
def DEFSET(setting):
return setting.value
def storedSetting(name):
@ -22,6 +22,9 @@ def storedSetting(name):
def ifSettingAboveZero(name):
return lambda setting: float(getSetting(name, '0.0')) > 0
def ifSettingIs(name, value):
return lambda setting: getSetting(name) == value
def storedPercentSetting(name):
return lambda setting: float(getSetting(name, setting.value)) / 100
@ -40,11 +43,16 @@ def calculateEdgeWidth(setting):
return lineWidth
def calculateShells(setting):
wallThickness = float(getSetting('wall_thickness'))
return calculateShellsImp(float(getSetting('wall_thickness')))
def calculateShellsBase(setting):
return calculateShellsImp(float(getSetting('wall_thickness')) + float(getSetting('extra_base_wall_thickness')))
def calculateShellsImp(wallThickness):
nozzleSize = float(getSetting('nozzle_size'))
if wallThickness < nozzleSize:
return wallThickness
return 0
lineCount = int(wallThickness / nozzleSize + 0.0001)
lineWidth = wallThickness / lineCount
@ -59,261 +67,271 @@ def calculateSolidLayerCount(setting):
ret = int(math.ceil(solidThickness / layerHeight - 0.0001))
return ret
def firstLayerSpeedRatio(setting):
bottomSpeed = float(getSetting('bottom_layer_speed'))
speed = float(getSetting('print_speed'))
return bottomSpeed/speed
def getSkeinPyPyProfileInformation():
return {
'carve': {
'Add_Layer_Template_to_SVG': defaultSetting,
'Add_Layer_Template_to_SVG': DEFSET,
'Edge_Width_mm': calculateEdgeWidth,
'Extra_Decimal_Places_float': defaultSetting,
'Import_Coarseness_ratio': defaultSetting,
'Extra_Decimal_Places_float': DEFSET,
'Import_Coarseness_ratio': DEFSET,
'Layer_Height_mm': storedSetting("layer_height"),
'Layers_From_index': defaultSetting,
'Layers_To_index': defaultSetting,
'Correct_Mesh': defaultSetting,
'Unproven_Mesh': defaultSetting,
'SVG_Viewer': defaultSetting,
'Layers_From_index': DEFSET,
'Layers_To_index': DEFSET,
'Correct_Mesh': DEFSET,
'Unproven_Mesh': DEFSET,
'SVG_Viewer': DEFSET,
},'scale': {
'Activate_Scale': "False",
'XY_Plane_Scale_ratio': defaultSetting,
'Z_Axis_Scale_ratio': defaultSetting,
'SVG_Viewer': defaultSetting,
'XY_Plane_Scale_ratio': DEFSET,
'Z_Axis_Scale_ratio': DEFSET,
'SVG_Viewer': DEFSET,
},'bottom': {
'Activate_Bottom': defaultSetting,
'Additional_Height_over_Layer_Thickness_ratio': defaultSetting,
'Altitude_mm': defaultSetting,
'SVG_Viewer': defaultSetting,
'Activate_Bottom': DEFSET,
'Additional_Height_over_Layer_Thickness_ratio': DEFSET,
'Altitude_mm': DEFSET,
'SVG_Viewer': DEFSET,
},'preface': {
'Meta': defaultSetting,
'Set_Positioning_to_Absolute': defaultSetting,
'Set_Units_to_Millimeters': defaultSetting,
'Start_at_Home': defaultSetting,
'Turn_Extruder_Off_at_Shut_Down': defaultSetting,
'Turn_Extruder_Off_at_Start_Up': defaultSetting,
'Meta': DEFSET,
'Set_Positioning_to_Absolute': DEFSET,
'Set_Units_to_Millimeters': DEFSET,
'Start_at_Home': DEFSET,
'Turn_Extruder_Off_at_Shut_Down': DEFSET,
'Turn_Extruder_Off_at_Start_Up': DEFSET,
},'widen': {
'Activate_Widen': defaultSetting,
'Activate_Widen': DEFSET,
},'inset': {
'Add_Custom_Code_for_Temperature_Reading': defaultSetting,
'Add_Custom_Code_for_Temperature_Reading': DEFSET,
'Infill_in_Direction_of_Bridge': "True",
'Infill_Width_over_Thickness_ratio': defaultSetting,
'Loop_Order_Choice': defaultSetting,
'Overlap_Removal_Width_over_Perimeter_Width_ratio': defaultSetting,
'Turn_Extruder_Heater_Off_at_Shut_Down': defaultSetting,
'Volume_Fraction_ratio': defaultSetting,
'Infill_Width_over_Thickness_ratio': DEFSET,
'Loop_Order_Choice': DEFSET,
'Overlap_Removal_Width_over_Perimeter_Width_ratio': DEFSET,
'Turn_Extruder_Heater_Off_at_Shut_Down': DEFSET,
'Volume_Fraction_ratio': DEFSET,
},'fill': {
'Activate_Fill': "True",
'Diaphragm_Period_layers': defaultSetting,
'Diaphragm_Thickness_layers': defaultSetting,
'Solid_Surface_Top': storedSetting("solid_top"),
'Override_First_Layer_Sequence': storedSetting("force_first_layer_sequence"),
'Diaphragm_Period_layers': DEFSET,
'Diaphragm_Thickness_layers': DEFSET,
'Extra_Shells_on_Alternating_Solid_Layer_layers': calculateShells,
'Extra_Shells_on_Base_layers': calculateShells,
'Extra_Shells_on_Base_layers': calculateShellsBase,
'Extra_Shells_on_Sparse_Layer_layers': calculateShells,
'Grid_Circle_Separation_over_Perimeter_Width_ratio': defaultSetting,
'Grid_Extra_Overlap_ratio': defaultSetting,
'Grid_Junction_Separation_Band_Height_layers': defaultSetting,
'Grid_Junction_Separation_over_Octogon_Radius_At_End_ratio': defaultSetting,
'Grid_Junction_Separation_over_Octogon_Radius_At_Middle_ratio': defaultSetting,
'Infill_Begin_Rotation_degrees': defaultSetting,
'Infill_Begin_Rotation_Repeat_layers': defaultSetting,
'Infill_Odd_Layer_Extra_Rotation_degrees': defaultSetting,
'Grid_Circular': defaultSetting,
'Grid_Hexagonal': defaultSetting,
'Grid_Rectangular': defaultSetting,
'Line': defaultSetting,
'Infill_Perimeter_Overlap_ratio': defaultSetting,
'Grid_Circle_Separation_over_Perimeter_Width_ratio': DEFSET,
'Grid_Extra_Overlap_ratio': DEFSET,
'Grid_Junction_Separation_Band_Height_layers': DEFSET,
'Grid_Junction_Separation_over_Octogon_Radius_At_End_ratio': DEFSET,
'Grid_Junction_Separation_over_Octogon_Radius_At_Middle_ratio': DEFSET,
'Infill_Begin_Rotation_degrees': DEFSET,
'Infill_Begin_Rotation_Repeat_layers': DEFSET,
'Infill_Odd_Layer_Extra_Rotation_degrees': DEFSET,
'Grid_Circular': ifSettingIs('infill_type', 'Grid Circular'),
'Grid_Hexagonal': ifSettingIs('infill_type', 'Grid Hexagonal'),
'Grid_Rectangular': ifSettingIs('infill_type', 'Grid Rectangular'),
'Line': ifSettingIs('infill_type', 'Line'),
'Infill_Perimeter_Overlap_ratio': DEFSET,
'Infill_Solidity_ratio': storedPercentSetting('fill_density'),
'Infill_Width': storedSetting("nozzle_size"),
'Solid_Surface_Thickness_layers': calculateSolidLayerCount,
'Start_From_Choice': defaultSetting,
'Surrounding_Angle_degrees': defaultSetting,
'Thread_Sequence_Choice': defaultSetting,
'Start_From_Choice': DEFSET,
'Surrounding_Angle_degrees': DEFSET,
'Thread_Sequence_Choice': storedSetting('sequence'),
},'multiply': {
'Activate_Multiply': "True",
'Center_X_mm': storedSetting("machine_center_x"),
'Center_Y_mm': storedSetting("machine_center_y"),
'Number_of_Columns_integer': "1",
'Number_of_Rows_integer': "1",
'Reverse_Sequence_every_Odd_Layer': defaultSetting,
'Separation_over_Perimeter_Width_ratio': defaultSetting,
'Reverse_Sequence_every_Odd_Layer': DEFSET,
'Separation_over_Perimeter_Width_ratio': DEFSET,
},'speed': {
'Activate_Speed': "True",
'Add_Flow_Rate': "True",
'Bridge_Feed_Rate_Multiplier_ratio': defaultSetting,
'Bridge_Flow_Rate_Multiplier_ratio': defaultSetting,
'Duty_Cyle_at_Beginning_portion': defaultSetting,
'Duty_Cyle_at_Ending_portion': defaultSetting,
'Bridge_Feed_Rate_Multiplier_ratio': DEFSET,
'Bridge_Flow_Rate_Multiplier_ratio': DEFSET,
'Duty_Cyle_at_Beginning_portion': DEFSET,
'Duty_Cyle_at_Ending_portion': DEFSET,
'Feed_Rate_mm/s': storedSetting("print_speed"),
'Flow_Rate_Setting_float': storedSetting("print_speed"),
'Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio': defaultSetting,
'Object_First_Layer_Feed_Rate_Perimeter_Multiplier_ratio': defaultSetting,
'Object_First_Layer_Feed_Rate_Travel_Multiplier_ratio': defaultSetting,
'Object_First_Layer_Flow_Rate_Infill_Multiplier_ratio': defaultSetting,
'Object_First_Layer_Flow_Rate_Perimeter_Multiplier_ratio': defaultSetting,
'Object_First_Layers_Amount_Of_Layers_For_Speed_Change': defaultSetting,
'Orbital_Feed_Rate_over_Operating_Feed_Rate_ratio': defaultSetting,
'Maximum_Z_Feed_Rate_mm/s': defaultSetting,
'Perimeter_Feed_Rate_Multiplier_ratio': defaultSetting,
'Perimeter_Flow_Rate_Multiplier_ratio': defaultSetting,
'Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio,
'Object_First_Layer_Feed_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio,
'Object_First_Layer_Feed_Rate_Travel_Multiplier_ratio': firstLayerSpeedRatio,
'Object_First_Layer_Flow_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio,
'Object_First_Layer_Flow_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio,
'Object_First_Layers_Amount_Of_Layers_For_Speed_Change': DEFSET,
'Orbital_Feed_Rate_over_Operating_Feed_Rate_ratio': DEFSET,
'Maximum_Z_Feed_Rate_mm/s': DEFSET,
'Perimeter_Feed_Rate_Multiplier_ratio': DEFSET,
'Perimeter_Flow_Rate_Multiplier_ratio': DEFSET,
'Travel_Feed_Rate_mm/s': storedSetting("travel_speed"),
},'temperature': {
'Activate_Temperature': defaultSetting,#ifSettingAboveZero('print_temperature'),
'Cooling_Rate_Celcius/second': defaultSetting,
'Heating_Rate_Celcius/second': defaultSetting,
'Base_Temperature_Celcius': defaultSetting,#storedSetting("print_temperature"),
'Interface_Temperature_Celcius': defaultSetting,#storedSetting("print_temperature"),
'Object_First_Layer_Infill_Temperature_Celcius': defaultSetting,#storedSetting("print_temperature"),
'Object_First_Layer_Perimeter_Temperature_Celcius': defaultSetting,#storedSetting("print_temperature"),
'Object_Next_Layers_Temperature_Celcius': defaultSetting,#storedSetting("print_temperature"),
'Support_Layers_Temperature_Celcius': defaultSetting,#storedSetting("print_temperature"),
'Supported_Layers_Temperature_Celcius': defaultSetting,#storedSetting("print_temperature"),
'Activate_Temperature': DEFSET,#ifSettingAboveZero('print_temperature'),
'Cooling_Rate_Celcius/second': DEFSET,
'Heating_Rate_Celcius/second': DEFSET,
'Base_Temperature_Celcius': DEFSET,#storedSetting("print_temperature"),
'Interface_Temperature_Celcius': DEFSET,#storedSetting("print_temperature"),
'Object_First_Layer_Infill_Temperature_Celcius': DEFSET,#storedSetting("print_temperature"),
'Object_First_Layer_Perimeter_Temperature_Celcius': DEFSET,#storedSetting("print_temperature"),
'Object_Next_Layers_Temperature_Celcius': DEFSET,#storedSetting("print_temperature"),
'Support_Layers_Temperature_Celcius': DEFSET,#storedSetting("print_temperature"),
'Supported_Layers_Temperature_Celcius': DEFSET,#storedSetting("print_temperature"),
},'raft': {
'Activate_Raft': "True",
'Add_Raft,_Elevate_Nozzle,_Orbit': defaultSetting,
'Base_Feed_Rate_Multiplier_ratio': defaultSetting,
'Base_Flow_Rate_Multiplier_ratio': defaultSetting,
'Base_Infill_Density_ratio': defaultSetting,
'Base_Layer_Thickness_over_Layer_Thickness': defaultSetting,
'Add_Raft,_Elevate_Nozzle,_Orbit': DEFSET,
'Base_Feed_Rate_Multiplier_ratio': DEFSET,
'Base_Flow_Rate_Multiplier_ratio': DEFSET,
'Base_Infill_Density_ratio': DEFSET,
'Base_Layer_Thickness_over_Layer_Thickness': DEFSET,
'Base_Layers_integer': '0',
'Base_Nozzle_Lift_over_Base_Layer_Thickness_ratio': defaultSetting,
'Initial_Circling': defaultSetting,
'Infill_Overhang_over_Extrusion_Width_ratio': defaultSetting,
'Interface_Feed_Rate_Multiplier_ratio': defaultSetting,
'Interface_Flow_Rate_Multiplier_ratio': defaultSetting,
'Interface_Infill_Density_ratio': defaultSetting,
'Interface_Layer_Thickness_over_Layer_Thickness': defaultSetting,
'Base_Nozzle_Lift_over_Base_Layer_Thickness_ratio': DEFSET,
'Initial_Circling': DEFSET,
'Infill_Overhang_over_Extrusion_Width_ratio': DEFSET,
'Interface_Feed_Rate_Multiplier_ratio': DEFSET,
'Interface_Flow_Rate_Multiplier_ratio': DEFSET,
'Interface_Infill_Density_ratio': DEFSET,
'Interface_Layer_Thickness_over_Layer_Thickness': DEFSET,
'Interface_Layers_integer': '0',
'Interface_Nozzle_Lift_over_Interface_Layer_Thickness_ratio': defaultSetting,
'Name_of_Support_End_File': defaultSetting,
'Name_of_Support_Start_File': defaultSetting,
'Operating_Nozzle_Lift_over_Layer_Thickness_ratio': defaultSetting,
'Raft_Additional_Margin_over_Length_%': defaultSetting,
'Raft_Margin_mm': defaultSetting,
'Interface_Nozzle_Lift_over_Interface_Layer_Thickness_ratio': DEFSET,
'Name_of_Support_End_File': DEFSET,
'Name_of_Support_Start_File': DEFSET,
'Operating_Nozzle_Lift_over_Layer_Thickness_ratio': DEFSET,
'Raft_Additional_Margin_over_Length_%': DEFSET,
'Raft_Margin_mm': DEFSET,
'Support_Cross_Hatch': 'False',
'Support_Flow_Rate_over_Operating_Flow_Rate_ratio': defaultSetting,
'Support_Gap_over_Perimeter_Extrusion_Width_ratio': defaultSetting,
'Support_Flow_Rate_over_Operating_Flow_Rate_ratio': DEFSET,
'Support_Gap_over_Perimeter_Extrusion_Width_ratio': DEFSET,
'Support_Material_Choice_': storedSetting("support"),
'Support_Minimum_Angle_degrees': defaultSetting,
'Support_Minimum_Angle_degrees': DEFSET,
},'skirt': {
'Skirt_line_count': storedSetting("skirt_line_count"),
'Convex': "True",
'Gap_Width_mm': storedSetting("skirt_gap"),
'Layers_To_index': "1",
},'joris': {
'Activate_Joris': storedSetting("joris"),
'Layers_From_index': calculateSolidLayerCount,
},'chamber': {
'Activate_Chamber': "False",
'Bed_Temperature_Celcius': defaultSetting,
'Bed_Temperature_Begin_Change_Height_mm': defaultSetting,
'Bed_Temperature_End_Change_Height_mm': defaultSetting,
'Bed_Temperature_End_Celcius': defaultSetting,
'Chamber_Temperature_Celcius': defaultSetting,
'Holding_Force_bar': defaultSetting,
'Bed_Temperature_Celcius': DEFSET,
'Bed_Temperature_Begin_Change_Height_mm': DEFSET,
'Bed_Temperature_End_Change_Height_mm': DEFSET,
'Bed_Temperature_End_Celcius': DEFSET,
'Chamber_Temperature_Celcius': DEFSET,
'Holding_Force_bar': DEFSET,
},'tower': {
'Activate_Tower': "False",
'Extruder_Possible_Collision_Cone_Angle_degrees': defaultSetting,
'Maximum_Tower_Height_layers': defaultSetting,
'Tower_Start_Layer_integer': defaultSetting,
'Extruder_Possible_Collision_Cone_Angle_degrees': DEFSET,
'Maximum_Tower_Height_layers': DEFSET,
'Tower_Start_Layer_integer': DEFSET,
},'jitter': {
'Activate_Jitter': "False",
'Jitter_Over_Perimeter_Width_ratio': defaultSetting,
'Jitter_Over_Perimeter_Width_ratio': DEFSET,
},'clip': {
'Activate_Clip': "False",
'Clip_Over_Perimeter_Width_ratio': defaultSetting,
'Maximum_Connection_Distance_Over_Perimeter_Width_ratio': defaultSetting,
'Clip_Over_Perimeter_Width_ratio': DEFSET,
'Maximum_Connection_Distance_Over_Perimeter_Width_ratio': DEFSET,
},'smooth': {
'Activate_Smooth': "False",
'Layers_From_index': defaultSetting,
'Maximum_Shortening_over_Width_float': defaultSetting,
'Layers_From_index': DEFSET,
'Maximum_Shortening_over_Width_float': DEFSET,
},'stretch': {
'Activate_Stretch': "False",
'Cross_Limit_Distance_Over_Perimeter_Width_ratio': defaultSetting,
'Loop_Stretch_Over_Perimeter_Width_ratio': defaultSetting,
'Path_Stretch_Over_Perimeter_Width_ratio': defaultSetting,
'Perimeter_Inside_Stretch_Over_Perimeter_Width_ratio': defaultSetting,
'Perimeter_Outside_Stretch_Over_Perimeter_Width_ratio': defaultSetting,
'Stretch_From_Distance_Over_Perimeter_Width_ratio': defaultSetting,
'Cross_Limit_Distance_Over_Perimeter_Width_ratio': DEFSET,
'Loop_Stretch_Over_Perimeter_Width_ratio': DEFSET,
'Path_Stretch_Over_Perimeter_Width_ratio': DEFSET,
'Perimeter_Inside_Stretch_Over_Perimeter_Width_ratio': DEFSET,
'Perimeter_Outside_Stretch_Over_Perimeter_Width_ratio': DEFSET,
'Stretch_From_Distance_Over_Perimeter_Width_ratio': DEFSET,
},'skin': {
'Activate_Skin': "False",
'Horizontal_Infill_Divisions_integer': defaultSetting,
'Horizontal_Perimeter_Divisions_integer': defaultSetting,
'Vertical_Divisions_integer': defaultSetting,
'Hop_When_Extruding_Infill': defaultSetting,
'Layers_From_index': defaultSetting,
'Horizontal_Infill_Divisions_integer': DEFSET,
'Horizontal_Perimeter_Divisions_integer': DEFSET,
'Vertical_Divisions_integer': DEFSET,
'Hop_When_Extruding_Infill': DEFSET,
'Layers_From_index': DEFSET,
},'comb': {
'Activate_Comb': "True",
'Running_Jump_Space_mm': defaultSetting,
'Running_Jump_Space_mm': DEFSET,
},'cool': {
'Activate_Cool': "True",
'Bridge_Cool_Celcius': defaultSetting,
'Cool_Type': defaultSetting,
'Maximum_Cool_Celcius': defaultSetting,
'Bridge_Cool_Celcius': DEFSET,
'Cool_Type': DEFSET,
'Maximum_Cool_Celcius': DEFSET,
'Minimum_Layer_Time_seconds': storedSetting("cool_min_layer_time"),
'Minimum_Orbital_Radius_millimeters': defaultSetting,
'Name_of_Cool_End_File': defaultSetting,
'Name_of_Cool_Start_File': defaultSetting,
'Orbital_Outset_millimeters': defaultSetting,
'Turn_Fan_On_at_Beginning': defaultSetting,
'Turn_Fan_Off_at_Ending': defaultSetting,
'Minimum_Orbital_Radius_millimeters': DEFSET,
'Name_of_Cool_End_File': DEFSET,
'Name_of_Cool_Start_File': DEFSET,
'Orbital_Outset_millimeters': DEFSET,
'Turn_Fan_On_at_Beginning': DEFSET,
'Turn_Fan_Off_at_Ending': DEFSET,
},'hop': {
'Activate_Hop': "False",
'Hop_Over_Layer_Thickness_ratio': defaultSetting,
'Minimum_Hop_Angle_degrees': defaultSetting,
'Hop_Over_Layer_Thickness_ratio': DEFSET,
'Minimum_Hop_Angle_degrees': DEFSET,
},'wipe': {
'Activate_Wipe': "False",
'Arrival_X_mm': defaultSetting,
'Arrival_Y_mm': defaultSetting,
'Arrival_Z_mm': defaultSetting,
'Departure_X_mm': defaultSetting,
'Departure_Y_mm': defaultSetting,
'Departure_Z_mm': defaultSetting,
'Wipe_X_mm': defaultSetting,
'Wipe_Y_mm': defaultSetting,
'Wipe_Z_mm': defaultSetting,
'Wipe_Period_layers': defaultSetting,
'Arrival_X_mm': DEFSET,
'Arrival_Y_mm': DEFSET,
'Arrival_Z_mm': DEFSET,
'Departure_X_mm': DEFSET,
'Departure_Y_mm': DEFSET,
'Departure_Z_mm': DEFSET,
'Wipe_X_mm': DEFSET,
'Wipe_Y_mm': DEFSET,
'Wipe_Z_mm': DEFSET,
'Wipe_Period_layers': DEFSET,
},'oozebane': {
'Activate_Oozebane': "False",
'After_Startup_Distance_millimeters': defaultSetting,
'Early_Shutdown_Distance_millimeters': defaultSetting,
'Early_Startup_Distance_Constant_millimeters': defaultSetting,
'Early_Startup_Maximum_Distance_millimeters': defaultSetting,
'First_Early_Startup_Distance_millimeters': defaultSetting,
'Minimum_Distance_for_Early_Startup_millimeters': defaultSetting,
'Minimum_Distance_for_Early_Shutdown_millimeters': defaultSetting,
'Slowdown_Startup_Steps_positive_integer': defaultSetting,
'After_Startup_Distance_millimeters': DEFSET,
'Early_Shutdown_Distance_millimeters': DEFSET,
'Early_Startup_Distance_Constant_millimeters': DEFSET,
'Early_Startup_Maximum_Distance_millimeters': DEFSET,
'First_Early_Startup_Distance_millimeters': DEFSET,
'Minimum_Distance_for_Early_Startup_millimeters': DEFSET,
'Minimum_Distance_for_Early_Shutdown_millimeters': DEFSET,
'Slowdown_Startup_Steps_positive_integer': DEFSET,
},'dwindle': {
'Activate_Dwindle': "False",
'End_Rate_Multiplier_ratio': defaultSetting,
'Pent_Up_Volume_cubic_millimeters': defaultSetting,
'Slowdown_Steps_positive_integer': defaultSetting,
'Slowdown_Volume_cubic_millimeters': defaultSetting,
'End_Rate_Multiplier_ratio': DEFSET,
'Pent_Up_Volume_cubic_millimeters': DEFSET,
'Slowdown_Steps_positive_integer': DEFSET,
'Slowdown_Volume_cubic_millimeters': DEFSET,
},'splodge': {
'Activate_Splodge': "False",
'Initial_Lift_over_Extra_Thickness_ratio': defaultSetting,
'Initial_Splodge_Feed_Rate_mm/s': defaultSetting,
'Operating_Splodge_Feed_Rate_mm/s': defaultSetting,
'Operating_Splodge_Quantity_Length_millimeters': defaultSetting,
'Initial_Splodge_Quantity_Length_millimeters': defaultSetting,
'Operating_Lift_over_Extra_Thickness_ratio': defaultSetting,
'Initial_Lift_over_Extra_Thickness_ratio': DEFSET,
'Initial_Splodge_Feed_Rate_mm/s': DEFSET,
'Operating_Splodge_Feed_Rate_mm/s': DEFSET,
'Operating_Splodge_Quantity_Length_millimeters': DEFSET,
'Initial_Splodge_Quantity_Length_millimeters': DEFSET,
'Operating_Lift_over_Extra_Thickness_ratio': DEFSET,
},'home': {
'Activate_Home': "False",
'Name_of_Home_File': defaultSetting,
'Name_of_Home_File': DEFSET,
},'lash': {
'Activate_Lash': "False",
'X_Backlash_mm': defaultSetting,
'Y_Backlash_mm': defaultSetting,
'X_Backlash_mm': DEFSET,
'Y_Backlash_mm': DEFSET,
},'fillet': {
'Activate_Fillet': "False",
'Arc_Point': defaultSetting,
'Arc_Radius': defaultSetting,
'Arc_Segment': defaultSetting,
'Bevel': defaultSetting,
'Corner_Feed_Rate_Multiplier_ratio': defaultSetting,
'Fillet_Radius_over_Perimeter_Width_ratio': defaultSetting,
'Reversal_Slowdown_Distance_over_Perimeter_Width_ratio': defaultSetting,
'Use_Intermediate_Feed_Rate_in_Corners': defaultSetting,
'Arc_Point': DEFSET,
'Arc_Radius': DEFSET,
'Arc_Segment': DEFSET,
'Bevel': DEFSET,
'Corner_Feed_Rate_Multiplier_ratio': DEFSET,
'Fillet_Radius_over_Perimeter_Width_ratio': DEFSET,
'Reversal_Slowdown_Distance_over_Perimeter_Width_ratio': DEFSET,
'Use_Intermediate_Feed_Rate_in_Corners': DEFSET,
},'limit': {
'Activate_Limit': "False",
'Maximum_Initial_Feed_Rate_mm/s': defaultSetting,
'Maximum_Initial_Feed_Rate_mm/s': DEFSET,
},'unpause': {
'Activate_Unpause': "False",
'Delay_milliseconds': defaultSetting,
'Maximum_Speed_ratio': defaultSetting,
'Delay_milliseconds': DEFSET,
'Maximum_Speed_ratio': DEFSET,
},'dimension': {
'Activate_Dimension': "True",
'Absolute_Extrusion_Distance': "True",
@ -321,9 +339,9 @@ def getSkeinPyPyProfileInformation():
'Extruder_Retraction_Speed_mm/s': storedSetting('retraction_speed'),
'Filament_Diameter_mm': storedSetting("filament_diameter"),
'Filament_Packing_Density_ratio': storedSetting("filament_density"),
'Maximum_E_Value_before_Reset_float': defaultSetting,
'Maximum_E_Value_before_Reset_float': DEFSET,
'Minimum_Travel_for_Retraction_millimeters': storedSetting("retraction_min_travel"),
'Retract_Within_Island': defaultSetting,
'Retract_Within_Island': DEFSET,
'Retraction_Distance_millimeters': storedSetting('retraction_amount'),
'Restart_Extra_Distance_millimeters': storedSetting('retraction_extra'),
},'alteration': {
@ -331,23 +349,23 @@ def getSkeinPyPyProfileInformation():
'Name_of_End_File': "end.gcode",
'Name_of_Start_File': "start.gcode",
'Remove_Redundant_Mcode': "True",
'Replace_Variable_with_Setting': defaultSetting,
'Replace_Variable_with_Setting': DEFSET,
},'export': {
'Activate_Export': "True",
'Add_Descriptive_Extension': defaultSetting,
'Add_Export_Suffix': defaultSetting,
'Add_Profile_Extension': defaultSetting,
'Add_Timestamp_Extension': defaultSetting,
'Also_Send_Output_To': defaultSetting,
'Analyze_Gcode': defaultSetting,
'Comment_Choice': defaultSetting,
'Do_Not_Change_Output': defaultSetting,
'binary_16_byte': defaultSetting,
'gcode_step': defaultSetting,
'gcode_time_segment': defaultSetting,
'gcode_small': defaultSetting,
'File_Extension': defaultSetting,
'Name_of_Replace_File': defaultSetting,
'Add_Descriptive_Extension': DEFSET,
'Add_Export_Suffix': DEFSET,
'Add_Profile_Extension': DEFSET,
'Add_Timestamp_Extension': DEFSET,
'Also_Send_Output_To': DEFSET,
'Analyze_Gcode': DEFSET,
'Comment_Choice': DEFSET,
'Do_Not_Change_Output': DEFSET,
'binary_16_byte': DEFSET,
'gcode_step': DEFSET,
'gcode_time_segment': DEFSET,
'gcode_small': DEFSET,
'File_Extension': DEFSET,
'Name_of_Replace_File': DEFSET,
'Save_Penultimate_Gcode': "False",
}
}

View File

@ -0,0 +1,39 @@
from __future__ import absolute_import
import __init__
import wx, os, platform, types
import ConfigParser
from fabmetheus_utilities import settings
from newui import configWindowBase
from newui import preview3d
from newui import sliceProgessPanel
from newui import alterationPanel
from newui import validators
class advancedConfigWindow(configWindowBase.configWindowBase):
"Advanced configuration window"
def __init__(self):
super(advancedConfigWindow, self).__init__(title='Advanced config')
left, right, main = self.CreateConfigPanel(self)
configWindowBase.TitleRow(left, "Accuracy")
c = configWindowBase.SettingRow(left, "Extra Wall thickness for bottom/top (mm)", 'extra_base_wall_thickness', '0.0', 'Additional wall thickness of the bottom and top layers.')
validators.validFloat(c, 0.0)
validators.wallThicknessValidator(c)
configWindowBase.TitleRow(left, "Sequence")
c = configWindowBase.SettingRow(left, "Print order sequence", 'sequence', ['Loops > Perimeter > Infill', 'Loops > Infill > Perimeter', 'Infill > Loops > Perimeter', 'Infill > Perimeter > Loops', 'Perimeter > Infill > Loops', 'Perimeter > Loops > Infill'], 'Sequence of printing. The perimeter is the outer print edge, the loops are the insides of the walls, and the infill is the insides.');
c = configWindowBase.SettingRow(left, "Force first layer sequence", 'force_first_layer_sequence', ['True', 'False'], 'This setting forces the order of the first layer to be \'Perimeter > Loops > Infill\'')
configWindowBase.TitleRow(left, "Infill")
c = configWindowBase.SettingRow(left, "Infill pattern", 'infill_type', ['Line', 'Grid Circular', 'Grid Hexagonal', 'Grid Rectangular'], 'Pattern of the none-solid infill. Line is default, but grids can provide a strong print.')
c = configWindowBase.SettingRow(left, "Solid infill top", 'solid_top', ['True', 'False'], 'Create a solid top surface, if set to false the top is filled with the fill percentage. Useful for cups/vases.')
configWindowBase.TitleRow(left, "Joris")
c = configWindowBase.SettingRow(left, "Joris the outer edge", 'joris', ['False', 'True'], '[Joris] is a code name for smoothing out the Z move of the outer edge. This will create a steady Z increase over the whole print. It is intended to be used with a single walled wall thickness to make cups/vases.')
main.Fit()
self.Fit()

View File

@ -0,0 +1,193 @@
from __future__ import absolute_import
import __init__
import wx, os, platform, types
import ConfigParser
from fabmetheus_utilities import settings
from newui import validators
def main():
app = wx.App(False)
mainWindow()
app.MainLoop()
class configWindowBase(wx.Frame):
"A base class for configuration dialogs. Handles creation of settings, and popups"
def __init__(self, title):
super(configWindowBase, self).__init__(None, title=title)
self.settingControlList = []
#Create the popup window
self.popup = wx.PopupWindow(self, wx.BORDER_SIMPLE)
self.popup.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
self.popup.setting = None
self.popup.text = wx.StaticText(self.popup, -1, '');
self.popup.sizer = wx.BoxSizer()
self.popup.sizer.Add(self.popup.text, flag=wx.EXPAND|wx.ALL, border=1)
self.popup.SetSizer(self.popup.sizer)
def CreateConfigTab(self, nb, name):
leftConfigPanel, rightConfigPanel, configPanel = self.CreateConfigPanel(nb)
nb.AddPage(configPanel, name)
return leftConfigPanel, rightConfigPanel
def CreateConfigPanel(self, parent):
configPanel = wx.Panel(parent);
leftConfigPanel = wx.Panel(configPanel)
rightConfigPanel = wx.Panel(configPanel)
sizer = wx.GridBagSizer(2, 2)
leftConfigPanel.SetSizer(sizer)
sizer = wx.GridBagSizer(2, 2)
rightConfigPanel.SetSizer(sizer)
sizer = wx.BoxSizer(wx.HORIZONTAL)
configPanel.SetSizer(sizer)
sizer.Add(leftConfigPanel)
sizer.Add(rightConfigPanel)
leftConfigPanel.main = self
rightConfigPanel.main = self
return leftConfigPanel, rightConfigPanel, configPanel
def OnPopupDisplay(self, setting):
x, y = setting.ctrl.ClientToScreenXY(0, 0)
sx, sy = setting.ctrl.GetSizeTuple()
if platform.system() == "Windows":
#for some reason, under windows, the popup is relative to the main window...
wx, wy = self.ClientToScreenXY(0, 0)
x -= wx
y -= wy
self.popup.setting = setting
self.UpdatePopup(setting)
self.popup.SetPosition((x, y+sy))
self.popup.Show(True)
def OnPopupHide(self, e):
self.popup.Show(False)
def UpdatePopup(self, setting):
if self.popup.setting == setting:
if setting.validationMsg != '':
self.popup.text.SetLabel(setting.validationMsg + '\n\n' + setting.helpText)
else:
self.popup.text.SetLabel(setting.helpText)
self.popup.text.Wrap(350)
self.popup.Fit()
def updateProfileToControls(self):
"Update the configuration wx controls to show the new configuration settings"
for setting in self.settingControlList:
setting.SetValue(settings.getSetting(setting.configName))
class TitleRow():
def __init__(self, panel, name):
"Add a title row to the configuration panel"
sizer = panel.GetSizer()
self.title = wx.StaticText(panel, -1, name)
self.title.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
sizer.Add(self.title, (sizer.GetRows(),sizer.GetCols()), (1,3), flag=wx.EXPAND)
sizer.Add(wx.StaticLine(panel), (sizer.GetRows()+1,sizer.GetCols()), (1,3), flag=wx.EXPAND)
sizer.SetRows(sizer.GetRows() + 2)
class SettingRow():
def __init__(self, panel, label, configName, defaultValue = '', helpText = 'Help: TODO'):
"Add a setting to the configuration panel"
sizer = panel.GetSizer()
x = sizer.GetRows()
y = sizer.GetCols()
self.validators = []
self.validationMsg = ''
self.helpText = helpText
self.configName = configName
self.panel = panel
self.label = wx.StaticText(panel, -1, label)
if isinstance(defaultValue, types.StringTypes):
self.ctrl = wx.TextCtrl(panel, -1, settings.getSetting(configName, defaultValue))
else:
self.ctrl = wx.ComboBox(panel, -1, settings.getSetting(configName, defaultValue[0]), choices=defaultValue, style=wx.CB_DROPDOWN|wx.CB_READONLY)
#self.helpButton = wx.Button(panel, -1, "?", style=wx.BU_EXACTFIT)
#self.helpButton.SetToolTip(wx.ToolTip(help))
self.ctrl.Bind(wx.EVT_TEXT, self.OnSettingTextChange)
self.ctrl.Bind(wx.EVT_ENTER_WINDOW, lambda e: panel.main.OnPopupDisplay(self))
self.ctrl.Bind(wx.EVT_LEAVE_WINDOW, panel.main.OnPopupHide)
panel.main.settingControlList.append(self)
sizer.Add(self.label, (x,y), flag=wx.ALIGN_CENTER_VERTICAL)
sizer.Add(self.ctrl, (x,y+1), flag=wx.ALIGN_BOTTOM|wx.EXPAND)
#sizer.Add(helpButton, (x,y+2))
sizer.SetRows(x+1)
def OnSettingTextChange(self, e):
result = validators.SUCCESS
msgs = []
for validator in self.validators:
res, err = validator.validate()
if res == validators.ERROR:
result = res
elif res == validators.WARNING and result != validators.ERROR:
result = res
if res != validators.SUCCESS:
msgs.append(err)
if result == validators.ERROR:
self.ctrl.SetBackgroundColour('Red')
elif result == validators.WARNING:
self.ctrl.SetBackgroundColour('Yellow')
else:
self.ctrl.SetBackgroundColour(wx.NullColour)
self.ctrl.Refresh()
settings.putSetting(self.configName, self.GetValue())
self.validationMsg = '\n'.join(msgs)
self.panel.main.UpdatePopup(self)
def GetValue(self):
return self.ctrl.GetValue()
def SetValue(self, value):
self.ctrl.SetValue(value)
#Settings notify works as a validator, but instead of validating anything, it calls another function, which can use the value.
class settingNotify():
def __init__(self, setting, func):
self.setting = setting
self.setting.validators.append(self)
self.func = func
def validate(self):
try:
f = float(self.setting.GetValue())
self.func(f)
return validators.SUCCESS, ''
except ValueError:
return validators.SUCCESS, ''
def getPreferencePath():
return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../preferences.ini"))
def getPreference(name, default):
if not globals().has_key('globalPreferenceParser'):
globalPreferenceParser = ConfigParser.ConfigParser()
globalPreferenceParser.read(getPreferencePath())
if not globalPreferenceParser.has_option('preference', name):
if not globalPreferenceParser.has_section('preference'):
globalPreferenceParser.add_section('preference')
globalPreferenceParser.set('preference', name, str(default))
print name + " not found in profile, so using default"
return default
return globalPreferenceParser.get('preference', name)
def putPreference(name, value):
#Check if we have a configuration file loaded, else load the default.
if not globals().has_key('globalPreferenceParser'):
globalPreferenceParser = ConfigParser.ConfigParser()
globalPreferenceParser.read(getPreferencePath())
if not globalPreferenceParser.has_section('preference'):
globalPreferenceParser.add_section('preference')
globalPreferenceParser.set('preference', name, str(value))
globalPreferenceParser.write(open(getPreferencePath(), 'w'))

View File

@ -6,6 +6,8 @@ import ConfigParser
from fabmetheus_utilities import settings
from newui import configWindowBase
from newui import advancedConfig
from newui import preview3d
from newui import sliceProgessPanel
from newui import alterationPanel
@ -16,31 +18,32 @@ def main():
mainWindow()
app.MainLoop()
class mainWindow(wx.Frame):
class mainWindow(configWindowBase.configWindowBase):
"Main user interface window"
def __init__(self):
super(mainWindow, self).__init__(None, title='SkeinPyPy')
super(mainWindow, self).__init__(title='SkeinPyPy')
wx.EVT_CLOSE(self, self.OnClose)
menubar = wx.MenuBar()
fileMenu = wx.Menu()
fitem = fileMenu.Append(-1, 'Open Profile...', 'Open Profile...')
self.Bind(wx.EVT_MENU, self.OnLoadProfile, fitem)
fitem = fileMenu.Append(-1, 'Save Profile...', 'Save Profile...')
self.Bind(wx.EVT_MENU, self.OnSaveProfile, fitem)
fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
i = fileMenu.Append(-1, 'Open Profile...', 'Open Profile...')
self.Bind(wx.EVT_MENU, self.OnLoadProfile, i)
i = fileMenu.Append(-1, 'Save Profile...', 'Save Profile...')
self.Bind(wx.EVT_MENU, self.OnSaveProfile, i)
i = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
self.Bind(wx.EVT_MENU, self.OnQuit, i)
menubar.Append(fileMenu, '&File')
#menubar.Append(wx.Menu(), 'Expert')
expertMenu = wx.Menu()
i = expertMenu.Append(-1, 'Open expert settings...', 'Open expert settings...')
self.Bind(wx.EVT_MENU, self.OnExpertOpen, i)
menubar.Append(expertMenu, 'Expert')
self.SetMenuBar(menubar)
wx.ToolTip.SetDelay(0)
self.lastPath = ""
self.filename = getPreference('lastFile', None)
self.filename = configWindowBase.getPreference('lastFile', None)
self.progressPanelList = []
self.settingControlList = []
#Preview window
self.preview3d = preview3d.previewPanel(self)
@ -50,85 +53,85 @@ class mainWindow(wx.Frame):
(left, right) = self.CreateConfigTab(nb, 'Print config')
TitleRow(left, "Accuracy")
c = SettingRow(left, "Layer height (mm)", 'layer_height', '0.2', 'Layer height in millimeters.\n0.2 is a good value for quick prints.\n0.1 gives high quality prints.')
configWindowBase.TitleRow(left, "Accuracy")
c = configWindowBase.SettingRow(left, "Layer height (mm)", 'layer_height', '0.2', 'Layer height in millimeters.\n0.2 is a good value for quick prints.\n0.1 gives high quality prints.')
validators.validFloat(c, 0.0)
validators.warningAbove(c, 0.31, "Thicker layers then 0.3mm usually give bad results and are not recommended.")
c = SettingRow(left, "Wall thickness (mm)", 'wall_thickness', '0.8', 'Thickness of the walls.\nThis is used in combination with the nozzle size to define the number\nof perimeter lines and the thickness of those perimeter lines.')
c = configWindowBase.SettingRow(left, "Wall thickness (mm)", 'wall_thickness', '0.8', 'Thickness of the walls.\nThis is used in combination with the nozzle size to define the number\nof perimeter lines and the thickness of those perimeter lines.')
validators.validFloat(c, 0.0)
validators.wallThicknessValidator(c)
TitleRow(left, "Fill")
c = SettingRow(left, "Bottom/Top thickness (mm)", 'solid_layer_thickness', '0.6', 'This controls the thickness of the bottom and top layers, the amount of solid layers put down is calculated by the layer thickness and this value.\nHaving this value a multiply of the layer thickness makes sense. And keep it near your wall thickness to make an evenly strong part.')
configWindowBase.TitleRow(left, "Fill")
c = configWindowBase.SettingRow(left, "Bottom/Top thickness (mm)", 'solid_layer_thickness', '0.6', 'This controls the thickness of the bottom and top layers, the amount of solid layers put down is calculated by the layer thickness and this value.\nHaving this value a multiply of the layer thickness makes sense. And keep it near your wall thickness to make an evenly strong part.')
validators.validFloat(c, 0.0)
c = SettingRow(left, "Fill Density (%)", 'fill_density', '20', 'This controls how densily filled the insides of your print will be. For a solid part use 100%, for an empty part use 0%. A value around 20% is usually enough')
c = configWindowBase.SettingRow(left, "Fill Density (%)", 'fill_density', '20', 'This controls how densily filled the insides of your print will be. For a solid part use 100%, for an empty part use 0%. A value around 20% is usually enough')
validators.validFloat(c, 0.0, 100.0)
TitleRow(left, "Skirt")
c = SettingRow(left, "Line count", 'skirt_line_count', '1', 'The skirt is a line drawn around the object at the first layer. This helps to prime your extruder, and to see if the object fits on your platform.\nSetting this to 0 will disable the skirt.')
configWindowBase.TitleRow(left, "Skirt")
c = configWindowBase.SettingRow(left, "Line count", 'skirt_line_count', '1', 'The skirt is a line drawn around the object at the first layer. This helps to prime your extruder, and to see if the object fits on your platform.\nSetting this to 0 will disable the skirt.')
validators.validInt(c, 0, 10)
c = SettingRow(left, "Start distance (mm)", 'skirt_gap', '6.0', 'The distance between the skirt and the first layer.\nThis is the minimal distance, multiple skirt lines will be put outwards from this distance.')
c = configWindowBase.SettingRow(left, "Start distance (mm)", 'skirt_gap', '6.0', 'The distance between the skirt and the first layer.\nThis is the minimal distance, multiple skirt lines will be put outwards from this distance.')
validators.validFloat(c, 0.0)
TitleRow(right, "Speed")
c = SettingRow(right, "Print speed (mm/s)", 'print_speed', '50')
configWindowBase.TitleRow(right, "Speed")
c = configWindowBase.SettingRow(right, "Print speed (mm/s)", 'print_speed', '50', 'Speed at which printing happens. A well adjusted Ultimaker can reach 150mm/s, but for good quality prints you want to print slower. Printing speed depends on a lot of factors. So you will be experimenting with optimal settings for this.')
validators.validFloat(c, 1.0)
validators.warningAbove(c, 150.0, "It is highly unlikely that your machine can achieve a printing speed above 150mm/s")
#Printing temperature is a problem right now, as our start code depends on a heated head.
#TitleRow(right, "Temperature")
#c = SettingRow(right, "Printing temperature", 'print_temperature', '0', 'Temperature used for printing. Set at 0 to pre-heat yourself')
#configWindowBase.TitleRow(right, "Temperature")
#c = configWindowBase.SettingRow(right, "Printing temperature", 'print_temperature', '0', 'Temperature used for printing. Set at 0 to pre-heat yourself')
#validators.validFloat(c, 0.0, 350.0)
#validators.warningAbove(c, 260.0, "Temperatures above 260C could damage your machine.")
TitleRow(right, "Support")
c = SettingRow(right, "Support type", 'support', ['None', 'Exterior only', 'Everywhere', 'Empty layers only'], 'Type of support structure build.\nNone does not do any support.\nExterior only only creates support on the outside.\nEverywhere creates support even on the insides of the model.\nOnly on empty layers is for stacked objects.')
configWindowBase.TitleRow(right, "Support")
c = configWindowBase.SettingRow(right, "Support type", 'support', ['None', 'Exterior only', 'Everywhere', 'Empty layers only'], 'Type of support structure build.\nNone does not do any support.\nExterior only only creates support on the outside.\nEverywhere creates support even on the insides of the model.\nOnly on empty layers is for stacked objects.')
(left, right) = self.CreateConfigTab(nb, 'Machine && Filament')
TitleRow(left, "Machine size")
c = SettingRow(left, "Machine center X (mm)", 'machine_center_x', '100', 'The center of your machine, your print will be placed at this location')
configWindowBase.TitleRow(left, "Machine size")
c = configWindowBase.SettingRow(left, "Machine center X (mm)", 'machine_center_x', '100', 'The center of your machine, your print will be placed at this location')
validators.validInt(c, 10)
settingNotify(c, self.preview3d.updateCenterX)
c = SettingRow(left, "Machine center Y (mm)", 'machine_center_y', '100', 'The center of your machine, your print will be placed at this location')
configWindowBase.settingNotify(c, self.preview3d.updateCenterX)
c = configWindowBase.SettingRow(left, "Machine center Y (mm)", 'machine_center_y', '100', 'The center of your machine, your print will be placed at this location')
validators.validInt(c, 10)
settingNotify(c, self.preview3d.updateCenterY)
configWindowBase.settingNotify(c, self.preview3d.updateCenterY)
#self.AddSetting(left, "Width (mm)", settings.IntSpin().getFromValue(10, "machine_width", None, 1000, 205))
#self.AddSetting(left, "Depth (mm)", settings.IntSpin().getFromValue(10, "machine_depth", None, 1000, 205))
#self.AddSetting(left, "Height (mm)", settings.IntSpin().getFromValue(10, "machine_height", None, 1000, 200))
TitleRow(left, "Machine nozzle")
c = SettingRow(left, "Nozzle size (mm)", 'nozzle_size', '0.4')
configWindowBase.TitleRow(left, "Machine nozzle")
c = configWindowBase.SettingRow(left, "Nozzle size (mm)", 'nozzle_size', '0.4', 'The nozzle size is very important, this is used to calculate the line width of the infill, and used to calculate the amount of outside wall lines and thickness for the wall thickness you entered in the print settings.')
validators.validFloat(c, 0.1, 1.0)
TitleRow(left, "Retraction")
c = SettingRow(left, "Minimal travel (mm)", 'retraction_min_travel', '5.0')
configWindowBase.TitleRow(left, "Retraction")
c = configWindowBase.SettingRow(left, "Minimal travel (mm)", 'retraction_min_travel', '5.0', 'Minimal amount of travel needed for a retraction to happen at all. To make sure you do not get a lot of retractions in a small area')
validators.validFloat(c, 0.0)
c = SettingRow(left, "Speed (mm/s)", 'retraction_speed', '13.5')
c = configWindowBase.SettingRow(left, "Speed (mm/s)", 'retraction_speed', '13.5', 'Speed at which the filament is retracted')
validators.validFloat(c, 0.1)
c = SettingRow(left, "Distance (mm)", 'retraction_amount', '0.0')
c = configWindowBase.SettingRow(left, "Distance (mm)", 'retraction_amount', '0.0', 'Amount of retraction, set at 0 for no retraction at all.')
validators.validFloat(c, 0.0)
c = SettingRow(left, "Extra length on start (mm)", 'retraction_extra', '0.0')
c = configWindowBase.SettingRow(left, "Extra length on start (mm)", 'retraction_extra', '0.0', 'Extra extrusion amount when restarting after a retraction, to better "Prime" your extruder')
validators.validFloat(c, 0.0)
TitleRow(right, "Speed")
c = SettingRow(right, "Travel speed (mm/s)", 'travel_speed', '150')
configWindowBase.TitleRow(right, "Speed")
c = configWindowBase.SettingRow(right, "Travel speed (mm/s)", 'travel_speed', '150', 'Speed at which travel moves are done')
validators.validFloat(c, 1.0)
validators.warningAbove(c, 300.0, "It is highly unlikely that your machine can achieve a travel speed above 150mm/s")
c = SettingRow(right, "Max Z speed (mm/s)", 'max_z_speed', '1.0')
c = configWindowBase.SettingRow(right, "Max Z speed (mm/s)", 'max_z_speed', '1.0', 'Speed at which Z moves are done.')
validators.validFloat(c, 0.5)
c = SettingRow(right, "Bottom layer speed", 'bottom_layer_speed', '25')
c = configWindowBase.SettingRow(right, "Bottom layer speed (mm/s)", 'bottom_layer_speed', '25', 'Print speed for the bottom layer, you want to print the first layer slower so it sticks better to the printer bed.')
validators.validFloat(c, 0.0)
TitleRow(right, "Cool")
configWindowBase.TitleRow(right, "Cool")
#c = SettingRow(right, "Cool type", self.plugins['cool'].preferencesDict['Cool_Type'])
c = SettingRow(right, "Minimal layer time (sec)", 'cool_min_layer_time', '10', 'Minimum time spend in a layer, gives the layer time to cool down before the next layer is put on top. If the layer will be placed down too fast the printer will slow down to make sure it has spend atleast this amount of seconds printing this layer.')
c = configWindowBase.SettingRow(right, "Minimal layer time (sec)", 'cool_min_layer_time', '10', 'Minimum time spend in a layer, gives the layer time to cool down before the next layer is put on top. If the layer will be placed down too fast the printer will slow down to make sure it has spend atleast this amount of seconds printing this layer.')
validators.validFloat(c, 0.0)
TitleRow(right, "Filament")
c = SettingRow(right, "Diameter (mm)", 'filament_diameter', '2.98', 'Diameter of your filament, as accurately as possible.\nIf you cannot measure this value you will have to callibrate it, a higher number means less extrusion, a smaller number generates more extrusion.')
configWindowBase.TitleRow(right, "Filament")
c = configWindowBase.SettingRow(right, "Diameter (mm)", 'filament_diameter', '2.98', 'Diameter of your filament, as accurately as possible.\nIf you cannot measure this value you will have to callibrate it, a higher number means less extrusion, a smaller number generates more extrusion.')
validators.validFloat(c, 1.0)
c = SettingRow(right, "Packing Density", 'filament_density', '1.00', 'Packing density of your filament. This should be 1.00 for PLA and 0.85 for ABS')
c = configWindowBase.SettingRow(right, "Packing Density", 'filament_density', '1.00', 'Packing density of your filament. This should be 1.00 for PLA and 0.85 for ABS')
validators.validFloat(c, 0.5, 1.5)
nb.AddPage(alterationPanel.alterationPanel(nb), "Start/End-GCode")
@ -150,71 +153,16 @@ class mainWindow(wx.Frame):
sizer.Add(sliceButton, (1,2))
self.sizer = sizer
#Create the popup window
self.popup = wx.PopupWindow(self, wx.BORDER_SIMPLE)
self.popup.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
self.popup.text = wx.StaticText(self.popup, -1, '');
self.popup.sizer = wx.BoxSizer()
self.popup.sizer.Add(self.popup.text, flag=wx.EXPAND|wx.ALL, border=1)
self.popup.SetSizer(self.popup.sizer)
if self.filename != None:
self.preview3d.loadModelFile(self.filename)
self.lastPath = os.path.split(self.filename)[0]
self.updateProfileToControls()
self.Fit()
self.Centre()
self.Show(True)
def CreateConfigTab(self, nb, name):
configPanel = wx.Panel(nb);
nb.AddPage(configPanel, name)
leftConfigPanel = wx.Panel(configPanel)
rightConfigPanel = wx.Panel(configPanel)
sizer = wx.GridBagSizer(2, 2)
leftConfigPanel.SetSizer(sizer)
sizer = wx.GridBagSizer(2, 2)
rightConfigPanel.SetSizer(sizer)
sizer = wx.BoxSizer(wx.HORIZONTAL)
configPanel.SetSizer(sizer)
sizer.Add(leftConfigPanel)
sizer.Add(rightConfigPanel)
leftConfigPanel.main = self
rightConfigPanel.main = self
return leftConfigPanel, rightConfigPanel
def OnPopupDisplay(self, setting):
x, y = setting.ctrl.ClientToScreenXY(0, 0)
sx, sy = setting.ctrl.GetSizeTuple()
if setting.validationMsg != '':
self.popup.text.SetLabel(setting.validationMsg + '\n\n' + setting.helpText)
else:
self.popup.text.SetLabel(setting.helpText)
self.popup.text.Wrap(350)
if platform.system() == "Windows":
#for some reason, under windows, the popup is relative to the main window...
wx, wy = self.ClientToScreenXY(0, 0)
x -= wx
y -= wy
self.popup.SetPosition((x, y+sy))
self.popup.Fit()
self.popup.Show(True)
def OnPopupHide(self, e):
self.popup.Show(False)
def OnSettingTextChange(self, e):
for validator in self.validators:
res, err = validator.validate()
if res == validators.ERROR:
validator.ctrl.SetBackgroundColour('Red')
elif res == validators.WARNING:
validator.ctrl.SetBackgroundColour('Orange')
else:
validator.ctrl.SetBackgroundColour(wx.NullColor)
def OnLoadProfile(self, e):
dlg=wx.FileDialog(self, "Select profile file to load", self.lastPath, style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("ini files (*.ini)|*.ini")
@ -239,7 +187,7 @@ class mainWindow(wx.Frame):
dlg.SetWildcard("OBJ, STL files (*.stl;*.obj)|*.stl;*.obj")
if dlg.ShowModal() == wx.ID_OK:
self.filename=dlg.GetPath()
putPreference('lastFile', self.filename)
configWindowBase.putPreference('lastFile', self.filename)
if not(os.path.exists(self.filename)):
return
self.lastPath = os.path.split(self.filename)[0]
@ -260,6 +208,11 @@ class mainWindow(wx.Frame):
self.SetSize(newSize)
self.progressPanelList.append(spp)
def OnExpertOpen(self, e):
acw = advancedConfig.advancedConfigWindow()
acw.Centre()
acw.Show(True)
def removeSliceProgress(self, spp):
self.progressPanelList.remove(spp)
newSize = self.GetSize();
@ -286,111 +239,3 @@ class mainWindow(wx.Frame):
settings.saveGlobalProfile(settings.getDefaultProfilePath())
self.Destroy()
class TitleRow():
def __init__(self, panel, name):
"Add a title row to the configuration panel"
sizer = panel.GetSizer()
self.title = wx.StaticText(panel, -1, name)
self.title.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
sizer.Add(self.title, (sizer.GetRows(),sizer.GetCols()), (1,3), flag=wx.EXPAND)
sizer.Add(wx.StaticLine(panel), (sizer.GetRows()+1,sizer.GetCols()), (1,3), flag=wx.EXPAND)
sizer.SetRows(sizer.GetRows() + 2)
class SettingRow():
def __init__(self, panel, label, configName, defaultValue = '', helpText = 'Help: TODO'):
"Add a setting to the configuration panel"
sizer = panel.GetSizer()
x = sizer.GetRows()
y = sizer.GetCols()
self.validators = []
self.validationMsg = ''
self.helpText = helpText
self.configName = configName
self.label = wx.StaticText(panel, -1, label)
if isinstance(defaultValue, types.StringTypes):
self.ctrl = wx.TextCtrl(panel, -1, settings.getSetting(configName, defaultValue))
else:
self.ctrl = wx.ComboBox(panel, -1, settings.getSetting(configName, defaultValue[0]), choices=defaultValue, style=wx.CB_DROPDOWN|wx.CB_READONLY)
#self.helpButton = wx.Button(panel, -1, "?", style=wx.BU_EXACTFIT)
#self.helpButton.SetToolTip(wx.ToolTip(help))
self.ctrl.Bind(wx.EVT_TEXT, self.OnSettingTextChange)
self.ctrl.Bind(wx.EVT_ENTER_WINDOW, lambda e: panel.main.OnPopupDisplay(self))
self.ctrl.Bind(wx.EVT_LEAVE_WINDOW, panel.main.OnPopupHide)
panel.main.settingControlList.append(self)
sizer.Add(self.label, (x,y), flag=wx.ALIGN_CENTER_VERTICAL)
sizer.Add(self.ctrl, (x,y+1), flag=wx.ALIGN_BOTTOM|wx.EXPAND)
#sizer.Add(helpButton, (x,y+2))
sizer.SetRows(x+1)
def OnSettingTextChange(self, e):
result = validators.SUCCESS
msgs = []
for validator in self.validators:
res, err = validator.validate()
if res == validators.ERROR:
result = res
elif res == validators.WARNING and result != validators.ERROR:
result = res
if res != validators.SUCCESS:
print err
msgs.append(err)
if result == validators.ERROR:
self.ctrl.SetBackgroundColour('Red')
elif result == validators.WARNING:
self.ctrl.SetBackgroundColour('Yellow')
else:
self.ctrl.SetBackgroundColour(wx.NullColour)
self.ctrl.Refresh()
settings.putSetting(self.configName, self.GetValue())
self.validationMsg = '\n'.join(msgs)
def GetValue(self):
return self.ctrl.GetValue()
def SetValue(self, value):
self.ctrl.SetValue(value)
#Settings notify works as a validator, but instead of validating anything, it calls another function, which can use the value.
class settingNotify():
def __init__(self, setting, func):
self.setting = setting
self.setting.validators.append(self)
self.func = func
def validate(self):
try:
f = float(self.setting.GetValue())
self.func(f)
return validators.SUCCESS, ''
except ValueError:
return validators.SUCCESS, ''
def getPreferencePath():
return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../preferences.ini"))
def getPreference(name, default):
if not globals().has_key('globalPreferenceParser'):
globalPreferenceParser = ConfigParser.ConfigParser()
globalPreferenceParser.read(getPreferencePath())
if not globalPreferenceParser.has_option('preference', name):
if not globalPreferenceParser.has_section('preference'):
globalPreferenceParser.add_section('preference')
globalPreferenceParser.set('preference', name, str(default))
print name + " not found in profile, so using default"
return default
return globalPreferenceParser.get('preference', name)
def putPreference(name, value):
#Check if we have a configuration file loaded, else load the default.
if not globals().has_key('globalPreferenceParser'):
globalPreferenceParser = ConfigParser.ConfigParser()
globalPreferenceParser.read(getPreferencePath())
if not globalPreferenceParser.has_section('preference'):
globalPreferenceParser.add_section('preference')
globalPreferenceParser.set('preference', name, str(value))
globalPreferenceParser.write(open(getPreferencePath(), 'w'))

View File

@ -28,6 +28,7 @@ class sliceProgessPanel(wx.Panel):
'speed': 12.759510994,
'raft': 31.4580039978,
'skirt': 19.3436040878,
'joris': 1.0,
'comb': 23.7805759907,
'cool': 27.148763895,
'dimension': 90.4914340973

View File

@ -18,12 +18,12 @@ class validFloat():
try:
f = float(self.setting.GetValue())
if self.minValue != None and f < self.minValue:
return ERROR, 'Should not be below ' + str(self.minValue)
return ERROR, 'This setting should not be below ' + str(self.minValue)
if self.maxValue != None and f > self.maxValue:
return ERROR, 'Should not be above ' + str(self.maxValue)
return ERROR, 'This setting should not be above ' + str(self.maxValue)
return SUCCESS, ''
except ValueError:
return ERROR, str(self.setting.GetValue()) + ' is not a valid number'
return ERROR, '"' + str(self.setting.GetValue()) + '" is not a valid number'
class validInt():
def __init__(self, setting, minValue = None, maxValue = None):
@ -36,12 +36,12 @@ class validInt():
try:
f = int(self.setting.GetValue())
if self.minValue != None and f < self.minValue:
return ERROR, 'Should not be below ' + str(self.minValue)
return ERROR, 'This setting should not be below ' + str(self.minValue)
if self.maxValue != None and f > self.maxValue:
return ERROR, 'Should not be above ' + str(self.maxValue)
return ERROR, 'This setting should not be above ' + str(self.maxValue)
return SUCCESS, ''
except ValueError:
return ERROR, str(self.setting.GetValue()) + ' is not a valid whole number'
return ERROR, '"' + str(self.setting.GetValue()) + '" is not a valid whole number'
class warningAbove():
def __init__(self, setting, minValueForWarning, warningMessage):

View File

@ -1,25 +0,0 @@
G21 ;metric values)
G90 ;absolute positioning
G21
G28 X0 Y0 ;move X/Y to min endstops
G28 Z0 ;move Z to min endstops
; if your prints start too high, try changing the Z0.0 below
; to Z1.0 - the number after the Z is the actual, physical
; height of the nozzle in mm. This can take some messing around
; with to get just right...
G21
G92 X0 Y0 Z0 E0 ;reset software position to front/left/z=0.0
G21
G1 Z15.0 F400 ;move the platform down 15mm
G92 E0 ;zero the extruded length
G21
G1 F75 E5 ;extrude 5mm of feed stock
G1 F75 E3.5 ;reverse feed stock by 1.5mm
G92 E0 ;zero the extruded length again
G21
M1 ;Clean the nozzle then press YES to continue...
G21
G1 X100 Y100 F3500 ;go to the middle of the platform
G1 Z0.0 F400 ;back to Z=0 and start the print!

View File

@ -769,6 +769,8 @@ class FillRepository:
self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Fill', self, '')
self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fill')
self.activateFill = settings.BooleanSetting().getFromValue('Activate Fill', self, True)
self.solidSurfaceTop = settings.BooleanSetting().getFromValue('Solid Surface Top', self, True)
self.overrideFirstLayerSequence = settings.BooleanSetting().getFromValue('Override First Layer Sequence', self, True)
settings.LabelSeparator().getFromRepository(self)
settings.LabelDisplay().getFromName('- Diaphragm -', self )
self.diaphragmPeriod = settings.IntSpin().getFromValue( 20, 'Diaphragm Period (layers):', self, 200, 100 )
@ -862,8 +864,12 @@ class FillSkein:
self.distanceFeedRate.addLine('(<layer> %s )' % rotatedLayer.z)
if layerRemainder >= int(round(self.repository.diaphragmThickness.value)):
for surroundingIndex in xrange(1, self.solidSurfaceThickness + 1):
self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves)
self.addRotatedCarve(layerIndex, surroundingIndex, reverseRotation, surroundingCarves)
if self.repository.solidSurfaceTop.value:
self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves)
self.addRotatedCarve(layerIndex, surroundingIndex, reverseRotation, surroundingCarves)
else:
self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves)
self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves)
if len(surroundingCarves) < self.doubleSolidSurfaceThickness:
extraShells = self.repository.extraShellsAlternatingSolidLayer.value
if self.lastExtraShells != self.repository.extraShellsBase.value:
@ -1085,7 +1091,7 @@ class FillSkein:
self.oldOrderedLocation = getLowerLeftCorner(nestedRings)
extrusionHalfWidth = 0.5 * self.infillWidth
threadSequence = self.threadSequence
if layerIndex < 1:
if layerIndex < 1 and self.repository.overrideFirstLayerSequence.value:
threadSequence = ['edge', 'loops', 'infill']
euclidean.addToThreadsRemove(extrusionHalfWidth, nestedRings, self.oldOrderedLocation, self, threadSequence)
if testLoops != None:

View File

@ -0,0 +1,189 @@
"""
This page is in the table of contents.
The Joris plugin makes the perimiter slowly increase in Z over the layer. This will make vases/cups without a z blob.
==Operation==
The default 'Activate Joris' checkbox is off. When it is on, the Joris plugin will do it's work.
==Settings==
===Layers From===
Default: 1
Defines which layer of the print the joris process starts from.
==Tips==
==Examples==
"""
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.fabmetheus_tools import fabmetheus_interpret
from fabmetheus_utilities.geometry.solids import triangle_mesh
from fabmetheus_utilities.vector3 import Vector3
from fabmetheus_utilities import archive
from fabmetheus_utilities import euclidean
from fabmetheus_utilities import gcodec
from fabmetheus_utilities import intercircle
from fabmetheus_utilities import settings
from skeinforge_application.skeinforge_utilities import skeinforge_craft
from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
from skeinforge_application.skeinforge_utilities import skeinforge_profile
import sys
__author__ = 'Daid (daid303@gmail.com'
__date__ = '$Date: 2012/24/01 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
def getCraftedText(fileName, gcodeText, repository=None):
'Joris a gcode linear move text.'
return getCraftedTextFromText(archive.getTextIfEmpty(fileName, gcodeText), repository)
def getCraftedTextFromText(gcodeText, repository=None):
'Joris a gcode linear move text.'
if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'Joris'):
return gcodeText
if repository == None:
repository = settings.getReadRepository(JorisRepository())
if not repository.activateJoris.value:
return gcodeText
return JorisSkein().getCraftedGcode(gcodeText, repository)
def getIsMinimumSides(loops, sides=3):
'Determine if all the loops have at least the given number of sides.'
for loop in loops:
if len(loop) < sides:
return False
return True
def getNewRepository():
'Get new repository.'
return JorisRepository()
def writeOutput(fileName, shouldAnalyze=True):
'Joris a gcode linear move file. Chain Joris the gcode if it is not already Jorised.'
skeinforge_craft.writeChainTextWithNounMessage(fileName, 'joris', shouldAnalyze)
class JorisRepository:
'A class to handle the Joris settings.'
def __init__(self):
'Set the default settings, execute title & settings fileName.'
skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.joris.html', self )
self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Joris', self, '')
self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Joris')
self.activateJoris = settings.BooleanSetting().getFromValue('Activate Joris', self, False)
settings.LabelSeparator().getFromRepository(self)
self.layersFrom = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers From (index):', self, 912345678, 1)
self.executeTitle = 'Joris'
def execute(self):
'Joris button has been clicked.'
fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
for fileName in fileNames:
writeOutput(fileName)
class JorisSkein:
'A class to Joris a skein of extrusions.'
def __init__(self):
'Initialize.'
self.distanceFeedRate = gcodec.DistanceFeedRate()
self.lines = None
self.layerIndex = -1
self.feedRateMinute = 959.0
self.travelFeedRateMinute = 957.0
self.perimeter = None
self.oldLocation = None
def getCraftedGcode( self, gcodeText, repository ):
'Parse gcode text and store the skin gcode.'
self.lines = archive.getTextLines(gcodeText)
self.repository = repository
self.layersFromBottom = repository.layersFrom.value
self.parseInitialization()
for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
line = self.lines[self.lineIndex]
self.parseLine(line)
return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue())
def parseInitialization(self):
'Parse gcode initialization and store the parameters.'
for self.lineIndex in xrange(len(self.lines)):
line = self.lines[self.lineIndex]
splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
firstWord = gcodec.getFirstWord(splitLine)
self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
if firstWord == '(<layerThickness>':
self.layerThickness = float(splitLine[1])
elif firstWord == '(</extruderInitialization>)':
self.distanceFeedRate.addTagBracketedProcedure('skin')
return
elif firstWord == '(<travelFeedRatePerSecond>':
self.travelFeedRateMinute = 60.0 * float(splitLine[1])
self.distanceFeedRate.addLine(line)
def parseLine(self, line):
'Parse a gcode line and add it to the joris skein.'
splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
if len(splitLine) < 1:
return
firstWord = splitLine[0]
print 'joris:' + firstWord
if firstWord == 'G1':
self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
self.oldLocation = location
if self.perimeter != None:
self.perimeter.append(location.dropAxis())
return
elif firstWord == '(<layer>':
self.layerIndex += 1
settings.printProgress(self.layerIndex, 'joris')
elif firstWord == 'M108':
self.oldFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1])
elif firstWord == '(<edge>':
if self.layerIndex >= self.layersFromBottom:
self.perimeter = []
elif firstWord == '(</edge>)':
self.addJorisedPerimeter()
self.distanceFeedRate.addLine(line)
def addJorisedPerimeter(self):
'Add jorised perimeter.'
if self.perimeter == None:
return
#Calculate the total length of the perimeter.
p = self.oldLocation.dropAxis()
perimeterLength = 0;
for point in self.perimeter[1 :]:
perimeterLength += abs( point - p );
p = point
#Build the perimeter with an increasing Z over the length.
p = self.oldLocation.dropAxis()
len = 0;
self.distanceFeedRate.addLine('M101') # Turn extruder on.
for point in self.perimeter[1 :]:
len += abs( point - p );
p = point
self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, point, self.oldLocation.z + self.layerThickness * len / perimeterLength)
self.distanceFeedRate.addLine('M103') # Turn extruder off.
self.perimeter = None
def main():
'Display the skin dialog.'
if len(sys.argv) > 1:
writeOutput(' '.join(sys.argv[1 :]))
else:
settings.startMainLoopFromConstructor(getNewRepository())
if __name__ == '__main__':
main()

View File

@ -28,7 +28,7 @@ __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agp
def getCraftSequence():
'Get the extrusion craft sequence.'
return 'carve scale bottom preface widen inset fill multiply speed temperature raft skirt chamber tower jitter clip smooth stretch skin comb cool hop wipe oozebane dwindle splodge home lash fillet limit unpause dimension alteration export'.split()
return 'carve scale bottom preface widen inset fill multiply speed temperature raft skirt chamber tower jitter clip smooth stretch skin joris comb cool hop wipe oozebane dwindle splodge home lash fillet limit unpause dimension alteration export'.split()
def getNewRepository():
'Get new repository.'

View File

@ -16,7 +16,7 @@ BUILD_TARGET=win32
##Do we need to create the final archive
ARCHIVE_FOR_DISTRIBUTION=1
##Which version name are we appending to the final archive
BUILD_NAME=Alpha4
BUILD_NAME=NewUI-Beta2
TARGET_DIR=${BUILD_TARGET}-SkeinPyPy-${BUILD_NAME}
##Which versions of external programs to use
@ -66,6 +66,9 @@ if [ $BUILD_TARGET = "win32" ]; then
curl -L -O http://sourceforge.net/projects/pyserial/files/pyserial/${WIN_PYSERIAL_VERSION}/pyserial-${WIN_PYSERIAL_VERSION}.win32.exe/download
mv download pyserial-${WIN_PYSERIAL_VERSION}.exe
fi
if [ ! -f PyOpenGL-3.0.1.win32.exe ]; then
curl -L -O http://sourceforge.net/projects/pyopengl/files/PyOpenGL/3.0.1/PyOpenGL-3.0.1.win32.exe
fi
#Get pypy
if [ ! -f "pypy-${PYPY_VERSION}-win32.zip" ]; then
curl -L -O https://bitbucket.org/pypy/pypy/downloads/pypy-${PYPY_VERSION}-win32.zip
@ -92,11 +95,13 @@ if [ $BUILD_TARGET = "win32" ]; then
7z x PortablePython_${WIN_PORTABLE_PY_VERSION}.exe \$_OUTDIR/App
7z x PortablePython_${WIN_PORTABLE_PY_VERSION}.exe \$_OUTDIR/Lib/site-packages
7z x pyserial-${WIN_PYSERIAL_VERSION}.exe PURELIB
7z x PyOpenGL-3.0.1.win32.exe PURELIB
mkdir -p ${TARGET_DIR}/python
mv \$_OUTDIR/App/* ${TARGET_DIR}/python
mv \$_OUTDIR/Lib/site-packages/wx* ${TARGET_DIR}/python/Lib/site-packages/
mv PURELIB/serial ${TARGET_DIR}/python/Lib
mv PURELIB/OpenGL ${TARGET_DIR}/python/Lib
rm -rf \$_OUTDIR
rm -rf PURELIB
@ -123,7 +128,7 @@ fi
rm -rf ${TARGET_DIR}/pypy/lib-python/2.7/test
#add Skeinforge
cp -a SkeinPyPy ${TARGET_DIR}/SkeinPyPy
cp -a SkeinPyPy_NewUI ${TARGET_DIR}/SkeinPyPy
#Add the SSE2 check if we can build it, else we skip it.
# If we don't have it SkeinPyPy will still function. But crash on machines that don't have SSE2

View File

@ -1,2 +0,0 @@
@python\python.exe SkeinPyPy\skeinforge_application\skeinforge.py

View File

@ -0,0 +1 @@
@python\python.exe SkeinPyPy\SkeinPyPy.py