chiark / gitweb /
.
authorDaid <daid303@gmail.com>
Tue, 28 Feb 2012 18:37:17 +0000 (19:37 +0100)
committerDaid <daid303@gmail.com>
Tue, 28 Feb 2012 18:37:17 +0000 (19:37 +0100)
Merge branch 'master' of github.com:daid/SkeinPyPy

Conflicts:
SkeinPyPy_NewUI/skeinforge_application/alterations/end.gcode
SkeinPyPy_NewUI/skeinforge_application/alterations/start.gcode

13 files changed:
SkeinPyPy_NewUI/fabmetheus_utilities/settings.py
SkeinPyPy_NewUI/newui/advancedConfig.py [new file with mode: 0644]
SkeinPyPy_NewUI/newui/configWindowBase.py [new file with mode: 0644]
SkeinPyPy_NewUI/newui/mainWindow.py
SkeinPyPy_NewUI/newui/sliceProgessPanel.py
SkeinPyPy_NewUI/newui/validators.py
SkeinPyPy_NewUI/skeinforge_application/alterations/start.gcode [deleted file]
SkeinPyPy_NewUI/skeinforge_application/skeinforge_plugins/craft_plugins/fill.py
SkeinPyPy_NewUI/skeinforge_application/skeinforge_plugins/craft_plugins/joris.py [new file with mode: 0644]
SkeinPyPy_NewUI/skeinforge_application/skeinforge_plugins/profile_plugins/extrusion.py
build.sh
scripts/win32/skeinforge.bat [deleted file]
scripts/win32/skeinpypy.bat [new file with mode: 0644]

index 3713501acd82e75111cfbc6f34a0c18d8b38d993..2c46aa8bb58a1d335129260c8aefdba4ceeba7ae 100644 (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",
                }
        }
diff --git a/SkeinPyPy_NewUI/newui/advancedConfig.py b/SkeinPyPy_NewUI/newui/advancedConfig.py
new file mode 100644 (file)
index 0000000..641e039
--- /dev/null
@@ -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()
+
diff --git a/SkeinPyPy_NewUI/newui/configWindowBase.py b/SkeinPyPy_NewUI/newui/configWindowBase.py
new file mode 100644 (file)
index 0000000..730cb73
--- /dev/null
@@ -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'))
+
index ed01fec1595cc62f6d3626bfb19c81ac05ad19aa..b2e06fe06abf072d7d54b3de5b7d7bb712cbba71 100644 (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')
-               self.SetMenuBar(menubar)
                
-               wx.ToolTip.SetDelay(0)
+               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)
                
                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'))
index 2c181ac0156dce72c826fa687811147ed02fd909..a3d3c7056405afc319572989189e89bcf1464f08 100644 (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
index 988609438ef62f5eeeb7d3066b06f90faf83a05e..30c407a45e80c03e970879939f26ce074c600ac5 100644 (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):
diff --git a/SkeinPyPy_NewUI/skeinforge_application/alterations/start.gcode b/SkeinPyPy_NewUI/skeinforge_application/alterations/start.gcode
deleted file mode 100644 (file)
index 7c3248d..0000000
+++ /dev/null
@@ -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!
-
index 75ea0f2058853180b9fde1ea57b6d5587c05cd8d..7cf5bcce346aeb099deb69b9f09d2ae0eeca5d7e 100644 (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:
diff --git a/SkeinPyPy_NewUI/skeinforge_application/skeinforge_plugins/craft_plugins/joris.py b/SkeinPyPy_NewUI/skeinforge_application/skeinforge_plugins/craft_plugins/joris.py
new file mode 100644 (file)
index 0000000..2c7fdbe
--- /dev/null
@@ -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()
index e32917b5c931d2c187a957fc388a7a72ed170ee1..e8f9a9a929767d1c9e91d52d495dbacbcf36790a 100644 (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.'
index 358c743ff5ab03995c3551292cb95b5f7ce95034..8ff80b14f026e751f3af94a2029bad192c0771bb 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -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
diff --git a/scripts/win32/skeinforge.bat b/scripts/win32/skeinforge.bat
deleted file mode 100644 (file)
index 19b9e46..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-@python\python.exe SkeinPyPy\skeinforge_application\skeinforge.py
-
diff --git a/scripts/win32/skeinpypy.bat b/scripts/win32/skeinpypy.bat
new file mode 100644 (file)
index 0000000..ef56c9a
--- /dev/null
@@ -0,0 +1 @@
+@python\python.exe SkeinPyPy\SkeinPyPy.py