diff --git a/localization/i18n/OrcaSlicer.pot b/localization/i18n/OrcaSlicer.pot index d885ff72779..980891d024f 100644 --- a/localization/i18n/OrcaSlicer.pot +++ b/localization/i18n/OrcaSlicer.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-10 14:54+0800\n" +"POT-Creation-Date: 2023-12-02 13:02+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -106,6 +106,9 @@ msgstr "" msgid "Support Generated" msgstr "" +msgid "Gizmo-Place on Face" +msgstr "" + msgid "Lay on face" msgstr "" @@ -151,7 +154,7 @@ msgstr "" msgid "Height range" msgstr "" -msgid "Ctrl + Shift + Enter" +msgid "Alt + Shift + Enter" msgstr "" msgid "Toggle Wireframe" @@ -182,9 +185,15 @@ msgstr "" msgid "Move" msgstr "" +msgid "Gizmo-Move" +msgstr "" + msgid "Rotate" msgstr "" +msgid "Gizmo-Rotate" +msgstr "" + msgid "Optimize orientation" msgstr "" @@ -194,10 +203,10 @@ msgstr "" msgid "Scale" msgstr "" -msgid "Error: Please close all toolbar menus first" +msgid "Gizmo-Scale" msgstr "" -msgid "Tool-Lay on Face" +msgid "Error: Please close all toolbar menus first" msgstr "" msgid "in" @@ -489,6 +498,15 @@ msgstr "" msgid "Remove selection" msgstr "" +msgid "Entering Seam painting" +msgstr "" + +msgid "Leaving Seam painting" +msgstr "" + +msgid "Paint-on seam editing" +msgstr "" + msgid "Font" msgstr "" @@ -683,6 +701,14 @@ msgstr "" msgid "Privacy Policy Update" msgstr "" +msgid "" +"The number of user presets cached in the cloud has exceeded the upper limit, " +"newly created user presets can only be used locally." +msgstr "" + +msgid "Sync user presets" +msgstr "" + msgid "Loading" msgstr "" @@ -876,7 +902,10 @@ msgstr "" msgid "Fix model" msgstr "" -msgid "Export as STL" +msgid "Export as one STL" +msgstr "" + +msgid "Export as STLs" msgstr "" msgid "Reload from disk" @@ -1376,6 +1405,18 @@ msgstr "" msgid "Open Documentation in web browser." msgstr "" +msgid "Color" +msgstr "" + +msgid "Pause" +msgstr "" + +msgid "Template" +msgstr "" + +msgid "Custom" +msgstr "" + msgid "Pause:" msgstr "" @@ -1451,7 +1492,7 @@ msgstr "" msgid "Failed to connect to the server" msgstr "" -msgid "Check cloud service status" +msgid "Check the status of current system services" msgstr "" msgid "code" @@ -1617,7 +1658,7 @@ msgstr "" msgid "Orienting" msgstr "" -msgid "Filling bed " +msgid "Filling" msgstr "" msgid "Bed filling canceled." @@ -1690,6 +1731,14 @@ msgstr "" msgid "Sending print job through cloud service" msgstr "" +msgid "Print task sending times out." +msgstr "" + +msgid "" +"The printer timed out while receiving a print job. Please check if the " +"network is functioning properly and send the print again." +msgstr "" + msgid "Service Unavailable" msgstr "" @@ -1802,16 +1851,16 @@ msgstr "" msgid "License" msgstr "" -msgid "Orca Slicer - Printago Edition is licensed under " +msgid "Orca Slicer is licensed under " msgstr "" msgid "GNU Affero General Public License, version 3" msgstr "" msgid "" -"Orca Slicer - Printago Edition is based on Orca Slicer, which is based on BambuStudio by Bambulab, -"which is from PrusaSlicer by Prusa Research. PrusaSlicer is from Slic3r by Alessandro Ranellucci" -"and the RepRap community" +"Orca Slicer is based on BambuStudio by Bambulab, which is from PrusaSlicer " +"by Prusa Research. PrusaSlicer is from Slic3r by Alessandro Ranellucci and " +"the RepRap community" msgstr "" msgid "Libraries" @@ -1826,10 +1875,10 @@ msgstr "" msgid "About %s" msgstr "" -msgid "based on Orca Slicer " +msgid "Orca Slicer " msgstr "" -msgid "OrcaSlicer - Printago Edition is based on OrcaSlicer, BambuStudio, PrusaSlicer, and SuperSlicer." +msgid "OrcaSlicer is based on BambuStudio, PrusaSlicer, and SuperSlicer." msgstr "" msgid "BambuStudio is originally based on PrusaSlicer by PrusaResearch." @@ -1900,10 +1949,10 @@ msgstr "" msgid "You need to select the material type and color first." msgstr "" -msgid "Please input a valid value (K in 0~0.5)" +msgid "Please input a valid value (K in 0~0.3)" msgstr "" -msgid "Please input a valid value (K in 0~0.5, N in 0.6~2.0)" +msgid "Please input a valid value (K in 0~0.3, N in 0.6~2.0)" msgstr "" msgid "Other Color" @@ -2239,9 +2288,6 @@ msgstr "" msgid "Circular" msgstr "" -msgid "Custom" -msgstr "" - msgid "Load shape from STL..." msgstr "" @@ -2378,16 +2424,6 @@ msgid "" "NO - Keep Independent Support Layer Height" msgstr "" -#, possible-boost-format -msgid "%1% infill pattern doesn't support 100%% density." -msgstr "" - -msgid "" -"Switch to rectilinear pattern?\n" -"Yes - switch to rectilinear pattern automaticlly\n" -"No - reset density to default non 100% value automaticlly" -msgstr "" - msgid "" "While printing by Object, the extruder may collide skirt.\n" "Thus, reset the skirt layer to 1 to avoid that." @@ -2486,6 +2522,18 @@ msgstr "" msgid "Motor noise showoff" msgstr "" +msgid "Nozzle filament covered detected pause" +msgstr "" + +msgid "Cutter error pause" +msgstr "" + +msgid "First layer error pause" +msgstr "" + +msgid "Nozzle clog pause" +msgstr "" + msgid "MC" msgstr "" @@ -2675,6 +2723,9 @@ msgstr "" msgid "Total" msgstr "" +msgid "Tower" +msgstr "" + msgid "Total Estimation" msgstr "" @@ -2762,15 +2813,18 @@ msgstr "" msgid "Print" msgstr "" -msgid "Pause" -msgstr "" - msgid "Printer" msgstr "" msgid "Print settings" msgstr "" +msgid "Custom g-code" +msgstr "" + +msgid "ToolChange" +msgstr "" + msgid "Time Estimation" msgstr "" @@ -2993,15 +3047,15 @@ msgstr "" msgid "Start Calibration" msgstr "" -msgid "No step selected" -msgstr "" - msgid "Completed" msgstr "" msgid "Calibrating" msgstr "" +msgid "No step selected" +msgstr "" + msgid "Auto-record Monitoring" msgstr "" @@ -3214,7 +3268,10 @@ msgstr "" msgid "Import" msgstr "" -msgid "Export all objects as STL" +msgid "Export all objects as one STL" +msgstr "" + +msgid "Export all objects as STLs" msgstr "" msgid "Export Generic 3MF" @@ -3304,6 +3361,12 @@ msgstr "" msgid "Use Orthogonal View" msgstr "" +msgid "Show &G-code Window" +msgstr "" + +msgid "Show g-code window in Previce scene" +msgstr "" + msgid "Show &Labels" msgstr "" @@ -3484,9 +3547,6 @@ msgstr "" msgid "Printer is busy downloading, Please wait for the downloading to finish." msgstr "" -msgid "Loading..." -msgstr "" - msgid "Initialize failed (Not supported on the current printer version)!" msgstr "" @@ -3544,6 +3604,9 @@ msgstr "" msgid "Load failed [%d]!" msgstr "" +msgid "Loading..." +msgstr "" + msgid "Year" msgstr "" @@ -3661,12 +3724,28 @@ msgstr "" msgid "Downloading %d%%..." msgstr "" +msgid "Connection lost. Please retry." +msgstr "" + +msgid "The device cannot handle more conversations. Please retry later." +msgstr "" + +msgid "File not exists." +msgstr "" + +msgid "File checksum error. Please retry." +msgstr "" + msgid "Not supported on the current printer version." msgstr "" msgid "Storage unavailable, insert SD card." msgstr "" +#, possible-c-format, possible-boost-format +msgid "Error code: %d" +msgstr "" + msgid "Speed:" msgstr "" @@ -3806,7 +3885,9 @@ msgstr "" msgid "Layer: %d/%d" msgstr "" -msgid "Please heat the nozzle to above 170 degree before loading filament." +msgid "" +"Please heat the nozzle to above 170 degree before loading or unloading " +"filament." msgstr "" msgid "Still unload" @@ -3995,6 +4076,12 @@ msgstr "" msgid "Details" msgstr "" +msgid "New printer config available." +msgstr "" + +msgid "Wiki" +msgstr "" + msgid "Undo integration failed." msgstr "" @@ -4043,9 +4130,6 @@ msgstr "" msgid "Cancel upload" msgstr "" -msgid "Slice ok." -msgstr "" - msgid "Jump to" msgstr "" @@ -4145,6 +4229,9 @@ msgstr "" msgid "Allow Prompt Sound" msgstr "" +msgid "Fliament Tangle Detect" +msgstr "" + msgid "Global" msgstr "" @@ -4239,6 +4326,9 @@ msgstr "" msgid "Set filaments to use" msgstr "" +msgid "Search plate, object and part." +msgstr "" + msgid "" "No AMS filaments. Please select a printer in 'Device' page to load AMS info." msgstr "" @@ -4324,34 +4414,32 @@ msgstr "" msgid "The 3mf is generated by old Orca Slicer, load geometry data only." msgstr "" -#, possible-c-format, possible-boost-format -msgid "" -"The 3mf's version %s is newer than %s's version %s, Found following keys " -"unrecognized:" +msgid "Invalid values found in the 3mf:" msgstr "" -msgid "You'd better upgrade your software.\n" +msgid "Please correct them in the param tabs" msgstr "" -msgid "Newer 3mf version" +msgid "The 3mf has following modified G-codes in filament or printer presets:" msgstr "" -#, possible-c-format, possible-boost-format msgid "" -"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " -"software." +"Please confirm that these modified G-codes are safe to prevent any damage to " +"the machine!" msgstr "" -msgid "Invalid values found in the 3mf:" +msgid "Modified G-codes" msgstr "" -msgid "Please correct them in the param tabs" +msgid "The 3mf has following customized filament or printer presets:" msgstr "" -msgid "The 3mf is not compatible, load geometry data only!" +msgid "" +"Please confirm that the G-codes within these presets are safe to prevent any " +"damage to the machine!" msgstr "" -msgid "Incompatible 3mf" +msgid "Customized Preset" msgstr "" msgid "Name of components inside step file is not UTF8 format!" @@ -4417,6 +4505,15 @@ msgstr "" msgid "Export OBJ file:" msgstr "" +#, possible-c-format, possible-boost-format +msgid "" +"The file %s already exists\n" +"Do you want to replace it?" +msgstr "" + +msgid "Comfirm Save As" +msgstr "" + msgid "Delete object which is a part of cut object" msgstr "" @@ -4432,15 +4529,15 @@ msgstr "" msgid "Another export job is running." msgstr "" -msgid "Replace from:" -msgstr "" - msgid "Unable to replace with more than one volume" msgstr "" msgid "Error during replace" msgstr "" +msgid "Replace from:" +msgstr "" + msgid "Select a new file" msgstr "" @@ -4784,10 +4881,10 @@ msgstr "" msgid "If enabled, useful hints are displayed at startup." msgstr "" -msgid "Show g-code window" +msgid "Flushing volumes: Auto-calculate everytime the color changed." msgstr "" -msgid "If enabled, g-code window will be displayed." +msgid "If enabled, auto-calculate everytime the color changed." msgstr "" msgid "Presets" @@ -4838,6 +4935,9 @@ msgstr "" msgid "Clear my choice on the unsaved projects." msgstr "" +msgid "No warnings when loading 3MF with modified G-codes" +msgstr "" + msgid "Auto-Backup" msgstr "" @@ -4989,7 +5089,10 @@ msgstr "" msgid "Add/Remove materials" msgstr "" -msgid "Add/Remove printers" +msgid "Select/Remove printers(system presets)" +msgstr "" + +msgid "Create printer" msgstr "" msgid "Incompatible" @@ -5142,6 +5245,9 @@ msgstr "" msgid "(LAN)" msgstr "" +msgid "Search" +msgstr "" + msgid "My Device" msgstr "" @@ -5172,16 +5278,16 @@ msgstr "" msgid "PLA Plate" msgstr "" -msgid "Bambu Engineering Plate" +msgid "Bamabu Engineering Plate" msgstr "" -msgid "Bambu Smooth PEI Plate" +msgid "Bamabu Smooth PEI Plate" msgstr "" msgid "High temperature Plate" msgstr "" -msgid "Bambu Textured PEI Plate" +msgid "Bamabu Textured PEI Plate" msgstr "" msgid "Send print job to" @@ -5205,9 +5311,6 @@ msgstr "" msgid "Error code" msgstr "" -msgid "Check the status of current system services" -msgstr "" - msgid "Printer local connection failed, please try again." msgstr "" @@ -5296,8 +5399,7 @@ msgid "" msgstr "" msgid "" -"When print by object, machines with I3 structure will not generate timelapse " -"videos." +"Timelapse is not supported because Print sequence is set to \"By object\"." msgstr "" msgid "Errors" @@ -5312,20 +5414,39 @@ msgid "" "type for slicing." msgstr "" -#, possible-c-format, possible-boost-format -msgid "%s is not supported by AMS." -msgstr "" - msgid "" "There are some unknown filaments in the AMS mappings. Please check whether " "they are the required filaments. If they are okay, press \"Confirm\" to " "start printing." msgstr "" +#, possible-c-format, possible-boost-format +msgid "nozzle in preset: %s %s" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "nozzle memorized: %.1f %s" +msgstr "" + +msgid "" +"Your nozzle diameter in preset is not consistent with memorized nozzle " +"diameter. Did you change your nozzle lately?" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "*Printing %s material with %s may cause nozzle damage" +msgstr "" + msgid "" "Please click the confirm button if you still want to proceed with printing." msgstr "" +msgid "Hardened Steel" +msgstr "" + +msgid "Stainless Steel" +msgstr "" + msgid "" "Connecting to the printer. Unable to cancel during the connection process." msgstr "" @@ -5365,6 +5486,12 @@ msgstr "" msgid "The printer does not support sending to printer SD card." msgstr "" +msgid "Slice ok." +msgstr "" + +msgid "View all Daily tips" +msgstr "" + msgid "Failed to create socket" msgstr "" @@ -5487,6 +5614,9 @@ msgid "" "model without prime tower. Do you want to enable prime tower?" msgstr "" +msgid "Still print by object?" +msgstr "" + msgid "" "We have added an experimental style \"Tree Slim\" that features smaller " "support volume but weaker strength.\n" @@ -5512,6 +5642,20 @@ msgid "" "independent support layer height" msgstr "" +msgid "" +"Layer height exceeds the limit in Printer Settings -> Extruder -> Layer " +"height limits ,this may cause printing quality issues." +msgstr "" + +msgid "Adjust to the set range automatically? \n" +msgstr "" + +msgid "Adjust" +msgstr "" + +msgid "Ignore" +msgstr "" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -5756,6 +5900,9 @@ msgstr "" msgid "Machine end G-code" msgstr "" +msgid "Printing by object G-code" +msgstr "" + msgid "Before layer change G-code" msgstr "" @@ -5822,18 +5969,38 @@ msgstr "" msgid "Detached" msgstr "" +#, possible-c-format, possible-boost-format +msgid "" +"%d Filament Preset and %d Process Preset is attached to this printer. Those " +"presets would be deleted if the printer is deleted." +msgstr "" + +msgid "Presets inherited by other presets can not be deleted!" +msgstr "" + +msgid "The following presets inherit this preset." +msgid_plural "The following preset inherits this preset." +msgstr[0] "" +msgstr[1] "" + +#. TRN Remove/Delete +#, possible-boost-format +msgid "%1% Preset" +msgstr "" + msgid "Following preset will be deleted too." msgid_plural "Following presets will be deleted too." msgstr[0] "" msgstr[1] "" -#, possible-boost-format -msgid "Are you sure to %1% the selected preset?" +msgid "" +"Are you sure to delete the selected preset? \n" +"If the preset corresponds to a filament currently in use on your printer, " +"please reset the filament information for that slot." msgstr "" -#. TRN Remove/Delete #, possible-boost-format -msgid "%1% Preset" +msgid "Are you sure to %1% the selected preset?" msgstr "" msgid "All" @@ -6057,10 +6224,16 @@ msgstr "" msgid "Auto-Calc" msgstr "" +msgid "Re-calculate" +msgstr "" + msgid "Flushing volumes for filament change" msgstr "" -msgid "Multiplier" +msgid "" +"Studio would re-calculate your flushing volumes everytime the filaments " +"color changed. You could disable the auto-calculate in Bambu Studio > " +"Preferences" msgstr "" msgid "Flushing volume (mm³) for each filament pair." @@ -6074,6 +6247,9 @@ msgstr "" msgid "The multiplier should be in range [%.2f, %.2f]." msgstr "" +msgid "Multiplier" +msgstr "" + msgid "unloaded" msgstr "" @@ -6089,6 +6265,12 @@ msgstr "" msgid "To" msgstr "" +msgid "Bambu Network plug-in not detected." +msgstr "" + +msgid "Click here to download it." +msgstr "" + msgid "Login" msgstr "" @@ -6122,6 +6304,9 @@ msgstr "" msgid "Show/Hide 3Dconnexion devices settings dialog" msgstr "" +msgid "Switch table page" +msgstr "" + msgid "Show keyboard shortcuts list" msgstr "" @@ -6368,12 +6553,15 @@ msgstr "" msgid "New version of Orca Slicer" msgstr "" -msgid "Don't remind me of this version again" +msgid "Skip this Version" msgstr "" msgid "Done" msgstr "" +msgid "Confirm and Update Nozzle" +msgstr "" + msgid "LAN Connection Failed (Sending print file)" msgstr "" @@ -6395,7 +6583,21 @@ msgstr "" msgid "Where to find your printer's IP and Access Code?" msgstr "" -msgid "Error: IP or Access Code are not correct" +msgid "Step 3: Ping the IP address to check for packet loss and latency." +msgstr "" + +msgid "Test" +msgstr "" + +msgid "IP and Access Code Verified! You may close the window" +msgstr "" + +msgid "Connection failed, please double check IP and Access Code" +msgstr "" + +msgid "" +"Connection failed! If your IP and Access Code is correct, \n" +"please move to step 3 for troubleshooting network issues" msgstr "" msgid "Model:" @@ -6753,6 +6955,25 @@ msgstr "" msgid "Variable layer height is not supported with Organic supports." msgstr "" +msgid "" +"Different nozzle diameters and different filament diameters is not allowed " +"when prime tower is enabled." +msgstr "" + +msgid "" +"The Wipe Tower is currently only supported with the relative extruder " +"addressing (use_relative_e_distances=1)." +msgstr "" + +msgid "" +"Ooze prevention is currently not supported with the prime tower enabled." +msgstr "" + +msgid "" +"The prime tower is currently only supported for the Marlin, RepRap/Sprinter, " +"RepRapFirmware and Repetier G-code flavors." +msgstr "" + msgid "The prime tower is not supported in \"By object\" print." msgstr "" @@ -7121,6 +7342,15 @@ msgid "" "material for bridge, to improve sag" msgstr "" +msgid "Internal bridge flow" +msgstr "" + +msgid "" +"This value governs the thickness of the internal bridge layer. This is the " +"first layer over sparse infill. Decrease this value slightly (for example " +"0.9) to improve surface quality over sparse infill." +msgstr "" + msgid "Top surface flow ratio" msgstr "" @@ -7191,7 +7421,28 @@ msgstr "" msgid "" "Extrude perimeters that have a part over an overhang in the reverse " "direction on odd layers. This alternating pattern can drastically improve " -"steep overhang." +"steep overhangs.\n" +"\n" +"This setting can also help reduce part warping due to the reduction of " +"stresses in the part walls." +msgstr "" + +msgid "Reverse only internal perimeters" +msgstr "" + +msgid "" +"Apply the reverse perimeters logic only on internal perimeters. \n" +"\n" +"This setting greatly reduces part stresses as they are now distributed in " +"alternating directions. This should reduce part warping while also " +"maintaining external wall quality. This feature can be very useful for warp " +"prone material, like ABS/ASA, and also for elastic filaments, like TPU and " +"Silk PLA. It can also help reduce warping on floating regions over " +"supports.\n" +"\n" +"For this setting to be the most effective, it is recomended to set the " +"Reverse Threshold to 0 so that all internal walls print in alternating " +"directions on odd layers irrespective of their overhang degree." msgstr "" msgid "Reverse threshold" @@ -7392,6 +7643,15 @@ msgid "" "shorter bridged distances." msgstr "" +msgid "Thick internal bridges" +msgstr "" + +msgid "" +"If enabled, thick internal bridges will be used. It's usually recommended to " +"have this feature turned on. However, consider turning it off if you are " +"using large nozzles." +msgstr "" + msgid "Max bridge length" msgstr "" @@ -7407,6 +7667,14 @@ msgstr "" msgid "End G-code when finish the whole printing" msgstr "" +msgid "Between Object Gcode" +msgstr "" + +msgid "" +"Insert Gcode between objects. This parameter will only come into effect when " +"you print your models object by object" +msgstr "" + msgid "End G-code when finish the printing of this filament" msgstr "" @@ -7489,25 +7757,25 @@ msgid "" "This sets the threshold for small perimeter length. Default threshold is 0mm" msgstr "" -msgid "Order of inner wall/outer wall/infil" +msgid "Order of walls" msgstr "" -msgid "Print sequence of inner wall, outer wall and infill. " +msgid "Print sequence of inner wall and outer wall. " msgstr "" -msgid "inner/outer/infill" +msgid "inner/outer" msgstr "" -msgid "outer/inner/infill" +msgid "outer/inner" msgstr "" -msgid "infill/inner/outer" +msgid "inner wall/outer wall/inner wall" msgstr "" -msgid "infill/outer/inner" +msgid "Print infill first" msgstr "" -msgid "inner-outer-inner/infill" +msgid "Order of wall/infill. false means print wall first. " msgstr "" msgid "Height to rod" @@ -7590,9 +7858,6 @@ msgstr "" msgid "Default filament color" msgstr "" -msgid "Color" -msgstr "" - msgid "Filament notes" msgstr "" @@ -7818,8 +8083,10 @@ msgstr "" msgid "Sparse infill density" msgstr "" -#, possible-c-format -msgid "Density of internal sparse infill, 100% means solid throughout" +#, possible-c-format, possible-boost-format +msgid "" +"Density of internal sparse infill, 100% turns all sparse infill into solid " +"infill and internal solid infill pattern will be used" msgstr "" msgid "Sparse infill pattern" @@ -7952,10 +8219,6 @@ msgid "" "Klipper's max_accel_to_decel will be adjusted to this %% of acceleration" msgstr "" -#, possible-c-format, possible-boost-format -msgid "%%" -msgstr "" - msgid "Jerk of outer walls" msgstr "" @@ -8070,6 +8333,12 @@ msgid "" "segment" msgstr "" +msgid "Apply fuzzy skin to first layer" +msgstr "" + +msgid "Whether to apply fuzzy skin on the first layer" +msgstr "" + msgid "Filter out tiny gaps" msgstr "" @@ -8290,6 +8559,18 @@ msgid "" "soluble support material" msgstr "" +msgid "Maximum width of a segmented region" +msgstr "" + +msgid "Maximum width of a segmented region. Zero disables this feature." +msgstr "" + +msgid "Interlocking depth of a segmented region" +msgstr "" + +msgid "Interlocking depth of a segmented region. Zero disables this feature." +msgstr "" + msgid "Ironing Type" msgstr "" @@ -8788,6 +9069,22 @@ msgid "" "print when travel move. Using spiral line to lift z can prevent stringing" msgstr "" +msgid "Z hop lower boundary" +msgstr "" + +msgid "" +"Z hop will only come into effect when Z is above this value and is below the " +"parameter: \"Z hop upper boundary\"" +msgstr "" + +msgid "Z hop upper boundary" +msgstr "" + +msgid "" +"If this value is positive, Z hop will only come into effect when Z is above " +"the parameter: \"Z hop lower boundary\" and is below this value" +msgstr "" + msgid "Z hop type" msgstr "" @@ -9170,6 +9467,12 @@ msgid "" "filament for support and current filament is used" msgstr "" +msgid "Reduce interface filament for base" +msgstr "" + +msgid "Avoid using support interface filament to print support base" +msgstr "" + msgid "" "Line width of support. If expressed as a %, it will be computed over the " "nozzle diameter." @@ -9199,6 +9502,12 @@ msgstr "" msgid "Bottom interface layers" msgstr "" +msgid "Number of bottom interface layers" +msgstr "" + +msgid "Same as top" +msgstr "" + msgid "Top interface spacing" msgstr "" @@ -9390,10 +9699,10 @@ msgid "" "double walls." msgstr "" -msgid "Tree support wall loops" +msgid "Support wall loops" msgstr "" -msgid "This setting specify the count of walls around tree support" +msgid "This setting specify the count of walls around support" msgstr "" msgid "Tree support with infill" @@ -9752,10 +10061,6 @@ msgstr "" msgid "invalid value " msgstr "" -#, possible-c-format, possible-boost-format -msgid " doesn't work at 100%% density " -msgstr "" - msgid "Invalid value when spiral vase mode is enabled: " msgstr "" @@ -9765,111 +10070,18 @@ msgstr "" msgid " not in range " msgstr "" -msgid "Export 3MF" -msgstr "" - -msgid "Export project as 3MF." -msgstr "" - -msgid "Export slicing data" -msgstr "" - -msgid "Export slicing data to a folder." -msgstr "" - -msgid "Load slicing data" -msgstr "" - -msgid "Load cached slicing data from directory" -msgstr "" - -msgid "Export STL" -msgstr "" - -msgid "Export the objects as multiple STL." -msgstr "" - -msgid "Slice" -msgstr "" - -msgid "Slice the plates: 0-all plates, i-plate i, others-invalid" -msgstr "" - -msgid "Show command help." -msgstr "" - -msgid "UpToDate" -msgstr "" - -msgid "Update the configs values of 3mf to latest." -msgstr "" - -msgid "Load default filaments" -msgstr "" - -msgid "Load first filament as default for those not loaded" -msgstr "" - msgid "Minimum save" msgstr "" msgid "export 3mf with minimum size." msgstr "" -msgid "mtcpp" -msgstr "" - -msgid "max triangle count per plate for slicing." -msgstr "" - -msgid "mstpp" -msgstr "" - -msgid "max slicing time per plate in seconds." -msgstr "" - msgid "No check" msgstr "" msgid "Do not run any validity checks, such as gcode path conflicts check." msgstr "" -msgid "Normative check" -msgstr "" - -msgid "Check the normative items." -msgstr "" - -msgid "Output Model Info" -msgstr "" - -msgid "Output the model's information." -msgstr "" - -msgid "Export Settings" -msgstr "" - -msgid "Export settings to a file." -msgstr "" - -msgid "Send progress to pipe" -msgstr "" - -msgid "Send progress to pipe." -msgstr "" - -msgid "Arrange Options" -msgstr "" - -msgid "Arrange options: 0-disable, 1-enable, others-auto" -msgstr "" - -msgid "Repetions count" -msgstr "" - -msgid "Repetions count of the whole model" -msgstr "" - msgid "Ensure on bed" msgstr "" @@ -9877,12 +10089,6 @@ msgid "" "Lift the object above the bed when it is partially below. Disabled by default" msgstr "" -msgid "Convert Unit" -msgstr "" - -msgid "Convert the units of model" -msgstr "" - msgid "Orient Options" msgstr "" @@ -9892,47 +10098,12 @@ msgstr "" msgid "Rotation angle around the Z axis in degrees." msgstr "" -msgid "Rotate around X" -msgstr "" - -msgid "Rotation angle around the X axis in degrees." -msgstr "" - msgid "Rotate around Y" msgstr "" msgid "Rotation angle around the Y axis in degrees." msgstr "" -msgid "Scale the model by a float factor" -msgstr "" - -msgid "Load General Settings" -msgstr "" - -msgid "Load process/machine settings from the specified file" -msgstr "" - -msgid "Load Filament Settings" -msgstr "" - -msgid "Load filament settings from the specified file list" -msgstr "" - -msgid "Skip Objects" -msgstr "" - -msgid "Skip some objects in this print" -msgstr "" - -msgid "load uptodate process/machine settings when using uptodate" -msgstr "" - -msgid "" -"load uptodate process/machine settings from the specified file when using " -"uptodate" -msgstr "" - msgid "Data directory" msgstr "" @@ -9942,20 +10113,6 @@ msgid "" "storage." msgstr "" -msgid "Output directory" -msgstr "" - -msgid "Output directory for the exported files." -msgstr "" - -msgid "Debug level" -msgstr "" - -msgid "" -"Sets debug logging level. 0:fatal, 1:error, 2:warning, 3:info, 4:debug, 5:" -"trace\n" -msgstr "" - msgid "Load custom gcode" msgstr "" @@ -10110,9 +10267,6 @@ msgstr "" msgid "Finish" msgstr "" -msgid "Wiki" -msgstr "" - msgid "How to use calibration result?" msgstr "" @@ -10128,6 +10282,12 @@ msgstr "" msgid "Calibration not supported" msgstr "" +msgid "Error desc" +msgstr "" + +msgid "Extra info" +msgstr "" + msgid "Flow Dynamics" msgstr "" @@ -10155,8 +10315,8 @@ msgstr "" msgid "The name cannot be empty." msgstr "" -#, possible-boost-format -msgid "The selected preset: %1% is not found." +#, possible-c-format, possible-boost-format +msgid "The selected preset: %s is not found." msgstr "" msgid "The name cannot be the same as the system preset name." @@ -10436,12 +10596,6 @@ msgid "" "- Different filament brand and family(Brand = Bambu, Family = Basic, Matte)" msgstr "" -msgid "Error desc" -msgstr "" - -msgid "Extra info" -msgstr "" - msgid "Pattern" msgstr "" @@ -10530,101 +10684,6 @@ msgid "" "Please select one that should be used." msgstr "" -msgid "Unable to perform boolean operation on selected parts" -msgstr "" - -msgid "Mesh Boolean" -msgstr "" - -msgid "Union" -msgstr "" - -msgid "Difference" -msgstr "" - -msgid "Intersection" -msgstr "" - -msgid "Source Volume" -msgstr "" - -msgid "Tool Volume" -msgstr "" - -msgid "Subtract from" -msgstr "" - -msgid "Subtract with" -msgstr "" - -msgid "selected" -msgstr "" - -msgid "Part 1" -msgstr "" - -msgid "Part 2" -msgstr "" - -msgid "Delete input" -msgstr "" - -msgid "Send G-Code to printer host" -msgstr "" - -msgid "Upload to Printer Host with the following filename:" -msgstr "" - -msgid "Use forward slashes ( / ) as a directory separator if needed." -msgstr "" - -msgid "Upload to storage" -msgstr "" - -#, possible-c-format, possible-boost-format -msgid "Upload filename doesn't end with \"%s\". Do you wish to continue?" -msgstr "" - -msgid "Upload" -msgstr "" - -msgid "Print host upload queue" -msgstr "" - -msgid "ID" -msgstr "" - -msgid "Progress" -msgstr "" - -msgid "Host" -msgstr "" - -msgctxt "OfFile" -msgid "Size" -msgstr "" - -msgid "Filename" -msgstr "" - -msgid "Cancel selected" -msgstr "" - -msgid "Show error message" -msgstr "" - -msgid "Enqueued" -msgstr "" - -msgid "Uploading" -msgstr "" - -msgid "Cancelling" -msgstr "" - -msgid "Error uploading to print host" -msgstr "" - msgid "PA Calibration" msgstr "" @@ -10749,16 +10808,620 @@ msgstr "" msgid "mm/mm" msgstr "" -msgid "Physical Printer" +msgid "Send G-Code to printer host" msgstr "" -msgid "Print Host upload" +msgid "Upload to Printer Host with the following filename:" msgstr "" -msgid "Test" +msgid "Use forward slashes ( / ) as a directory separator if needed." msgstr "" -msgid "Could not get a valid Printer Host reference" +msgid "Upload to storage" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "Upload filename doesn't end with \"%s\". Do you wish to continue?" +msgstr "" + +msgid "Upload" +msgstr "" + +msgid "Print host upload queue" +msgstr "" + +msgid "ID" +msgstr "" + +msgid "Progress" +msgstr "" + +msgid "Host" +msgstr "" + +msgctxt "OfFile" +msgid "Size" +msgstr "" + +msgid "Filename" +msgstr "" + +msgid "Cancel selected" +msgstr "" + +msgid "Show error message" +msgstr "" + +msgid "Enqueued" +msgstr "" + +msgid "Uploading" +msgstr "" + +msgid "Cancelling" +msgstr "" + +msgid "Error uploading to print host" +msgstr "" + +msgid "Unable to perform boolean operation on selected parts" +msgstr "" + +msgid "Mesh Boolean" +msgstr "" + +msgid "Union" +msgstr "" + +msgid "Difference" +msgstr "" + +msgid "Intersection" +msgstr "" + +msgid "Source Volume" +msgstr "" + +msgid "Tool Volume" +msgstr "" + +msgid "Subtract from" +msgstr "" + +msgid "Subtract with" +msgstr "" + +msgid "selected" +msgstr "" + +msgid "Part 1" +msgstr "" + +msgid "Part 2" +msgstr "" + +msgid "Delete input" +msgstr "" + +msgid "Network Test" +msgstr "" + +msgid "Start Test Multi-Thread" +msgstr "" + +msgid "Start Test Single-Thread" +msgstr "" + +msgid "Export Log" +msgstr "" + +msgid "Studio Version:" +msgstr "" + +msgid "System Version:" +msgstr "" + +msgid "DNS Server:" +msgstr "" + +msgid "Test BambuLab" +msgstr "" + +msgid "Test BambuLab:" +msgstr "" + +msgid "Test Bing.com" +msgstr "" + +msgid "Test bing.com:" +msgstr "" + +msgid "Test HTTP" +msgstr "" + +msgid "Test HTTP Service:" +msgstr "" + +msgid "Test storage" +msgstr "" + +msgid "Test Storage Upload:" +msgstr "" + +msgid "Test storage upgrade" +msgstr "" + +msgid "Test Storage Upgrade:" +msgstr "" + +msgid "Test storage download" +msgstr "" + +msgid "Test Storage Download:" +msgstr "" + +msgid "Test plugin download" +msgstr "" + +msgid "Test Plugin Download:" +msgstr "" + +msgid "Test Storage Upload" +msgstr "" + +msgid "Log Info" +msgstr "" + +msgid "Select filament preset" +msgstr "" + +msgid "Create Filament" +msgstr "" + +msgid "Create Based on Current Filament" +msgstr "" + +msgid "Copy Current Filament Preset " +msgstr "" + +msgid "Basic Information" +msgstr "" + +msgid "Add Filament Preset under this filament" +msgstr "" + +msgid "We could create the filament presets for your following printer:" +msgstr "" + +msgid "Select Vendor" +msgstr "" + +msgid "Input Custom Vendor" +msgstr "" + +msgid "Can't find vendor I want" +msgstr "" + +msgid "Select Type" +msgstr "" + +msgid "Select Filament Preset" +msgstr "" + +msgid "Serial" +msgstr "" + +msgid "e.g. Basic, Matte, Silk, Marble" +msgstr "" + +msgid "Filament Preset" +msgstr "" + +msgid "Create" +msgstr "" + +msgid "Vendor is not selected, please reselect vendor." +msgstr "" + +msgid "Custom vendor is not input, please input custom vendor." +msgstr "" + +msgid "" +"\"Bambu\" or \"Generic\" can not be used as a Vendor for custom filaments." +msgstr "" + +msgid "Filament type is not selected, please reselect type." +msgstr "" + +msgid "Filament serial is not inputed, please input serial." +msgstr "" + +msgid "" +"There may be escape characters in the vendor or serial input of filament. " +"Please delete and re-enter." +msgstr "" + +msgid "All inputs in the custom vendor or serial are spaces. Please re-enter." +msgstr "" + +msgid "The beginning of the vendor can not be a number. Please re-enter." +msgstr "" + +msgid "" +"You have not selected a printer or preset yet. Please select at least one." +msgstr "" + +msgid "Some existing presets have failed to be created, as follows:\n" +msgstr "" + +msgid "" +"\n" +"Do you want to rewrite it?" +msgstr "" + +msgid "" +"We would rename the presets as \"Vendor Type Serial @printer you selected" +"\". \n" +"To add preset for more prinetrs, Please go to printer selection" +msgstr "" + +msgid "Create Printer/Nozzle" +msgstr "" + +msgid "Create Printer" +msgstr "" + +msgid "Create Nozzle for Existing Printer" +msgstr "" + +msgid "Create from Template" +msgstr "" + +msgid "Create Based on Current Printer" +msgstr "" + +msgid "wiki" +msgstr "" + +msgid "Import Preset" +msgstr "" + +msgid "Create Type" +msgstr "" + +msgid "The model is not fond, place reselect vendor." +msgstr "" + +msgid "Select Model" +msgstr "" + +msgid "Select Printer" +msgstr "" + +msgid "Input Custom Model" +msgstr "" + +msgid "Can't find my printer model" +msgstr "" + +msgid "Rectangle" +msgstr "" + +msgid "Printable Space" +msgstr "" + +msgid "X" +msgstr "" + +msgid "Y" +msgstr "" + +msgid "Hot Bed STL" +msgstr "" + +msgid "Load stl" +msgstr "" + +msgid "Hot Bed SVG" +msgstr "" + +msgid "Load svg" +msgstr "" + +msgid "Max Print Height" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "The file exceeds %d MB, please import again." +msgstr "" + +msgid "Exception in obtaining file size, please import again." +msgstr "" + +msgid "Preset path is not find, please reselect vendor." +msgstr "" + +msgid "The printer model was not found, please reselect." +msgstr "" + +msgid "The nozzle diameter is not fond, place reselect." +msgstr "" + +msgid "The printer preset is not fond, place reselect." +msgstr "" + +msgid "Printer Preset" +msgstr "" + +msgid "Filament Preset Template" +msgstr "" + +msgid "Deselect All" +msgstr "" + +msgid "Process Preset Template" +msgstr "" + +msgid "Back Page 1" +msgstr "" + +msgid "" +"You have not yet chosen which printer preset to create based on. Please " +"choose the vendor and model of the printer" +msgstr "" + +msgid "" +"You have entered an illegal input in the printable area section on the first " +"page. Please check before creating it." +msgstr "" + +msgid "The custom printer or model is not inputed, place input." +msgstr "" + +msgid "" +"The printer preset you created already has a preset with the same name. Do " +"you want to overwrite it?\n" +"\tYes: Overwrite the printer preset with the same name, and filament and " +"process presets with the same preset name will be recreated \n" +"and filament and process presets without the same preset name will be " +"reserve.\n" +"\tCancel: Do not create a preset, return to the creation interface." +msgstr "" + +msgid "You need to select at least one filament preset." +msgstr "" + +msgid "You need to select at least one process preset." +msgstr "" + +msgid "Create filament presets failed. As follows:\n" +msgstr "" + +msgid "Create process presets failed. As follows:\n" +msgstr "" + +msgid "Vendor is not find, please reselect." +msgstr "" + +msgid "Current vendor has no models, please reselect." +msgstr "" + +msgid "" +"You have not selected the vendor and model or inputed the custom vendor and " +"model." +msgstr "" + +msgid "" +"There may be escape characters in the custom printer vendor or model. Please " +"delete and re-enter." +msgstr "" + +msgid "" +"All inputs in the custom printer vendor or model are spaces. Please re-enter." +msgstr "" + +msgid "Please check bed printable shape and origin input." +msgstr "" + +msgid "" +"You have not yet selected the printer to replace the nozzle, please choose." +msgstr "" + +msgid "Create Printer Successful" +msgstr "" + +msgid "Create Filament Successful" +msgstr "" + +msgid "Printer Created" +msgstr "" + +msgid "Please go to printer settings to edit your presets" +msgstr "" + +msgid "Filament Created" +msgstr "" + +msgid "" +"Please go to filament setting to edit your presets if you need.\n" +"Please note that nozzle temperature, hot bed temperature, and maximum " +"volumetric speed have a significant impact on printing quality. Please set " +"them carefully." +msgstr "" + +msgid "Printer Setting" +msgstr "" + +msgid "Export Configs" +msgstr "" + +msgid "Printer config bundle(.bbscfg)" +msgstr "" + +msgid "Filament bundle(.bbsflmt)" +msgstr "" + +msgid "Printer presets(.zip)" +msgstr "" + +msgid "Filament presets(.zip)" +msgstr "" + +msgid "Process presets(.zip)" +msgstr "" + +msgid "initialize fail" +msgstr "" + +msgid "add file fail" +msgstr "" + +msgid "add bundle structure file fail" +msgstr "" + +msgid "finalize fail" +msgstr "" + +msgid "open zip written fail" +msgstr "" + +msgid "Export successful" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "" +"The '%s' folder already exists in the current directory. Do you want to " +"clear it and rebuild it.\n" +"If not, a time suffix will be added, and you can modify the name after " +"creation." +msgstr "" + +msgid "" +"Printer and all the filament&process presets that belongs to the printer. \n" +"Can be shared with others." +msgstr "" + +msgid "" +"User's fillment preset set. \n" +"Can be shared with others." +msgstr "" + +msgid "" +"Only display printer names with changes to printer, filament, and process " +"presets." +msgstr "" + +msgid "Only display the filament names with changes to filament presets." +msgstr "" + +msgid "" +"Only printer names with user printer presets will be displayed, and each " +"preset you choose will be exported as a zip." +msgstr "" + +msgid "" +"Only the filament names with user filament presets will be displayed, \n" +"and all user filament presets in each filament name you select will be " +"exported as a zip." +msgstr "" + +msgid "" +"Only printer names with changed process presets will be displayed, \n" +"and all user process presets in each printer name you select will be " +"exported as a zip." +msgstr "" + +msgid "Please select at least one printer or filament." +msgstr "" + +msgid "Please select a type you want to export" +msgstr "" + +msgid "Edit Filament" +msgstr "" + +msgid "Filament presets under this filament" +msgstr "" + +msgid "" +"Note: If the only preset under this filament is deleted, the filament will " +"be deleted after exiting the dialog." +msgstr "" + +msgid "Presets inherited by other presets can not be deleted" +msgstr "" + +msgid "The following presets inherits this preset." +msgid_plural "The following preset inherits this preset." +msgstr[0] "" +msgstr[1] "" + +msgid "Delete Preset" +msgstr "" + +msgid "Are you sure to delete the selected preset?" +msgstr "" + +msgid "Delete preset" +msgstr "" + +msgid "+ Add Preset" +msgstr "" + +msgid "Delete Filament" +msgstr "" + +msgid "" +"All the filament presets belong to this filament would be deleted. \n" +"If you are using this filament on your printer, please reset the filament " +"information for that slot." +msgstr "" + +msgid "Delete filament" +msgstr "" + +msgid "Add Preset" +msgstr "" + +msgid "Add preset for new printer" +msgstr "" + +msgid "Copy preset from filament" +msgstr "" + +msgid "The filament choice not find filament preset, please reselect it" +msgstr "" + +msgid "Edit Preset" +msgstr "" + +msgid "For more information, please check out Wiki" +msgstr "" + +msgid "Collapse" +msgstr "" + +msgid "Daily Tips" +msgstr "" + +msgid "Need select printer" +msgstr "" + +msgid "The start, end or step is not valid value." +msgstr "" + +msgid "" +"Unable to calibrate: maybe because the set calibration value range is too " +"large, or the step is too small" +msgstr "" + +msgid "Physical Printer" +msgstr "" + +msgid "Print Host upload" +msgstr "" + +msgid "Could not get a valid Printer Host reference" msgstr "" msgid "Success!" @@ -10792,19 +11455,130 @@ msgstr "" msgid "Connection to printers connected via the print host failed." msgstr "" -msgid "The start, end or step is not valid value." +#, possible-c-format, possible-boost-format +msgid "Mismatched type of print host: %s" +msgstr "" + +msgid "Connection to AstroBox works correctly." +msgstr "" + +msgid "Could not connect to AstroBox" +msgstr "" + +msgid "Note: AstroBox version at least 1.1.0 is required." +msgstr "" + +msgid "Connection to Duet works correctly." +msgstr "" + +msgid "Could not connect to Duet" +msgstr "" + +msgid "Unknown error occured" +msgstr "" + +msgid "Wrong password" +msgstr "" + +msgid "Could not get resources to create a new connection" +msgstr "" + +msgid "Upload not enabled on FlashAir card." +msgstr "" + +msgid "Connection to FlashAir works correctly and upload is enabled." +msgstr "" + +msgid "Could not connect to FlashAir" msgstr "" msgid "" -"Unable to calibrate: maybe because the set calibration value range is too " -"large, or the step is too small" +"Note: FlashAir with firmware 2.00.02 or newer and activated upload function " +"is required." msgstr "" -msgid "Need select printer" +msgid "Connection to MKS works correctly." +msgstr "" + +msgid "Could not connect to MKS" +msgstr "" + +msgid "Connection to OctoPrint works correctly." +msgstr "" + +msgid "Could not connect to OctoPrint" +msgstr "" + +msgid "Note: OctoPrint version at least 1.1.0 is required." +msgstr "" + +msgid "Connection to Prusa SL1 / SL1S works correctly." +msgstr "" + +msgid "Could not connect to Prusa SLA" +msgstr "" + +msgid "Connection to PrusaLink works correctly." +msgstr "" + +msgid "Could not connect to PrusaLink" +msgstr "" + +msgid "Storages found" msgstr "" -#: resources/data/hints.ini: [hint:3D Scene Operations] -msgid "3D Scene Operations\nDid you know how to control view and object/part selection with mouse and touchpanel in the 3D scene?" +#. TRN %1% = storage path +#, possible-boost-format +msgid "%1% : read only" +msgstr "" + +#. TRN %1% = storage path +#, possible-boost-format +msgid "%1% : no free space" +msgstr "" + +#. TRN %1% = host +#, possible-boost-format +msgid "Upload has failed. There is no suitable storage found at %1%." +msgstr "" + +msgid "Connection to Prusa Connect works correctly." +msgstr "" + +msgid "Could not connect to Prusa Connect" +msgstr "" + +msgid "Connection to Repetier works correctly." +msgstr "" + +msgid "Could not connect to Repetier" +msgstr "" + +msgid "Note: Repetier version at least 0.90.0 is required." +msgstr "" + +#, possible-boost-format +msgid "" +"HTTP status: %1%\n" +"Message body: \"%2%\"" +msgstr "" + +#, possible-boost-format +msgid "" +"Parsing of host response failed.\n" +"Message body: \"%1%\"\n" +"Error: \"%2%\"" +msgstr "" + +#, possible-boost-format +msgid "" +"Enumeration of host printers failed.\n" +"Message body: \"%1%\"\n" +"Error: \"%2%\"" +msgstr "" + +#: resources/data/hints.ini: [hint:How to use keyboard shortcuts] +msgid "How to use keyboard shortcuts\nDid you know that Orca Slicer offers a wide range of keyboard shortcuts and 3D scene operations." msgstr "" #: resources/data/hints.ini: [hint:Cut Tool] @@ -10812,7 +11586,7 @@ msgid "Cut Tool\nDid you know that you can cut a model at any angle and position msgstr "" #: resources/data/hints.ini: [hint:Fix Model] -msgid "Fix Model\nDid you know that you can fix a corrupted 3D model to avoid a lot of slicing problems?" +msgid "Fix Model\nDid you know that you can fix a corrupted 3D model to avoid a lot of slicing problems on the Windows system?" msgstr "" #: resources/data/hints.ini: [hint:Timelapse] @@ -10835,6 +11609,10 @@ msgstr "" msgid "Object List\nDid you know that you can view all objects/parts in a list and change settings for each object/part?" msgstr "" +#: resources/data/hints.ini: [hint:Search Functionality] +msgid "Search Functionality\nDid you know that you use the Search tool to quickly find a specific Orca Slicer setting?" +msgstr "" + #: resources/data/hints.ini: [hint:Simplify Model] msgid "Simplify Model\nDid you know that you can reduce the number of triangles in a mesh using the Simplify mesh feature? Right-click the model and select Simplify model. Read more in the documentation." msgstr "" @@ -10904,5 +11682,9 @@ msgid "Improve strength\nDid you know that you can use more wall loops and highe msgstr "" #: resources/data/hints.ini: [hint:When need to print with the printer door opened] -msgid "When need to print with the printer door opened\nOpening the printer door can reduce the probability of extruder/hotend clogging when printing lower temperature filament with a higher enclosure temperature. More info about this in the Wiki." +msgid "When need to print with the printer door opened\nDid you know that opening the printer door can reduce the probability of extruder/hotend clogging when printing lower temperature filament with a higher enclosure temperature. More info about this in the Wiki." msgstr "" + +#: resources/data/hints.ini: [hint:Avoid warping] +msgid "Avoid warping\nDid you know that when printing materials that are prone to warping such as ABS, appropriately increasing the heatbed temperature can reduce the probability of warping." +msgstr "" \ No newline at end of file diff --git a/src/libslic3r/libslic3r.h b/src/libslic3r/libslic3r.h index fbe345b4b81..0d5c965d98f 100644 --- a/src/libslic3r/libslic3r.h +++ b/src/libslic3r/libslic3r.h @@ -2,9 +2,9 @@ #define _libslic3r_h_ #include "libslic3r_version.h" -#define SLIC3R_APP_FULL_NAME "Orca Slicer - Printago Edition" +#define SLIC3R_APP_FULL_NAME "Orca Slicer" #define GCODEVIEWER_APP_NAME "OrcaSlicer G-code Viewer" -#define GCODEVIEWER_APP_KEY "OrcaSlicerGcodeViewer" +#define GCODEVIEWER_APP_KEY "OrcaSlicerGcodeViewer" #define GCODEVIEWER_BUILD_ID std::string("OrcaSlicer G-code Viewer-") + std::string(SLIC3R_VERSION) + std::string("-RC") // this needs to be included early for MSVC (listing it in Build.PL is not enough) @@ -39,16 +39,16 @@ // Saves around 32% RAM after slicing step, 6.7% after G-code export (tested on PrusaSlicer 2.2.0 final). using coord_t = int32_t; #else -//FIXME At least FillRectilinear2 and std::boost Voronoi require coord_t to be 32bit. +// FIXME At least FillRectilinear2 and std::boost Voronoi require coord_t to be 32bit. typedef int64_t coord_t; #endif using coordf_t = double; -//FIXME This epsilon value is used for many non-related purposes: -// For a threshold of a squared Euclidean distance, -// for a trheshold in a difference of radians, -// for a threshold of a cross product of two non-normalized vectors etc. +// FIXME This epsilon value is used for many non-related purposes: +// For a threshold of a squared Euclidean distance, +// for a trheshold in a difference of radians, +// for a threshold of a cross product of two non-normalized vectors etc. static constexpr double EPSILON = 1e-4; // Scaling factor for a conversion from coord_t to coordf_t: 10e-6 // This scaling generates a following fixed point representation with for a 32bit integer: @@ -63,37 +63,38 @@ static constexpr double PI = 3.141592653589793238; // SoftFever: replaced by seam_gap now // static constexpr double LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER = 0.15; static constexpr double RESOLUTION = 0.0125; -#define SCALED_RESOLUTION (RESOLUTION / SCALING_FACTOR) +#define SCALED_RESOLUTION (RESOLUTION / SCALING_FACTOR) static constexpr double SPARSE_INFILL_RESOLUTION = 0.04; -#define SCALED_SPARSE_INFILL_RESOLUTION (SPARSE_INFILL_RESOLUTION / SCALING_FACTOR) +#define SCALED_SPARSE_INFILL_RESOLUTION (SPARSE_INFILL_RESOLUTION / SCALING_FACTOR) -static constexpr double SUPPORT_RESOLUTION = 0.05; -#define SCALED_SUPPORT_RESOLUTION (SUPPORT_RESOLUTION / SCALING_FACTOR) -// Maximum perimeter length for the loop to apply the small perimeter speed. -#define SMALL_PERIMETER_LENGTH(LENGTH) (((LENGTH) / SCALING_FACTOR) * 2 * PI) +static constexpr double SUPPORT_RESOLUTION = 0.1; +#define SCALED_SUPPORT_RESOLUTION (SUPPORT_RESOLUTION / SCALING_FACTOR) +// Maximum perimeter length for the loop to apply the small perimeter speed. +#define SMALL_PERIMETER_LENGTH(LENGTH) (((LENGTH) / SCALING_FACTOR) * 2 * PI) static constexpr double INSET_OVERLAP_TOLERANCE = 0.4; // 3mm ring around the top / bottom / bridging areas. -//FIXME This is quite a lot. +// FIXME This is quite a lot. static constexpr double EXTERNAL_INFILL_MARGIN = 3; -static constexpr double BRIDGE_INFILL_MARGIN = 1; -//FIXME Better to use an inline function with an explicit return type. -//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); } +static constexpr double BRIDGE_INFILL_MARGIN = 1; +static constexpr double WIPE_TOWER_MARGIN = 15.; +// FIXME Better to use an inline function with an explicit return type. +// inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); } #define scale_(val) ((val) / SCALING_FACTOR) -#define unscale_(val) ((val) * SCALING_FACTOR) +#define unscale_(val) ((val) *SCALING_FACTOR) #define SCALED_EPSILON scale_(EPSILON) #ifndef UNUSED -#define UNUSED(x) (void)(x) +#define UNUSED(x) (void) (x) #endif /* UNUSED */ -//BBS: some global const config which user can not change, but developer can -static constexpr bool g_config_support_sharp_tails = true; -static constexpr bool g_config_remove_small_overhangs = true; +// BBS: some global const config which user can not change, but developer can +static constexpr bool g_config_support_sharp_tails = true; +static constexpr bool g_config_remove_small_overhangs = true; static constexpr float g_config_tree_support_collision_resolution = 0.2; // Write slices as SVG images into out directory during the 2D processing of the slices. -//#define SLIC3R_DEBUG_SLICE_PROCESSING +// #define SLIC3R_DEBUG_SLICE_PROCESSING namespace Slic3r { @@ -109,27 +110,25 @@ using deque = std::deque; #endif // _WIN32 -template -inline T unscale(Q v) { return T(v) * T(SCALING_FACTOR); } +template inline T unscale(Q v) { return T(v) * T(SCALING_FACTOR); } -enum Axis { - X=0, - Y, - Z, - E, - F, - //BBS: add I, J, P axis +enum Axis { + X = 0, + Y, + Z, + E, + F, + // BBS: add I, J, P axis I, J, P, - NUM_AXES, - // For the GCodeReader to mark a parsed axis, which is not in "XYZEF", it was parsed correctly. - UNKNOWN_AXIS = NUM_AXES, - NUM_AXES_WITH_UNKNOWN, + NUM_AXES, + // For the GCodeReader to mark a parsed axis, which is not in "XYZEF", it was parsed correctly. + UNKNOWN_AXIS = NUM_AXES, + NUM_AXES_WITH_UNKNOWN, }; -template -inline void append(std::vector& dest, const std::vector& src) +template inline void append(std::vector &dest, const std::vector &src) { if (dest.empty()) dest = src; @@ -137,8 +136,7 @@ inline void append(std::vector& dest, const std::vector& src) dest.insert(dest.end(), src.begin(), src.end()); } -template -inline void append(std::vector& dest, std::vector&& src) +template inline void append(std::vector &dest, std::vector &&src) { if (dest.empty()) dest = std::move(src); @@ -151,7 +149,7 @@ inline void append(std::vector& dest, std::vector&& src) } template // Arbitrary allocator can be used -void clear_and_shrink(std::vector& vec) +void clear_and_shrink(std::vector &vec) { // shrink_to_fit does not garantee the release of memory nor does it clear() std::vector tmp; @@ -160,8 +158,7 @@ void clear_and_shrink(std::vector& vec) } // Append the source in reverse. -template -inline void append_reversed(std::vector& dest, const std::vector& src) +template inline void append_reversed(std::vector &dest, const std::vector &src) { if (dest.empty()) dest = src; @@ -170,8 +167,7 @@ inline void append_reversed(std::vector& dest, const std::vector& src) } // Append the source in reverse. -template -inline void append_reversed(std::vector& dest, std::vector&& src) +template inline void append_reversed(std::vector &dest, std::vector &&src) { if (dest.empty()) dest = std::move(src); @@ -184,34 +180,29 @@ inline void append_reversed(std::vector& dest, std::vector&& src) } // Casting an std::vector<> from one type to another type without warnings about a loss of accuracy. -template -std::vector cast(const std::vector &src) +template std::vector cast(const std::vector &src) { std::vector dst; dst.reserve(src.size()); for (const T_FROM &a : src) - dst.emplace_back((T_TO)a); + dst.emplace_back((T_TO) a); return dst; } -template -inline void remove_nulls(std::vector &vec) +template inline void remove_nulls(std::vector &vec) { - vec.erase( - std::remove_if(vec.begin(), vec.end(), [](const T *ptr) { return ptr == nullptr; }), - vec.end()); + vec.erase(std::remove_if(vec.begin(), vec.end(), [](const T *ptr) { return ptr == nullptr; }), vec.end()); } -template -inline void sort_remove_duplicates(std::vector &vec) +template inline void sort_remove_duplicates(std::vector &vec) { - std::sort(vec.begin(), vec.end()); - vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); + std::sort(vec.begin(), vec.end()); + vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); } // Older compilers do not provide a std::make_unique template. Provide a simple one. -template -inline std::unique_ptr make_unique(Args&&... args) { +template inline std::unique_ptr make_unique(Args &&...args) +{ return std::unique_ptr(new T(std::forward(args)...)); } @@ -220,32 +211,31 @@ inline std::unique_ptr make_unique(Args&&... args) { template ForwardIt lower_bound_by_predicate(ForwardIt first, ForwardIt last, LowerThanKeyPredicate lower_than_key) { - ForwardIt it; + ForwardIt it; typename std::iterator_traits::difference_type count, step; count = std::distance(first, last); - + while (count > 0) { - it = first; + it = first; step = count / 2; std::advance(it, step); if (lower_than_key(*it)) { first = ++it; count -= step + 1; - } - else + } else count = step; } return first; } // from https://en.cppreference.com/w/cpp/algorithm/lower_bound -template> -ForwardIt binary_find(ForwardIt first, ForwardIt last, const T& value, Compare comp={}) +template> +ForwardIt binary_find(ForwardIt first, ForwardIt last, const T &value, Compare comp = {}) { - // Note: BOTH type T and the type after ForwardIt is dereferenced - // must be implicitly convertible to BOTH Type1 and Type2, used in Compare. + // Note: BOTH type T and the type after ForwardIt is dereferenced + // must be implicitly convertible to BOTH Type1 and Type2, used in Compare. // This is stricter than lower_bound requirement (see above) - + first = std::lower_bound(first, last, value, comp); return first != last && !comp(value, *first) ? first : last; } @@ -254,64 +244,55 @@ ForwardIt binary_find(ForwardIt first, ForwardIt last, const T& value, Compare c template ForwardIt binary_find_by_predicate(ForwardIt first, ForwardIt last, LowerThanKeyPredicate lower_thank_key, EqualToKeyPredicate equal_to_key) { - // Note: BOTH type T and the type after ForwardIt is dereferenced - // must be implicitly convertible to BOTH Type1 and Type2, used in Compare. + // Note: BOTH type T and the type after ForwardIt is dereferenced + // must be implicitly convertible to BOTH Type1 and Type2, used in Compare. // This is stricter than lower_bound requirement (see above) - + first = lower_bound_by_predicate(first, last, lower_thank_key); return first != last && equal_to_key(*first) ? first : last; } template inline bool contains(const ContainerType &c, const ValueType &v) - { return std::find(c.begin(), c.end(), v) != c.end(); } +{ + return std::find(c.begin(), c.end(), v) != c.end(); +} template inline bool contains(const std::initializer_list &il, const T &v) - { return std::find(il.begin(), il.end(), v) != il.end(); } - -template inline bool one_of(const ValueType &v, const ContainerType &c) - { return contains(c, v); } -template inline bool one_of(const T& v, const std::initializer_list& il) - { return contains(il, v); } - -template -constexpr inline T sqr(T x) { - return x * x; + return std::find(il.begin(), il.end(), v) != il.end(); } -template constexpr -inline bool is_zero(Number value) +template inline bool one_of(const ValueType &v, const ContainerType &c) { - return std::fabs(double(value)) < 1e-6; + return contains(c, v); } +template inline bool one_of(const T &v, const std::initializer_list &il) { return contains(il, v); } -template -constexpr inline T lerp(const T& a, const T& b, Number t) +template constexpr inline T sqr(T x) { return x * x; } + +template constexpr inline bool is_zero(Number value) { return std::fabs(double(value)) < 1e-6; } + +template constexpr inline T lerp(const T &a, const T &b, Number t) { assert((t >= Number(-EPSILON)) && (t <= Number(1) + Number(EPSILON))); return (Number(1) - t) * a + t * b; } -template -constexpr inline bool is_approx(Number value, Number test_value, Number precision = EPSILON) +template constexpr inline bool is_approx(Number value, Number test_value, Number precision = EPSILON) { return std::fabs(double(value) - double(test_value)) < double(precision); } -template -constexpr inline bool is_approx(const std::optional &value, - const std::optional &test_value) +template constexpr inline bool is_approx(const std::optional &value, const std::optional &test_value) { return (!value.has_value() && !test_value.has_value()) || - (value.has_value() && test_value.has_value() && is_approx(*value, *test_value)); + (value.has_value() && test_value.has_value() && is_approx(*value, *test_value)); } // A meta-predicate which is true for integers wider than or equal to coord_t template struct is_scaled_coord { - static const constexpr bool value = - std::is_integral::value && - std::numeric_limits::digits >= - std::numeric_limits::digits; + static const constexpr bool value = std::is_integral::value && + std::numeric_limits::digits >= std::numeric_limits::digits; }; // Meta predicates for floating, 'scaled coord' and generic arithmetic types @@ -324,49 +305,43 @@ template struct is_scaled_coord // return type will be bool. // For more info how to use, see docs for std::enable_if // -template -using FloatingOnly = std::enable_if_t::value, O>; +template using FloatingOnly = std::enable_if_t::value, O>; -template -using ScaledCoordOnly = std::enable_if_t::value, O>; +template using ScaledCoordOnly = std::enable_if_t::value, O>; -template -using IntegerOnly = std::enable_if_t::value, O>; +template using IntegerOnly = std::enable_if_t::value, O>; -template -using ArithmeticOnly = std::enable_if_t::value, O>; +template using ArithmeticOnly = std::enable_if_t::value, O>; template -using IteratorOnly = std::enable_if_t< - !std::is_same_v::value_type, void>, O ->; +using IteratorOnly = std::enable_if_t::value_type, void>, O>; template // Arbitrary allocator can be used IntegerOnly> reserve_vector(I capacity) { std::vector ret; - if (capacity > I(0)) ret.reserve(size_t(capacity)); + if (capacity > I(0)) + ret.reserve(size_t(capacity)); return ret; } // Borrowed from C++20 -template -using remove_cvref_t = std::remove_cv_t>; +template using remove_cvref_t = std::remove_cv_t>; // A very simple range concept implementation with iterator-like objects. // This should be replaced by std::ranges::subrange (C++20) template class Range { It from, to; -public: +public: // The class is ready for range based for loops. It begin() const { return from; } It end() const { return to; } // The iterator type can be obtained this way. - using iterator = It; + using iterator = It; using value_type = typename std::iterator_traits::value_type; Range() = default; @@ -377,13 +352,9 @@ template class Range inline bool empty() const { return from == to; } }; -template auto range(Cont &&cont) -{ - return Range{std::begin(cont), std::end(cont)}; -} +template auto range(Cont &&cont) { return Range{std::begin(cont), std::end(cont)}; } -template> -constexpr T NaN = std::numeric_limits::quiet_NaN(); +template> constexpr T NaN = std::numeric_limits::quiet_NaN(); constexpr float NaNf = NaN; constexpr double NaNd = NaN; @@ -399,8 +370,7 @@ constexpr double NaNd = NaN; // -1.51 is rounded to -2. // If input is not a valid float (it is infinity NaN or if it does not fit) // the float to int conversion produces a max int on Intel and +-max int on ARM. -template -inline IntegerOnly fast_round_up(double a) +template inline IntegerOnly fast_round_up(double a) { // Why does Java Math.round(0.49999999999999994) return 1? // https://stackoverflow.com/questions/9902968/why-does-math-round0-49999999999999994-return-1 @@ -411,4 +381,4 @@ template using SamePair = std::pair; } // namespace Slic3r -#endif +#endif \ No newline at end of file diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index e42173410c5..2f120c0d0b2 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -2,6 +2,7 @@ #include "I18N.hpp" #include "libslic3r/Utils.hpp" +#include "libslic3r/Color.hpp" #include "GUI.hpp" #include "GUI_App.hpp" #include "MainFrame.hpp" @@ -10,15 +11,13 @@ #include -namespace Slic3r { -namespace GUI { +namespace Slic3r { namespace GUI { -AboutDialogLogo::AboutDialogLogo(wxWindow* parent) - : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) +AboutDialogLogo::AboutDialogLogo(wxWindow *parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) { this->SetBackgroundColour(*wxWHITE); this->logo = ScalableBitmap(this, Slic3r::var("OrcaSlicer_192px.png"), wxBITMAP_TYPE_PNG); - this->SetMinSize(this->logo.GetBmpSize()); + this->SetMinSize(this->logo.GetSize()); this->Bind(wxEVT_PAINT, &AboutDialogLogo::onRepaint, this); } @@ -28,45 +27,47 @@ void AboutDialogLogo::onRepaint(wxEvent &event) wxPaintDC dc(this); dc.SetBackgroundMode(wxTRANSPARENT); - wxSize size = this->GetSize(); - int logo_w = this->logo.GetBmpWidth(); - int logo_h = this->logo.GetBmpHeight(); - dc.DrawBitmap(this->logo.bmp(), (size.GetWidth() - logo_w)/2, (size.GetHeight() - logo_h)/2, true); + wxSize size = this->GetSize(); + int logo_w = this->logo.GetWidth(); + int logo_h = this->logo.GetHeight(); + dc.DrawBitmap(this->logo.get_bitmap(), (size.GetWidth() - logo_w) / 2, (size.GetHeight() - logo_h) / 2, true); event.Skip(); } - // ----------------------------------------- // CopyrightsDialog // ----------------------------------------- CopyrightsDialog::CopyrightsDialog() - : DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, from_u8((boost::format("%1% - %2%") - % (wxGetApp().is_editor() ? SLIC3R_APP_FULL_NAME : GCODEVIEWER_APP_NAME) - % _utf8(L("Portions copyright"))).str()), - wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + : DPIDialog(static_cast(wxGetApp().mainframe), + wxID_ANY, + from_u8((boost::format("%1% - %2%") % (wxGetApp().is_editor() ? SLIC3R_APP_FULL_NAME : GCODEVIEWER_APP_NAME) % + _utf8(L("Portions copyright"))) + .str()), + wxDefaultPosition, + wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { this->SetFont(wxGetApp().normal_font()); - this->SetBackgroundColour(*wxWHITE); + this->SetBackgroundColour(*wxWHITE); std::string icon_path = (boost::format("%1%/images/OrcaSlicerTitle.ico") % resources_dir()).str(); SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); - wxStaticLine *staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + wxStaticLine *staticline1 = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL); - auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add( staticline1, 0, wxEXPAND | wxALL, 5 ); + auto sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(staticline1, 0, wxEXPAND | wxALL, 5); fill_entries(); - m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, - wxSize(40 * em_unit(), 20 * em_unit()), wxHW_SCROLLBAR_AUTO); - m_html->SetMinSize(wxSize(FromDIP(870),FromDIP(520))); + m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxSize(40 * em_unit(), 20 * em_unit()), wxHW_SCROLLBAR_AUTO); + m_html->SetMinSize(wxSize(FromDIP(870), FromDIP(520))); m_html->SetBackgroundColour(*wxWHITE); - wxFont font = get_default_font(this); - const int fs = font.GetPointSize(); - const int fs2 = static_cast(1.2f*fs); - int size[] = { fs, fs, fs, fs, fs2, fs2, fs2 }; + wxFont font = get_default_font(this); + const int fs = font.GetPointSize(); + const int fs2 = static_cast(1.2f * fs); + int size[] = {fs, fs, fs, fs, fs2, fs2, fs2}; m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); m_html->SetBorders(2); @@ -84,108 +85,102 @@ CopyrightsDialog::CopyrightsDialog() void CopyrightsDialog::fill_entries() { m_entries = { - { "Admesh", "", "https://admesh.readthedocs.io/" }, - { "Anti-Grain Geometry", "", "http://antigrain.com" }, - { "ArcWelderLib", "", "https://plugins.octoprint.org/plugins/arc_welder" }, - { "Boost", "", "http://www.boost.org" }, - { "Cereal", "", "http://uscilab.github.io/cereal" }, - { "CGAL", "", "https://www.cgal.org" }, - { "Clipper", "", "http://www.angusj.co" }, - { "libcurl", "", "https://curl.se/libcurl" }, - { "Eigen3", "", "http://eigen.tuxfamily.org" }, - { "Expat", "", "http://www.libexpat.org" }, - { "fast_float", "", "https://github.com/fastfloat/fast_float" }, - { "GLEW (The OpenGL Extension Wrangler Library)", "", "http://glew.sourceforge.net" }, - { "GLFW", "", "https://www.glfw.org" }, - { "GNU gettext", "", "https://www.gnu.org/software/gettext" }, - { "ImGUI", "", "https://github.com/ocornut/imgui" }, - { "Libigl", "", "https://libigl.github.io" }, - { "libnest2d", "", "https://github.com/tamasmeszaros/libnest2d" }, - { "lib_fts", "", "https://www.forrestthewoods.com" }, - { "Mesa 3D", "", "https://mesa3d.org" }, - { "Miniz", "", "https://github.com/richgel999/miniz" }, - { "Nanosvg", "", "https://github.com/memononen/nanosvg" }, - { "nlohmann/json", "", "https://json.nlohmann.me" }, - { "Qhull", "", "http://qhull.org" }, - { "Open Cascade", "", "https://www.opencascade.com" }, - { "OpenGL", "", "https://www.opengl.org" }, - { "PoEdit", "", "https://poedit.net" }, - { "PrusaSlicer", "", "https://www.prusa3d.com" }, - { "Real-Time DXT1/DXT5 C compression library", "", "https://github.com/Cyan4973/RygsDXTc" }, - { "SemVer", "", "https://semver.org" }, - { "Shinyprofiler", "", "https://code.google.com/p/shinyprofiler" }, - { "SuperSlicer", "", "https://github.com/supermerill/SuperSlicer" }, - { "TBB", "", "https://www.intel.cn/content/www/cn/zh/developer/tools/oneapi/onetbb.html" }, - { "wxWidgets", "", "https://www.wxwidgets.org" }, - { "zlib", "", "http://zlib.net" }, + {"Admesh", "", "https://admesh.readthedocs.io/"}, + {"Anti-Grain Geometry", "", "http://antigrain.com"}, + {"ArcWelderLib", "", "https://plugins.octoprint.org/plugins/arc_welder"}, + {"Boost", "", "http://www.boost.org"}, + {"Cereal", "", "http://uscilab.github.io/cereal"}, + {"CGAL", "", "https://www.cgal.org"}, + {"Clipper", "", "http://www.angusj.co"}, + {"libcurl", "", "https://curl.se/libcurl"}, + {"Eigen3", "", "http://eigen.tuxfamily.org"}, + {"Expat", "", "http://www.libexpat.org"}, + {"fast_float", "", "https://github.com/fastfloat/fast_float"}, + {"GLEW (The OpenGL Extension Wrangler Library)", "", "http://glew.sourceforge.net"}, + {"GLFW", "", "https://www.glfw.org"}, + {"GNU gettext", "", "https://www.gnu.org/software/gettext"}, + {"ImGUI", "", "https://github.com/ocornut/imgui"}, + {"Libigl", "", "https://libigl.github.io"}, + {"libnest2d", "", "https://github.com/tamasmeszaros/libnest2d"}, + {"lib_fts", "", "https://www.forrestthewoods.com"}, + {"Mesa 3D", "", "https://mesa3d.org"}, + {"Miniz", "", "https://github.com/richgel999/miniz"}, + {"Nanosvg", "", "https://github.com/memononen/nanosvg"}, + {"nlohmann/json", "", "https://json.nlohmann.me"}, + {"Qhull", "", "http://qhull.org"}, + {"Open Cascade", "", "https://www.opencascade.com"}, + {"OpenGL", "", "https://www.opengl.org"}, + {"PoEdit", "", "https://poedit.net"}, + {"PrusaSlicer", "", "https://www.prusa3d.com"}, + {"Real-Time DXT1/DXT5 C compression library", "", "https://github.com/Cyan4973/RygsDXTc"}, + {"SemVer", "", "https://semver.org"}, + {"Shinyprofiler", "", "https://code.google.com/p/shinyprofiler"}, + {"SuperSlicer", "", "https://github.com/supermerill/SuperSlicer"}, + {"TBB", "", "https://www.intel.cn/content/www/cn/zh/developer/tools/oneapi/onetbb.html"}, + {"wxWidgets", "", "https://www.wxwidgets.org"}, + {"zlib", "", "http://zlib.net"}, }; } wxString CopyrightsDialog::get_html_text() { - wxColour bgr_clr = wxGetApp().get_window_default_clr();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + wxColour bgr_clr = wxGetApp().get_window_default_clr(); // wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - const auto text_clr = wxGetApp().get_label_clr_default();// wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); - const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); - const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); + const auto text_clr = wxGetApp().get_label_clr_default(); // wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + const auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue())); + const auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue())); - const wxString copyright_str = _(L("Copyright")) + "© "; + const wxString copyright_str = _L("Copyright") + "© "; wxString text = wxString::Format( "" - "" - "" - "%s
" - "%s" - "%s.
" - "%s.
" - "

" - "%s
" - "%s:
" - "
" - "", - bgr_clr_str, text_clr_str, text_clr_str, - _L("License"), - _L("Orca Slicer - Printago Edition is licensed under "), - "https://www.gnu.org/licenses/agpl-3.0.html",_L("GNU Affero General Public License, version 3"), - _L("Orca Slicer - Printago Edition is based on Orca Slicer, which is based on BambuStudio by Bambulab, which is from PrusaSlicer by Prusa Research. PrusaSlicer is from Slic3r by Alessandro Ranellucci and the RepRap community"), + "" + "" + "%s
" + "%s" + "%s.
" + "%s.
" + "

" + "%s
" + "%s:
" + "
" + "", + bgr_clr_str, text_clr_str, text_clr_str, _L("License"), _L("Orca Slicer is licensed under "), + "https://www.gnu.org/licenses/agpl-3.0.html", _L("GNU Affero General Public License, version 3"), + _L("Orca Slicer is based on BambuStudio by Bambulab, which is from PrusaSlicer by Prusa Research. PrusaSlicer is from Slic3r by " + "Alessandro Ranellucci and the RepRap community"), _L("Libraries"), _L("This software uses open source components whose copyright and other proprietary rights belong to their respective owners")); - for (auto& entry : m_entries) { - text += format_wxstr( - "%s
" - , entry.lib_name); + for (auto &entry : m_entries) { + text += format_wxstr("%s
", entry.lib_name); - text += wxString::Format( - "%s

" - , entry.link, entry.link); + text += wxString::Format("%s

", entry.link, entry.link); } - text += wxString( - "
" - "
" - "" - ""); + text += wxString("
" + "
" + "" + ""); return text; } void CopyrightsDialog::on_dpi_changed(const wxRect &suggested_rect) { - const wxFont& font = GetFont(); - const int fs = font.GetPointSize(); - const int fs2 = static_cast(1.2f*fs); - int font_size[] = { fs, fs, fs, fs, fs2, fs2, fs2 }; + const wxFont &font = GetFont(); + const int fs = font.GetPointSize(); + const int fs2 = static_cast(1.2f * fs); + int font_size[] = {fs, fs, fs, fs, fs2, fs2, fs2}; m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size); - const int& em = em_unit(); + const int &em = em_unit(); - msw_buttons_rescale(this, em, { wxID_CLOSE }); + msw_buttons_rescale(this, em, {wxID_CLOSE}); - const wxSize& size = wxSize(40 * em, 20 * em); + const wxSize &size = wxSize(40 * em, 20 * em); m_html->SetMinSize(size); m_html->Refresh(); @@ -202,17 +197,19 @@ void CopyrightsDialog::onLinkClicked(wxHtmlLinkEvent &event) event.Skip(false); } -void CopyrightsDialog::onCloseDialog(wxEvent &) -{ - this->EndModal(wxID_CLOSE); -} +void CopyrightsDialog::onCloseDialog(wxEvent &) { this->EndModal(wxID_CLOSE); } AboutDialog::AboutDialog() - : DPIDialog(static_cast(wxGetApp().mainframe),wxID_ANY,from_u8((boost::format(_utf8(L("About %s"))) % (wxGetApp().is_editor() ? SLIC3R_APP_FULL_NAME : GCODEVIEWER_APP_NAME)).str()),wxDefaultPosition, - wxDefaultSize, /*wxCAPTION*/wxDEFAULT_DIALOG_STYLE) + : DPIDialog(static_cast(wxGetApp().mainframe), + wxID_ANY, + from_u8( + (boost::format(_utf8(L("About %s"))) % (wxGetApp().is_editor() ? SLIC3R_APP_FULL_NAME : GCODEVIEWER_APP_NAME)).str()), + wxDefaultPosition, + wxDefaultSize, + /*wxCAPTION*/ wxDEFAULT_DIALOG_STYLE) { SetFont(wxGetApp().normal_font()); - SetBackgroundColour(*wxWHITE); + SetBackgroundColour(*wxWHITE); std::string icon_path = (boost::format("%1%/images/OrcaSlicerTitle.ico") % resources_dir()).str(); SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); @@ -220,19 +217,19 @@ AboutDialog::AboutDialog() wxPanel *m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(237)), wxTAB_TRAVERSAL); wxBoxSizer *panel_versizer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *vesizer = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *vesizer = new wxBoxSizer(wxVERTICAL); m_panel->SetSizer(panel_versizer); wxBoxSizer *ver_sizer = new wxBoxSizer(wxVERTICAL); - auto main_sizer = new wxBoxSizer(wxVERTICAL); + auto main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(m_panel, 1, wxEXPAND | wxALL, 0); main_sizer->Add(ver_sizer, 0, wxEXPAND | wxALL, 0); // logo m_logo_bitmap = ScalableBitmap(this, "OrcaSlicer_about", 250); - m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bitmap.bmp(), wxDefaultPosition,wxDefaultSize, 0); + m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bitmap.bmp(), wxDefaultPosition, wxDefaultSize, 0); m_logo->SetSizer(vesizer); panel_versizer->Add(m_logo, 1, wxALL | wxEXPAND, 0); @@ -240,16 +237,17 @@ AboutDialog::AboutDialog() // version { vesizer->Add(0, FromDIP(165), 1, wxEXPAND, FromDIP(5)); - auto version_string = _L("based on Orca Slicer ") + " " + std::string(SoftFever_VERSION); - wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize); - wxStaticText* bs_version = new wxStaticText(this, wxID_ANY, wxString::Format("Based on BambuStudio and PrusaSlicer"), wxDefaultPosition, wxDefaultSize); + auto version_string = _L("Orca Slicer ") + " " + std::string(SoftFever_VERSION); + wxStaticText *version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize); + wxStaticText *bs_version = new wxStaticText(this, wxID_ANY, wxString::Format("Based on BambuStudio and PrusaSlicer"), + wxDefaultPosition, wxDefaultSize); bs_version->SetFont(Label::Body_12); wxFont version_font = GetFont(); - #ifdef __WXMSW__ - version_font.SetPointSize(version_font.GetPointSize()-1); - #else - version_font.SetPointSize(11); - #endif +#ifdef __WXMSW__ + version_font.SetPointSize(version_font.GetPointSize() - 1); +#else + version_font.SetPointSize(11); +#endif version_font.SetPointSize(FromDIP(16)); version->SetFont(version_font); version->SetForegroundColour(wxColour("#FFFFFD")); @@ -257,42 +255,40 @@ AboutDialog::AboutDialog() version->SetBackgroundColour(wxColour("#4d4d4d")); bs_version->SetBackgroundColour(wxColour("#4d4d4d")); - vesizer->Add(version, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5)); vesizer->Add(bs_version, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5)); -// #if BBL_INTERNAL_TESTING -// wxString build_time = wxString::Format("Build Time: %s", std::string(SLIC3R_BUILD_TIME)); -// wxStaticText* build_time_text = new wxStaticText(this, wxID_ANY, build_time, wxDefaultPosition, wxDefaultSize); -// build_time_text->SetForegroundColour(wxColour("#FFFFFE")); -// build_time_text->SetBackgroundColour(wxColour("#00AF42")); -// vesizer->Add(build_time_text, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5)); -// #endif + // #if BBL_INTERNAL_TESTING + // wxString build_time = wxString::Format("Build Time: %s", std::string(SLIC3R_BUILD_TIME)); + // wxStaticText* build_time_text = new wxStaticText(this, wxID_ANY, build_time, wxDefaultPosition, wxDefaultSize); + // build_time_text->SetForegroundColour(wxColour("#FFFFFE")); + // build_time_text->SetBackgroundColour(wxColour("#00AF42")); + // vesizer->Add(build_time_text, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5)); + // #endif vesizer->Add(0, 0, 1, wxEXPAND, FromDIP(5)); } wxBoxSizer *text_sizer_horiz = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer *text_sizer = new wxBoxSizer(wxVERTICAL); - text_sizer_horiz->Add( 0, 0, 0, wxLEFT, FromDIP(20)); + wxBoxSizer *text_sizer = new wxBoxSizer(wxVERTICAL); + text_sizer_horiz->Add(0, 0, 0, wxLEFT, FromDIP(20)); std::vector text_list; - text_list.push_back(_L("OrcaSlicer - Printago Edition is based on OrcaSlicer, BambuStudio, PrusaSlicer, and SuperSlicer.")); + text_list.push_back(_L("OrcaSlicer is based on BambuStudio, PrusaSlicer, and SuperSlicer.")); text_list.push_back(_L("BambuStudio is originally based on PrusaSlicer by PrusaResearch.")); text_list.push_back(_L("PrusaSlicer is originally based on Slic3r by Alessandro Ranellucci.")); text_list.push_back(_L("Slic3r was created by Alessandro Ranellucci with the help of many other contributors.")); - text_sizer->Add( 0, 0, 0, wxTOP, FromDIP(33)); + text_sizer->Add(0, 0, 0, wxTOP, FromDIP(33)); bool is_zh = wxGetApp().app_config->get("language") == "zh_CN"; - for (int i = 0; i < text_list.size(); i++) - { - auto staticText = new wxStaticText( this, wxID_ANY, wxEmptyString,wxDefaultPosition,wxSize(FromDIP(520), -1), wxALIGN_LEFT ); + for (int i = 0; i < text_list.size(); i++) { + auto staticText = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(520), -1), wxALIGN_LEFT); staticText->SetForegroundColour(wxColour(107, 107, 107)); staticText->SetBackgroundColour(*wxWHITE); staticText->SetMinSize(wxSize(FromDIP(520), -1)); staticText->SetFont(Label::Body_12); if (is_zh) { - wxString find_txt = ""; + wxString find_txt = ""; wxString count_txt = ""; - for (auto o = 0; o < text_list[i].length(); o++) { + for (auto o = 0; o < text_list[i].length(); o++) { auto size = staticText->GetTextExtent(count_txt); if (size.x < FromDIP(506)) { find_txt += text_list[i][o]; @@ -308,70 +304,75 @@ AboutDialog::AboutDialog() staticText->Wrap(FromDIP(520)); } - text_sizer->Add( staticText, 0, wxUP | wxDOWN, FromDIP(3)); + text_sizer->Add(staticText, 0, wxUP | wxDOWN, FromDIP(3)); } - text_sizer_horiz->Add(text_sizer, 1, wxALL,0); - ver_sizer->Add(text_sizer_horiz, 0, wxALL,0); - ver_sizer->Add( 0, 0, 0, wxTOP, FromDIP(43)); + text_sizer_horiz->Add(text_sizer, 1, wxALL, 0); + ver_sizer->Add(text_sizer_horiz, 0, wxALL, 0); + ver_sizer->Add(0, 0, 0, wxTOP, FromDIP(43)); wxBoxSizer *copyright_ver_sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer *copyright_hor_sizer = new wxBoxSizer(wxHORIZONTAL); copyright_hor_sizer->Add(copyright_ver_sizer, 0, wxLEFT, FromDIP(20)); - wxStaticText *html_text = new wxStaticText(this, wxID_ANY, "Copyright(C) 2023-2024 Printago.io All Rights Reserved", wxDefaultPosition, wxDefaultSize); + wxStaticText *html_text = new wxStaticText(this, wxID_ANY, "Copyright(C) 2022-2023 Li Jiang All Rights Reserved", wxDefaultPosition, + wxDefaultSize); html_text->SetForegroundColour(wxColour(107, 107, 107)); - copyright_ver_sizer->Add(html_text, 0, wxALL , 0); + copyright_ver_sizer->Add(html_text, 0, wxALL, 0); m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER /*NEVER*/); - { - wxFont font = get_default_font(this); - const int fs = font.GetPointSize()-1; - int size[] = {fs,fs,fs,fs,fs,fs,fs}; - m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); - m_html->SetMinSize(wxSize(FromDIP(-1), FromDIP(16))); - m_html->SetBorders(2); - const auto text = from_u8( - (boost::format( - "" - "" - "

https://github.com/printago/OrcaSlicer-PrintagoEdition

" - "" - "") - ).str()); - m_html->SetPage(text); - copyright_ver_sizer->Add(m_html, 0, wxEXPAND, 0); - m_html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this); - } - //Add "Portions copyright" button - Button* button_portions = new Button(this,_L("Portions copyright")); - StateColor report_bg(std::pair(wxColour(255, 255, 255), StateColor::Disabled), std::pair(wxColour(206, 206, 206), StateColor::Pressed), - std::pair(wxColour(238, 238, 238), StateColor::Hovered), std::pair(wxColour(255, 255, 255), StateColor::Enabled), + { + wxFont font = get_default_font(this); + const int fs = font.GetPointSize() - 1; + int size[] = {fs, fs, fs, fs, fs, fs, fs}; + m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); + m_html->SetMinSize(wxSize(FromDIP(-1), FromDIP(16))); + m_html->SetBorders(2); + const auto text = from_u8( + (boost::format("" + "" + "

https://github.com/SoftFever/Orcaslicer

" + "" + "")) + .str()); + m_html->SetPage(text); + copyright_ver_sizer->Add(m_html, 0, wxEXPAND, 0); + m_html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this); + } + // Add "Portions copyright" button + Button *button_portions = new Button(this, _L("Portions copyright")); + StateColor report_bg(std::pair(wxColour(255, 255, 255), StateColor::Disabled), + std::pair(wxColour(206, 206, 206), StateColor::Pressed), + std::pair(wxColour(238, 238, 238), StateColor::Hovered), + std::pair(wxColour(255, 255, 255), StateColor::Enabled), std::pair(wxColour(255, 255, 255), StateColor::Normal)); button_portions->SetBackgroundColor(report_bg); - StateColor report_bd(std::pair(wxColour(144, 144, 144), StateColor::Disabled), std::pair(wxColour(38, 46, 48), StateColor::Enabled)); + StateColor report_bd(std::pair(wxColour(144, 144, 144), StateColor::Disabled), + std::pair(wxColour(38, 46, 48), StateColor::Enabled)); button_portions->SetBorderColor(report_bd); - StateColor report_text(std::pair(wxColour(144, 144, 144), StateColor::Disabled), std::pair(wxColour(38, 46, 48), StateColor::Enabled)); + StateColor report_text(std::pair(wxColour(144, 144, 144), StateColor::Disabled), + std::pair(wxColour(38, 46, 48), StateColor::Enabled)); button_portions->SetTextColor(report_text); button_portions->SetFont(Label::Body_12); button_portions->SetCornerRadius(FromDIP(12)); button_portions->SetMinSize(wxSize(FromDIP(120), FromDIP(24))); wxBoxSizer *copyright_button_ver = new wxBoxSizer(wxVERTICAL); - copyright_button_ver->Add( 0, 0, 0, wxTOP, FromDIP(10)); - copyright_button_ver->Add(button_portions, 0, wxALL,0); + copyright_button_ver->Add(0, 0, 0, wxTOP, FromDIP(10)); + copyright_button_ver->Add(button_portions, 0, wxALL, 0); copyright_hor_sizer->AddStretchSpacer(); copyright_hor_sizer->Add(copyright_button_ver, 0, wxRIGHT, FromDIP(20)); - ver_sizer->Add(copyright_hor_sizer, 0, wxEXPAND ,0); - ver_sizer->Add( 0, 0, 0, wxTOP, FromDIP(30)); + ver_sizer->Add(copyright_hor_sizer, 0, wxEXPAND, 0); + ver_sizer->Add(0, 0, 0, wxTOP, FromDIP(30)); button_portions->Bind(wxEVT_BUTTON, &AboutDialog::onCopyrightBtn, this); wxGetApp().UpdateDlgDarkUI(this); - SetSizer(main_sizer); + SetSizer(main_sizer); Layout(); Fit(); CenterOnParent(); @@ -379,22 +380,22 @@ AboutDialog::AboutDialog() void AboutDialog::on_dpi_changed(const wxRect &suggested_rect) { - m_logo_bitmap.msw_rescale(); + m_logo_bitmap.sys_color_changed(); m_logo->SetBitmap(m_logo_bitmap.bmp()); - const wxFont& font = GetFont(); - const int fs = font.GetPointSize() - 1; - int font_size[] = { fs, fs, fs, fs, fs, fs, fs }; + const wxFont &font = GetFont(); + const int fs = font.GetPointSize() - 1; + int font_size[] = {fs, fs, fs, fs, fs, fs, fs}; m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size); - const int& em = em_unit(); + const int &em = em_unit(); - msw_buttons_rescale(this, em, { wxID_CLOSE, m_copy_rights_btn_id }); + msw_buttons_rescale(this, em, {wxID_CLOSE, m_copy_rights_btn_id}); m_html->SetMinSize(wxSize(-1, 16 * em)); m_html->Refresh(); - const wxSize& size = wxSize(65 * em, 30 * em); + const wxSize &size = wxSize(65 * em, 30 * em); SetMinSize(size); Fit(); @@ -407,10 +408,7 @@ void AboutDialog::onLinkClicked(wxHtmlLinkEvent &event) event.Skip(false); } -void AboutDialog::onCloseDialog(wxEvent &) -{ - this->EndModal(wxID_CLOSE); -} +void AboutDialog::onCloseDialog(wxEvent &) { this->EndModal(wxID_CLOSE); } void AboutDialog::onCopyrightBtn(wxEvent &) { @@ -418,12 +416,11 @@ void AboutDialog::onCopyrightBtn(wxEvent &) dlg.ShowModal(); } -void AboutDialog::onCopyToClipboard(wxEvent&) +void AboutDialog::onCopyToClipboard(wxEvent &) { wxTheClipboard->Open(); wxTheClipboard->SetData(new wxTextDataObject(_L("Version") + " " + GUI_App::format_display_version())); wxTheClipboard->Close(); } -} // namespace GUI -} // namespace Slic3r +}} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 5f88f34cc7e..4bf940b8c79 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1,3 +1,25 @@ +///|/ Copyright (c) Prusa Research 2018 - 2023 Vojtěch Bubník @bubnikv, Lukáš Matěna @lukasmatena, Oleksandra Iushchenko @YuSanka, Enrico +///Turri @enricoturri1966, Tomáš Mészáros @tamasmeszaros, David Kocík @kocikdav, Lukáš Hejl @hejllukas, Pavel Mikuš @Godrak, Filip Sykala +///@Jony01, Vojtěch Král @vojtechkral +///|/ Copyright (c) 2022 Michael Kirsch +///|/ Copyright (c) 2021 Boleslaw Ciesielski +///|/ Copyright (c) 2019 John Drake @foxox +///|/ +///|/ ported from lib/Slic3r/GUI/Plater.pm: +///|/ Copyright (c) Prusa Research 2016 - 2019 Vojtěch Bubník @bubnikv, Vojtěch Král @vojtechkral, Enrico Turri @enricoturri1966, Oleksandra +///Iushchenko @YuSanka, Lukáš Matěna @lukasmatena, Tomáš Mészáros @tamasmeszaros +///|/ Copyright (c) 2018 Martin Loidl @LoidlM +///|/ Copyright (c) 2017 Matthias Gazzari @qtux +///|/ Copyright (c) Slic3r 2012 - 2016 Alessandro Ranellucci @alranel +///|/ Copyright (c) 2017 Joseph Lenox @lordofhyphens +///|/ Copyright (c) 2015 Daren Schwenke +///|/ Copyright (c) 2014 Mark Hindess +///|/ Copyright (c) 2012 Mike Sheldrake @mesheldrake +///|/ Copyright (c) 2012 Henrik Brix Andersen @henrikbrixandersen +///|/ Copyright (c) 2012 Sam Wong +///|/ +///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher +///|/ #include "Plater.hpp" #include "libslic3r/Config.hpp" @@ -46,7 +68,7 @@ #include "libslic3r/Format/STL.hpp" #include "libslic3r/Format/STEP.hpp" #include "libslic3r/Format/AMF.hpp" -//#include "libslic3r/Format/3mf.hpp" +// #include "libslic3r/Format/3mf.hpp" #include "libslic3r/Format/bbs_3mf.hpp" #include "libslic3r/GCode/ThumbnailData.hpp" #include "libslic3r/Model.hpp" @@ -128,7 +150,8 @@ #include "Gizmos/GLGizmosManager.hpp" #endif // __APPLE__ -#include // Needs to be last because reasons :-/ +#include +#include // Needs to be last because reasons :-/ #include "WipeTowerDialog.hpp" #include "libslic3r/CustomGCode.hpp" @@ -138,6 +161,8 @@ #include "PhysicalPrinterDialog.hpp" #include "PrintHostDialogs.hpp" #include "PlateSettingsDialog.hpp" +#include "DailyTips.hpp" +#include "CreatePresetsDialog.hpp" using boost::optional; namespace fs = boost::filesystem; @@ -146,48 +171,50 @@ using Slic3r::Preset; using Slic3r::GUI::format_wxstr; using namespace nlohmann; -static const std::pair THUMBNAIL_SIZE_3MF = { 512, 512 }; +static const std::pair THUMBNAIL_SIZE_3MF = {512, 512}; -namespace Slic3r { -namespace GUI { +namespace Slic3r { namespace GUI { -wxDEFINE_EVENT(EVT_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent); -wxDEFINE_EVENT(EVT_SLICING_UPDATE, SlicingStatusEvent); -wxDEFINE_EVENT(EVT_SLICING_COMPLETED, wxCommandEvent); -wxDEFINE_EVENT(EVT_PROCESS_COMPLETED, SlicingProcessCompletedEvent); -wxDEFINE_EVENT(EVT_EXPORT_BEGAN, wxCommandEvent); -wxDEFINE_EVENT(EVT_EXPORT_FINISHED, wxCommandEvent); -wxDEFINE_EVENT(EVT_IMPORT_MODEL_ID, wxCommandEvent); -wxDEFINE_EVENT(EVT_DOWNLOAD_PROJECT, wxCommandEvent); -wxDEFINE_EVENT(EVT_PUBLISH, wxCommandEvent); +wxDEFINE_EVENT(EVT_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent); +wxDEFINE_EVENT(EVT_SLICING_UPDATE, SlicingStatusEvent); +wxDEFINE_EVENT(EVT_SLICING_COMPLETED, wxCommandEvent); +wxDEFINE_EVENT(EVT_PROCESS_COMPLETED, SlicingProcessCompletedEvent); +wxDEFINE_EVENT(EVT_EXPORT_BEGAN, wxCommandEvent); +wxDEFINE_EVENT(EVT_EXPORT_FINISHED, wxCommandEvent); +wxDEFINE_EVENT(EVT_IMPORT_MODEL_ID, wxCommandEvent); +wxDEFINE_EVENT(EVT_DOWNLOAD_PROJECT, wxCommandEvent); +wxDEFINE_EVENT(EVT_PUBLISH, wxCommandEvent); +wxDEFINE_EVENT(EVT_OPEN_PLATESETTINGSDIALOG, wxCommandEvent); // BBS: backup & restore -wxDEFINE_EVENT(EVT_RESTORE_PROJECT, wxCommandEvent); -wxDEFINE_EVENT(EVT_PRINT_FINISHED, wxCommandEvent); -wxDEFINE_EVENT(EVT_SEND_CALIBRATION_FINISHED, wxCommandEvent); -wxDEFINE_EVENT(EVT_SEND_FINISHED, wxCommandEvent); -wxDEFINE_EVENT(EVT_PUBLISH_FINISHED, wxCommandEvent); -//BBS: repair model -wxDEFINE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent); -wxDEFINE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent); -wxDEFINE_EVENT(EVT_INSTALL_PLUGIN_NETWORKING, wxCommandEvent); -wxDEFINE_EVENT(EVT_UPDATE_PLUGINS_WHEN_LAUNCH, wxCommandEvent); -wxDEFINE_EVENT(EVT_INSTALL_PLUGIN_HINT, wxCommandEvent); -wxDEFINE_EVENT(EVT_PREVIEW_ONLY_MODE_HINT, wxCommandEvent); -//BBS: change light/dark mode -wxDEFINE_EVENT(EVT_GLCANVAS_COLOR_MODE_CHANGED, SimpleEvent); -//BBS: print -wxDEFINE_EVENT(EVT_PRINT_FROM_SDCARD_VIEW, SimpleEvent); - - -bool Plater::has_illegal_filename_characters(const wxString& wxs_name) +wxDEFINE_EVENT(EVT_RESTORE_PROJECT, wxCommandEvent); +wxDEFINE_EVENT(EVT_PRINT_FINISHED, wxCommandEvent); +wxDEFINE_EVENT(EVT_SEND_CALIBRATION_FINISHED, wxCommandEvent); +wxDEFINE_EVENT(EVT_SEND_FINISHED, wxCommandEvent); +wxDEFINE_EVENT(EVT_PUBLISH_FINISHED, wxCommandEvent); +// BBS: repair model +wxDEFINE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent); +wxDEFINE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent); +wxDEFINE_EVENT(EVT_INSTALL_PLUGIN_NETWORKING, wxCommandEvent); +wxDEFINE_EVENT(EVT_UPDATE_PLUGINS_WHEN_LAUNCH, wxCommandEvent); +wxDEFINE_EVENT(EVT_INSTALL_PLUGIN_HINT, wxCommandEvent); +wxDEFINE_EVENT(EVT_PREVIEW_ONLY_MODE_HINT, wxCommandEvent); +// BBS: change light/dark mode +wxDEFINE_EVENT(EVT_GLCANVAS_COLOR_MODE_CHANGED, SimpleEvent); +// BBS: print +wxDEFINE_EVENT(EVT_PRINT_FROM_SDCARD_VIEW, SimpleEvent); + +wxDEFINE_EVENT(EVT_CREATE_FILAMENT, SimpleEvent); +wxDEFINE_EVENT(EVT_MODIFY_FILAMENT, SimpleEvent); + +bool Plater::has_illegal_filename_characters(const wxString &wxs_name) { std::string name = into_u8(wxs_name); return has_illegal_filename_characters(name); } -bool Plater::has_illegal_filename_characters(const std::string& name) +bool Plater::has_illegal_filename_characters(const std::string &name) { - const char* illegal_characters = "<>:/\\|?*\""; + const char *illegal_characters = "<>:/\\|?*\""; for (size_t i = 0; i < std::strlen(illegal_characters); i++) if (name.find_first_of(illegal_characters[i]) != std::string::npos) return true; @@ -195,13 +222,12 @@ bool Plater::has_illegal_filename_characters(const std::string& name) return false; } -void Plater::show_illegal_characters_warning(wxWindow* parent) +void Plater::show_illegal_characters_warning(wxWindow *parent) { show_error(parent, _L("Invalid name, the following characters are not allowed:") + " <>:/\\|?*\""); } -enum SlicedInfoIdx -{ +enum SlicedInfoIdx { siFilament_m, siFilament_mm3, siFilament_g, @@ -221,26 +247,19 @@ enum class LoadFilesType { Multiple3MFOther, }; -enum class LoadType : unsigned char -{ - Unknown, - OpenProject, - LoadGeometry, - LoadConfig -}; +enum class LoadType : unsigned char { Unknown, OpenProject, LoadGeometry, LoadConfig }; class SlicedInfo : public wxStaticBoxSizer { public: SlicedInfo(wxWindow *parent); - void SetTextAndShow(SlicedInfoIdx idx, const wxString& text, const wxString& new_label=""); + void SetTextAndShow(SlicedInfoIdx idx, const wxString &text, const wxString &new_label = ""); private: - std::vector> info_vec; + std::vector> info_vec; }; -SlicedInfo::SlicedInfo(wxWindow *parent) : - wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _L("Sliced Info")), wxVERTICAL) +SlicedInfo::SlicedInfo(wxWindow *parent) : wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _L("Sliced Info")), wxVERTICAL) { GetStaticBox()->SetFont(wxGetApp().bold_font()); wxGetApp().UpdateDarkUI(GetStaticBox()); @@ -259,7 +278,7 @@ SlicedInfo::SlicedInfo(wxWindow *parent) : info_label->SetFont(wxGetApp().small_font()); grid_sizer->Add(text, 0); grid_sizer->Add(info_label, 0); - info_vec.push_back(std::pair(text, info_label)); + info_vec.push_back(std::pair(text, info_label)); }; init_info_label(_L("Used Filament (m)")); @@ -274,7 +293,7 @@ SlicedInfo::SlicedInfo(wxWindow *parent) : this->Show(false); } -void SlicedInfo::SetTextAndShow(SlicedInfoIdx idx, const wxString& text, const wxString& new_label/*=""*/) +void SlicedInfo::SetTextAndShow(SlicedInfoIdx idx, const wxString &text, const wxString &new_label /*=""*/) { const bool show = text != "N/A"; if (show) @@ -289,82 +308,83 @@ static wxString temp_dir; // Sidebar / private -enum class ActionButtonType : int { - abReslice, - abExport, - abSendGCode -}; +enum class ActionButtonType : int { abReslice, abExport, abSendGCode }; struct Sidebar::priv { Plater *plater; - wxPanel *scrolled; - PlaterPresetComboBox *combo_print; - std::vector combos_filament; - int editing_filament = -1; - wxBoxSizer *sizer_filaments; - PlaterPresetComboBox *combo_sla_print; - PlaterPresetComboBox *combo_sla_material; - PlaterPresetComboBox* combo_printer = nullptr; - wxBoxSizer *sizer_params; - - //BBS Sidebar widgets - wxPanel* m_panel_print_title; - wxStaticText* m_staticText_print_title; - wxPanel* m_panel_print_content; - wxComboBox* m_comboBox_print_preset; - wxStaticLine* m_staticline1; - StaticBox* m_panel_filament_title; - wxStaticText* m_staticText_filament_settings; - ScalableButton * m_bpButton_add_filament; - ScalableButton * m_bpButton_del_filament; - ScalableButton * m_bpButton_ams_filament; - ScalableButton * m_bpButton_set_filament; - wxPanel* m_panel_filament_content; - wxScrolledWindow* m_scrolledWindow_filament_content; - wxStaticLine* m_staticline2; - wxPanel* m_panel_project_title; - ScalableButton* m_filament_icon = nullptr; - Button * m_flushing_volume_btn = nullptr; + wxPanel *scrolled; + PlaterPresetComboBox *combo_print; + std::vector combos_filament; + int editing_filament = -1; + wxBoxSizer *sizer_filaments; + PlaterPresetComboBox *combo_sla_print; + PlaterPresetComboBox *combo_sla_material; + PlaterPresetComboBox *combo_printer = nullptr; + wxBoxSizer *sizer_params; + + // BBS Sidebar widgets + wxPanel *m_panel_print_title; + wxStaticText *m_staticText_print_title; + wxPanel *m_panel_print_content; + wxComboBox *m_comboBox_print_preset; + wxStaticLine *m_staticline1; + StaticBox *m_panel_filament_title; + wxStaticText *m_staticText_filament_settings; + ScalableButton *m_bpButton_add_filament; + ScalableButton *m_bpButton_del_filament; + ScalableButton *m_bpButton_ams_filament; + ScalableButton *m_bpButton_set_filament; + wxPanel *m_panel_filament_content; + wxScrolledWindow *m_scrolledWindow_filament_content; + wxStaticLine *m_staticline2; + wxPanel *m_panel_project_title; + ScalableButton *m_filament_icon = nullptr; + Button *m_flushing_volume_btn = nullptr; + wxSearchCtrl *m_search_bar = nullptr; + Search::SearchObjectDialog *dia = nullptr; // BBS printer config - StaticBox* m_panel_printer_title = nullptr; - ScalableButton* m_printer_icon = nullptr; - ScalableButton* m_printer_setting = nullptr; - wxStaticText* m_text_printer_settings = nullptr; - wxPanel* m_panel_printer_content = nullptr; - - ObjectList *m_object_list{ nullptr }; - ObjectSettings *object_settings{ nullptr }; - ObjectLayers *object_layers{ nullptr }; - - wxButton *btn_export_gcode; - wxButton *btn_reslice; + StaticBox *m_panel_printer_title = nullptr; + ScalableButton *m_printer_icon = nullptr; + ScalableButton *m_printer_setting = nullptr; + wxStaticText *m_text_printer_settings = nullptr; + wxPanel *m_panel_printer_content = nullptr; + + ObjectList *m_object_list{nullptr}; + ObjectSettings *object_settings{nullptr}; + ObjectLayers *object_layers{nullptr}; + + wxButton *btn_export_gcode; + wxButton *btn_reslice; ScalableButton *btn_send_gcode; - //ScalableButton *btn_eject_device; - ScalableButton* btn_export_gcode_removable; //exports to removable drives (appears only if removable drive is connected) + // ScalableButton *btn_eject_device; + ScalableButton *btn_export_gcode_removable; // exports to removable drives (appears only if removable drive is connected) - bool is_collapsed {false}; - Search::OptionsSearcher searcher; - std::string ams_list_device; + bool is_collapsed{false}; + Search::OptionsSearcher searcher; + std::string ams_list_device; priv(Plater *plater) : plater(plater) {} ~priv(); void show_preset_comboboxes(); + void on_search_update(); + void jump_to_object(ObjectDataViewModelNode *item); + void can_search(); #ifdef _WIN32 wxString btn_reslice_tip; - void show_rich_tip(const wxString& tooltip, wxButton* btn); - void hide_rich_tip(wxButton* btn); + void show_rich_tip(const wxString &tooltip, wxButton *btn); + void hide_rich_tip(wxButton *btn); #endif }; Sidebar::priv::~priv() { // BBS - //delete object_manipulation; + // delete object_manipulation; delete object_settings; // BBS #if 0 @@ -376,7 +396,7 @@ void Sidebar::priv::show_preset_comboboxes() { const bool showSLA = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA; -//BBS +// BBS #if 0 for (size_t i = 0; i < 4; ++i) sizer_presets->Show(i, !showSLA); @@ -393,18 +413,36 @@ void Sidebar::priv::show_preset_comboboxes() scrolled->Refresh(); } +void Sidebar::priv::on_search_update() +{ + m_object_list->assembly_plate_object_name(); + + wxString search_text = m_search_bar->GetValue(); + m_object_list->GetModel()->search_object(search_text); + dia->update_list(); +} + +void Sidebar::priv::jump_to_object(ObjectDataViewModelNode *item) { m_object_list->selected_object(item); } + +void Sidebar::priv::can_search() +{ + if (m_search_bar->IsShown()) { + m_search_bar->SetFocus(); + } +} + #ifdef _WIN32 using wxRichToolTipPopup = wxCustomBackgroundWindow; -static wxRichToolTipPopup* get_rtt_popup(wxButton* btn) +static wxRichToolTipPopup *get_rtt_popup(wxButton *btn) { auto children = btn->GetChildren(); for (auto child : children) if (child->IsShown()) - return dynamic_cast(child); + return dynamic_cast(child); return nullptr; } -void Sidebar::priv::show_rich_tip(const wxString& tooltip, wxButton* btn) +void Sidebar::priv::show_rich_tip(const wxString &tooltip, wxButton *btn) { if (tooltip.IsEmpty()) return; @@ -418,7 +456,7 @@ void Sidebar::priv::show_rich_tip(const wxString& tooltip, wxButton* btn) // Every call of the ShowFor() creates new RichToolTip and show it. // Every one else are hidden. // So, set a text color just for the shown rich tooltip - if (wxRichToolTipPopup* popup = get_rtt_popup(btn)) { + if (wxRichToolTipPopup *popup = get_rtt_popup(btn)) { auto children = popup->GetChildren(); for (auto child : children) { child->SetForegroundColour(wxGetApp().get_label_clr_default()); @@ -428,9 +466,9 @@ void Sidebar::priv::show_rich_tip(const wxString& tooltip, wxButton* btn) } } -void Sidebar::priv::hide_rich_tip(wxButton* btn) +void Sidebar::priv::hide_rich_tip(wxButton *btn) { - if (wxRichToolTipPopup* popup = get_rtt_popup(btn)) + if (wxRichToolTipPopup *popup = get_rtt_popup(btn)) popup->Dismiss(); } #endif @@ -439,7 +477,7 @@ void Sidebar::priv::hide_rich_tip(wxButton* btn) static struct DynamicFilamentList : DynamicList { - std::vector> items; + std::vector> items; void apply_on(Choice *c) override { @@ -471,21 +509,21 @@ static struct DynamicFilamentList : DynamicList items.clear(); if (!force && m_choices.empty()) return; - auto icons = get_extruder_color_icons(true); + auto icons = get_extruder_color_icons(true); auto presets = wxGetApp().preset_bundle->filament_presets; for (int i = 0; i < presets.size(); ++i) { - wxString str; + wxString str; std::string type; wxGetApp().preset_bundle->filaments.find_preset(presets[i])->get_filament_type(type); str << type; - items.push_back({str, icons[i]}); + wxBitmapBundle *bmp = icons[i]; + items.push_back({str, bmp}); } DynamicList::update(); } } dynamic_filament_list; -Sidebar::Sidebar(Plater *parent) - : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(42 * wxGetApp().em_unit(), -1)), p(new priv(parent)) +Sidebar::Sidebar(Plater *parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(42 * wxGetApp().em_unit(), -1)), p(new priv(parent)) { Choice::register_dynamic_list("support_filament", &dynamic_filament_list); Choice::register_dynamic_list("support_interface_filament", &dynamic_filament_list); @@ -495,10 +533,9 @@ Sidebar::Sidebar(Plater *parent) // but this cause the bad layout of the sidebar, when all infoboxes appear. // As a result we can see the empty block at the bottom of the sidebar // But if we set this value to 5, layout will be better - //p->scrolled->SetScrollRate(0, 5); + // p->scrolled->SetScrollRate(0, 5); p->scrolled->SetBackgroundColour(*wxWHITE); - SetFont(wxGetApp().normal_font()); #ifndef __APPLE__ #ifdef _WIN32 @@ -510,14 +547,14 @@ Sidebar::Sidebar(Plater *parent) #endif int em = wxGetApp().em_unit(); - //BBS refine layout and styles - // Sizer in the scrolled area - auto* scrolled_sizer = m_scrolled_sizer = new wxBoxSizer(wxVERTICAL); + // BBS refine layout and styles + // Sizer in the scrolled area + auto *scrolled_sizer = m_scrolled_sizer = new wxBoxSizer(wxVERTICAL); p->scrolled->SetSizer(scrolled_sizer); - wxColour title_bg = wxColour(248, 248, 248); - wxColour inactive_text = wxColour(86, 86, 86); - wxColour active_text = wxColour(0, 0, 0); + wxColour title_bg = wxColour(248, 248, 248); + wxColour inactive_text = wxColour(86, 86, 86); + wxColour active_text = wxColour(0, 0, 0); wxColour static_line_col = wxColour(166, 169, 170); #ifdef __WINDOWS__ @@ -532,14 +569,13 @@ Sidebar::Sidebar(Plater *parent) p->m_panel_printer_title->SetBackgroundColor(title_bg); p->m_panel_printer_title->SetBackgroundColor2(0xF1F1F1); - p->m_printer_icon = new ScalableButton(p->m_panel_printer_title, wxID_ANY, "printer"); + p->m_printer_icon = new ScalableButton(p->m_panel_printer_title, wxID_ANY, "printer"); p->m_text_printer_settings = new Label(p->m_panel_printer_title, _L("Printer"), LB_PROPAGATE_MOUSE_EVENT); - p->m_printer_icon->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) { - //auto wizard_t = new ConfigWizard(wxGetApp().mainframe); - //wizard_t->run(ConfigWizard::RR_USER, ConfigWizard::SP_CUSTOM); - }); - + p->m_printer_icon->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { + // auto wizard_t = new ConfigWizard(wxGetApp().mainframe); + // wizard_t->run(ConfigWizard::RR_USER, ConfigWizard::SP_CUSTOM); + }); p->m_printer_setting = new ScalableButton(p->m_panel_printer_title, wxID_ANY, "settings"); p->m_printer_setting->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { @@ -547,9 +583,9 @@ Sidebar::Sidebar(Plater *parent) // wxGetApp().params_dialog()->Popup(); // wxGetApp().get_tab(Preset::TYPE_FILAMENT)->restore_last_select_item(); wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_PRINTERS); - }); + }); - wxBoxSizer* h_sizer_title = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *h_sizer_title = new wxBoxSizer(wxHORIZONTAL); h_sizer_title->Add(p->m_printer_icon, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, em); h_sizer_title->Add(p->m_text_printer_settings, 0, wxALIGN_CENTER); h_sizer_title->AddStretchSpacer(); @@ -562,13 +598,13 @@ Sidebar::Sidebar(Plater *parent) // 1.2 Add spliters around title bar // add spliter 1 - //auto spliter_1 = new ::StaticLine(p->scrolled); - //spliter_1->SetBackgroundColour("#A6A9AA"); - //scrolled_sizer->Add(spliter_1, 0, wxEXPAND); + // auto spliter_1 = new ::StaticLine(p->scrolled); + // spliter_1->SetBackgroundColour("#A6A9AA"); + // scrolled_sizer->Add(spliter_1, 0, wxEXPAND); // add printer title scrolled_sizer->Add(p->m_panel_printer_title, 0, wxEXPAND | wxALL, 0); - p->m_panel_printer_title->Bind(wxEVT_LEFT_UP, [this] (auto & e) { + p->m_panel_printer_title->Bind(wxEVT_LEFT_UP, [this](auto &e) { if (p->m_panel_printer_content->GetMaxHeight() == 0) p->m_panel_printer_content->SetMaxSize({-1, -1}); else @@ -581,34 +617,31 @@ Sidebar::Sidebar(Plater *parent) spliter_2->SetLineColour("#CECECE"); scrolled_sizer->Add(spliter_2, 0, wxEXPAND); - /*************************** 2. add printer content ************************/ p->m_panel_printer_content = new wxPanel(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); p->m_panel_printer_content->SetBackgroundColour(wxColour(255, 255, 255)); - PlaterPresetComboBox* combo_printer = new PlaterPresetComboBox(p->m_panel_printer_content, Preset::TYPE_PRINTER); - ScalableButton* edit_btn = new ScalableButton(p->m_panel_printer_content, wxID_ANY, "edit"); + PlaterPresetComboBox *combo_printer = new PlaterPresetComboBox(p->m_panel_printer_content, Preset::TYPE_PRINTER); + ScalableButton *edit_btn = new ScalableButton(p->m_panel_printer_content, wxID_ANY, "edit"); edit_btn->SetToolTip(_L("Click to edit preset")); - edit_btn->Bind(wxEVT_BUTTON, [this, combo_printer](wxCommandEvent) - { - p->editing_filament = -1; - if (combo_printer->switch_to_tab()) - p->editing_filament = 0; - }); + edit_btn->Bind(wxEVT_BUTTON, [this, combo_printer](wxCommandEvent) { + p->editing_filament = -1; + if (combo_printer->switch_to_tab()) + p->editing_filament = 0; + }); combo_printer->edit_btn = edit_btn; - p->combo_printer = combo_printer; + p->combo_printer = combo_printer; connection_btn = new ScalableButton(p->m_panel_printer_content, wxID_ANY, "monitor_signal_strong"); connection_btn->SetBackgroundColour(wxColour(255, 255, 255)); connection_btn->SetToolTip(_L("Connection")); - connection_btn->Bind(wxEVT_BUTTON, [this, combo_printer](wxCommandEvent) - { - PhysicalPrinterDialog dlg(this->GetParent()); - dlg.ShowModal(); - }); + connection_btn->Bind(wxEVT_BUTTON, [this, combo_printer](wxCommandEvent) { + PhysicalPrinterDialog dlg(this->GetParent()); + dlg.ShowModal(); + }); - wxBoxSizer* vsizer_printer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer* hsizer_printer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *vsizer_printer = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *hsizer_printer = new wxBoxSizer(wxHORIZONTAL); vsizer_printer->AddSpacer(FromDIP(16)); hsizer_printer->Add(combo_printer, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3)); @@ -619,13 +652,14 @@ Sidebar::Sidebar(Plater *parent) vsizer_printer->Add(hsizer_printer, 0, wxEXPAND, 0); // Bed type selection - wxBoxSizer* bed_type_sizer = new wxBoxSizer(wxHORIZONTAL); - wxStaticText* bed_type_title = new wxStaticText(p->m_panel_printer_content, wxID_ANY, _L("Bed type")); - //bed_type_title->SetBackgroundColour(); + wxBoxSizer *bed_type_sizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticText *bed_type_title = new wxStaticText(p->m_panel_printer_content, wxID_ANY, _L("Bed type")); + // bed_type_title->SetBackgroundColour(); bed_type_title->Wrap(-1); bed_type_title->SetFont(Label::Body_14); - m_bed_type_list = new ComboBox(p->m_panel_printer_content, wxID_ANY, wxString(""), wxDefaultPosition, {-1, FromDIP(30)}, 0, nullptr, wxCB_READONLY); - const ConfigOptionDef* bed_type_def = print_config_def.get("curr_bed_type"); + m_bed_type_list = new ComboBox(p->m_panel_printer_content, wxID_ANY, wxString(""), wxDefaultPosition, {-1, FromDIP(30)}, 0, nullptr, + wxCB_READONLY); + const ConfigOptionDef *bed_type_def = print_config_def.get("curr_bed_type"); if (bed_type_def && bed_type_def->enum_keys_map) { for (auto item : bed_type_def->enum_labels) { m_bed_type_list->AppendString(_L(item)); @@ -650,9 +684,9 @@ Sidebar::Sidebar(Plater *parent) wxLaunchDefaultBrowser("https://wiki.bambulab.com/en/x1/manual/compatibility-and-parameter-settings-of-filaments"); }); - AppConfig *app_config = wxGetApp().app_config; - std::string str_bed_type = app_config->get("curr_bed_type"); - int bed_type_value = atoi(str_bed_type.c_str()); + AppConfig *app_config = wxGetApp().app_config; + std::string str_bed_type = app_config->get("curr_bed_type"); + int bed_type_value = atoi(str_bed_type.c_str()); // hotfix: btDefault is added as the first one in BedType, and app_config should not be btDefault if (bed_type_value == 0) { app_config->set("curr_bed_type", "1"); @@ -666,14 +700,14 @@ Sidebar::Sidebar(Plater *parent) vsizer_printer->Add(bed_type_sizer, 0, wxEXPAND | wxTOP, FromDIP(5)); vsizer_printer->AddSpacer(FromDIP(16)); - auto& project_config = wxGetApp().preset_bundle->project_config; + auto &project_config = wxGetApp().preset_bundle->project_config; /*const t_config_enum_values* keys_map = print_config_def.get("curr_bed_type")->enum_keys_map; BedType bed_type = btCount; for (auto item : *keys_map) { if (item.first == str_bed_type) bed_type = (BedType)item.second; }*/ - BedType bed_type = (BedType)bed_type_value; + BedType bed_type = (BedType) bed_type_value; project_config.set_key_value("curr_bed_type", new ConfigOptionEnum(bed_type)); p->m_panel_printer_content->SetSizer(vsizer_printer); @@ -682,254 +716,276 @@ Sidebar::Sidebar(Plater *parent) } { - // add filament title - p->m_panel_filament_title = new StaticBox(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_NONE); - p->m_panel_filament_title->SetBackgroundColor(title_bg); - p->m_panel_filament_title->SetBackgroundColor2(0xF1F1F1); - p->m_panel_filament_title->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &e) { - if (e.GetPosition().x > (p->m_flushing_volume_btn->IsShown() - ? p->m_flushing_volume_btn->GetPosition().x : p->m_bpButton_add_filament->GetPosition().x)) - return; - if (p->m_panel_filament_content->GetMaxHeight() == 0) - p->m_panel_filament_content->SetMaxSize({-1, -1}); - else - p->m_panel_filament_content->SetMaxSize({-1, 0}); - m_scrolled_sizer->Layout(); - }); + // add filament title + p->m_panel_filament_title = new StaticBox(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_NONE); + p->m_panel_filament_title->SetBackgroundColor(title_bg); + p->m_panel_filament_title->SetBackgroundColor2(0xF1F1F1); + p->m_panel_filament_title->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &e) { + if (e.GetPosition().x > (p->m_flushing_volume_btn->IsShown() ? p->m_flushing_volume_btn->GetPosition().x : + p->m_bpButton_add_filament->GetPosition().x)) + return; + if (p->m_panel_filament_content->GetMaxHeight() == 0) + p->m_panel_filament_content->SetMaxSize({-1, -1}); + else + p->m_panel_filament_content->SetMaxSize({-1, 0}); + m_scrolled_sizer->Layout(); + }); - wxBoxSizer* bSizer39; - bSizer39 = new wxBoxSizer( wxHORIZONTAL ); - p->m_filament_icon = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "filament"); - p->m_staticText_filament_settings = new Label(p->m_panel_filament_title, _L("Filament"), LB_PROPAGATE_MOUSE_EVENT); - bSizer39->Add(p->m_filament_icon, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(10)); - bSizer39->Add( p->m_staticText_filament_settings, 0, wxALIGN_CENTER ); - bSizer39->Add(FromDIP(10), 0, 0, 0, 0); - bSizer39->SetMinSize(-1, FromDIP(30)); - - p->m_panel_filament_title->SetSizer( bSizer39 ); - p->m_panel_filament_title->Layout(); - auto spliter_1 = new ::StaticLine(p->scrolled); - spliter_1->SetLineColour("#A6A9AA"); - scrolled_sizer->Add(spliter_1, 0, wxEXPAND); - scrolled_sizer->Add(p->m_panel_filament_title, 0, wxEXPAND | wxALL, 0); - auto spliter_2 = new ::StaticLine(p->scrolled); - spliter_2->SetLineColour("#CECECE"); - scrolled_sizer->Add(spliter_2, 0, wxEXPAND); + wxBoxSizer *bSizer39; + bSizer39 = new wxBoxSizer(wxHORIZONTAL); + p->m_filament_icon = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "filament"); + p->m_staticText_filament_settings = new Label(p->m_panel_filament_title, _L("Filament"), LB_PROPAGATE_MOUSE_EVENT); + bSizer39->Add(p->m_filament_icon, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(10)); + bSizer39->Add(p->m_staticText_filament_settings, 0, wxALIGN_CENTER); + bSizer39->Add(FromDIP(10), 0, 0, 0, 0); + bSizer39->SetMinSize(-1, FromDIP(30)); + + p->m_panel_filament_title->SetSizer(bSizer39); + p->m_panel_filament_title->Layout(); + auto spliter_1 = new ::StaticLine(p->scrolled); + spliter_1->SetLineColour("#A6A9AA"); + scrolled_sizer->Add(spliter_1, 0, wxEXPAND); + scrolled_sizer->Add(p->m_panel_filament_title, 0, wxEXPAND | wxALL, 0); + auto spliter_2 = new ::StaticLine(p->scrolled); + spliter_2->SetLineColour("#CECECE"); + scrolled_sizer->Add(spliter_2, 0, wxEXPAND); - bSizer39->AddStretchSpacer(1); + bSizer39->AddStretchSpacer(1); - // BBS - // add wiping dialog - //wiping_dialog_button->SetFont(wxGetApp().normal_font()); - p->m_flushing_volume_btn = new Button(p->m_panel_filament_title, _L("Flushing volumes")); - p->m_flushing_volume_btn->SetFont(Label::Body_10); - p->m_flushing_volume_btn->SetPaddingSize(wxSize(FromDIP(8),FromDIP(3))); - p->m_flushing_volume_btn->SetCornerRadius(FromDIP(8)); - - StateColor flush_bg_col(std::pair(wxColour(219, 253, 231), StateColor::Pressed), - std::pair(wxColour(238, 238, 238), StateColor::Hovered), - std::pair(wxColour(238, 238, 238), StateColor::Normal)); - - StateColor flush_fg_col(std::pair(wxColour(107, 107, 106), StateColor::Pressed), - std::pair(wxColour(107, 107, 106), StateColor::Hovered), - std::pair(wxColour(107, 107, 106), StateColor::Normal)); - - StateColor flush_bd_col(std::pair(wxColour(0, 150, 136), StateColor::Pressed), - std::pair(wxColour(0, 150, 136), StateColor::Hovered), - std::pair(wxColour(172, 172, 172), StateColor::Normal)); - - p->m_flushing_volume_btn->SetBackgroundColor(flush_bg_col); - p->m_flushing_volume_btn->SetBorderColor(flush_bd_col); - p->m_flushing_volume_btn->SetTextColor(flush_fg_col); - p->m_flushing_volume_btn->SetFocus(); - p->m_flushing_volume_btn->SetId(wxID_RESET); - p->m_flushing_volume_btn->Rescale(); + // BBS + // add wiping dialog + // wiping_dialog_button->SetFont(wxGetApp().normal_font()); + p->m_flushing_volume_btn = new Button(p->m_panel_filament_title, _L("Flushing volumes")); + p->m_flushing_volume_btn->SetFont(Label::Body_10); + p->m_flushing_volume_btn->SetPaddingSize(wxSize(FromDIP(8), FromDIP(3))); + p->m_flushing_volume_btn->SetCornerRadius(FromDIP(8)); + + StateColor flush_bg_col(std::pair(wxColour(219, 253, 231), StateColor::Pressed), + std::pair(wxColour(238, 238, 238), StateColor::Hovered), + std::pair(wxColour(238, 238, 238), StateColor::Normal)); + + StateColor flush_fg_col(std::pair(wxColour(107, 107, 106), StateColor::Pressed), + std::pair(wxColour(107, 107, 106), StateColor::Hovered), + std::pair(wxColour(107, 107, 106), StateColor::Normal)); + + StateColor flush_bd_col(std::pair(wxColour(0, 150, 136), StateColor::Pressed), + std::pair(wxColour(0, 150, 136), StateColor::Hovered), + std::pair(wxColour(172, 172, 172), StateColor::Normal)); + + p->m_flushing_volume_btn->SetBackgroundColor(flush_bg_col); + p->m_flushing_volume_btn->SetBorderColor(flush_bd_col); + p->m_flushing_volume_btn->SetTextColor(flush_fg_col); + p->m_flushing_volume_btn->SetFocus(); + p->m_flushing_volume_btn->SetId(wxID_RESET); + p->m_flushing_volume_btn->Rescale(); + + p->m_flushing_volume_btn->Bind( + wxEVT_BUTTON, ([parent](wxCommandEvent &e) { + auto &project_config = wxGetApp().preset_bundle->project_config; + auto &printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + const std::vector &init_matrix = (project_config.option("flush_volumes_matrix"))->values; + const std::vector &init_extruders = (project_config.option("flush_volumes_vector"))->values; + ConfigOption *extra_flush_volume_opt = printer_config.option("nozzle_volume"); + int extra_flush_volume = extra_flush_volume_opt ? (int) extra_flush_volume_opt->getFloat() : 0; + ConfigOptionFloat *flush_multi_opt = project_config.option("flush_multiplier"); + float flush_multiplier = flush_multi_opt ? flush_multi_opt->getFloat() : 1.f; + + const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); + + WipingDialog dlg(parent, cast(init_matrix), cast(init_extruders), extruder_colours, extra_flush_volume, + flush_multiplier); + + if (dlg.ShowModal() == wxID_OK) { + std::vector matrix = dlg.get_matrix(); + (project_config.option("flush_volumes_matrix"))->values = std::vector(matrix.begin(), + matrix.end()); + (project_config.option("flush_multiplier"))->set(new ConfigOptionFloat(dlg.get_flush_multiplier())); + + wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); + + wxGetApp().plater()->update_project_dirty_from_presets(); + wxPostEvent(parent, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, parent)); + } + })); - p->m_flushing_volume_btn->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent &e) - { - auto& project_config = wxGetApp().preset_bundle->project_config; - auto& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config; - const std::vector& init_matrix = (project_config.option("flush_volumes_matrix"))->values; - const std::vector& init_extruders = (project_config.option("flush_volumes_vector"))->values; - ConfigOption* extra_flush_volume_opt = printer_config.option("nozzle_volume"); - int extra_flush_volume = extra_flush_volume_opt ? (int)extra_flush_volume_opt->getFloat() : 0; - ConfigOptionFloat* flush_multi_opt = project_config.option("flush_multiplier"); - float flush_multiplier = flush_multi_opt ? flush_multi_opt->getFloat() : 1.f; + bSizer39->Add(p->m_flushing_volume_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5)); + bSizer39->Hide(p->m_flushing_volume_btn); + bSizer39->Add(FromDIP(10), 0, 0, 0, 0); - const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); + ScalableButton *add_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "add_filament"); + add_btn->SetToolTip(_L("Add one filament")); + add_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) { + // Orca: limit filament choices to 64 + if (p->combos_filament.size() >= 64) + return; - WipingDialog dlg(parent, cast(init_matrix), cast(init_extruders), extruder_colours, extra_flush_volume, flush_multiplier); + int filament_count = p->combos_filament.size() + 1; + wxColour new_col = Plater::get_next_color_for_filament(); + std::string new_color = new_col.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(); + wxGetApp().preset_bundle->set_num_filaments(filament_count, new_color); + wxGetApp().plater()->on_filaments_change(filament_count); + wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); + wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); + auto_calc_flushing_volumes(filament_count - 1); + }); + p->m_bpButton_add_filament = add_btn; - if (dlg.ShowModal() == wxID_OK) { - std::vector matrix = dlg.get_matrix(); - std::vector extruders = dlg.get_extruders(); - (project_config.option("flush_volumes_matrix"))->values = std::vector(matrix.begin(), matrix.end()); - (project_config.option("flush_volumes_vector"))->values = std::vector(extruders.begin(), extruders.end()); - (project_config.option("flush_multiplier"))->set(new ConfigOptionFloat(dlg.get_flush_multiplier())); + bSizer39->Add(add_btn, 0, wxALIGN_CENTER | wxALL, FromDIP(5)); + bSizer39->Add(FromDIP(10), 0, 0, 0, 0); - wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); + ScalableButton *del_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "delete_filament"); + del_btn->SetToolTip(_L("Remove last filament")); + del_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) { + if (p->combos_filament.size() <= 1) + return; - wxGetApp().plater()->update_project_dirty_from_presets(); - wxPostEvent(parent, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, parent)); + size_t filament_count = p->combos_filament.size() - 1; + if (wxGetApp().preset_bundle->is_the_only_edited_filament(filament_count) || (filament_count == 1)) { + wxGetApp().get_tab(Preset::TYPE_FILAMENT)->select_preset(wxGetApp().preset_bundle->filament_presets[0], false, "", true); } - })); - bSizer39->Add(p->m_flushing_volume_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5)); - bSizer39->Hide(p->m_flushing_volume_btn); - bSizer39->Add(FromDIP(10), 0, 0, 0, 0 ); - - ScalableButton* add_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "add_filament"); - add_btn->SetToolTip(_L("Add one filament")); - add_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent& e){ - // Orca: limit filament choices to 64 - if (p->combos_filament.size() >= 64) - return; - - int filament_count = p->combos_filament.size() + 1; - wxColour new_col = Plater::get_next_color_for_filament(); - std::string new_color = new_col.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(); - wxGetApp().preset_bundle->set_num_filaments(filament_count, new_color); - wxGetApp().plater()->on_filaments_change(filament_count); - wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); - wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); - }); - p->m_bpButton_add_filament = add_btn; - bSizer39->Add(add_btn, 0, wxALIGN_CENTER|wxALL, FromDIP(5)); - bSizer39->Add(FromDIP(10), 0, 0, 0, 0 ); - - ScalableButton* del_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "delete_filament"); - del_btn->SetToolTip(_L("Remove last filament")); - del_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) { - if (p->combos_filament.size() <= 1) - return; - - size_t filament_count = p->combos_filament.size() - 1; - if (wxGetApp().preset_bundle->is_the_only_edited_filament(filament_count) || (filament_count == 1)) { - wxGetApp().get_tab(Preset::TYPE_FILAMENT)->select_preset(wxGetApp().preset_bundle->filament_presets[0], false, "", true); - } - - if (p->editing_filament >= filament_count) { - p->editing_filament = -1; - } + if (p->editing_filament >= filament_count) { + p->editing_filament = -1; + } - wxGetApp().preset_bundle->set_num_filaments(filament_count); - wxGetApp().plater()->on_filaments_change(filament_count); - wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); - wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); - }); - p->m_bpButton_del_filament = del_btn; + wxGetApp().preset_bundle->set_num_filaments(filament_count); + wxGetApp().plater()->on_filaments_change(filament_count); + wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); + wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); + }); + p->m_bpButton_del_filament = del_btn; - bSizer39->Add(del_btn, 0, wxALIGN_CENTER_VERTICAL, FromDIP(5)); - bSizer39->Add(FromDIP(20), 0, 0, 0, 0); + bSizer39->Add(del_btn, 0, wxALIGN_CENTER_VERTICAL, FromDIP(5)); + bSizer39->Add(FromDIP(20), 0, 0, 0, 0); - ams_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "ams_fila_sync", wxEmptyString, wxDefaultSize, wxDefaultPosition, - wxBU_EXACTFIT | wxNO_BORDER, false, 18); - ams_btn->SetToolTip(_L("Synchronize filament list from AMS")); - ams_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) { - sync_ams_list(); - }); - p->m_bpButton_ams_filament = ams_btn; + ams_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "ams_fila_sync", wxEmptyString, wxDefaultSize, wxDefaultPosition, + wxBU_EXACTFIT | wxNO_BORDER, 18); + ams_btn->SetToolTip(_L("Synchronize filament list from AMS")); + ams_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) { sync_ams_list(); }); + p->m_bpButton_ams_filament = ams_btn; - bSizer39->Add(ams_btn, 0, wxALIGN_CENTER|wxALL, FromDIP(5)); - bSizer39->Add(FromDIP(10), 0, 0, 0, 0 ); + bSizer39->Add(ams_btn, 0, wxALIGN_CENTER | wxALL, FromDIP(5)); + bSizer39->Add(FromDIP(10), 0, 0, 0, 0); - ScalableButton* set_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "settings"); - set_btn->SetToolTip(_L("Set filaments to use")); - set_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { - p->editing_filament = -1; - // wxGetApp().params_dialog()->Popup(); - // wxGetApp().get_tab(Preset::TYPE_FILAMENT)->restore_last_select_item(); - wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_FILAMENTS); + ScalableButton *set_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "settings"); + set_btn->SetToolTip(_L("Set filaments to use")); + set_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { + p->editing_filament = -1; + // wxGetApp().params_dialog()->Popup(); + // wxGetApp().get_tab(Preset::TYPE_FILAMENT)->restore_last_select_item(); + wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_FILAMENTS); }); - p->m_bpButton_set_filament = set_btn; + p->m_bpButton_set_filament = set_btn; - bSizer39->Add(set_btn, 0, wxALIGN_CENTER); - bSizer39->Add(FromDIP(15), 0, 0, 0, 0); + bSizer39->Add(set_btn, 0, wxALIGN_CENTER); + bSizer39->Add(FromDIP(15), 0, 0, 0, 0); - // add filament content - p->m_panel_filament_content = new wxPanel( p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - p->m_panel_filament_content->SetBackgroundColour( wxColour( 255, 255, 255 ) ); + // add filament content + p->m_panel_filament_content = new wxPanel(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + p->m_panel_filament_content->SetBackgroundColour(wxColour(255, 255, 255)); - //wxBoxSizer* bSizer_filament_content; - //bSizer_filament_content = new wxBoxSizer( wxHORIZONTAL ); + // wxBoxSizer* bSizer_filament_content; + // bSizer_filament_content = new wxBoxSizer( wxHORIZONTAL ); - // BBS: filament double columns - p->sizer_filaments = new wxBoxSizer(wxHORIZONTAL); - p->sizer_filaments->Add(new wxBoxSizer(wxVERTICAL), 1, wxEXPAND); - p->sizer_filaments->Add(new wxBoxSizer(wxVERTICAL), 1, wxEXPAND); + // BBS: filament double columns + p->sizer_filaments = new wxBoxSizer(wxHORIZONTAL); + p->sizer_filaments->Add(new wxBoxSizer(wxVERTICAL), 1, wxEXPAND); + p->sizer_filaments->Add(new wxBoxSizer(wxVERTICAL), 1, wxEXPAND); - p->combos_filament.push_back(nullptr); + p->combos_filament.push_back(nullptr); - /* first filament item */ - p->combos_filament[0] = new PlaterPresetComboBox(p->m_panel_filament_content, Preset::TYPE_FILAMENT); - auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL); - // BBS: filament double columns - combo_and_btn_sizer->Add(FromDIP(8), 0, 0, 0, 0); - if (p->combos_filament[0]->clr_picker) { - p->combos_filament[0]->clr_picker->SetLabel("1"); - combo_and_btn_sizer->Add(p->combos_filament[0]->clr_picker, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(3)); - } - combo_and_btn_sizer->Add(p->combos_filament[0], 1, wxALL | wxEXPAND, FromDIP(2))->SetMinSize({-1, FromDIP(30) }); + /* first filament item */ + p->combos_filament[0] = new PlaterPresetComboBox(p->m_panel_filament_content, Preset::TYPE_FILAMENT); + auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL); + // BBS: filament double columns + combo_and_btn_sizer->Add(FromDIP(8), 0, 0, 0, 0); + if (p->combos_filament[0]->clr_picker) { + p->combos_filament[0]->clr_picker->SetLabel("1"); + combo_and_btn_sizer->Add(p->combos_filament[0]->clr_picker, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(3)); + } + combo_and_btn_sizer->Add(p->combos_filament[0], 1, wxALL | wxEXPAND, FromDIP(2))->SetMinSize({-1, FromDIP(30)}); - ScalableButton* edit_btn = new ScalableButton(p->m_panel_filament_content, wxID_ANY, "edit"); - edit_btn->SetBackgroundColour(wxColour(255, 255, 255)); - edit_btn->SetToolTip(_L("Click to edit preset")); + ScalableButton *edit_btn = new ScalableButton(p->m_panel_filament_content, wxID_ANY, "edit"); + edit_btn->SetBackgroundColour(wxColour(255, 255, 255)); + edit_btn->SetToolTip(_L("Click to edit preset")); - PlaterPresetComboBox* combobox = p->combos_filament[0]; - edit_btn->Bind(wxEVT_BUTTON, [this, combobox](wxCommandEvent) - { + PlaterPresetComboBox *combobox = p->combos_filament[0]; + edit_btn->Bind(wxEVT_BUTTON, [this, combobox](wxCommandEvent) { p->editing_filament = 0; combobox->switch_to_tab(); }); - combobox->edit_btn = edit_btn; + combobox->edit_btn = edit_btn; - combo_and_btn_sizer->Add(edit_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3)); - combo_and_btn_sizer->Add(FromDIP(8), 0, 0, 0, 0); + combo_and_btn_sizer->Add(edit_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3)); + combo_and_btn_sizer->Add(FromDIP(8), 0, 0, 0, 0); - p->combos_filament[0]->set_filament_idx(0); - p->sizer_filaments->GetItem((size_t)0)->GetSizer()->Add(combo_and_btn_sizer, 1, wxEXPAND); + p->combos_filament[0]->set_filament_idx(0); + p->sizer_filaments->GetItem((size_t) 0)->GetSizer()->Add(combo_and_btn_sizer, 1, wxEXPAND); - //bSizer_filament_content->Add(p->sizer_filaments, 1, wxALIGN_CENTER | wxALL); - wxSizer *sizer_filaments2 = new wxBoxSizer(wxVERTICAL); - sizer_filaments2->AddSpacer(FromDIP(16)); - sizer_filaments2->Add(p->sizer_filaments, 0, wxEXPAND, 0); - sizer_filaments2->AddSpacer(FromDIP(16)); - p->m_panel_filament_content->SetSizer(sizer_filaments2); - p->m_panel_filament_content->Layout(); - scrolled_sizer->Add(p->m_panel_filament_content, 0, wxEXPAND, 0); + // bSizer_filament_content->Add(p->sizer_filaments, 1, wxALIGN_CENTER | wxALL); + wxSizer *sizer_filaments2 = new wxBoxSizer(wxVERTICAL); + sizer_filaments2->AddSpacer(FromDIP(16)); + sizer_filaments2->Add(p->sizer_filaments, 0, wxEXPAND, 0); + sizer_filaments2->AddSpacer(FromDIP(16)); + p->m_panel_filament_content->SetSizer(sizer_filaments2); + p->m_panel_filament_content->Layout(); + scrolled_sizer->Add(p->m_panel_filament_content, 0, wxEXPAND, 0); } { - //add project title - auto params_panel = ((MainFrame*)parent->GetParent())->m_param_panel; - if (params_panel) { - params_panel->get_top_panel()->Reparent(p->scrolled); - auto spliter_1 = new ::StaticLine(p->scrolled); - spliter_1->SetLineColour("#A6A9AA"); - scrolled_sizer->Add(spliter_1, 0, wxEXPAND); - scrolled_sizer->Add(params_panel->get_top_panel(), 0, wxEXPAND); - auto spliter_2 = new ::StaticLine(p->scrolled); - spliter_2->SetLineColour("#CECECE"); - scrolled_sizer->Add(spliter_2, 0, wxEXPAND); - } + // add project title + auto params_panel = ((MainFrame *) parent->GetParent())->m_param_panel; + if (params_panel) { + params_panel->get_top_panel()->Reparent(p->scrolled); + auto spliter_1 = new ::StaticLine(p->scrolled); + spliter_1->SetLineColour("#A6A9AA"); + scrolled_sizer->Add(spliter_1, 0, wxEXPAND); + scrolled_sizer->Add(params_panel->get_top_panel(), 0, wxEXPAND); + auto spliter_2 = new ::StaticLine(p->scrolled); + spliter_2->SetLineColour("#CECECE"); + scrolled_sizer->Add(spliter_2, 0, wxEXPAND); + } + + // add project content + p->sizer_params = new wxBoxSizer(wxVERTICAL); + + p->m_search_bar = new wxSearchCtrl(p->scrolled, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); + p->m_search_bar->ShowSearchButton(true); + p->m_search_bar->ShowCancelButton(true); + p->m_search_bar->SetDescriptiveText(_L("Search plate, object and part.")); + + p->m_search_bar->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent &) { + this->p->on_search_update(); + wxPoint pos = this->p->m_search_bar->ClientToScreen(wxPoint(0, 0)); + pos.y += this->p->m_search_bar->GetRect().height; + p->dia->SetPosition(pos); + p->dia->Popup(); + }); + p->m_search_bar->Bind(wxEVT_COMMAND_TEXT_UPDATED, [this](wxCommandEvent &) { this->p->on_search_update(); }); + p->m_search_bar->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &e) { + p->dia->Dismiss(); + e.Skip(); + }); + + p->m_object_list = new ObjectList(p->scrolled); - //add project content - p->sizer_params = new wxBoxSizer(wxVERTICAL); - p->m_object_list = new ObjectList(p->scrolled); - p->sizer_params->Add(p->m_object_list, 1, wxEXPAND | wxTOP, 0); - scrolled_sizer->Add(p->sizer_params, 2, wxEXPAND | wxLEFT, 0); - p->m_object_list->Hide(); + p->sizer_params->Add(p->m_search_bar, 0, wxALL | wxEXPAND, 0); + p->sizer_params->Add(p->m_object_list, 1, wxEXPAND | wxTOP, 0); + scrolled_sizer->Add(p->sizer_params, 2, wxEXPAND | wxLEFT, 0); + p->m_object_list->Hide(); + p->m_search_bar->Hide(); + // Frequently Object Settings + p->object_settings = new ObjectSettings(p->scrolled); - // Frequently Object Settings - p->object_settings = new ObjectSettings(p->scrolled); + p->dia = new Search::SearchObjectDialog(p->m_object_list, p->m_search_bar); #if !NEW_OBJECT_SETTING - p->object_settings->Hide(); - p->sizer_params->Add(p->object_settings->get_sizer(), 0, wxEXPAND | wxTOP, 5 * em / 10); + p->object_settings->Hide(); + p->sizer_params->Add(p->object_settings->get_sizer(), 0, wxEXPAND | wxTOP, 5 * em / 10); #else - if (params_panel) { - params_panel->Reparent(p->scrolled); - scrolled_sizer->Add(params_panel, 3, wxEXPAND); - } + if (params_panel) { + params_panel->Reparent(p->scrolled); + scrolled_sizer->Add(params_panel, 3, wxEXPAND); + } #endif } @@ -944,7 +1000,27 @@ Sidebar::Sidebar(Plater *parent) Sidebar::~Sidebar() {} -void Sidebar::init_filament_combo(PlaterPresetComboBox **combo, const int filament_idx) { +void Sidebar::create_printer_preset() +{ + CreatePrinterPresetDialog dlg(wxGetApp().mainframe); + int res = dlg.ShowModal(); + if (wxID_OK == res) { + wxGetApp().mainframe->update_side_preset_ui(); + update_ui_from_settings(); + update_all_preset_comboboxes(); + wxGetApp().load_current_presets(); + CreatePresetSuccessfulDialog success_dlg(wxGetApp().mainframe, SuccessType::PRINTER); + int res = success_dlg.ShowModal(); + if (res == wxID_OK) { + p->editing_filament = -1; + if (p->combo_printer->switch_to_tab()) + p->editing_filament = 0; + } + } +} + +void Sidebar::init_filament_combo(PlaterPresetComboBox **combo, const int filament_idx) +{ *combo = new PlaterPresetComboBox(p->m_panel_filament_content, Slic3r::Preset::TYPE_FILAMENT); (*combo)->set_filament_idx(filament_idx); @@ -952,7 +1028,7 @@ void Sidebar::init_filament_combo(PlaterPresetComboBox **combo, const int filame // BBS: filament double columns int em = wxGetApp().em_unit(); - combo_and_btn_sizer->Add(FromDIP(8), 0, 0, 0, 0 ); + combo_and_btn_sizer->Add(FromDIP(8), 0, 0, 0, 0); (*combo)->clr_picker->SetLabel(wxString::Format("%d", filament_idx + 1)); combo_and_btn_sizer->Add((*combo)->clr_picker, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(3)); combo_and_btn_sizer->Add(*combo, 1, wxALL | wxEXPAND, FromDIP(2))->SetMinSize({-1, FromDIP(30)}); @@ -971,16 +1047,15 @@ void Sidebar::init_filament_combo(PlaterPresetComboBox **combo, const int filame combo_and_btn_sizer->Add(32 * em / 10, 0, 0, 0, 0); combo_and_btn_sizer->Add(del_btn, 0, wxALIGN_CENTER_VERTICAL, 5 * em / 10); */ - ScalableButton* edit_btn = new ScalableButton(p->m_panel_filament_content, wxID_ANY, "edit"); + ScalableButton *edit_btn = new ScalableButton(p->m_panel_filament_content, wxID_ANY, "edit"); edit_btn->SetToolTip(_L("Click to edit preset")); - PlaterPresetComboBox* combobox = (*combo); - edit_btn->Bind(wxEVT_BUTTON, [this, combobox, filament_idx](wxCommandEvent) - { - p->editing_filament = -1; - if (combobox->switch_to_tab()) - p->editing_filament = filament_idx; // sync with TabPresetComboxBox's m_filament_idx - }); + PlaterPresetComboBox *combobox = (*combo); + edit_btn->Bind(wxEVT_BUTTON, [this, combobox, filament_idx](wxCommandEvent) { + p->editing_filament = -1; + if (combobox->switch_to_tab()) + p->editing_filament = filament_idx; // sync with TabPresetComboxBox's m_filament_idx + }); combobox->edit_btn = edit_btn; combo_and_btn_sizer->Add(edit_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3)); @@ -988,9 +1063,10 @@ void Sidebar::init_filament_combo(PlaterPresetComboBox **combo, const int filame combo_and_btn_sizer->Add(FromDIP(8), 0, 0, 0, 0); // BBS: filament double columns - auto side = filament_idx % 2; - auto /***/sizer_filaments = this->p->sizer_filaments->GetItem(side)->GetSizer(); - if (side == 1 && filament_idx > 1) sizer_filaments->Remove(filament_idx / 2); + auto side = filament_idx % 2; + auto /***/ sizer_filaments = this->p->sizer_filaments->GetItem(side)->GetSizer(); + if (side == 1 && filament_idx > 1) + sizer_filaments->Remove(filament_idx / 2); sizer_filaments->Add(combo_and_btn_sizer, 1, wxEXPAND); if (side == 0) { sizer_filaments = this->p->sizer_filaments->GetItem(1)->GetSizer(); @@ -1003,14 +1079,14 @@ void Sidebar::remove_unused_filament_combos(const size_t current_extruder_count) if (current_extruder_count >= p->combos_filament.size()) return; while (p->combos_filament.size() > current_extruder_count) { - const int last = p->combos_filament.size() - 1; - auto sizer_filaments = this->p->sizer_filaments->GetItem(last % 2)->GetSizer(); + const int last = p->combos_filament.size() - 1; + auto sizer_filaments = this->p->sizer_filaments->GetItem(last % 2)->GetSizer(); sizer_filaments->Remove(last / 2); (*p->combos_filament[last]).Destroy(); p->combos_filament.pop_back(); } // BBS: filament double columns - auto sizer_filaments0 = this->p->sizer_filaments->GetItem((size_t)0)->GetSizer(); + auto sizer_filaments0 = this->p->sizer_filaments->GetItem((size_t) 0)->GetSizer(); auto sizer_filaments1 = this->p->sizer_filaments->GetItem(1)->GetSizer(); if (current_extruder_count < 2) { sizer_filaments1->Clear(); @@ -1027,7 +1103,7 @@ void Sidebar::remove_unused_filament_combos(const size_t current_extruder_count) void Sidebar::update_all_preset_comboboxes() { PresetBundle &preset_bundle = *wxGetApp().preset_bundle; - const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); + const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); bool is_bbl_vendor = preset_bundle.is_bbl_vendor(); @@ -1036,44 +1112,44 @@ void Sidebar::update_all_preset_comboboxes() p_mainframe->show_device(is_bbl_vendor); if (is_bbl_vendor) { - //only show connection button for not-BBL printer + // only show connection button for not-BBL printer connection_btn->Hide(); - //only show sync-ams button for BBL printer + // only show sync-ams button for BBL printer ams_btn->Show(); - //update print button default value for bbl or third-party printer + // update print button default value for bbl or third-party printer p_mainframe->set_print_button_to_default(MainFrame::PrintSelectType::ePrintPlate); - AppConfig* config = wxGetApp().app_config; + AppConfig *config = wxGetApp().app_config; if (config && !config->get("curr_bed_type").empty()) { - int bed_type_idx = 0; - std::string str_bed_type = config->get("curr_bed_type"); - int bed_type_value = (int)btPC; + int bed_type_idx = 0; + std::string str_bed_type = config->get("curr_bed_type"); + int bed_type_value = (int) btPC; try { bed_type_value = atoi(str_bed_type.c_str()); - } catch(...) {} + } catch (...) {} bed_type_idx = bed_type_value - 1; m_bed_type_list->SelectAndNotify(bed_type_idx); } else { BedType bed_type = preset_bundle.printers.get_edited_preset().get_default_bed_type(&preset_bundle); - m_bed_type_list->SelectAndNotify((int)bed_type - 1); + m_bed_type_list->SelectAndNotify((int) bed_type - 1); } m_bed_type_list->Enable(); - auto str_bed_type = wxGetApp().app_config->get_printer_setting(wxGetApp().preset_bundle->printers.get_selected_preset_name(), "curr_bed_type"); - if(!str_bed_type.empty()){ + auto str_bed_type = wxGetApp().app_config->get_printer_setting(wxGetApp().preset_bundle->printers.get_selected_preset_name(), + "curr_bed_type"); + if (!str_bed_type.empty()) { int bed_type_value = atoi(str_bed_type.c_str()); - if(bed_type_value == 0) + if (bed_type_value == 0) bed_type_value = 1; m_bed_type_list->SelectAndNotify(bed_type_value - 1); } } else { connection_btn->Show(); ams_btn->Hide(); - auto cfg = preset_bundle.printers.get_edited_preset().config; - auto print_btn_type = MainFrame::PrintSelectType::eExportGcode; + auto cfg = preset_bundle.printers.get_edited_preset().config; + auto print_btn_type = MainFrame::PrintSelectType::eExportGcode; wxString url = cfg.opt_string("print_host_webui").empty() ? cfg.opt_string("print_host") : cfg.opt_string("print_host_webui"); - if(!url.empty()) - { - if(!url.Lower().starts_with("http")) - url = wxString::Format("http://%s",url); + if (!url.empty()) { + if (!url.Lower().starts_with("http")) + url = wxString::Format("http://%s", url); wxString apikey; if (cfg.has("printhost_apikey")) @@ -1084,19 +1160,19 @@ void Sidebar::update_all_preset_comboboxes() } p_mainframe->set_print_button_to_default(print_btn_type); - m_bed_type_list->SelectAndNotify(btPEI-1); + m_bed_type_list->SelectAndNotify(btPEI - 1); m_bed_type_list->Disable(); } // Update the print choosers to only contain the compatible presets, update the dirty flags. - //BBS + // BBS // Update the printer choosers, update the dirty flags. - //p->combo_printer->update(); + // p->combo_printer->update(); // Update the filament choosers to only contain the compatible presets, update the color preview, // update the dirty flags. if (print_tech == ptFFF) { - for (PlaterPresetComboBox* cb : p->combos_filament) + for (PlaterPresetComboBox *cb : p->combos_filament) cb->update(); } @@ -1109,12 +1185,11 @@ void Sidebar::update_all_preset_comboboxes() void Sidebar::update_presets(Preset::Type preset_type) { PresetBundle &preset_bundle = *wxGetApp().preset_bundle; - const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); + const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": enter, preset_type %1%")%preset_type; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": enter, preset_type %1%") % preset_type; switch (preset_type) { - case Preset::TYPE_FILAMENT: - { + case Preset::TYPE_FILAMENT: { // BBS #if 0 const size_t extruder_cnt = print_tech != ptFFF ? 1 : @@ -1128,7 +1203,11 @@ void Sidebar::update_presets(Preset::Type preset_type) preset_bundle.set_filament_preset(p->editing_filament, name); } else if (filament_cnt == 1) { // Single filament printer, synchronize the filament presets. - preset_bundle.set_filament_preset(0, name); + Preset *preset = preset_bundle.filaments.find_preset(name, false); + if (preset) { + if (preset->is_compatible) + preset_bundle.set_filament_preset(0, name); + } } for (size_t i = 0; i < filament_cnt; i++) @@ -1139,37 +1218,41 @@ void Sidebar::update_presets(Preset::Type preset_type) } case Preset::TYPE_PRINT: - //wxGetApp().mainframe->m_param_panel; - //p->combo_print->update(); + // wxGetApp().mainframe->m_param_panel; + // p->combo_print->update(); { - Tab* print_tab = wxGetApp().get_tab(Preset::TYPE_PRINT); - if (print_tab) { - print_tab->get_combo_box()->update(); - } - break; + Tab *print_tab = wxGetApp().get_tab(Preset::TYPE_PRINT); + if (print_tab) { + print_tab->get_combo_box()->update(); + } + break; } - case Preset::TYPE_SLA_PRINT: - ;// p->combo_sla_print->update(); + case Preset::TYPE_SLA_PRINT:; // p->combo_sla_print->update(); break; - case Preset::TYPE_SLA_MATERIAL: - ;// p->combo_sla_material->update(); + case Preset::TYPE_SLA_MATERIAL:; // p->combo_sla_material->update(); break; - case Preset::TYPE_PRINTER: - { + case Preset::TYPE_PRINTER: { update_all_preset_comboboxes(); p->show_preset_comboboxes(); /* update bed shape */ - Tab* printer_tab = wxGetApp().get_tab(Preset::TYPE_PRINTER); + Tab *printer_tab = wxGetApp().get_tab(Preset::TYPE_PRINTER); if (printer_tab) { printer_tab->update(); } - bool isBBL = preset_bundle.is_bbl_vendor(); + Preset &printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset(); + bool isBBL = preset_bundle.is_bbl_vendor(); wxGetApp().mainframe->show_calibration_button(!isBBL); + if (auto printer_structure_opt = printer_preset.config.option>("printer_structure")) { + wxGetApp().plater()->get_current_canvas3D()->get_arrange_settings().align_to_y_axis = (printer_structure_opt->value == + PrinterStructure::psI3); + } else + wxGetApp().plater()->get_current_canvas3D()->get_arrange_settings().align_to_y_axis = false; + break; } @@ -1182,19 +1265,17 @@ void Sidebar::update_presets(Preset::Type preset_type) BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": exit."); } -//BBS +// BBS void Sidebar::update_presets_from_to(Slic3r::Preset::Type preset_type, std::string from, std::string to) { PresetBundle &preset_bundle = *wxGetApp().preset_bundle; - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": enter, preset_type %1%, from %2% to %3%")%preset_type %from %to; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": enter, preset_type %1%, from %2% to %3%") % preset_type % from % to; switch (preset_type) { - case Preset::TYPE_FILAMENT: - { + case Preset::TYPE_FILAMENT: { const size_t filament_cnt = p->combos_filament.size(); - for (auto it = preset_bundle.filament_presets.begin(); it != preset_bundle.filament_presets.end(); it++) - { + for (auto it = preset_bundle.filament_presets.begin(); it != preset_bundle.filament_presets.end(); it++) { if ((*it).compare(from) == 0) { (*it) = to; } @@ -1228,49 +1309,47 @@ void Sidebar::msw_rescale() { SetMinSize(wxSize(42 * wxGetApp().em_unit(), -1)); p->m_panel_printer_title->GetSizer()->SetMinSize(-1, 3 * wxGetApp().em_unit()); - p->m_panel_filament_title->GetSizer() - ->SetMinSize(-1, 3 * wxGetApp().em_unit()); - p->m_printer_icon->msw_rescale(); - p->m_printer_setting->msw_rescale(); - p->m_filament_icon->msw_rescale(); - p->m_bpButton_add_filament->msw_rescale(); - p->m_bpButton_del_filament->msw_rescale(); - p->m_bpButton_ams_filament->msw_rescale(); - p->m_bpButton_set_filament->msw_rescale(); + p->m_panel_filament_title->GetSizer()->SetMinSize(-1, 3 * wxGetApp().em_unit()); + p->m_printer_icon->sys_color_changed(); + p->m_printer_setting->sys_color_changed(); + p->m_filament_icon->sys_color_changed(); + p->m_bpButton_add_filament->sys_color_changed(); + p->m_bpButton_del_filament->sys_color_changed(); + p->m_bpButton_ams_filament->sys_color_changed(); + p->m_bpButton_set_filament->sys_color_changed(); p->m_flushing_volume_btn->Rescale(); - //BBS + // BBS m_bed_type_list->Rescale(); m_bed_type_list->SetMinSize({-1, 3 * wxGetApp().em_unit()}); #if 0 if (p->mode_sizer) - p->mode_sizer->msw_rescale(); + p->mode_sizer->sys_color_changed(); #endif - //for (PlaterPresetComboBox* combo : std::vector { p->combo_print, - // //p->combo_sla_print, - // //p->combo_sla_material, - // //p->combo_printer - // } ) - // combo->msw_rescale(); + // for (PlaterPresetComboBox* combo : std::vector { p->combo_print, + // //p->combo_sla_print, + // //p->combo_sla_material, + // //p->combo_printer + // } ) + // combo->msw_rescale(); p->combo_printer->msw_rescale(); - for (PlaterPresetComboBox* combo : p->combos_filament) + for (PlaterPresetComboBox *combo : p->combos_filament) combo->msw_rescale(); - // BBS - //p->frequently_changed_parameters->msw_rescale(); - //obj_list()->msw_rescale(); - // BBS TODO: add msw_rescale for newly added windows - // BBS - //p->object_manipulation->msw_rescale(); - p->object_settings->msw_rescale(); + // BBS + // p->frequently_changed_parameters->msw_rescale(); + // obj_list()->msw_rescale(); + // BBS TODO: add msw_rescale for newly added windows + // BBS + // p->object_manipulation->msw_rescale(); - // BBS + // BBS #if 0 p->object_info->msw_rescale(); - p->btn_send_gcode->msw_rescale(); + p->btn_send_gcode->sys_color_changed(); // p->btn_eject_device->msw_rescale(); - p->btn_export_gcode_removable->msw_rescale(); + p->btn_export_gcode_removable->sys_color_changed(); #ifdef _WIN32 const int scaled_height = p->btn_export_gcode_removable->GetBitmapHeight(); #else @@ -1291,31 +1370,31 @@ void Sidebar::sys_color_changed() #if 0 for (wxWindow* win : std::vector{ this, p->sliced_info->GetStaticBox(), p->object_info->GetStaticBox(), p->btn_reslice, p->btn_export_gcode }) wxGetApp().UpdateDarkUI(win); - p->object_info->msw_rescale(); + p->object_info->sys_color_changed(); for (wxWindow* win : std::vector{ p->scrolled, p->presets_panel }) wxGetApp().UpdateAllStaticTextDarkUI(win); #endif - //for (wxWindow* btn : std::vector{ p->btn_reslice, p->btn_export_gcode }) - // wxGetApp().UpdateDarkUI(btn, true); - p->m_printer_icon->msw_rescale(); - p->m_printer_setting->msw_rescale(); - p->m_filament_icon->msw_rescale(); - p->m_bpButton_add_filament->msw_rescale(); - p->m_bpButton_del_filament->msw_rescale(); - p->m_bpButton_ams_filament->msw_rescale(); - p->m_bpButton_set_filament->msw_rescale(); + // for (wxWindow* btn : std::vector{ p->btn_reslice, p->btn_export_gcode }) + // wxGetApp().UpdateDarkUI(btn, true); + p->m_printer_icon->sys_color_changed(); + p->m_printer_setting->sys_color_changed(); + p->m_filament_icon->sys_color_changed(); + p->m_bpButton_add_filament->sys_color_changed(); + p->m_bpButton_del_filament->sys_color_changed(); + p->m_bpButton_ams_filament->sys_color_changed(); + p->m_bpButton_set_filament->sys_color_changed(); p->m_flushing_volume_btn->Rescale(); // BBS #if 0 if (p->mode_sizer) - p->mode_sizer->msw_rescale(); + p->mode_sizer->sys_color_changed(); p->frequently_changed_parameters->sys_color_changed(); #endif p->object_settings->sys_color_changed(); - //BBS: remove print related combos + // BBS: remove print related combos #if 0 for (PlaterPresetComboBox* combo : std::vector{ p->combo_print, p->combo_sla_print, @@ -1323,35 +1402,33 @@ void Sidebar::sys_color_changed() p->combo_printer }) combo->sys_color_changed(); #endif - for (PlaterPresetComboBox* combo : p->combos_filament) + for (PlaterPresetComboBox *combo : p->combos_filament) combo->sys_color_changed(); // BBS obj_list()->sys_color_changed(); obj_layers()->sys_color_changed(); // BBS - //p->object_manipulation->sys_color_changed(); + // p->object_manipulation->sys_color_changed(); // btn...->msw_rescale() updates icon on button, so use it - //p->btn_send_gcode->msw_rescale(); -// p->btn_eject_device->msw_rescale(); - //p->btn_export_gcode_removable->msw_rescale(); + // p->btn_send_gcode->msw_rescale(); + // p->btn_eject_device->msw_rescale(); + // p->btn_export_gcode_removable->msw_rescale(); p->scrolled->Layout(); + p->scrolled->Refresh(); p->searcher.dlg_sys_color_changed(); } -void Sidebar::search() -{ - p->searcher.search(); -} +void Sidebar::search() { p->searcher.search(); } -void Sidebar::jump_to_option(const std::string& opt_key, Preset::Type type, const std::wstring& category) +void Sidebar::jump_to_option(const std::string &opt_key, Preset::Type type, const std::wstring &category) { - //const Search::Option& opt = p->searcher.get_option(opt_key, type); + // const Search::Option& opt = p->searcher.get_option(opt_key, type); if (type == Preset::TYPE_PRINT) { - auto tab = dynamic_cast(wxGetApp().params_panel()->get_current_tab()); + auto tab = dynamic_cast(wxGetApp().params_panel()->get_current_tab()); if (tab && tab->has_key(opt_key)) { tab->activate_option(opt_key, category); return; @@ -1363,17 +1440,17 @@ void Sidebar::jump_to_option(const std::string& opt_key, Preset::Type type, cons void Sidebar::jump_to_option(size_t selected) { - const Search::Option& opt = p->searcher.get_option(selected); + const Search::Option &opt = p->searcher.get_option(selected); jump_to_option(opt.opt_key(), opt.type, opt.category); // Switch to the Settings NotePad -// wxGetApp().mainframe->select_tab(); + // wxGetApp().mainframe->select_tab(); } // BBS. Move logic from Plater::on_extruders_change() to Sidebar::on_filaments_change(). void Sidebar::on_filaments_change(size_t num_filaments) { - auto& choices = combos_filament(); + auto &choices = combos_filament(); if (num_filaments == choices.size()) return; @@ -1384,14 +1461,15 @@ void Sidebar::on_filaments_change(size_t num_filaments) wxWindowUpdateLocker noUpdates_scrolled_panel(this); size_t i = choices.size(); - while (i < num_filaments) - { - PlaterPresetComboBox* choice/*{ nullptr }*/; + while (i < num_filaments) { + PlaterPresetComboBox *choice /*{ nullptr }*/; init_filament_combo(&choice, i); + int last_selection = choices.back()->GetSelection(); choices.push_back(choice); // initialize selection choice->update(); + choice->SetSelection(last_selection); ++i; } @@ -1415,26 +1493,27 @@ void Sidebar::on_filaments_change(size_t num_filaments) void Sidebar::on_bed_type_change(BedType bed_type) { // btDefault option is not included in global bed type setting - int sel_idx = (int)bed_type - 1; + int sel_idx = (int) bed_type - 1; if (m_bed_type_list != nullptr) m_bed_type_list->SetSelection(sel_idx); } -std::map Sidebar::build_filament_ams_list(MachineObject* obj) +std::map Sidebar::build_filament_ams_list(MachineObject *obj) { std::map filament_ams_list; - if (!obj) return filament_ams_list; + if (!obj) + return filament_ams_list; auto vt_tray = obj->vt_tray; - bool is_support_virtual_tray = obj->is_function_supported(PrinterFunction::FUNC_VIRTUAL_TYAY); - if (is_support_virtual_tray) { + if (obj->ams_support_virtual_tray) { DynamicPrintConfig vt_tray_config; - vt_tray_config.set_key_value("filament_id", new ConfigOptionStrings{ vt_tray.setting_id }); - vt_tray_config.set_key_value("tag_uid", new ConfigOptionStrings{ vt_tray.tag_uid }); - vt_tray_config.set_key_value("filament_type", new ConfigOptionStrings{ vt_tray.type }); - vt_tray_config.set_key_value("tray_name", new ConfigOptionStrings{ std::string("Ext") }); - vt_tray_config.set_key_value("filament_colour", new ConfigOptionStrings{ into_u8(wxColour("#" + vt_tray.color).GetAsString(wxC2S_HTML_SYNTAX)) }); - vt_tray_config.set_key_value("filament_exist", new ConfigOptionBools{ true }); + vt_tray_config.set_key_value("filament_id", new ConfigOptionStrings{vt_tray.setting_id}); + vt_tray_config.set_key_value("tag_uid", new ConfigOptionStrings{vt_tray.tag_uid}); + vt_tray_config.set_key_value("filament_type", new ConfigOptionStrings{vt_tray.type}); + vt_tray_config.set_key_value("tray_name", new ConfigOptionStrings{std::string("Ext")}); + vt_tray_config.set_key_value("filament_colour", + new ConfigOptionStrings{into_u8(wxColour("#" + vt_tray.color).GetAsString(wxC2S_HTML_SYNTAX))}); + vt_tray_config.set_key_value("filament_exist", new ConfigOptionBools{true}); filament_ams_list.emplace(VIRTUAL_TRAY_ID, std::move(vt_tray_config)); } @@ -1444,15 +1523,17 @@ std::map Sidebar::build_filament_ams_list(MachineObject char n = ams.first.front() - '0' + 'A'; for (auto tray : ams.second->trayList) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ - << boost::format(": ams %1% tray %2% id %3% color %4%") % ams.first % tray.first % tray.second->setting_id % tray.second->color; - char t = tray.first.front() - '0' + '1'; + << boost::format(": ams %1% tray %2% id %3% color %4%") % ams.first % tray.first % + tray.second->setting_id % tray.second->color; + char t = tray.first.front() - '0' + '1'; DynamicPrintConfig tray_config; - tray_config.set_key_value("filament_id", new ConfigOptionStrings{ tray.second->setting_id }); - tray_config.set_key_value("tag_uid", new ConfigOptionStrings{ tray.second->tag_uid }); - tray_config.set_key_value("filament_type", new ConfigOptionStrings{ tray.second->type }); - tray_config.set_key_value("tray_name", new ConfigOptionStrings{ std::string(1, n) + std::string(1, t) }); - tray_config.set_key_value("filament_colour", new ConfigOptionStrings{ into_u8(wxColour("#" + tray.second->color).GetAsString(wxC2S_HTML_SYNTAX)) }); - tray_config.set_key_value("filament_exist", new ConfigOptionBools{ tray.second->is_exists }); + tray_config.set_key_value("filament_id", new ConfigOptionStrings{tray.second->setting_id}); + tray_config.set_key_value("tag_uid", new ConfigOptionStrings{tray.second->tag_uid}); + tray_config.set_key_value("filament_type", new ConfigOptionStrings{tray.second->type}); + tray_config.set_key_value("tray_name", new ConfigOptionStrings{std::string(1, n) + std::string(1, t)}); + tray_config.set_key_value("filament_colour", + new ConfigOptionStrings{into_u8(wxColour("#" + tray.second->color).GetAsString(wxC2S_HTML_SYNTAX))}); + tray_config.set_key_value("filament_exist", new ConfigOptionBools{tray.second->is_exists}); filament_ams_list.emplace(((n - 'A') * 4 + t - '1'), std::move(tray_config)); } @@ -1460,46 +1541,43 @@ std::map Sidebar::build_filament_ams_list(MachineObject return filament_ams_list; } -void Sidebar::load_ams_list(std::string const &device, MachineObject* obj) +void Sidebar::load_ams_list(std::string const &device, MachineObject *obj) { std::map filament_ams_list = build_filament_ams_list(obj); - if (!obj) { - p->ams_list_device = device; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " clear list"; - wxGetApp().preset_bundle->filament_ams_list = filament_ams_list; - for (auto c : p->combos_filament) - c->update(); - return; - } - p->ams_list_device = device; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": %1% items") % filament_ams_list.size(); + if (wxGetApp().preset_bundle->filament_ams_list == filament_ams_list) + return; wxGetApp().preset_bundle->filament_ams_list = filament_ams_list; + for (auto c : p->combos_filament) c->update(); } void Sidebar::sync_ams_list() { - auto & list = wxGetApp().preset_bundle->filament_ams_list; + auto &list = wxGetApp().preset_bundle->filament_ams_list; if (list.empty()) { - MessageDialog dlg(this, - _L("No AMS filaments. Please select a printer in 'Device' page to load AMS info."), - _L("Sync filaments with AMS"), wxOK); + MessageDialog dlg(this, _L("No AMS filaments. Please select a printer in 'Device' page to load AMS info."), + _L("Sync filaments with AMS"), wxOK); dlg.ShowModal(); return; } - std::string ams_filament_ids = wxGetApp().app_config->get("ams_filament_ids", p->ams_list_device); + std::string ams_filament_ids = wxGetApp().app_config->get("ams_filament_ids", p->ams_list_device); std::vector list2; if (!ams_filament_ids.empty()) boost::algorithm::split(list2, ams_filament_ids, boost::algorithm::is_any_of(",")); - struct SyncAmsDialog : MessageDialog { - SyncAmsDialog(wxWindow * parent, bool first): MessageDialog(parent, - first - ? _L("Sync filaments with AMS will drop all current selected filament presets and colors. Do you want to continue?") - : _L("Already did a synchronization, do you want to sync only changes or resync all?"), - _L("Sync filaments with AMS"), 0) + struct SyncAmsDialog : MessageDialog + { + SyncAmsDialog(wxWindow *parent, bool first) + : MessageDialog( + parent, + first ? + _L("Sync filaments with AMS will drop all current selected filament presets and colors. Do you want to continue?") : + _L("Already did a synchronization, do you want to sync only changes or resync all?"), + _L("Sync filaments with AMS"), + 0) { if (first) { add_button(wxID_YES, true, _L("Yes")); @@ -1511,30 +1589,30 @@ void Sidebar::sync_ams_list() } } dlg(this, ams_filament_ids.empty()); auto res = dlg.ShowModal(); - if (res == wxID_CANCEL) return; + if (res == wxID_CANCEL) + return; list2.resize(list.size()); auto iter = list.begin(); for (int i = 0; i < list.size(); ++i, ++iter) { - auto & ams = iter->second; - auto filament_id = ams.opt_string("filament_id", 0u); + auto &ams = iter->second; + auto filament_id = ams.opt_string("filament_id", 0u); ams.set_key_value("filament_changed", new ConfigOptionBool{res == wxID_YES || list2[i] != filament_id}); list2[i] = filament_id; } unsigned int unknowns = 0; - auto n = wxGetApp().preset_bundle->sync_ams_list(unknowns); + auto n = wxGetApp().preset_bundle->sync_ams_list(unknowns); if (n == 0) { - MessageDialog dlg(this, - _L("There are no compatible filaments, and sync is not performed."), - _L("Sync filaments with AMS"), wxOK); + MessageDialog dlg(this, _L("There are no compatible filaments, and sync is not performed."), _L("Sync filaments with AMS"), wxOK); dlg.ShowModal(); return; } ams_filament_ids = boost::algorithm::join(list2, ","); - wxGetApp().app_config ->set("ams_filament_ids", p->ams_list_device, ams_filament_ids); + wxGetApp().app_config->set("ams_filament_ids", p->ams_list_device, ams_filament_ids); if (unknowns > 0) { MessageDialog dlg(this, - _L("There are some unknown filaments mapped to generic preset. Please update Orca Slicer or restart Orca Slicer to check if there is an update to system presets."), - _L("Sync filaments with AMS"), wxOK); + _L("There are some unknown filaments mapped to generic preset. Please update Orca Slicer or restart Orca Slicer " + "to check if there is an update to system presets."), + _L("Sync filaments with AMS"), wxOK); dlg.ShowModal(); } wxGetApp().plater()->on_filaments_change(n); @@ -1548,39 +1626,24 @@ void Sidebar::sync_ams_list() Layout(); } -ObjectList* Sidebar::obj_list() +ObjectList *Sidebar::obj_list() { // BBS - //return obj_list(); + // return obj_list(); return p->m_object_list; } -ObjectSettings* Sidebar::obj_settings() -{ - return p->object_settings; -} +ObjectSettings *Sidebar::obj_settings() { return p->object_settings; } -ObjectLayers* Sidebar::obj_layers() -{ - return p->object_layers; -} +ObjectLayers *Sidebar::obj_layers() { return p->object_layers; } -wxPanel* Sidebar::scrolled_panel() -{ - return p->scrolled; -} +wxPanel *Sidebar::scrolled_panel() { return p->scrolled; } -wxPanel* Sidebar::print_panel() -{ - return p->m_panel_print_content; -} +wxPanel *Sidebar::print_panel() { return p->m_panel_print_content; } -wxPanel* Sidebar::filament_panel() -{ - return p->m_panel_filament_content; -} +wxPanel *Sidebar::filament_panel() { return p->m_panel_filament_content; } -ConfigOptionsGroup* Sidebar::og_freq_chng_params(const bool is_fff) +ConfigOptionsGroup *Sidebar::og_freq_chng_params(const bool is_fff) { // BBS #if 0 @@ -1589,7 +1652,7 @@ ConfigOptionsGroup* Sidebar::og_freq_chng_params(const bool is_fff) return NULL; } -wxButton* Sidebar::get_wiping_dialog_button() +wxButton *Sidebar::get_wiping_dialog_button() { #if 0 return p->frequently_changed_parameters->get_wiping_dialog_button(); @@ -1608,51 +1671,45 @@ void Sidebar::enable_buttons(bool enable) #endif } -bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); } -bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); } -bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); } +bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); } +bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); } +bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); } bool Sidebar::show_export_removable(bool show) const { return p->btn_export_gcode_removable->Show(show); } -//bool Sidebar::show_eject(bool show) const { return p->btn_eject_device->Show(show); } -//bool Sidebar::get_eject_shown() const { return p->btn_eject_device->IsShown(); } +// bool Sidebar::show_eject(bool show) const { return p->btn_eject_device->Show(show); } +// bool Sidebar::get_eject_shown() const { return p->btn_eject_device->IsShown(); } -bool Sidebar::is_multifilament() -{ - return p->combos_filament.size() > 1; -} +bool Sidebar::is_multifilament() { return p->combos_filament.size() > 1; } static std::vector get_search_inputs(ConfigOptionMode mode) { - std::vector ret {}; + std::vector ret{}; - auto& tabs_list = wxGetApp().tabs_list; - auto print_tech = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology(); + auto &tabs_list = wxGetApp().tabs_list; + auto print_tech = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology(); for (auto tab : tabs_list) if (tab->supports_printer_technology(print_tech)) - ret.emplace_back(Search::InputInfo {tab->get_config(), tab->type(), mode}); + ret.emplace_back(Search::InputInfo{tab->get_config(), tab->type(), mode}); return ret; } -void Sidebar::update_searcher() -{ - p->searcher.init(get_search_inputs(m_mode)); -} +void Sidebar::update_searcher() { p->searcher.init(get_search_inputs(m_mode)); } void Sidebar::update_mode() { m_mode = wxGetApp().get_mode(); - //BBS: remove print related combos + // BBS: remove print related combos update_searcher(); wxWindowUpdateLocker noUpdates(this); // BBS - //obj_list()->get_sizer()->Show(m_mode > comSimple); + // obj_list()->get_sizer()->Show(m_mode > comSimple); obj_list()->unselect_objects(); obj_list()->update_selections(); -// obj_list()->update_object_menu(); + // obj_list()->update_object_menu(); Layout(); } @@ -1667,21 +1724,21 @@ void Sidebar::collapse(bool collapse) p->plater->Layout(); // save collapsing state to the AppConfig - //if (wxGetApp().is_editor()) + // if (wxGetApp().is_editor()) // wxGetApp().app_config->set_bool("collapsed_sidebar", collapse); } #ifdef _MSW_DARK_MODE void Sidebar::show_mode_sizer(bool show) { - //p->mode_sizer->Show(show); + // p->mode_sizer->Show(show); } #endif void Sidebar::update_ui_from_settings() { // BBS - //p->object_manipulation->update_ui_from_settings(); + // p->object_manipulation->update_ui_from_settings(); // update Cut gizmo, if it's open p->plater->canvas3D()->update_gizmos_on_off_state(); p->plater->set_current_canvas_as_dirty(); @@ -1693,6 +1750,7 @@ void Sidebar::update_ui_from_settings() bool Sidebar::show_object_list(bool show) const { + p->m_search_bar->Show(show); if (!p->m_object_list->Show(show)) return false; if (!show) @@ -1705,34 +1763,98 @@ bool Sidebar::show_object_list(bool show) const void Sidebar::finish_param_edit() { p->editing_filament = -1; } -std::vector& Sidebar::combos_filament() -{ - return p->combos_filament; -} +std::vector &Sidebar::combos_filament() { return p->combos_filament; } + +Search::OptionsSearcher &Sidebar::get_searcher() { return p->searcher; } + +std::string &Sidebar::get_search_line() { return p->searcher.search_string(); } + +void Sidebar::auto_calc_flushing_volumes(const int modify_id) +{ + auto &project_config = wxGetApp().preset_bundle->project_config; + auto &printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + const std::vector &init_matrix = (project_config.option("flush_volumes_matrix"))->values; + const std::vector &init_extruders = (project_config.option("flush_volumes_vector"))->values; + ConfigOption *extra_flush_volume_opt = printer_config.option("nozzle_volume"); + int extra_flush_volume = extra_flush_volume_opt ? (int) extra_flush_volume_opt->getFloat() : 0; + ConfigOptionFloat *flush_multi_opt = project_config.option("flush_multiplier"); + float flush_multiplier = flush_multi_opt ? flush_multi_opt->getFloat() : 1.f; + vector matrix = init_matrix; + int m_min_flush_volume = extra_flush_volume; + int m_max_flush_volume = Slic3r::g_max_flush_volume; + unsigned int m_number_of_extruders = (int) (sqrt(init_matrix.size()) + 0.001); + const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); + vector m_colours; + for (const std::string &color : extruder_colours) { + m_colours.push_back(wxColor(color)); + } + if (modify_id >= 0 && modify_id < m_colours.size()) { + for (int i = 0; i < m_colours.size(); ++i) { + int from_idx = i; + if (from_idx != modify_id) { + const wxColour &from = m_colours[from_idx]; + bool is_from_support = is_support_filament(from_idx); + const wxColour &to = m_colours[modify_id]; + bool is_to_support = is_support_filament(modify_id); + int flushing_volume = 0; + if (is_to_support) { + flushing_volume = Slic3r::g_flush_volume_to_support; + } else { + const wxColour &to = m_colours[modify_id]; + Slic3r::FlushVolCalculator calculator(m_min_flush_volume, m_max_flush_volume); + flushing_volume = calculator.calc_flush_vol(from.Alpha(), from.Red(), from.Green(), from.Blue(), to.Alpha(), to.Red(), + to.Green(), to.Blue()); + if (is_from_support) { + flushing_volume = std::max(Slic3r::g_min_flush_volume_from_support, flushing_volume); + } + } + matrix[m_number_of_extruders * from_idx + modify_id] = flushing_volume; + } + int to_idx = i; + if (to_idx != modify_id) { + const wxColour &from = m_colours[modify_id]; + bool is_from_support = is_support_filament(modify_id); + const wxColour &to = m_colours[to_idx]; + bool is_to_support = is_support_filament(to_idx); + int flushing_volume = 0; + if (is_to_support) { + flushing_volume = Slic3r::g_flush_volume_to_support; + } else { + const wxColour &to = m_colours[to_idx]; + Slic3r::FlushVolCalculator calculator(m_min_flush_volume, m_max_flush_volume); + flushing_volume = calculator.calc_flush_vol(from.Alpha(), from.Red(), from.Green(), from.Blue(), to.Alpha(), to.Red(), + to.Green(), to.Blue()); + if (is_from_support) { + flushing_volume = std::max(Slic3r::g_min_flush_volume_from_support, flushing_volume); + } + } + matrix[m_number_of_extruders * modify_id + to_idx] = flushing_volume; + } + } + } + (project_config.option("flush_volumes_matrix"))->values = std::vector(matrix.begin(), matrix.end()); -Search::OptionsSearcher& Sidebar::get_searcher() -{ - return p->searcher; -} + wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); -std::string& Sidebar::get_search_line() -{ - return p->searcher.search_string(); + wxGetApp().plater()->update_project_dirty_from_presets(); + wxPostEvent(this, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, this)); } -// Plater::DropTarget +void Sidebar::jump_to_object(ObjectDataViewModelNode *item) { p->jump_to_object(item); } + +void Sidebar::can_search() { p->can_search(); } class PlaterDropTarget : public wxFileDropTarget { public: - PlaterDropTarget(Plater* plater) : m_plater(plater) { this->SetDefaultAction(wxDragCopy); } + PlaterDropTarget(Plater *plater) : m_plater(plater) { this->SetDefaultAction(wxDragCopy); } virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames); - void handleOnIdle(wxIdleEvent & event); + void handleOnIdle(wxIdleEvent &event); private: - Plater* m_plater; + Plater *m_plater; wxArrayString m_filenames; }; @@ -1743,7 +1865,7 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi this->MSWUpdateDragImageOnLeave(); #endif // WIN32 - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": drag %1% files into app")%filenames.size(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": drag %1% files into app") % filenames.size(); m_filenames = filenames; wxGetApp().Bind(wxEVT_IDLE, &PlaterDropTarget::handleOnIdle, this); return true; @@ -1757,103 +1879,97 @@ void PlaterDropTarget::handleOnIdle(wxIdleEvent &event) m_plater->load_files(m_filenames); wxGetApp().mainframe->update_title(); } - //m_filenames.clear(); + // m_filenames.clear(); } // State to manage showing after export notifications and device ejecting -enum ExportingStatus{ - NOT_EXPORTING, - EXPORTING_TO_REMOVABLE, - EXPORTING_TO_LOCAL -}; +enum ExportingStatus { NOT_EXPORTING, EXPORTING_TO_REMOVABLE, EXPORTING_TO_LOCAL }; // Plater / private struct Plater::priv { // PIMPL back pointer ("Q-Pointer") - Plater *q; + Plater *q; MainFrame *main_frame; MenuFactory menus; - SelectMachineDialog* m_select_machine_dlg = nullptr; - SendToPrinterDialog* m_send_to_sdcard_dlg = nullptr; - PublishDialog *m_publish_dlg = nullptr; + SelectMachineDialog *m_select_machine_dlg = nullptr; + SendToPrinterDialog *m_send_to_sdcard_dlg = nullptr; + PublishDialog *m_publish_dlg = nullptr; // Data - Slic3r::DynamicPrintConfig *config; // FIXME: leak? - Slic3r::Print fff_print; - Slic3r::SLAPrint sla_print; - Slic3r::Model model; - PrinterTechnology printer_technology = ptFFF; + Slic3r::DynamicPrintConfig *config; // FIXME: leak? + Slic3r::Print fff_print; + Slic3r::SLAPrint sla_print; + Slic3r::Model model; + PrinterTechnology printer_technology = ptFFF; Slic3r::GCodeProcessorResult gcode_result; // GUI elements - wxSizer* panel_sizer{ nullptr }; - wxPanel* current_panel{ nullptr }; - std::vector panels; - Sidebar *sidebar; - Bed3D bed; - Camera camera; - //BBS: partplate related structure + wxSizer *panel_sizer{nullptr}; + wxPanel *current_panel{nullptr}; + std::vector panels; + Sidebar *sidebar; + Bed3D bed; + Camera camera; + // BBS: partplate related structure PartPlateList partplate_list; - //BBS: add a flag to ignore cancel event + // BBS: add a flag to ignore cancel event bool m_ignore_event{false}; bool m_slice_all{false}; - bool m_is_slicing {false}; - bool m_is_publishing {false}; - int m_is_RightClickInLeftUI{-1}; - int m_cur_slice_plate; - //BBS: m_slice_all in .gcode.3mf file case, set true when slice all - bool m_slice_all_only_has_gcode{ false }; + bool m_is_slicing{false}; + bool m_is_publishing{false}; + int m_is_RightClickInLeftUI{-1}; + int m_cur_slice_plate; + // BBS: m_slice_all in .gcode.3mf file case, set true when slice all + bool m_slice_all_only_has_gcode{false}; bool m_need_update{false}; - //BBS: add popup object table logic - //ObjectTableDialog* m_popup_table{ nullptr }; + // BBS: add popup object table logic + // ObjectTableDialog* m_popup_table{ nullptr }; #if ENABLE_ENVIRONMENT_MAP GLTexture environment_texture; #endif // ENABLE_ENVIRONMENT_MAP Mouse3DController mouse3d_controller; - View3D* view3D; + View3D *view3D; // BBS - //GLToolbar view_toolbar; - GLToolbar collapse_toolbar; - Preview *preview; - AssembleView* assemble_view { nullptr }; - bool first_enter_assemble{ true }; + // GLToolbar view_toolbar; + GLToolbar collapse_toolbar; + Preview *preview; + AssembleView *assemble_view{nullptr}; + bool first_enter_assemble{true}; std::unique_ptr notification_manager; ProjectDirtyStateManager dirty_state; - BackgroundSlicingProcess background_process; - bool suppressed_backround_processing_update { false }; + BackgroundSlicingProcess background_process; + bool suppressed_backround_processing_update{false}; // Jobs defined inside the group class will be managed so that only one can // run at a time. Also, the background process will be stopped if a job is // started. It is up the the plater to ensure that the background slicing // can't be restarted while a ui job is still running. - class Jobs: public ExclusiveJobGroup + class Jobs : public ExclusiveJobGroup { - priv *m; - size_t m_arrange_id, m_fill_bed_id, m_rotoptimize_id, m_sla_import_id, m_orient_id; + priv *m; + size_t m_arrange_id, m_fill_bed_id, m_rotoptimize_id, m_sla_import_id, m_orient_id; std::shared_ptr m_pri; - //BBS + // BBS size_t m_print_id; void before_start() override { m->background_process.stop(); } public: - Jobs(priv *_m) : - m(_m), - m_pri{std::make_shared(m->notification_manager.get())} + Jobs(priv *_m) : m(_m), m_pri{std::make_shared(m->notification_manager.get())} { - m_arrange_id = add_job(std::make_unique(m_pri, m->q)); - m_orient_id = add_job(std::make_unique(m_pri, m->q)); - m_fill_bed_id = add_job(std::make_unique(m_pri, m->q)); + m_arrange_id = add_job(std::make_unique(m_pri, m->q)); + m_orient_id = add_job(std::make_unique(m_pri, m->q)); + m_fill_bed_id = add_job(std::make_unique(m_pri, m->q)); m_rotoptimize_id = add_job(std::make_unique(m_pri, m->q)); - m_sla_import_id = add_job(std::make_unique(m_pri, m->q)); - //BBS add print id + m_sla_import_id = add_job(std::make_unique(m_pri, m->q)); + // BBS add print id m_print_id = add_job(std::make_unique(m_pri, m->q)); } @@ -1887,26 +2003,23 @@ struct Plater::priv start(m_sla_import_id); } - //BBS bbl printing job - void print() - { - start(m_print_id); - } + // BBS bbl printing job + void print() { start(m_print_id); } } m_ui_jobs; - int m_job_prepare_state; + int m_job_prepare_state; - bool delayed_scene_refresh; - std::string delayed_error_message; + bool delayed_scene_refresh; + std::string delayed_error_message; - wxTimer background_process_timer; + wxTimer background_process_timer; - std::string label_btn_export; - std::string label_btn_send; + std::string label_btn_export; + std::string label_btn_send; - bool show_render_statistic_dialog{ false }; - bool show_wireframe{ false }; - bool wireframe_enabled{ true }; + bool show_render_statistic_dialog{false}; + bool show_wireframe{false}; + bool wireframe_enabled{true}; static const std::regex pattern_bundle; static const std::regex pattern_3mf; @@ -1919,7 +2032,6 @@ struct Plater::priv priv(Plater *q, MainFrame *main_frame); ~priv(); - bool need_update() const { return m_need_update; } void set_need_update(bool need_update) { m_need_update = need_update; } @@ -1932,19 +2044,22 @@ struct Plater::priv Slic3r::put_other_changes(); dirty_state.update_from_presets(); } - int save_project_if_dirty(const wxString& reason) { + int save_project_if_dirty(const wxString &reason) + { int res = wxID_NO; if (dirty_state.is_dirty()) { - MainFrame* mainframe = wxGetApp().mainframe; + MainFrame *mainframe = wxGetApp().mainframe; if (mainframe->can_save_as()) { wxString suggested_project_name; wxString project_name = suggested_project_name = get_project_filename(".3mf"); if (suggested_project_name.IsEmpty()) { - fs::path output_file = get_export_file_path(FT_3MF); + fs::path output_file = get_export_file_path(FT_3MF); suggested_project_name = output_file.empty() ? _L("Untitled") : from_u8(output_file.stem().string()); } - res = MessageDialog(mainframe, reason + "\n" + format_wxstr(_L("Do you want to save changes to \"%1%\"?"), suggested_project_name), - wxString(SLIC3R_APP_FULL_NAME), wxYES_NO | wxCANCEL).ShowModal(); + res = MessageDialog(mainframe, + reason + "\n" + format_wxstr(_L("Do you want to save changes to \"%1%\"?"), suggested_project_name), + wxString(SLIC3R_APP_FULL_NAME), wxYES_NO | wxCANCEL) + .ShowModal(); if (res == wxID_YES) if (!mainframe->save_project_as(project_name)) res = wxID_CANCEL; @@ -1952,7 +2067,11 @@ struct Plater::priv } return res; } - void reset_project_dirty_after_save() { m_undo_redo_stack_main.mark_current_as_saved(); dirty_state.reset_after_save(); } + void reset_project_dirty_after_save() + { + m_undo_redo_stack_main.mark_current_as_saved(); + dirty_state.reset_after_save(); + } void reset_project_dirty_initial_presets() { dirty_state.reset_initial_presets(); } #if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW @@ -1965,9 +2084,9 @@ struct Plater::priv POSTPONE_VALIDATION_ERROR_MESSAGE = 4, }; void update(unsigned int flags = 0); - void select_view(const std::string& direction); - //BBS: add no_slice option - void select_view_3D(const std::string& name, bool no_slice = true); + void select_view(const std::string &direction); + // BBS: add no_slice option + void select_view_3D(const std::string &name, bool no_slice = true); void select_next_view_3D(); bool is_preview_shown() const { return current_panel == preview; } @@ -1976,23 +2095,31 @@ struct Plater::priv bool is_assemble_view_show() const { return current_panel == assemble_view; } bool are_view3D_labels_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->are_labels_shown(); } - void show_view3D_labels(bool show) { if (current_panel == view3D) view3D->get_canvas3d()->show_labels(show); } + void show_view3D_labels(bool show) + { + if (current_panel == view3D) + view3D->get_canvas3d()->show_labels(show); + } bool is_view3D_overhang_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->is_overhang_shown(); } void show_view3D_overhang(bool show) { - if (current_panel == view3D) view3D->get_canvas3d()->show_overhang(show); + if (current_panel == view3D) + view3D->get_canvas3d()->show_overhang(show); } - bool is_sidebar_collapsed() const { return sidebar->is_collapsed(); } + bool is_sidebar_collapsed() const { return sidebar->is_collapsed(); } void collapse_sidebar(bool collapse); - bool is_view3D_layers_editing_enabled() const { return (current_panel == view3D) && view3D->get_canvas3d()->is_layers_editing_enabled(); } + bool is_view3D_layers_editing_enabled() const + { + return (current_panel == view3D) && view3D->get_canvas3d()->is_layers_editing_enabled(); + } - void set_current_canvas_as_dirty(); - GLCanvas3D* get_current_canvas3D(bool exclude_preview = false); - void unbind_canvas_event_handlers(); - void reset_canvas_volumes(); + void set_current_canvas_as_dirty(); + GLCanvas3D *get_current_canvas3D(bool exclude_preview = false); + void unbind_canvas_event_handlers(); + void reset_canvas_volumes(); // BBS bool init_collapse_toolbar(); @@ -2021,13 +2148,13 @@ struct Plater::priv void update_ui_from_settings(); // BBS std::shared_ptr statusbar(); - std::string get_config(const std::string &key) const; - BoundingBoxf bed_shape_bb() const; - BoundingBox scaled_bed_shape_bb() const; + std::string get_config(const std::string &key) const; + BoundingBoxf bed_shape_bb() const; + BoundingBox scaled_bed_shape_bb() const; // BBS: backup & restore - std::vector load_files(const std::vector& input_files, LoadStrategy strategy, bool ask_multi = false); - std::vector load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z = false, bool split_object = false); + std::vector load_files(const std::vector &input_files, LoadStrategy strategy, bool ask_multi = false); + std::vector load_model_objects(const ModelObjectPtrs &model_objects, bool allow_negative_z = false, bool split_object = false); fs::path get_export_file_path(GUI::FileType file_type); wxString get_export_file(GUI::FileType file_type); @@ -2035,12 +2162,12 @@ struct Plater::priv // BBS void load_auxiliary_files(); - const Selection& get_selection() const; - Selection& get_selection(); - Selection& get_curr_selection(); + const Selection &get_selection() const; + Selection &get_selection(); + Selection &get_curr_selection(); - int get_selected_object_idx() const; - int get_selected_volume_idx() const; + int get_selected_object_idx() const; + int get_selected_volume_idx() const; void selection_changed(); void object_list_changed(); @@ -2051,7 +2178,7 @@ struct Plater::priv void select_all(); void deselect_all(); void remove(size_t obj_idx); - bool delete_object_from_model(size_t obj_idx, bool refresh_immediately = true); //BBS + bool delete_object_from_model(size_t obj_idx, bool refresh_immediately = true); // BBS void delete_all_objects_from_model(); void reset(bool apply_presets_change = false); void center_selection(); @@ -2061,15 +2188,19 @@ struct Plater::priv void scale_selection_to_fit_print_volume(); // Return the active Undo/Redo stack. It may be either the main stack or the Gimzo stack. - Slic3r::UndoRedo::Stack& undo_redo_stack() { assert(m_undo_redo_stack_active != nullptr); return *m_undo_redo_stack_active; } - Slic3r::UndoRedo::Stack& undo_redo_stack_main() { return m_undo_redo_stack_main; } - void enter_gizmos_stack(); - bool leave_gizmos_stack(); + Slic3r::UndoRedo::Stack &undo_redo_stack() + { + assert(m_undo_redo_stack_active != nullptr); + return *m_undo_redo_stack_active; + } + Slic3r::UndoRedo::Stack &undo_redo_stack_main() { return m_undo_redo_stack_main; } + void enter_gizmos_stack(); + bool leave_gizmos_stack(); - void take_snapshot(const std::string& snapshot_name, UndoRedo::SnapshotType snapshot_type = UndoRedo::SnapshotType::Action); + void take_snapshot(const std::string &snapshot_name, UndoRedo::SnapshotType snapshot_type = UndoRedo::SnapshotType::Action); /*void take_snapshot(const wxString& snapshot_name, UndoRedo::SnapshotType snapshot_type = UndoRedo::SnapshotType::Action) { this->take_snapshot(std::string(snapshot_name.ToUTF8().data()), snapshot_type); }*/ - int get_active_snapshot_index(); + int get_active_snapshot_index(); void undo(); void redo(); @@ -2078,21 +2209,24 @@ struct Plater::priv // BBS: backup bool up_to_date(bool saved, bool backup); - void suppress_snapshots() { m_prevent_snapshots++; } - void allow_snapshots() { m_prevent_snapshots--; } + void suppress_snapshots() { m_prevent_snapshots++; } + void allow_snapshots() { m_prevent_snapshots--; } // BBS: single snapshot void single_snapshots_enter(SingleSnapshot *single) { - if (m_single == nullptr) m_single = single; + if (m_single == nullptr) + m_single = single; } void single_snapshots_leave(SingleSnapshot *single) { - if (m_single == single) m_single = nullptr; + if (m_single == single) + m_single = nullptr; } void process_validation_warning(StringObjectException const &warning) const; - bool background_processing_enabled() const { + bool background_processing_enabled() const + { #ifdef SUPPORT_BACKGROUND_PROCESSING return this->get_config("background_processing") == "1"; #else @@ -2123,7 +2257,8 @@ struct Plater::priv bool restart_background_process(unsigned int state); // returns bit mask of UpdateBackgroundProcessReturnState unsigned int update_restart_background_process(bool force_scene_update, bool force_preview_update); - void show_delayed_error_message() { + void show_delayed_error_message() + { if (!this->delayed_error_message.empty()) { std::string msg = std::move(this->delayed_error_message); this->delayed_error_message.clear(); @@ -2134,84 +2269,91 @@ struct Plater::priv void export_gcode(fs::path output_path, bool output_path_on_removable_media, PrintHostJob upload_job); void reload_from_disk(); - bool replace_volume_with_stl(int object_idx, int volume_idx, const fs::path& new_path, const std::string& snapshot = ""); + bool replace_volume_with_stl(int object_idx, int volume_idx, const fs::path &new_path, const std::string &snapshot = ""); void replace_with_stl(); void reload_all_from_disk(); - //BBS: add no_slice option - void set_current_panel(wxPanel* panel, bool no_slice = true); - - void on_combobox_select(wxCommandEvent&); - void on_select_bed_type(wxCommandEvent&); - void on_select_preset(wxCommandEvent&); - void on_slicing_update(SlicingStatusEvent&); - void on_slicing_completed(wxCommandEvent&); - void on_process_completed(SlicingProcessCompletedEvent&); - void on_export_began(wxCommandEvent&); - void on_export_finished(wxCommandEvent&); + // BBS: add no_slice option + void set_current_panel(wxPanel *panel, bool no_slice = true); + + void on_combobox_select(wxCommandEvent &); + void on_select_bed_type(wxCommandEvent &); + void on_select_preset(wxCommandEvent &); + void on_slicing_update(SlicingStatusEvent &); + void on_slicing_completed(wxCommandEvent &); + void on_process_completed(SlicingProcessCompletedEvent &); + void on_export_began(wxCommandEvent &); + void on_export_finished(wxCommandEvent &); void on_slicing_began(); void clear_warnings(); void add_warning(const Slic3r::PrintStateBase::Warning &warning, size_t oid); // Update notification manager with the current state of warnings produced by the background process (slicing). void actualize_slicing_warnings(const PrintBase &print); - void actualize_object_warnings(const PrintBase& print); + void actualize_object_warnings(const PrintBase &print); // Displays dialog window with list of warnings. // Returns true if user clicks OK. // Returns true if current_warnings vector is empty without showning the dialog bool warnings_dialog(); - void on_action_add(SimpleEvent&); - void on_action_add_plate(SimpleEvent&); - void on_action_del_plate(SimpleEvent&); - void on_action_split_objects(SimpleEvent&); - void on_action_split_volumes(SimpleEvent&); - void on_action_layersediting(SimpleEvent&); - - void on_object_select(SimpleEvent&); - void on_right_click(RBtnEvent&); - //BBS: add model repair + void on_action_add(SimpleEvent &); + void on_action_add_plate(SimpleEvent &); + void on_action_del_plate(SimpleEvent &); + void on_action_split_objects(SimpleEvent &); + void on_action_split_volumes(SimpleEvent &); + void on_action_layersediting(SimpleEvent &); + void on_create_filament(SimpleEvent &); + void on_modify_filament(SimpleEvent &); + + void on_object_select(SimpleEvent &); + void on_right_click(RBtnEvent &); + // BBS: add model repair void on_repair_model(wxCommandEvent &event); void on_filament_color_changed(wxCommandEvent &event); void show_install_plugin_hint(wxCommandEvent &event); void install_network_plugin(wxCommandEvent &event); void show_preview_only_hint(wxCommandEvent &event); - //BBS: add part plate related logic - void on_plate_right_click(RBtnPlateEvent&); - void on_plate_selected(SimpleEvent&); - void on_action_request_model_id(wxCommandEvent& evt); - void on_action_download_project(wxCommandEvent& evt); + // BBS: add part plate related logic + void on_plate_right_click(RBtnPlateEvent &); + void on_plate_selected(SimpleEvent &); + void on_action_request_model_id(wxCommandEvent &evt); + void on_action_download_project(wxCommandEvent &evt); void on_slice_button_status(bool enable); - //BBS: GUI refactor: GLToolbar - void on_action_open_project(SimpleEvent&); - void on_action_slice_plate(SimpleEvent&); - void on_action_slice_all(SimpleEvent&); + // BBS: GUI refactor: GLToolbar + void on_action_open_project(SimpleEvent &); + void on_action_slice_plate(SimpleEvent &); + void on_action_slice_all(SimpleEvent &); void on_action_publish(wxCommandEvent &evt); - void on_action_print_plate(SimpleEvent&); - void on_action_print_all(SimpleEvent&); - void on_action_export_gcode(SimpleEvent&); - void on_action_send_gcode(SimpleEvent&); - void on_action_export_sliced_file(SimpleEvent&); - void on_action_export_all_sliced_file(SimpleEvent&); - void on_action_select_sliced_plate(wxCommandEvent& evt); - //BBS: change dark/light mode - void on_change_color_mode(SimpleEvent& evt); - void on_apple_change_color_mode(wxSysColourChangedEvent& evt); - void on_update_geometry(Vec3dsEvent<2>&); - void on_3dcanvas_mouse_dragging_started(SimpleEvent&); - void on_3dcanvas_mouse_dragging_finished(SimpleEvent&); - - //void show_action_buttons(const bool is_ready_to_slice) const; + void on_action_print_plate(SimpleEvent &); + void on_action_print_all(SimpleEvent &); + void on_action_export_gcode(SimpleEvent &); + void on_action_send_gcode(SimpleEvent &); + void on_action_export_sliced_file(SimpleEvent &); + void on_action_export_all_sliced_file(SimpleEvent &); + void on_action_select_sliced_plate(wxCommandEvent &evt); + // BBS: change dark/light mode + void on_change_color_mode(SimpleEvent &evt); + void on_apple_change_color_mode(wxSysColourChangedEvent &evt); + void on_update_geometry(Vec3dsEvent<2> &); + void on_3dcanvas_mouse_dragging_started(SimpleEvent &); + void on_3dcanvas_mouse_dragging_finished(SimpleEvent &); + + // void show_action_buttons(const bool is_ready_to_slice) const; bool show_publish_dlg(bool show = true); void update_publish_dialog_status(wxString &msg, int percent = -1); - void on_action_print_plate_from_sdcard(SimpleEvent&); + void on_action_print_plate_from_sdcard(SimpleEvent &); // Set the bed shape to a single closed 2D polygon(array of two element arrays), // triangulate the bed and store the triangles into m_bed.m_triangles, // fills the m_bed.m_grid_lines and sets m_bed.m_origin. // Sets m_bed.m_polygon to limit the object placement. - //BBS: add bed exclude area - void set_bed_shape(const Pointfs& shape, const Pointfs& exclude_areas, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false); + // BBS: add bed exclude area + void set_bed_shape(const Pointfs &shape, + const Pointfs &exclude_areas, + const double printable_height, + const std::string &custom_texture, + const std::string &custom_model, + bool force_as_custom = false); bool can_delete() const; bool can_delete_all() const; @@ -2229,7 +2371,7 @@ struct Plater::priv bool can_set_instance_to_object() const; bool can_mirror() const; bool can_reload_from_disk() const; - //BBS: + // BBS: bool can_fillcolor() const; bool has_assemble_view() const; bool can_replace_with_stl() const; @@ -2238,49 +2380,61 @@ struct Plater::priv bool can_scale_to_print_volume() const; #endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT - //BBS: add plate_id for thumbnail - void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); - ThumbnailsList generate_thumbnails(const ThumbnailsParams& params, Camera::EType camera_type); - //BBS - void generate_calibration_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params); + // BBS: add plate_id for thumbnail + void generate_thumbnail(ThumbnailData &data, + unsigned int w, + unsigned int h, + const ThumbnailsParams &thumbnail_params, + Camera::EType camera_type, + bool use_top_view = false, + bool for_picking = false); + ThumbnailsList generate_thumbnails(const ThumbnailsParams ¶ms, Camera::EType camera_type); + // BBS + void generate_calibration_thumbnail(ThumbnailData &data, unsigned int w, unsigned int h, const ThumbnailsParams &thumbnail_params); PlateBBoxData generate_first_layer_bbox(); void bring_instance_forward() const; // returns the path to project file with the given extension (none if extension == wxEmptyString) // extension should contain the leading dot, i.e.: ".3mf" - wxString get_project_filename(const wxString& extension = wxEmptyString) const; - wxString get_export_gcode_filename(const wxString& extension = wxEmptyString, bool only_filename = false, bool export_all = false) const; - void set_project_filename(const wxString& filename); + wxString get_project_filename(const wxString &extension = wxEmptyString) const; + wxString get_export_gcode_filename(const wxString &extension = wxEmptyString, bool only_filename = false, bool export_all = false) const; + void set_project_filename(const wxString &filename); - //BBS store bbs project name + // BBS store bbs project name wxString get_project_name(); - void set_project_name(const wxString& project_name); + void set_project_name(const wxString &project_name); // Call after plater and Canvas#D is initialized void init_notification_manager(); - // Caching last value of show_action_buttons parameter for show_action_buttons(), so that a callback which does not know this state will not override it. - //mutable bool ready_to_slice = { false }; - // Flag indicating that the G-code export targets a removable device, therefore the show_action_buttons() needs to be called at any case when the background processing finishes. - ExportingStatus exporting_status { NOT_EXPORTING }; - std::string last_output_path; - std::string last_output_dir_path; - //BBS store machine_sn and 3mf_path for PrintJob - PrintPrepareData m_print_job_data; - bool inside_snapshot_capture() { return m_prevent_snapshots != 0; } - int process_completed_with_error { -1 }; //-1 means no error - - //BBS: project - BBLProject project; - - //BBS: add print project related logic + // Caching last value of show_action_buttons parameter for show_action_buttons(), so that a callback which does not know this state will + // not override it. + // mutable bool ready_to_slice = { false }; + // Flag indicating that the G-code export targets a removable device, therefore the show_action_buttons() needs to be called at any case + // when the background processing finishes. + ExportingStatus exporting_status{NOT_EXPORTING}; + std::string last_output_path; + std::string last_output_dir_path; + // BBS store machine_sn and 3mf_path for PrintJob + PrintPrepareData m_print_job_data; + bool inside_snapshot_capture() { return m_prevent_snapshots != 0; } + int process_completed_with_error{-1}; //-1 means no error + + // BBS: project + BBLProject project; + + // BBS: add print project related logic void update_fff_scene_only_shells(bool only_shells = true); - //BBS: add popup object table logic - bool PopupObjectTable(int object_id, int volume_id, const wxPoint& position); + // BBS: add popup object table logic + bool PopupObjectTable(int object_id, int volume_id, const wxPoint &position); void on_action_send_to_printer(bool isall = false); - int update_print_required_data(Slic3r::DynamicPrintConfig config, Slic3r::Model model, Slic3r::PlateDataPtrs plate_data_list, std::string file_name, std::string file_path); + int update_print_required_data(Slic3r::DynamicPrintConfig config, + Slic3r::Model model, + Slic3r::PlateDataPtrs plate_data_list, + std::string file_name, + std::string file_path); + private: bool layers_height_allowed() const; @@ -2288,39 +2442,38 @@ struct Plater::priv void update_sla_scene(); void undo_redo_to(std::vector::const_iterator it_snapshot); - void update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool temp_snapshot_was_taken = false); - void on_action_export_to_sdcard(SimpleEvent&); - void on_action_export_to_sdcard_all(SimpleEvent&); - void update_plugin_when_launch(wxCommandEvent& event); + void update_after_undo_redo(const UndoRedo::Snapshot &snapshot, bool temp_snapshot_was_taken = false); + void on_action_export_to_sdcard(SimpleEvent &); + void on_action_export_to_sdcard_all(SimpleEvent &); + void update_plugin_when_launch(wxCommandEvent &event); // path to project folder stored with no extension - boost::filesystem::path m_project_folder; + boost::filesystem::path m_project_folder; /* display project name */ - wxString m_project_name; - - Slic3r::UndoRedo::Stack m_undo_redo_stack_main; - Slic3r::UndoRedo::Stack m_undo_redo_stack_gizmos; - Slic3r::UndoRedo::Stack *m_undo_redo_stack_active = &m_undo_redo_stack_main; - int m_prevent_snapshots = 0; /* Used for avoid of excess "snapshoting". - * Like for "delete selected" or "set numbers of copies" - * we should call tack_snapshot just ones - * instead of calls for each action separately - * */ + wxString m_project_name; + + Slic3r::UndoRedo::Stack m_undo_redo_stack_main; + Slic3r::UndoRedo::Stack m_undo_redo_stack_gizmos; + Slic3r::UndoRedo::Stack *m_undo_redo_stack_active = &m_undo_redo_stack_main; + int m_prevent_snapshots = 0; /* Used for avoid of excess "snapshoting". + * Like for "delete selected" or "set numbers of copies" + * we should call tack_snapshot just ones + * instead of calls for each action separately + * */ // BBS: single snapshot - Plater::SingleSnapshot *m_single = nullptr; + Plater::SingleSnapshot *m_single = nullptr; // BBS: backup - size_t m_saved_timestamp = 0; - size_t m_backup_timestamp = 0; - std::string m_last_fff_printer_profile_name; - std::string m_last_sla_printer_profile_name; + size_t m_saved_timestamp = 0; + size_t m_backup_timestamp = 0; + std::string m_last_fff_printer_profile_name; + std::string m_last_sla_printer_profile_name; // vector of all warnings generated by last slicing std::vector> current_warnings; - bool show_warning_dialog { false }; + bool show_warning_dialog{false}; - //record print preset + // record print preset void record_start_print_preset(std::string action); - }; const std::regex Plater::priv::pattern_bundle(".*[.](amf|amf[.]xml|zip[.]amf|3mf)", std::regex::icase); @@ -2332,40 +2485,37 @@ const std::regex Plater::priv::pattern_prusa(".*bbl", std::regex::icase); Plater::priv::priv(Plater *q, MainFrame *main_frame) : q(q) , main_frame(main_frame) - //BBS: add bed_exclude_area - , config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({ - "printable_area", "bed_exclude_area", "bed_custom_texture", "bed_custom_model", "print_sequence", - "extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod", "skirt_loops", "skirt_speed", "skirt_distance", - "brim_width", "brim_object_gap", "brim_type", "nozzle_diameter", "single_extruder_multi_material", - "enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_volume", - "extruder_colour", "filament_colour", "material_colour", "printable_height", "printer_model", "printer_technology", - // These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor. - "layer_height", "initial_layer_print_height", "min_layer_height", "max_layer_height", - "brim_width", "wall_loops", "wall_filament", "sparse_infill_density", "sparse_infill_filament", "top_shell_layers", - "enable_support", "support_filament", "support_interface_filament", - "support_top_z_distance", "support_bottom_z_distance", "raft_layers", - "wipe_tower_rotation_angle", "wipe_tower_cone_angle", "wipe_tower_extra_spacing", "wipe_tower_extruder", - "best_object_pos" - })) + // BBS: add bed_exclude_area + , config(Slic3r::DynamicPrintConfig::new_from_defaults_keys( + {"printable_area", "bed_exclude_area", "bed_custom_texture", "bed_custom_model", "print_sequence", "extruder_clearance_radius", + "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod", "skirt_loops", "skirt_speed", "skirt_distance", + "brim_width", "brim_object_gap", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "enable_prime_tower", + "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_volume", "extruder_colour", + "filament_colour", "material_colour", "printable_height", "printer_model", "printer_technology", + // These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor. + "layer_height", "initial_layer_print_height", "min_layer_height", "max_layer_height", "brim_width", "wall_loops", + "wall_filament", "sparse_infill_density", "sparse_infill_filament", "top_shell_layers", "enable_support", "support_filament", + "support_interface_filament", "support_top_z_distance", "support_bottom_z_distance", "raft_layers", "wipe_tower_rotation_angle", + "wipe_tower_cone_angle", "wipe_tower_extra_spacing", "wipe_tower_extruder", "best_object_pos"})) , sidebar(new Sidebar(q)) , notification_manager(std::make_unique(q)) , m_ui_jobs(this) , m_job_prepare_state(Job::JobPrepareState::PREPARE_STATE_DEFAULT) , delayed_scene_refresh(false) , collapse_toolbar(GLToolbar::Normal, "Collapse") - //BBS :partplatelist construction + // BBS :partplatelist construction , partplate_list(this->q, &model) { this->q->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - //BBS: use the first partplate's print for background process + // BBS: use the first partplate's print for background process partplate_list.update_slice_context_to_current_plate(background_process); /* background_process.set_fff_print(&fff_print); background_process.set_sla_print(&sla_print); background_process.set_gcode_result(&gcode_result); - background_process.set_thumbnail_cb([this](const ThumbnailsParams& params) { return this->generate_thumbnails(params, Camera::EType::Ortho); }); - background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); + background_process.set_thumbnail_cb([this](const ThumbnailsParams& params) { return this->generate_thumbnails(params, + Camera::EType::Ortho); }); background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); background_process.set_export_began_event(EVT_EXPORT_BEGAN); // Default printer technology for default config. @@ -2379,7 +2529,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) sla_print.set_status_callback(statuscb); */ // BBS: to be checked. Not follow patch. - background_process.set_thumbnail_cb([this](const ThumbnailsParams& params) { return this->generate_thumbnails(params, Camera::EType::Ortho); }); + background_process.set_thumbnail_cb( + [this](const ThumbnailsParams ¶ms) { return this->generate_thumbnails(params, Camera::EType::Ortho); }); background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); background_process.set_export_began_event(EVT_EXPORT_BEGAN); @@ -2394,17 +2545,20 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) this->q->Bind(EVT_PREVIEW_ONLY_MODE_HINT, &priv::show_preview_only_hint, this); this->q->Bind(EVT_GLCANVAS_COLOR_MODE_CHANGED, &priv::on_change_color_mode, this); this->q->Bind(wxEVT_SYS_COLOUR_CHANGED, &priv::on_apple_change_color_mode, this); + this->q->Bind(EVT_CREATE_FILAMENT, &priv::on_create_filament, this); + this->q->Bind(EVT_MODIFY_FILAMENT, &priv::on_modify_filament, this); view3D = new View3D(q, bed, &model, config, &background_process); - //BBS: use partplater's gcode - preview = new Preview(q, bed, &model, config, &background_process, partplate_list.get_current_slice_result(), [this]() { schedule_background_process(); }); + // BBS: use partplater's gcode + preview = new Preview(q, bed, &model, config, &background_process, partplate_list.get_current_slice_result(), + [this]() { schedule_background_process(); }); assemble_view = new AssembleView(q, bed, &model, config, &background_process); #ifdef __APPLE__ // BBS // set default view_toolbar icons size equal to GLGizmosManager::Default_Icons_Size - //view_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size); + // view_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size); #endif // __APPLE__ panels.push_back(view3D); @@ -2412,16 +2566,15 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) panels.push_back(assemble_view); this->background_process_timer.SetOwner(this->q, 0); - this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) - { + this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { if (!this->suppressed_backround_processing_update) this->update_restart_background_process(false, false); }); update(); - auto* hsizer = new wxBoxSizer(wxHORIZONTAL); - auto* vsizer = new wxBoxSizer(wxVERTICAL); + auto *hsizer = new wxBoxSizer(wxHORIZONTAL); + auto *vsizer = new wxBoxSizer(wxVERTICAL); // BBS: move sidebar to left side hsizer->Add(sidebar, 0, wxEXPAND | wxLEFT | wxRIGHT, 0); @@ -2440,137 +2593,155 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) menus.init(q); - // Events: if (wxGetApp().is_editor()) { // Preset change event sidebar->Bind(wxEVT_COMBOBOX, &priv::on_combobox_select, this); - sidebar->Bind(EVT_OBJ_LIST_OBJECT_SELECT, [this](wxEvent&) { priv::selection_changed(); }); + sidebar->Bind(EVT_OBJ_LIST_OBJECT_SELECT, [this](wxEvent &) { priv::selection_changed(); }); // BBS: should bind BACKGROUND_PROCESS event to plater - q->Bind(EVT_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { this->schedule_background_process(); }); + q->Bind(EVT_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent &) { this->schedule_background_process(); }); // jump to found option from SearchDialog - q->Bind(wxCUSTOMEVT_JUMP_TO_OPTION, [this](wxCommandEvent& evt) { sidebar->jump_to_option(evt.GetInt()); }); + q->Bind(wxCUSTOMEVT_JUMP_TO_OPTION, [this](wxCommandEvent &evt) { sidebar->jump_to_option(evt.GetInt()); }); + q->Bind(wxCUSTOMEVT_JUMP_TO_OBJECT, [this](wxCommandEvent &evt) { + auto client_data = evt.GetClientData(); + ObjectDataViewModelNode *data = static_cast(client_data); + sidebar->jump_to_object(data); + }); } - wxGLCanvas* view3D_canvas = view3D->get_wxglcanvas(); - //BBS: GUI refactor - wxGLCanvas* preview_canvas = preview->get_wxglcanvas(); + wxGLCanvas *view3D_canvas = view3D->get_wxglcanvas(); + // BBS: GUI refactor + wxGLCanvas *preview_canvas = preview->get_wxglcanvas(); if (wxGetApp().is_editor()) { // 3DScene events: - view3D_canvas->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { + view3D_canvas->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent &) { delayed_error_message.clear(); this->background_process_timer.Start(500, wxTIMER_ONE_SHOT); - }); + }); view3D_canvas->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this); view3D_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this); - //BBS: add part plate related logic + // BBS: add part plate related logic view3D_canvas->Bind(EVT_GLCANVAS_PLATE_RIGHT_CLICK, &priv::on_plate_right_click, this); - view3D_canvas->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent&) { q->remove_selected(); }); - view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent& evt) { - //BBS arrage from EVT set default state. + view3D_canvas->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent &) { q->remove_selected(); }); + view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent &evt) { + // BBS arrage from EVT set default state. this->q->set_prepare_state(Job::PREPARE_STATE_DEFAULT); - this->q->arrange(); }); - view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE_PARTPLATE, [this](SimpleEvent& evt) { - //BBS arrage from EVT set default state. + this->q->arrange(); + }); + view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE_PARTPLATE, [this](SimpleEvent &evt) { + // BBS arrage from EVT set default state. this->q->set_prepare_state(Job::PREPARE_STATE_MENU); - this->q->arrange(); }); - view3D_canvas->Bind(EVT_GLCANVAS_ORIENT, [this](SimpleEvent& evt) { - //BBS oriant from EVT set default state. + this->q->arrange(); + }); + view3D_canvas->Bind(EVT_GLCANVAS_ORIENT, [this](SimpleEvent &evt) { + // BBS oriant from EVT set default state. this->q->set_prepare_state(Job::PREPARE_STATE_DEFAULT); - this->q->orient(); }); - view3D_canvas->Bind(EVT_GLCANVAS_ORIENT_PARTPLATE, [this](SimpleEvent& evt) { - //BBS oriant from EVT set default state. + this->q->orient(); + }); + view3D_canvas->Bind(EVT_GLCANVAS_ORIENT_PARTPLATE, [this](SimpleEvent &evt) { + // BBS oriant from EVT set default state. this->q->set_prepare_state(Job::PREPARE_STATE_MENU); - this->q->orient(); }); - //BBS - view3D_canvas->Bind(EVT_GLCANVAS_SELECT_CURR_PLATE_ALL, [this](SimpleEvent&) {this->q->select_curr_plate_all(); }); - - view3D_canvas->Bind(EVT_GLCANVAS_SELECT_ALL, [this](SimpleEvent&) { this->q->select_all(); }); - view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); - view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event& evt) - { if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); }); - view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); }); - view3D_canvas->Bind(EVT_GLCANVAS_FORCE_UPDATE, [this](SimpleEvent&) { update(); }); - view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); }); - view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent&) { update(); }); + this->q->orient(); + }); + // BBS + view3D_canvas->Bind(EVT_GLCANVAS_SELECT_CURR_PLATE_ALL, [this](SimpleEvent &) { this->q->select_curr_plate_all(); }); + + view3D_canvas->Bind(EVT_GLCANVAS_SELECT_ALL, [this](SimpleEvent &) { this->q->select_all(); }); + view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [](SimpleEvent &) { wxGetApp().keyboard_shortcuts(); }); + view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event &evt) { + if (evt.data == 1) + this->q->increase_instances(); + else if (this->can_decrease_instances()) + this->q->decrease_instances(); + }); + view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent &) { update(); }); + view3D_canvas->Bind(EVT_GLCANVAS_FORCE_UPDATE, [this](SimpleEvent &) { update(); }); + view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent &) { update(); }); + view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent &) { update(); }); // BBS - //view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event& evt) { this->sidebar->enable_buttons(evt.data); }); - view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event& evt) { on_slice_button_status(evt.data); }); + // view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event& evt) { this->sidebar->enable_buttons(evt.data); }); + view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event &evt) { on_slice_button_status(evt.data); }); view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_GEOMETRY, &priv::on_update_geometry, this); view3D_canvas->Bind(EVT_GLCANVAS_MOUSE_DRAGGING_STARTED, &priv::on_3dcanvas_mouse_dragging_started, this); view3D_canvas->Bind(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, &priv::on_3dcanvas_mouse_dragging_finished, this); - view3D_canvas->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); - view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); }); - view3D_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); }); - view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); }); - view3D_canvas->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, [this](SimpleEvent&) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); }); - view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); - view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); }); - view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](HeightProfileSmoothEvent& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); }); - view3D_canvas->Bind(EVT_GLCANVAS_RELOAD_FROM_DISK, [this](SimpleEvent&) { this->reload_all_from_disk(); }); + view3D_canvas->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent &) { select_next_view_3D(); }); + view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent &) { reset_all_gizmos(); }); + view3D_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent &) { this->undo(); }); + view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent &) { this->redo(); }); + view3D_canvas->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, + [this](SimpleEvent &) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); }); + view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, + [this](SimpleEvent &) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); + view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, + [this](Event &evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); }); + view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, + [this](HeightProfileSmoothEvent &evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); }); + view3D_canvas->Bind(EVT_GLCANVAS_RELOAD_FROM_DISK, [this](SimpleEvent &) { this->reload_all_from_disk(); }); // 3DScene/Toolbar: view3D_canvas->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this); - view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); }); - view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { delete_all_objects_from_model(); }); -// view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [q](SimpleEvent&) { q->reset_with_confirm(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent &) { q->remove_selected(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent &) { delete_all_objects_from_model(); }); + // view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [q](SimpleEvent&) { q->reset_with_confirm(); }); view3D_canvas->Bind(EVT_GLTOOLBAR_ADD_PLATE, &priv::on_action_add_plate, this); view3D_canvas->Bind(EVT_GLTOOLBAR_DEL_PLATE, &priv::on_action_del_plate, this); - view3D_canvas->Bind(EVT_GLTOOLBAR_ORIENT, [this](SimpleEvent&) { - //BBS arrage from EVT set default state. + view3D_canvas->Bind(EVT_GLTOOLBAR_ORIENT, [this](SimpleEvent &) { + // BBS arrage from EVT set default state. this->q->set_prepare_state(Job::PREPARE_STATE_DEFAULT); - this->q->orient(); }); - view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { - //BBS arrage from EVT set default state. + this->q->orient(); + }); + view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent &) { + // BBS arrage from EVT set default state. this->q->set_prepare_state(Job::PREPARE_STATE_DEFAULT); this->q->arrange(); - }); - view3D_canvas->Bind(EVT_GLTOOLBAR_CUT, [q](SimpleEvent&) { q->cut_selection_to_clipboard(); }); - view3D_canvas->Bind(EVT_GLTOOLBAR_COPY, [q](SimpleEvent&) { q->copy_selection_to_clipboard(); }); - view3D_canvas->Bind(EVT_GLTOOLBAR_PASTE, [q](SimpleEvent&) { q->paste_from_clipboard(); }); + }); + view3D_canvas->Bind(EVT_GLTOOLBAR_CUT, [q](SimpleEvent &) { q->cut_selection_to_clipboard(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_COPY, [q](SimpleEvent &) { q->copy_selection_to_clipboard(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_PASTE, [q](SimpleEvent &) { q->paste_from_clipboard(); }); view3D_canvas->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this); - //BBS: add clone - view3D_canvas->Bind(EVT_GLTOOLBAR_CLONE, [q](SimpleEvent&) { q->clone_selection(); }); - view3D_canvas->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase_instances(); }); - view3D_canvas->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); }); + // BBS: add clone + view3D_canvas->Bind(EVT_GLTOOLBAR_CLONE, [q](SimpleEvent &) { q->clone_selection(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent &) { q->increase_instances(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent &) { q->decrease_instances(); }); view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this); view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this); - //BBS: GUI refactor: GLToolbar + // BBS: GUI refactor: GLToolbar view3D_canvas->Bind(EVT_GLTOOLBAR_OPEN_PROJECT, &priv::on_action_open_project, this); - //view3D_canvas->Bind(EVT_GLTOOLBAR_SLICE_PLATE, &priv::on_action_slice_plate, this); - //view3D_canvas->Bind(EVT_GLTOOLBAR_SLICE_ALL, &priv::on_action_slice_all, this); - //view3D_canvas->Bind(EVT_GLTOOLBAR_PRINT_PLATE, &priv::on_action_print_plate, this); - //view3D_canvas->Bind(EVT_GLTOOLBAR_PRINT_ALL, &priv::on_action_print_all, this); - //view3D_canvas->Bind(EVT_GLTOOLBAR_EXPORT_GCODE, &priv::on_action_export_gcode, this); - view3D_canvas->Bind(EVT_GLVIEWTOOLBAR_ASSEMBLE, [q](SimpleEvent&) { q->select_view_3D("Assemble"); }); - //preview also send these events - //preview_canvas->Bind(EVT_GLTOOLBAR_SLICE_PLATE, &priv::on_action_slice_plate, this); - //preview_canvas->Bind(EVT_GLTOOLBAR_PRINT_PLATE, &priv::on_action_print_plate, this); - //preview_canvas->Bind(EVT_GLTOOLBAR_PRINT_ALL, &priv::on_action_print_all, this); - //review_canvas->Bind(EVT_GLTOOLBAR_EXPORT_GCODE, &priv::on_action_export_gcode, this); - } - view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent&) { q->set_bed_shape(); }); + // view3D_canvas->Bind(EVT_GLTOOLBAR_SLICE_PLATE, &priv::on_action_slice_plate, this); + // view3D_canvas->Bind(EVT_GLTOOLBAR_SLICE_ALL, &priv::on_action_slice_all, this); + // view3D_canvas->Bind(EVT_GLTOOLBAR_PRINT_PLATE, &priv::on_action_print_plate, this); + // view3D_canvas->Bind(EVT_GLTOOLBAR_PRINT_ALL, &priv::on_action_print_all, this); + // view3D_canvas->Bind(EVT_GLTOOLBAR_EXPORT_GCODE, &priv::on_action_export_gcode, this); + view3D_canvas->Bind(EVT_GLVIEWTOOLBAR_ASSEMBLE, [q](SimpleEvent &) { q->select_view_3D("Assemble"); }); + // preview also send these events + // preview_canvas->Bind(EVT_GLTOOLBAR_SLICE_PLATE, &priv::on_action_slice_plate, this); + // preview_canvas->Bind(EVT_GLTOOLBAR_PRINT_PLATE, &priv::on_action_print_plate, this); + // preview_canvas->Bind(EVT_GLTOOLBAR_PRINT_ALL, &priv::on_action_print_all, this); + // review_canvas->Bind(EVT_GLTOOLBAR_EXPORT_GCODE, &priv::on_action_export_gcode, this); + } + view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent &) { q->set_bed_shape(); }); // Preview events: - preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_QUESTION_MARK, [](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); - preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent&) { q->set_bed_shape(); }); - preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE, [this](SimpleEvent &) { - preview->get_canvas3d()->set_as_dirty(); - }); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_QUESTION_MARK, [](SimpleEvent &) { wxGetApp().keyboard_shortcuts(); }); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent &) { q->set_bed_shape(); }); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE, [this](SimpleEvent &) { preview->get_canvas3d()->set_as_dirty(); }); if (wxGetApp().is_editor()) { - preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); - preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, [this](SimpleEvent&) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); }); - preview->get_wxglcanvas()->Bind(EVT_CUSTOMEVT_TICKSCHANGED, [this](wxCommandEvent& event) { - Type tick_event_type = (Type)event.GetInt(); - Model& model = wxGetApp().plater()->model(); - //BBS: replace model custom gcode with current plate custom gcode - model.plates_custom_gcodes[model.curr_plate_index] = preview->get_canvas3d()->get_gcode_viewer().get_layers_slider()->GetTicksValues(); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent &) { select_next_view_3D(); }); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, + [this](SimpleEvent &) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); }); + preview->get_wxglcanvas()->Bind(EVT_CUSTOMEVT_TICKSCHANGED, [this](wxCommandEvent &event) { + Type tick_event_type = (Type) event.GetInt(); + Model &model = wxGetApp().plater()->model(); + // BBS: replace model custom gcode with current plate custom gcode + model.plates_custom_gcodes[model.curr_plate_index] = + preview->get_canvas3d()->get_gcode_viewer().get_layers_slider()->GetTicksValues(); // BBS set to invalid state only - if (tick_event_type == Type::ToolChange || tick_event_type == Type::Custom || tick_event_type == Type::Template || tick_event_type == Type::PausePrint) { + if (tick_event_type == Type::ToolChange || tick_event_type == Type::Custom || tick_event_type == Type::Template || + tick_event_type == Type::PausePrint) { PartPlate *plate = this->q->get_partplate_list().get_curr_plate(); if (plate) { plate->update_slice_result_valid_state(false); @@ -2586,17 +2757,18 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) }); } if (wxGetApp().is_gcode_viewer()) - preview->Bind(EVT_GLCANVAS_RELOAD_FROM_DISK, [this](SimpleEvent&) { this->q->reload_gcode_from_disk(); }); + preview->Bind(EVT_GLCANVAS_RELOAD_FROM_DISK, [this](SimpleEvent &) { this->q->reload_gcode_from_disk(); }); - //BBS - wxGLCanvas* assemble_canvas = assemble_view->get_wxglcanvas(); + // BBS + wxGLCanvas *assemble_canvas = assemble_view->get_wxglcanvas(); if (wxGetApp().is_editor()) { - assemble_canvas->Bind(EVT_GLTOOLBAR_FILLCOLOR, [q](IntEvent& evt) { q->fill_color(evt.get_data()); }); + assemble_canvas->Bind(EVT_GLTOOLBAR_FILLCOLOR, [q](IntEvent &evt) { q->fill_color(evt.get_data()); }); assemble_canvas->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this); - assemble_canvas->Bind(EVT_GLVIEWTOOLBAR_3D, [q](SimpleEvent&) { q->select_view_3D("3D"); }); + assemble_canvas->Bind(EVT_GLVIEWTOOLBAR_3D, [q](SimpleEvent &) { q->select_view_3D("3D"); }); assemble_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this); - assemble_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); }); - assemble_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); }); + assemble_canvas->Bind(EVT_GLCANVAS_FORCE_UPDATE, [this](SimpleEvent &) { update(); }); + assemble_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent &) { this->undo(); }); + assemble_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent &) { this->redo(); }); } if (wxGetApp().is_editor()) { @@ -2604,9 +2776,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) q->Bind(EVT_PROCESS_COMPLETED, &priv::on_process_completed, this); q->Bind(EVT_EXPORT_BEGAN, &priv::on_export_began, this); q->Bind(EVT_EXPORT_FINISHED, &priv::on_export_finished, this); - q->Bind(EVT_GLVIEWTOOLBAR_3D, [q](SimpleEvent&) { q->select_view_3D("3D"); }); - //BBS: set on_slice to false - q->Bind(EVT_GLVIEWTOOLBAR_PREVIEW, [q](SimpleEvent&) { q->select_view_3D("Preview", false); }); + q->Bind(EVT_GLVIEWTOOLBAR_3D, [q](SimpleEvent &) { q->select_view_3D("3D"); }); + // BBS: set on_slice to false + q->Bind(EVT_GLVIEWTOOLBAR_PREVIEW, [q](SimpleEvent &) { q->select_view_3D("Preview", false); }); q->Bind(EVT_GLTOOLBAR_SLICE_PLATE, &priv::on_action_slice_plate, this); q->Bind(EVT_GLTOOLBAR_SLICE_ALL, &priv::on_action_slice_all, this); q->Bind(EVT_GLTOOLBAR_PRINT_PLATE, &priv::on_action_print_plate, this); @@ -2623,17 +2795,18 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) q->Bind(EVT_DOWNLOAD_PROJECT, &priv::on_action_download_project, this); q->Bind(EVT_IMPORT_MODEL_ID, &priv::on_action_request_model_id, this); q->Bind(EVT_PRINT_FINISHED, [q](wxCommandEvent &evt) { q->print_job_finished(evt); }); - q->Bind(EVT_SEND_CALIBRATION_FINISHED, [q](wxCommandEvent& evt) { q->send_calibration_job_finished(evt); }); + q->Bind(EVT_SEND_CALIBRATION_FINISHED, [q](wxCommandEvent &evt) { q->send_calibration_job_finished(evt); }); q->Bind(EVT_SEND_FINISHED, [q](wxCommandEvent &evt) { q->send_job_finished(evt); }); - q->Bind(EVT_PUBLISH_FINISHED, [q](wxCommandEvent &evt) { q->publish_job_finished(evt);}); - //q->Bind(EVT_GLVIEWTOOLBAR_ASSEMBLE, [q](SimpleEvent&) { q->select_view_3D("Assemble"); }); + q->Bind(EVT_PUBLISH_FINISHED, [q](wxCommandEvent &evt) { q->publish_job_finished(evt); }); + q->Bind(EVT_OPEN_PLATESETTINGSDIALOG, [q](wxCommandEvent &evt) { q->open_platesettings_dialog(evt); }); + // q->Bind(EVT_GLVIEWTOOLBAR_ASSEMBLE, [q](SimpleEvent&) { q->select_view_3D("Assemble"); }); } // Drop target: - q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership + q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership q->Layout(); - set_current_panel(wxGetApp().is_editor() ? static_cast(view3D) : static_cast(preview)); + set_current_panel(wxGetApp().is_editor() ? static_cast(view3D) : static_cast(preview)); // updates camera type from .ini file camera.enable_update_config_on_type_change(true); @@ -2654,59 +2827,61 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // Register an USB HID (Human Interface Device) attach event. evt contains Win32 path to the USB device containing VID, PID and other info. // This event wakes up the Mouse3DController's background thread to enumerate HID devices, if the VID of the callback event // is one of the 3D Mouse vendors (3DConnexion or Logitech). - this->q->Bind(EVT_HID_DEVICE_ATTACHED, [this](HIDDeviceAttachedEvent &evt) { - mouse3d_controller.device_attached(evt.data); - }); - this->q->Bind(EVT_HID_DEVICE_DETACHED, [this](HIDDeviceAttachedEvent& evt) { - mouse3d_controller.device_detached(evt.data); - }); + this->q->Bind(EVT_HID_DEVICE_ATTACHED, [this](HIDDeviceAttachedEvent &evt) { mouse3d_controller.device_attached(evt.data); }); + this->q->Bind(EVT_HID_DEVICE_DETACHED, [this](HIDDeviceAttachedEvent &evt) { mouse3d_controller.device_detached(evt.data); }); #endif /* _WIN32 */ - //notification_manager = new NotificationManager(this->q); + // notification_manager = new NotificationManager(this->q); if (wxGetApp().is_editor()) { - this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent&) { this->q->eject_drive(); }); - this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent&) { this->q->export_gcode(true); }); - this->q->Bind(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, [](PresetUpdateAvailableClickedEvent&) { wxGetApp().get_preset_updater()->on_update_notification_confirm(); }); + this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent &) { this->q->eject_drive(); }); + this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent &) { this->q->export_gcode(true); }); + this->q->Bind(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, + [](PresetUpdateAvailableClickedEvent &) { wxGetApp().get_preset_updater()->on_update_notification_confirm(); }); + this->q->Bind(EVT_PRINTER_CONFIG_UPDATE_AVAILABLE_CLICKED, [](PrinterConfigUpdateAvailableClickedEvent &) { + wxGetApp().get_preset_updater()->do_printer_config_update(); + wxGetApp().getDeviceManager()->reload_printer_settings(); + }); /* BBS do not handle removeable driver event */ this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this](RemovableDriveEjectEvent &evt) { if (evt.data.second) { // BBS - //this->show_action_buttons(this->ready_to_slice); + // this->show_action_buttons(this->ready_to_slice); notification_manager->close_notification_of_type(NotificationType::ExportFinished); - notification_manager->push_notification(NotificationType::CustomNotification, - NotificationManager::NotificationLevel::RegularNotificationLevel, - format(_L("Successfully unmounted. The device %s(%s) can now be safely removed from the computer."), evt.data.first.name, evt.data.first.path) - ); + notification_manager + ->push_notification(NotificationType::CustomNotification, + NotificationManager::NotificationLevel::RegularNotificationLevel, + format(_L("Successfully unmounted. The device %s(%s) can now be safely removed from the computer."), + evt.data.first.name, evt.data.first.path)); } else { notification_manager->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, - format(_L("Ejecting of device %s(%s) has failed."), evt.data.first.name, evt.data.first.path) - ); + format(_L("Ejecting of device %s(%s) has failed."), evt.data.first.name, + evt.data.first.path)); } }); this->q->Bind(EVT_REMOVABLE_DRIVES_CHANGED, [this](RemovableDrivesChangedEvent &) { // BBS - //this->show_action_buttons(this->ready_to_slice); + // this->show_action_buttons(this->ready_to_slice); // Close notification ExportingFinished but only if last export was to removable notification_manager->device_ejected(); }); // Start the background thread and register this window as a target for update events. wxGetApp().removable_drive_manager()->init(this->q); #ifdef _WIN32 - //Trigger enumeration of removable media on Win32 notification. + // Trigger enumeration of removable media on Win32 notification. this->q->Bind(EVT_VOLUME_ATTACHED, [this](VolumeAttachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); }); this->q->Bind(EVT_VOLUME_DETACHED, [this](VolumeDetachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); }); #endif /* _WIN32 */ } // Initialize the Undo / Redo stack with a first snapshot. - //this->take_snapshot("New Project", UndoRedo::SnapshotType::ProjectSeparator); + // this->take_snapshot("New Project", UndoRedo::SnapshotType::ProjectSeparator); // Reset the "dirty project" flag. m_undo_redo_stack_main.mark_current_as_saved(); dirty_state.update_from_undo_redo_stack(false); - //this->take_snapshot("New Project"); - // BBS: save project confirm + // this->take_snapshot("New Project"); + // BBS: save project confirm up_to_date(true, false); up_to_date(true, true); model.set_need_backup(); @@ -2714,11 +2889,13 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // BBS: restore project if (wxGetApp().is_editor()) { auto last_backup = wxGetApp().app_config->get_last_backup_dir(); - this->q->Bind(EVT_RESTORE_PROJECT, [this, last = last_backup](wxCommandEvent& e) { + this->q->Bind(EVT_RESTORE_PROJECT, [this, last = last_backup](wxCommandEvent &e) { std::string last_backup = last; std::string originfile; if (Slic3r::has_restore_data(last_backup, originfile)) { - auto result = MessageDialog(this->q, _L("Previous unsaved project detected, do you want to restore it?"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Restore"), wxYES_NO | wxYES_DEFAULT | wxCENTRE).ShowModal(); + auto result = MessageDialog(this->q, _L("Previous unsaved project detected, do you want to restore it?"), + wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Restore"), wxYES_NO | wxYES_DEFAULT | wxCENTRE) + .ShowModal(); if (result == wxID_YES) { this->q->load_project(from_path(last_backup), from_path(originfile)); Slic3r::backup_soon(); @@ -2728,12 +2905,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) try { if (originfile != "") // see bbs_3mf.cpp for lock detail boost::filesystem::remove_all(last); - } - catch (...) {} + } catch (...) {} int skip_confirm = e.GetInt(); this->q->new_project(skip_confirm, true); - }); - //wxPostEvent(this->q, wxCommandEvent{EVT_RESTORE_PROJECT}); + }); + // wxPostEvent(this->q, wxCommandEvent{EVT_RESTORE_PROJECT}); } /*this->q->Bind(EVT_LOAD_MODEL_OTHER_INSTANCE, [this](LoadFromOtherInstanceEvent& evt) { @@ -2748,10 +2924,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) this->q->Bind(EVT_INSTANCE_GO_TO_FRONT, [this](InstanceGoToFrontEvent &) { bring_instance_forward(); });*/ - //wxGetApp().other_instance_message_handler()->init(this->q); + // wxGetApp().other_instance_message_handler()->init(this->q); // collapse sidebar according to saved value - //if (wxGetApp().is_editor()) { + // if (wxGetApp().is_editor()) { // bool is_collapsed = wxGetApp().app_config->get("collapsed_sidebar") == "1"; // sidebar->collapse(is_collapsed); //} @@ -2774,21 +2950,22 @@ void Plater::priv::update(unsigned int flags) model.center_instances_around_point(this->bed.build_volume().bed_center()); #endif - unsigned int update_status = 0; - const bool force_background_processing_restart = this->printer_technology == ptSLA || (flags & (unsigned int)UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE); + unsigned int update_status = 0; + const bool force_background_processing_restart = this->printer_technology == ptSLA || + (flags & (unsigned int) UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE); if (force_background_processing_restart) // Update the SLAPrint from the current Model, so that the reload_scene() // pulls the correct data. - update_status = this->update_background_process(false, flags & (unsigned int)UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE); - //BBS TODO reload_scene - this->view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH); + update_status = this->update_background_process(false, flags & (unsigned int) UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE); + // BBS TODO reload_scene + this->view3D->reload_scene(false, flags & (unsigned int) UpdateParams::FORCE_FULL_SCREEN_REFRESH); this->preview->reload_print(); - //BBS assemble view + // BBS assemble view this->assemble_view->reload_scene(false, flags); if (current_panel && q->is_preview_shown()) { q->force_update_all_plate_thumbnails(); - //update_fff_scene_only_shells(true); + // update_fff_scene_only_shells(true); } if (force_background_processing_restart) @@ -2796,26 +2973,24 @@ void Plater::priv::update(unsigned int flags) else this->schedule_background_process(); - // BBS + // BBS #if 0 if (get_config("autocenter") == "true" && this->sidebar->obj_manipul()->IsShown()) this->sidebar->obj_manipul()->UpdateAndShow(true); #endif } -void Plater::priv::select_view(const std::string& direction) +void Plater::priv::select_view(const std::string &direction) { if (current_panel == view3D) { - BOOST_LOG_TRIVIAL(info) << "select view3D"; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << "select view3D"; view3D->select_view(direction); wxGetApp().update_ui_from_settings(); - } - else if (current_panel == preview) { + } else if (current_panel == preview) { BOOST_LOG_TRIVIAL(info) << "select preview"; preview->select_view(direction); wxGetApp().update_ui_from_settings(); - } - else if (current_panel == assemble_view) { + } else if (current_panel == assemble_view) { BOOST_LOG_TRIVIAL(info) << "select assemble view"; assemble_view->select_view(direction); } @@ -2825,44 +3000,44 @@ wxColour Plater::get_next_color_for_filament() { static int curr_color_filamenet = 0; // refs to https://www.ebaomonthly.com/window/photo/lesson/colorList.htm - wxColour colors[FILAMENT_SYSTEM_COLORS_NUM] = { - *wxYELLOW, - * wxRED, - *wxBLUE, - *wxCYAN, - *wxLIGHT_GREY, - *wxWHITE, - *wxBLACK, - wxColour(0,127,255), - wxColour(139,0,255), - wxColour(102,255,0), - wxColour(255,215,0), - wxColour(0,35,100), - wxColour(255,0,255), - wxColour(8,37,103), - wxColour(127,255,212), - wxColour(255,191,0) - }; + wxColour colors[FILAMENT_SYSTEM_COLORS_NUM] = {*wxYELLOW, + *wxRED, + *wxBLUE, + *wxCYAN, + *wxLIGHT_GREY, + *wxWHITE, + *wxBLACK, + wxColour(0, 127, 255), + wxColour(139, 0, 255), + wxColour(102, 255, 0), + wxColour(255, 215, 0), + wxColour(0, 35, 100), + wxColour(255, 0, 255), + wxColour(8, 37, 103), + wxColour(127, 255, 212), + wxColour(255, 191, 0)}; return colors[curr_color_filamenet++ % FILAMENT_SYSTEM_COLORS_NUM]; } -wxString Plater::get_slice_warning_string(GCodeProcessorResult::SliceWarning& warning) +wxString Plater::get_slice_warning_string(GCodeProcessorResult::SliceWarning &warning) { if (warning.msg == BED_TEMP_TOO_HIGH_THAN_FILAMENT) { - return _L("The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed enclosure. Please open the front door and/or remove the upper glass."); + return _L("The current hot bed temperature is relatively high. The nozzle may be clogged when printing this filament in a closed " + "enclosure. Please open the front door and/or remove the upper glass."); } else if (warning.msg == NOZZLE_HRC_CHECKER) { - return _L("The nozzle hardness required by the filament is higher than the default nozzle hardness of the printer. Please replace the hardened nozzle or filament, otherwise, the nozzle will be attrited or damaged."); + return _L("The nozzle hardness required by the filament is higher than the default nozzle hardness of the printer. Please replace " + "the hardened nozzle or filament, otherwise, the nozzle will be attrited or damaged."); } else if (warning.msg == NOT_SUPPORT_TRADITIONAL_TIMELAPSE) { - return _L("Enabling traditional timelapse photography may cause surface imperfections. It is recommended to change to smooth mode."); + return _L( + "Enabling traditional timelapse photography may cause surface imperfections. It is recommended to change to smooth mode."); } else if (warning.msg == NOT_GENERATE_TIMELAPSE) { return wxString(); - } - else { + } else { return wxString(warning.msg); } } -void Plater::priv::apply_free_camera_correction(bool apply/* = true*/) +void Plater::priv::apply_free_camera_correction(bool apply /* = true*/) { bool use_perspective_camera = get_config("use_perspective_camera").compare("true") == 0; if (use_perspective_camera) @@ -2873,34 +3048,32 @@ void Plater::priv::apply_free_camera_correction(bool apply/* = true*/) camera.recover_from_free_camera(); } -//BBS: add no slice option -void Plater::priv::select_view_3D(const std::string& name, bool no_slice) +// BBS: add no slice option +void Plater::priv::select_view_3D(const std::string &name, bool no_slice) { if (name == "3D") { - BOOST_LOG_TRIVIAL(info) << "select view3D"; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << "select view3D"; if (q->only_gcode_mode() || q->using_exported_file()) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("goto preview page when loading gcode/exported_3mf"); } set_current_panel(view3D, no_slice); - } - else if (name == "Preview") { + } else if (name == "Preview") { BOOST_LOG_TRIVIAL(info) << "select preview"; - //BBS update extruder params and speed table before slicing - const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config(); - auto& print = q->get_partplate_list().get_current_fff_print(); - auto print_config = print.config(); - int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); + // BBS update extruder params and speed table before slicing + const Slic3r::DynamicPrintConfig &config = wxGetApp().preset_bundle->full_config(); + auto &print = q->get_partplate_list().get_current_fff_print(); + auto print_config = print.config(); + int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); Model::setExtruderParams(config, numExtruders); Model::setPrintSpeedTable(config, print_config); set_current_panel(preview, no_slice); - } - else if (name == "Assemble") { + } else if (name == "Assemble") { BOOST_LOG_TRIVIAL(info) << "select assemble view"; set_current_panel(assemble_view, no_slice); } - //BBS update selection + // BBS update selection wxGetApp().obj_list()->update_selections(); selection_changed(); @@ -2909,13 +3082,12 @@ void Plater::priv::select_view_3D(const std::string& name, bool no_slice) void Plater::priv::select_next_view_3D() { - if (current_panel == view3D) wxGetApp().mainframe->select_tab(size_t(MainFrame::tpPreview)); else if (current_panel == preview) wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); -// else if (current_panel == assemble_view) -// set_current_panel(view3D); + // else if (current_panel == assemble_view) + // set_current_panel(view3D); } void Plater::priv::collapse_sidebar(bool collapse) @@ -2926,11 +3098,7 @@ void Plater::priv::collapse_sidebar(bool collapse) notification_manager->set_sidebar_collapsed(collapse); } - -void Plater::priv::reset_all_gizmos() -{ - view3D->get_canvas3d()->reset_all_gizmos(); -} +void Plater::priv::reset_all_gizmos() { view3D->get_canvas3d()->reset_all_gizmos(); } // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. @@ -2945,15 +3113,9 @@ void Plater::priv::update_ui_from_settings() } // BBS -std::shared_ptr Plater::priv::statusbar() -{ - return nullptr; -} +std::shared_ptr Plater::priv::statusbar() { return nullptr; } -std::string Plater::priv::get_config(const std::string &key) const -{ - return wxGetApp().app_config->get(key); -} +std::string Plater::priv::get_config(const std::string &key) const { return wxGetApp().app_config->get(key); } BoundingBoxf Plater::priv::bed_shape_bb() const { @@ -2963,31 +3125,77 @@ BoundingBoxf Plater::priv::bed_shape_bb() const BoundingBox Plater::priv::scaled_bed_shape_bb() const { - const auto *bed_shape_opt = config->opt("printable_area"); - const auto printable_area = Slic3r::Polygon::new_scale(bed_shape_opt->values); + const auto *bed_shape_opt = config->opt("printable_area"); + const auto printable_area = Slic3r::Polygon::new_scale(bed_shape_opt->values); return printable_area.bounding_box(); } -// BBS: backup & restore -std::vector Plater::priv::load_files(const std::vector& input_files, LoadStrategy strategy, bool ask_multi) +std::string read_binary_stl(const std::string &filename) { - std::vector empty_result; - bool dlg_cont = true; - bool is_user_cancel = false; - bool translate_old = false; - int current_width, current_depth, current_height; + std::string model_id; + std::ifstream file(filename, std::ios::binary); + if (!file) { + return model_id; + } - if (input_files.empty()) { return std::vector(); } - - // SoftFever: ugly fix so we can exist pa calib mode - background_process.fff_print()->calib_mode() = CalibMode::Calib_None; + try { + // Read the first 80 bytes + char data[80]; + file.read(data, 80); + if (!file) { + file.close(); + return model_id; + } + if (data[0] == '\0' || data[0] == ' ') { + file.close(); + return model_id; + } - // BBS - int filaments_cnt = config->opt("filament_colour")->values.size(); - bool one_by_one = input_files.size() == 1 || printer_technology == ptSLA/* || filaments_cnt <= 1*/; - if (! one_by_one) { - for (const auto &path : input_files) { + char magic[2] = {data[0], data[1]}; + if (magic[0] != 'M' || magic[1] != 'W') { + file.close(); + return model_id; + } + + if (data[2] != ' ') { + file.close(); + return model_id; + } + + char protocol_version[3] = {data[3], data[4], data[5]}; + + // version + if (protocol_version[0] == '1' && protocol_version[1] == '.' && protocol_version[2] == '0') { + model_id = std::string(&data[7], &data[80]); + } + + file.close(); + } catch (...) {} + return model_id; +} + +// BBS: backup & restore +std::vector Plater::priv::load_files(const std::vector &input_files, LoadStrategy strategy, bool ask_multi) +{ + std::vector empty_result; + bool dlg_cont = true; + bool is_user_cancel = false; + bool translate_old = false; + int current_width, current_depth, current_height; + + if (input_files.empty()) { + return std::vector(); + } + + // SoftFever: ugly fix so we can exist pa calib mode + background_process.fff_print()->calib_mode() = CalibMode::Calib_None; + + // BBS + int filaments_cnt = config->opt("filament_colour")->values.size(); + bool one_by_one = input_files.size() == 1 || printer_technology == ptSLA /* || filaments_cnt <= 1*/; + if (!one_by_one) { + for (const auto &path : input_files) { if (std::regex_match(path.string(), pattern_bundle)) { one_by_one = true; break; @@ -2995,72 +3203,74 @@ std::vector Plater::priv::load_files(const std::vector& input_ } } - bool load_model = strategy & LoadStrategy::LoadModel; - bool load_config = strategy & LoadStrategy::LoadConfig; + bool load_model = strategy & LoadStrategy::LoadModel; + bool load_config = strategy & LoadStrategy::LoadConfig; bool imperial_units = strategy & LoadStrategy::ImperialUnits; - bool silence = strategy & LoadStrategy::Silence; + bool silence = strategy & LoadStrategy::Silence; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": load_model %1%, load_config %2%, input_files size %3%")%load_model %load_config %input_files.size(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": load_model %1%, load_config %2%, input_files size %3%") % load_model % load_config % + input_files.size(); - const auto loading = _L("Loading") + dots; + const auto loading = _L("Loading") + dots; ProgressDialog dlg(loading, "", 100, find_toplevel_parent(q), wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_APP_MODAL); - wxBusyCursor busy; + wxBusyCursor busy; - auto *new_model = (!load_model || one_by_one) ? nullptr : new Slic3r::Model(); + auto *new_model = (!load_model || one_by_one) ? nullptr : new Slic3r::Model(); std::vector obj_idxs; - int answer_convert_from_meters = wxOK_DEFAULT; - int answer_convert_from_imperial_units = wxOK_DEFAULT; - int tolal_model_count = 0; - - int progress_percent = 0; - int total_files = input_files.size(); - const int stage_percent[IMPORT_STAGE_MAX+1] = { - 5, // IMPORT_STAGE_RESTORE - 10, // IMPORT_STAGE_OPEN - 30, // IMPORT_STAGE_READ_FILES - 50, // IMPORT_STAGE_EXTRACT - 60, // IMPORT_STAGE_LOADING_OBJECTS - 70, // IMPORT_STAGE_LOADING_PLATES - 80, // IMPORT_STAGE_FINISH - 85, // IMPORT_STAGE_ADD_INSTANCE - 90, // IMPORT_STAGE_UPDATE_GCODE - 92, // IMPORT_STAGE_CHECK_MODE_GCODE - 95, // UPDATE_GCODE_RESULT - 98, // IMPORT_LOAD_CONFIG - 99, // IMPORT_LOAD_MODEL_OBJECTS - 100 - }; - const int step_percent[LOAD_STEP_STAGE_NUM+1] = { - 5, // LOAD_STEP_STAGE_READ_FILE - 30, // LOAD_STEP_STAGE_GET_SOLID - 60, // LOAD_STEP_STAGE_GET_MESH - 100 - }; - - const float INPUT_FILES_RATIO = 0.7; - const float INIT_MODEL_RATIO = 0.75; - const float CENTER_AROUND_ORIGIN_RATIO = 0.8; - const float LOAD_MODEL_RATIO = 0.9; + std::string designer_model_id; + + int answer_convert_from_meters = wxOK_DEFAULT; + int answer_convert_from_imperial_units = wxOK_DEFAULT; + int tolal_model_count = 0; + + int progress_percent = 0; + int total_files = input_files.size(); + const int stage_percent[IMPORT_STAGE_MAX + 1] = {5, // IMPORT_STAGE_RESTORE + 10, // IMPORT_STAGE_OPEN + 30, // IMPORT_STAGE_READ_FILES + 50, // IMPORT_STAGE_EXTRACT + 60, // IMPORT_STAGE_LOADING_OBJECTS + 70, // IMPORT_STAGE_LOADING_PLATES + 80, // IMPORT_STAGE_FINISH + 85, // IMPORT_STAGE_ADD_INSTANCE + 90, // IMPORT_STAGE_UPDATE_GCODE + 92, // IMPORT_STAGE_CHECK_MODE_GCODE + 95, // UPDATE_GCODE_RESULT + 98, // IMPORT_LOAD_CONFIG + 99, // IMPORT_LOAD_MODEL_OBJECTS + 100}; + const int step_percent[LOAD_STEP_STAGE_NUM + 1] = {5, // LOAD_STEP_STAGE_READ_FILE + 30, // LOAD_STEP_STAGE_GET_SOLID + 60, // LOAD_STEP_STAGE_GET_MESH + 100}; + + const float INPUT_FILES_RATIO = 0.7; + const float INIT_MODEL_RATIO = 0.75; + const float CENTER_AROUND_ORIGIN_RATIO = 0.8; + const float LOAD_MODEL_RATIO = 0.9; for (size_t i = 0; i < input_files.size(); ++i) { int file_percent = 0; #ifdef _WIN32 auto path = input_files[i]; - // On Windows, we swap slashes to back slashes, see GH #6803 as read_from_file() does not understand slashes on Windows thus it assignes full path to names of loaded objects. + // On Windows, we swap slashes to back slashes, see GH #6803 as read_from_file() does not understand slashes on Windows thus it + // assignes full path to names of loaded objects. path.make_preferred(); #else // _WIN32 // Don't make a copy on Posix. Slash is a path separator, back slashes are not accepted as a substitute. const auto &path = input_files[i]; #endif // _WIN32 const auto filename = path.filename(); - int progress_percent = static_cast(100.0f * static_cast(i) / static_cast(input_files.size())); + int progress_percent = static_cast(100.0f * static_cast(i) / static_cast(input_files.size())); const auto real_filename = (strategy & LoadStrategy::Restore) ? input_files[++i].filename() : filename; const auto dlg_info = _L("Loading file") + ": " + from_path(real_filename); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": load file %1%") % filename; dlg_cont = dlg.Update(progress_percent, dlg_info); - if (!dlg_cont) return empty_result; + if (!dlg_cont) + return empty_result; const bool type_3mf = std::regex_match(path.string(), pattern_3mf); // const bool type_zip_amf = !type_3mf && std::regex_match(path.string(), pattern_zip_amf); @@ -3074,7 +3284,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ load_aux = true; strategy = strategy | LoadStrategy::LoadAuxiliary; } - if (load_config) strategy = strategy | LoadStrategy::CheckVersion; + if (load_config) + strategy = strategy | LoadStrategy::CheckVersion; bool is_project_file = false; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": is_project_file %1%, type_3mf %2%") % is_project_file % type_3mf; try { @@ -3091,33 +3302,51 @@ std::vector Plater::priv::load_files(const std::vector& input_ std::vector project_presets; // BBS: backup & restore q->skip_thumbnail_invalid = true; - model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, &config_substitutions, en_3mf_file_type, strategy, &plate_data, &project_presets, - &file_version, - [this, &dlg, real_filename, &progress_percent, &file_percent, stage_percent, INPUT_FILES_RATIO, total_files, i, + model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, &config_substitutions, en_3mf_file_type, + strategy, &plate_data, &project_presets, &file_version, + [this, &dlg, real_filename, &progress_percent, &file_percent, stage_percent, + INPUT_FILES_RATIO, total_files, i, &is_user_cancel](int import_stage, int current, int total, bool &cancel) { - bool cont = true; - float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * ((float)stage_percent[import_stage] + (float)current * (float)(stage_percent[import_stage + 1] - stage_percent[import_stage]) /(float) total) / (float)total_files; - BOOST_LOG_TRIVIAL(trace) << "load_3mf_file: percent(float)=" << percent_float << ", stage = " << import_stage << ", curr = " << current << ", total = " << total; - progress_percent = (int)percent_float; - wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename)); - cont = dlg.Update(progress_percent, msg); - cancel = !cont; + bool cont = true; + float percent_float = (100.0f * (float) i / (float) total_files) + + INPUT_FILES_RATIO * + ((float) stage_percent[import_stage] + + (float) current * + (float) (stage_percent[import_stage + 1] - + stage_percent[import_stage]) / + (float) total) / + (float) total_files; + BOOST_LOG_TRIVIAL(trace) + << "load_3mf_file: percent(float)=" << percent_float + << ", stage = " << import_stage << ", curr = " << current + << ", total = " << total; + progress_percent = (int) percent_float; + wxString msg = wxString::Format(_L("Loading file: %s"), + from_path(real_filename)); + cont = dlg.Update(progress_percent, msg); + cancel = !cont; if (cancel) is_user_cancel = cancel; }); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ - << boost::format(", plate_data.size %1%, project_preset.size %2%, is_bbs_3mf %3%, file_version %4% \n") % plate_data.size() % - project_presets.size() % (en_3mf_file_type == En3mfType::From_BBS) % file_version.to_string(); + << boost::format( + ", plate_data.size %1%, project_preset.size %2%, is_bbs_3mf %3%, file_version %4% \n") % + plate_data.size() % project_presets.size() % (en_3mf_file_type == En3mfType::From_BBS) % + file_version.to_string(); // 1. add extruder for prusa model if the number of existing extruders is not enough // 2. add extruder for BBS or Other model if only import geometry if (en_3mf_file_type == En3mfType::From_Prusa || (load_model && !load_config)) { std::set extruderIds; for (ModelObject *o : model.objects) { - if (o->config.option("extruder")) extruderIds.insert(o->config.extruder()); + if (o->config.option("extruder")) + extruderIds.insert(o->config.extruder()); for (auto volume : o->volumes) { - if (volume->config.option("extruder")) extruderIds.insert(volume->config.extruder()); - for (int extruder : volume->get_extruders()) { extruderIds.insert(extruder); } + if (volume->config.option("extruder")) + extruderIds.insert(volume->config.extruder()); + for (int extruder : volume->get_extruders()) { + extruderIds.insert(extruder); + } } } int size = extruderIds.size() == 0 ? 0 : *(extruderIds.rbegin()); @@ -3135,21 +3364,20 @@ std::vector Plater::priv::load_files(const std::vector& input_ } std::string import_project_action = wxGetApp().app_config->get("import_project_action"); - LoadType load_type; + LoadType load_type; if (import_project_action.empty()) load_type = LoadType::Unknown; else - load_type = static_cast(std::stoi(import_project_action)); + load_type = static_cast(std::stoi(import_project_action)); // BBS: version check Semver app_version = *(Semver::parse(SLIC3R_VERSION)); if (en_3mf_file_type == En3mfType::From_Prusa) { // do not reset the model config load_config = false; - if(load_type != LoadType::LoadGeometry) + if (load_type != LoadType::LoadGeometry) show_info(q, _L("The 3mf is not supported by OrcaSlicer, load geometry data only."), _L("Load 3mf")); - } - else if (load_config && (file_version.maj() != app_version.maj())) { + } else if (load_config && (file_version.maj() != app_version.maj())) { // version mismatch, only load geometries load_config = false; if (!load_model) { @@ -3172,58 +3400,72 @@ std::vector Plater::priv::load_files(const std::vector& input_ for (ModelObject *model_object : model.objects) { model_object->config.reset(); // Is there any modifier or advanced config data? - for (ModelVolume *model_volume : model_object->volumes) model_volume->config.reset(); - } - } else if (load_config && (file_version > app_version)) { - if (config_substitutions.unrecogized_keys.size() > 0) { - wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, Found following keys unrecognized:"), - file_version.to_string(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string()); - text += "\n"; - bool first = true; - // std::string context = into_u8(text); - wxString context = text; - for (auto &key : config_substitutions.unrecogized_keys) { - context += " -"; - context += key; - context += ";\n"; - first = false; - } - wxString append = _L("You'd better upgrade your software.\n"); - context += "\n\n"; - // context += into_u8(append); - context += append; - show_info(q, context, _L("Newer 3mf version")); - } - else { - //if the minor version is not matched - if (file_version.min() != app_version.min()) { - wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your software."), - file_version.to_string(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string()); - text += "\n"; - show_info(q, text, _L("Newer 3mf version")); - } + for (ModelVolume *model_volume : model_object->volumes) + model_volume->config.reset(); } - } else if (!load_config) { + } + // else if (load_config && (file_version > app_version)) { + // if (config_substitutions.unrecogized_keys.size() > 0) { + // wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, Found following + // keys unrecognized:"), + // file_version.to_string(), std::string(SLIC3R_APP_FULL_NAME), + // app_version.to_string()); + // text += "\n"; + // bool first = true; + // // std::string context = into_u8(text); + // wxString context = text; + // for (auto &key : config_substitutions.unrecogized_keys) { + // context += " -"; + // context += key; + // context += ";\n"; + // first = false; + // } + // wxString append = _L("You'd better upgrade your software.\n"); + // context += "\n\n"; + // // context += into_u8(append); + // context += append; + // show_info(q, context, _L("Newer 3mf version")); + // } + // else { + // //if the minor version is not matched + // if (file_version.min() != app_version.min()) { + // wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, Suggest to + // upgrade your software."), + // file_version.to_string(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string()); + // text += "\n"; + // show_info(q, text, _L("Newer 3mf version")); + // } + // } + // } + else if (!load_config) { // reset config except color for (ModelObject *model_object : model.objects) { bool has_extruder = model_object->config.has("extruder"); int extruder_id = -1; // save the extruder information before reset - if (has_extruder) { extruder_id = model_object->config.extruder(); } + if (has_extruder) { + extruder_id = model_object->config.extruder(); + } model_object->config.reset(); // restore the extruder after reset - if (has_extruder) { model_object->config.set("extruder", extruder_id); } + if (has_extruder) { + model_object->config.set("extruder", extruder_id); + } // Is there any modifier or advanced config data? for (ModelVolume *model_volume : model_object->volumes) { has_extruder = model_volume->config.has("extruder"); - if (has_extruder) { extruder_id = model_volume->config.extruder(); } + if (has_extruder) { + extruder_id = model_volume->config.extruder(); + } model_volume->config.reset(); - if (has_extruder) { model_volume->config.set("extruder", extruder_id); } + if (has_extruder) { + model_volume->config.set("extruder", extruder_id); + } } } } @@ -3239,15 +3481,17 @@ std::vector Plater::priv::load_files(const std::vector& input_ } Semver old_version(1, 5, 9); - if ((en_3mf_file_type == En3mfType::From_BBS) && (file_version < old_version) && load_model && load_config && !config_loaded.empty()) { + if ((en_3mf_file_type == En3mfType::From_BBS) && (file_version < old_version) && load_model && load_config && + !config_loaded.empty()) { translate_old = true; partplate_list.get_plate_size(current_width, current_depth, current_height); } if (load_config) { if (translate_old) { - //set the size back - partplate_list.reset_size(current_width + Bed3D::Axes::DefaultTipRadius, current_depth + Bed3D::Axes::DefaultTipRadius, current_height, false); + // set the size back + partplate_list.reset_size(current_width + Bed3D::Axes::DefaultTipRadius, + current_depth + Bed3D::Axes::DefaultTipRadius, current_height, false); } partplate_list.load_from_3mf_structure(plate_data); partplate_list.update_slice_context_to_current_plate(background_process); @@ -3263,12 +3507,16 @@ std::vector Plater::priv::load_files(const std::vector& input_ if ((project_presets.size() > 0) && load_config) { // load project embedded presets PresetsConfigSubstitutions preset_substitutions; - PresetBundle & preset_bundle = *wxGetApp().preset_bundle; - preset_substitutions = preset_bundle.load_project_embedded_presets(project_presets, ForwardCompatibilitySubstitutionRule::Enable); - if (!preset_substitutions.empty()) show_substitutions_info(preset_substitutions); + PresetBundle &preset_bundle = *wxGetApp().preset_bundle; + preset_substitutions = preset_bundle.load_project_embedded_presets(project_presets, + ForwardCompatibilitySubstitutionRule::Enable); + if (!preset_substitutions.empty()) + show_substitutions_info(preset_substitutions); } if (project_presets.size() > 0) { - for (unsigned int i = 0; i < project_presets.size(); i++) { delete project_presets[i]; } + for (unsigned int i = 0; i < project_presets.size(); i++) { + delete project_presets[i]; + } project_presets.clear(); } @@ -3290,29 +3538,30 @@ std::vector Plater::priv::load_files(const std::vector& input_ std::map validity = config.validate(); if (!validity.empty()) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("Param values in 3mf error: "); - for (std::map::iterator it=validity.begin(); it!=validity.end(); ++it) - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("%1%: %2%")%it->first %it->second; + for (std::map::iterator it = validity.begin(); it != validity.end(); ++it) + BOOST_LOG_TRIVIAL(info) + << __FUNCTION__ << ":" << __LINE__ << boost::format("%1%: %2%") % it->first % it->second; // NotificationManager *notify_manager = q->get_notification_manager(); - std::string error_message = L("Invalid values found in the 3mf:"); + std::string error_message = L("Invalid values found in the 3mf:"); error_message += "\n"; - for (std::map::iterator it=validity.begin(); it!=validity.end(); ++it) + for (std::map::iterator it = validity.begin(); it != validity.end(); ++it) error_message += "-" + it->first + ": " + it->second + "\n"; error_message += "\n"; error_message += L("Please correct them in the param tabs"); notify_manager->bbl_show_3mf_warn_notification(error_message); } } - if (!config_substitutions.empty()) show_substitutions_info(config_substitutions.substitutions, filename.string()); + if (!config_substitutions.empty()) + show_substitutions_info(config_substitutions.substitutions, filename.string()); // BBS if (load_model && !load_config) { ; - } - else { + } else { this->model.plates_custom_gcodes = model.plates_custom_gcodes; - this->model.design_info = model.design_info; - this->model.model_info = model.model_info; + this->model.design_info = model.design_info; + this->model.model_info = model.model_info; } } @@ -3320,32 +3569,66 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (!config.empty()) { Preset::normalize(config); PresetBundle *preset_bundle = wxGetApp().preset_bundle; - // BBS: first validate the printer - // TODO: remove it after released"" - bool validated = preset_bundle->validate_printers(filename.string(), config); - if (!validated) { - load_config = false; - load_old_project = true; - // select view to 3D - q->select_view_3D("3D"); - // select plate 0 as default - q->select_plate(0); - show_info(q, _L("The 3mf is not compatible, load geometry data only!"), _L("Incompatible 3mf")); - for (ModelObject *model_object : model.objects) { - model_object->config.reset(); - // Is there any modifier or advanced config data? - for (ModelVolume *model_volume : model_object->volumes) model_volume->config.reset(); + + auto choise = wxGetApp().app_config->get("no_warn_when_modified_gcodes"); + if (choise.empty() || choise != "true") { + // BBS: first validate the printer + // validate the system profiles + std::set modified_gcodes; + int validated = preset_bundle->validate_presets(filename.string(), config, modified_gcodes); + if (validated == VALIDATE_PRESETS_MODIFIED_GCODES) { + std::string warning_message; + warning_message += "\n"; + for (std::set::iterator it = modified_gcodes.begin(); it != modified_gcodes.end(); ++it) + warning_message += "-" + *it + "\n"; + warning_message += "\n"; + // show_info(q, _L("The 3mf has following modified G-codes in filament or printer presets:") + + // warning_message+ _L("Please confirm that these modified G-codes are safe to prevent any damage to the + // machine!"), _L("Modified G-codes")); + + MessageDialog + dlg(q, + _L("The 3mf has following modified G-codes in filament or printer presets:") + warning_message + + _L("Please confirm that these modified G-codes are safe to prevent any damage to the machine!"), + _L("Modified G-codes")); + dlg.show_dsa_button(); + auto res = dlg.ShowModal(); + if (dlg.get_checkbox_state()) + wxGetApp().app_config->set("no_warn_when_modified_gcodes", "true"); + } else if ((validated == VALIDATE_PRESETS_PRINTER_NOT_FOUND) || + (validated == VALIDATE_PRESETS_FILAMENTS_NOT_FOUND)) { + std::string warning_message; + warning_message += "\n"; + for (std::set::iterator it = modified_gcodes.begin(); it != modified_gcodes.end(); ++it) + warning_message += "-" + *it + "\n"; + warning_message += "\n"; + // show_info(q, _L("The 3mf has following customized filament or printer presets:") + warning_message + + // _L("Please confirm that the G-codes within these presets are safe to prevent any damage to the + // machine!"), _L("Customized Preset")); + MessageDialog dlg(q, + _L("The 3mf has following customized filament or printer presets:") + + from_u8(warning_message) + + _L("Please confirm that the G-codes within these presets are safe to prevent any " + "damage to the machine!"), + _L("Customized Preset")); + dlg.show_dsa_button(); + auto res = dlg.ShowModal(); + if (dlg.get_checkbox_state()) + wxGetApp().app_config->set("no_warn_when_modified_gcodes", "true"); } - } else { + } + + // always load config + { preset_bundle->load_config_model(filename.string(), std::move(config), file_version); - ConfigOption* bed_type_opt = preset_bundle->project_config.option("curr_bed_type"); + ConfigOption *bed_type_opt = preset_bundle->project_config.option("curr_bed_type"); if (bed_type_opt != nullptr) { - BedType bed_type = (BedType)bed_type_opt->getInt(); + BedType bed_type = (BedType) bed_type_opt->getInt(); // update app config for bed type bool is_bbl_preset = preset_bundle->is_bbl_vendor(); if (is_bbl_preset) { - AppConfig* app_config = wxGetApp().app_config; + AppConfig *app_config = wxGetApp().app_config; if (app_config) app_config->set("curr_bed_type", std::to_string(int(bed_type))); } @@ -3389,9 +3672,10 @@ std::vector Plater::priv::load_files(const std::vector& input_ // // show notification about temporarily installed presets // if (!names.empty()) { - // std::string notif_text = into_u8(_L_PLURAL("The preset below was temporarily installed on the active instance of PrusaSlicer", - // "The presets below were temporarily installed on the active instance of PrusaSlicer", - // names.size())) + ":"; + // std::string notif_text = into_u8(_L_PLURAL("The preset below was temporarily installed on the active + // instance of PrusaSlicer", + // "The presets below were temporarily installed on the active + // instance of PrusaSlicer", names.size())) + ":"; // for (std::string& name : names) // notif_text += "\n - " + name; // notification_manager->push_notification(NotificationType::CustomNotification, @@ -3401,11 +3685,11 @@ std::vector Plater::priv::load_files(const std::vector& input_ // BBS // if (printer_technology == ptFFF) - // CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, &preset_bundle->project_config); + // CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, + // &preset_bundle->project_config); - // For exporting from the amf/3mf we shouldn't check printer_presets for the containing information about "Print Host upload" - // BBS: add preset combo box re-active logic - // currently found only needs re-active here + // For exporting from the amf/3mf we shouldn't check printer_presets for the containing information about "Print + // Host upload" BBS: add preset combo box re-active logic currently found only needs re-active here wxGetApp().load_current_presets(false, false); // Update filament colors for the MM-printer profile in the full config // to avoid black (default) colors for Extruders in the ObjectList, @@ -3414,7 +3698,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ is_project_file = true; } } - if (!silence) wxGetApp().app_config->update_config_dir(path.parent_path().string()); + if (!silence) + wxGetApp().app_config->update_config_dir(path.parent_path().string()); } } else { // BBS: add plate data related logic @@ -3423,38 +3708,56 @@ std::vector Plater::priv::load_files(const std::vector& input_ std::vector project_presets; bool is_xxx; Semver file_version; + model = Slic3r::Model::read_from_file( path.string(), nullptr, nullptr, strategy, &plate_data, &project_presets, &is_xxx, &file_version, nullptr, - [this, &dlg, real_filename, &progress_percent, &file_percent, INPUT_FILES_RATIO, total_files, i](int current, int total, bool &cancel) - { - bool cont = true; - float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * 100.0f * ((float)current / (float)total) / (float)total_files; - BOOST_LOG_TRIVIAL(trace) << "load_stl_file: percent(float)=" << percent_float << ", curr = " << current << ", total = " << total; - progress_percent = (int)percent_float; - wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename)); - cont = dlg.Update(progress_percent, msg); - cancel = !cont; - }, - [this, &dlg, real_filename, &progress_percent, &file_percent, step_percent, INPUT_FILES_RATIO, total_files, i](int load_stage, int current, int total, bool &cancel) - { - bool cont = true; - float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * ((float)step_percent[load_stage] + (float)current * (float)(step_percent[load_stage + 1] - step_percent[load_stage]) / (float)total) / (float)total_files; - BOOST_LOG_TRIVIAL(trace) << "load_step_file: percent(float)=" << percent_float << ", stage = " << load_stage << ", curr = " << current << ", total = " << total; - progress_percent = (int)percent_float; - wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename)); - cont = dlg.Update(progress_percent, msg); - cancel = !cont; + [this, &dlg, real_filename, &progress_percent, &file_percent, INPUT_FILES_RATIO, total_files, i, + &designer_model_id](int current, int total, bool &cancel, std::string &mode_id) { + designer_model_id = mode_id; + bool cont = true; + float percent_float = (100.0f * (float) i / (float) total_files) + + INPUT_FILES_RATIO * 100.0f * ((float) current / (float) total) / (float) total_files; + BOOST_LOG_TRIVIAL(trace) + << "load_stl_file: percent(float)=" << percent_float << ", curr = " << current << ", total = " << total; + progress_percent = (int) percent_float; + wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename)); + cont = dlg.Update(progress_percent, msg); + cancel = !cont; + }, + [this, &dlg, real_filename, &progress_percent, &file_percent, step_percent, INPUT_FILES_RATIO, total_files, + i](int load_stage, int current, int total, bool &cancel) { + bool cont = true; + float percent_float = (100.0f * (float) i / (float) total_files) + + INPUT_FILES_RATIO * + ((float) step_percent[load_stage] + + (float) current * (float) (step_percent[load_stage + 1] - step_percent[load_stage]) / + (float) total) / + (float) total_files; + BOOST_LOG_TRIVIAL(trace) << "load_step_file: percent(float)=" << percent_float << ", stage = " << load_stage + << ", curr = " << current << ", total = " << total; + progress_percent = (int) percent_float; + wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename)); + cont = dlg.Update(progress_percent, msg); + cancel = !cont; }, [](int isUtf8StepFile) { if (!isUtf8StepFile) - Slic3r::GUI::show_info(nullptr, _L("Name of components inside step file is not UTF8 format!") + "\n\n" + _L("The name may show garbage characters!"), + Slic3r::GUI::show_info(nullptr, + _L("Name of components inside step file is not UTF8 format!") + "\n\n" + + _L("The name may show garbage characters!"), _L("Attention!")); }); - if (type_any_amf && is_xxx) imperial_units = true; + if (designer_model_id.empty() && boost::algorithm::iends_with(path.string(), ".stl")) { + designer_model_id = read_binary_stl(path.string()); + } + + if (type_any_amf && is_xxx) + imperial_units = true; for (auto obj : model.objects) - if (obj->name.empty()) obj->name = fs::path(obj->input_file).filename().string(); + if (obj->name.empty()) + obj->name = fs::path(obj->input_file).filename().string(); if (plate_data.size() > 0) { partplate_list.load_from_3mf_structure(plate_data); @@ -3468,16 +3771,21 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (project_presets.size() > 0) { // load project embedded presets PresetsConfigSubstitutions preset_substitutions; - PresetBundle & preset_bundle = *wxGetApp().preset_bundle; - preset_substitutions = preset_bundle.load_project_embedded_presets(project_presets, ForwardCompatibilitySubstitutionRule::Enable); - if (!preset_substitutions.empty()) show_substitutions_info(preset_substitutions); - - for (unsigned int i = 0; i < project_presets.size(); i++) { delete project_presets[i]; } + PresetBundle &preset_bundle = *wxGetApp().preset_bundle; + preset_substitutions = preset_bundle.load_project_embedded_presets(project_presets, + ForwardCompatibilitySubstitutionRule::Enable); + if (!preset_substitutions.empty()) + show_substitutions_info(preset_substitutions); + + for (unsigned int i = 0; i < project_presets.size(); i++) { + delete project_presets[i]; + } project_presets.clear(); } } } catch (const ConfigurationError &e) { - std::string message = GUI::format(_L("Failed loading file \"%1%\". An invalid configuration was found."), filename.string()) + "\n\n" + e.what(); + std::string message = GUI::format(_L("Failed loading file \"%1%\". An invalid configuration was found."), filename.string()) + + "\n\n" + e.what(); GUI::show_error(q, message); continue; } catch (const std::exception &e) { @@ -3486,8 +3794,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ continue; } - progress_percent = 100.0f * (float)i / (float)total_files + INIT_MODEL_RATIO * 100.0f / (float)total_files; - dlg_cont = dlg.Update(progress_percent); + progress_percent = 100.0f * (float) i / (float) total_files + INIT_MODEL_RATIO * 100.0f / (float) total_files; + dlg_cont = dlg.Update(progress_percent); if (!dlg_cont) { q->skip_thumbnail_invalid = false; return empty_result; @@ -3495,13 +3803,17 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (load_model) { // The model should now be initialized - auto convert_from_imperial_units = [](Model &model, bool only_small_volumes) { model.convert_from_imperial_units(only_small_volumes); }; + auto convert_from_imperial_units = [](Model &model, bool only_small_volumes) { + model.convert_from_imperial_units(only_small_volumes); + }; // BBS: add load_old_project logic if ((!is_project_file) && (!load_old_project)) { // if (!is_project_file) { if (int deleted_objects = model.removed_objects_with_zero_volume(); deleted_objects > 0) { - MessageDialog(q, _L("Objects with zero volume removed"), _L("The volume of the object is zero"), wxICON_INFORMATION | wxOK).ShowModal(); + MessageDialog(q, _L("Objects with zero volume removed"), _L("The volume of the object is zero"), + wxICON_INFORMATION | wxOK) + .ShowModal(); } if (imperial_units) // Convert even if the object is big. @@ -3509,19 +3821,23 @@ std::vector Plater::priv::load_files(const std::vector& input_ else if (model.looks_like_saved_in_meters()) { // BBS do not handle look like in meters MessageDialog dlg(q, - format_wxstr(_L("The object from file %s is too small, and maybe in meters or inches.\n Do you want to scale to millimeters?"), + format_wxstr(_L("The object from file %s is too small, and maybe in meters or inches.\n Do you want " + "to scale to millimeters?"), from_path(filename)), _L("Object too small"), wxICON_QUESTION | wxYES_NO); int answer = dlg.ShowModal(); - if (answer == wxID_YES) model.convert_from_meters(true); + if (answer == wxID_YES) + model.convert_from_meters(true); } else if (model.looks_like_imperial_units()) { // BBS do not handle look like in meters MessageDialog dlg(q, - format_wxstr(_L("The object from file %s is too small, and maybe in meters or inches.\n Do you want to scale to millimeters?"), + format_wxstr(_L("The object from file %s is too small, and maybe in meters or inches.\n Do you want " + "to scale to millimeters?"), from_path(filename)), _L("Object too small"), wxICON_QUESTION | wxYES_NO); int answer = dlg.ShowModal(); - if (answer == wxID_YES) convert_from_imperial_units(model, true); + if (answer == wxID_YES) + convert_from_imperial_units(model, true); } // else if (model.looks_like_imperial_units()) { // BBS do not handle look like in imperial @@ -3535,7 +3851,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ // "The dimensions of the object from file %s seem to be defined in inches.\n" // "The internal unit of PrusaSlicer is a millimeter. Do you want to recalculate the dimensions of the object?", // "The dimensions of some objects from file %s seem to be defined in inches.\n" - // "The internal unit of PrusaSlicer is a millimeter. Do you want to recalculate the dimensions of these objects?", model.objects.size()), from_path(filename)) + // "The internal unit of PrusaSlicer is a millimeter. Do you want to recalculate the dimensions of these objects?", + // model.objects.size()), from_path(filename)) // + "\n", _L("The object is too small"), wxICON_QUESTION | wxYES_NO); // dlg.ShowCheckBox(_L("Apply to all the remaining small objects being loaded.")); // int answer = dlg.ShowModal(); @@ -3547,12 +3864,13 @@ std::vector Plater::priv::load_files(const std::vector& input_ // convert_model_if(model, answer_convert_from_imperial_units == wxID_YES); } - if (!is_project_file && model.looks_like_multipart_object()) { - MessageDialog msg_dlg(q, _L( - "This file contains several objects positioned at multiple heights.\n" - "Instead of considering them as multiple objects, should \n" - "the file be loaded as a single object having multiple parts?") + "\n", - _L("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO); + if (!is_project_file && model.looks_like_multipart_object()) { + MessageDialog msg_dlg(q, + _L("This file contains several objects positioned at multiple heights.\n" + "Instead of considering them as multiple objects, should \n" + "the file be loaded as a single object having multiple parts?") + + "\n", + _L("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO); if (msg_dlg.ShowModal() == wxID_YES) { model.convert_multipart_object(filaments_cnt); } @@ -3569,8 +3887,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ // return obj_idxs; //} - progress_percent = 100.0f * (float)i / (float)total_files + CENTER_AROUND_ORIGIN_RATIO * 100.0f / (float)total_files; - dlg_cont = dlg.Update(progress_percent); + progress_percent = 100.0f * (float) i / (float) total_files + CENTER_AROUND_ORIGIN_RATIO * 100.0f / (float) total_files; + dlg_cont = dlg.Update(progress_percent); if (!dlg_cont) { q->skip_thumbnail_invalid = false; return empty_result; @@ -3578,7 +3896,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ int model_idx = 0; for (ModelObject *model_object : model.objects) { - if (!type_3mf && !type_any_amf) model_object->center_around_origin(false); + if (!type_3mf && !type_any_amf) + model_object->center_around_origin(false); // BBS BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_LOAD_MODEL_OBJECTS \n"); @@ -3595,8 +3914,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ tolal_model_count += model_idx; - progress_percent = 100.0f * (float)i / (float)total_files + LOAD_MODEL_RATIO * 100.0f / (float)total_files; - dlg_cont = dlg.Update(progress_percent); + progress_percent = 100.0f * (float) i / (float) total_files + LOAD_MODEL_RATIO * 100.0f / (float) total_files; + dlg_cont = dlg.Update(progress_percent); if (!dlg_cont) { q->skip_thumbnail_invalid = false; return empty_result; @@ -3640,26 +3959,29 @@ std::vector Plater::priv::load_files(const std::vector& input_ } if (new_model != nullptr && new_model->objects.size() > 1) { - //BBS do not popup this dialog + // BBS do not popup this dialog if (ask_multi) { - MessageDialog msg_dlg(q, _L("Load these files as a single object with multiple parts?\n"), _L("Object with multiple parts was detected"), - wxICON_WARNING | wxYES | wxNO); - if (msg_dlg.ShowModal() == wxID_YES) { new_model->convert_multipart_object(filaments_cnt); } + MessageDialog msg_dlg(q, _L("Load these files as a single object with multiple parts?\n"), + _L("Object with multiple parts was detected"), wxICON_WARNING | wxYES | wxNO); + if (msg_dlg.ShowModal() == wxID_YES) { + new_model->convert_multipart_object(filaments_cnt); + } } auto loaded_idxs = load_model_objects(new_model->objects); obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end()); } - if (new_model) delete new_model; + if (new_model) + delete new_model; - //BBS: translate old 3mf to correct positions + // BBS: translate old 3mf to correct positions if (translate_old) { - //translate the objects + // translate the objects int plate_count = partplate_list.get_plate_count(); - for (int index = 1; index < plate_count; index ++) { - PartPlate* cur_plate = (PartPlate *)partplate_list.get_plate(index); + for (int index = 1; index < plate_count; index++) { + PartPlate *cur_plate = (PartPlate *) partplate_list.get_plate(index); Vec3d cur_origin = cur_plate->get_origin(); Vec3d new_origin = partplate_list.compute_origin_using_new_size(index, current_width, current_depth); @@ -3669,56 +3991,53 @@ std::vector Plater::priv::load_files(const std::vector& input_ partplate_list.reset_size(current_width, current_depth, current_height, true, true); } - //BBS: add gcode loading logic in the end - q->m_exported_file = false; + // BBS: add gcode loading logic in the end + q->m_exported_file = false; q->skip_thumbnail_invalid = false; if (load_model && load_config) { if (model.objects.empty()) { partplate_list.load_gcode_files(); - PartPlate * first_plate = nullptr, *cur_plate = nullptr; - int plate_cnt = partplate_list.get_plate_count(); - int index = 0, first_plate_index = 0; + PartPlate *first_plate = nullptr, *cur_plate = nullptr; + int plate_cnt = partplate_list.get_plate_count(); + int index = 0, first_plate_index = 0; q->m_valid_plates_count = 0; - for (index = 0; index < plate_cnt; index ++) - { + for (index = 0; index < plate_cnt; index++) { cur_plate = partplate_list.get_plate(index); if (!first_plate && cur_plate->is_slice_result_valid()) { - first_plate = cur_plate; + first_plate = cur_plate; first_plate_index = index; } if (cur_plate->is_slice_result_valid()) - q->m_valid_plates_count ++; + q->m_valid_plates_count++; } - if (first_plate&&first_plate->is_slice_result_valid()) { + if (first_plate && first_plate->is_slice_result_valid()) { q->m_exported_file = true; - //select plate 0 as default + // select plate 0 as default q->select_plate(first_plate_index); - //set to 3d tab + // set to 3d tab q->select_view_3D("Preview"); wxGetApp().mainframe->select_tab(MainFrame::tpPreview); - } - else { - //set to 3d tab + } else { + // set to 3d tab q->select_view_3D("3D"); - //select plate 0 as default + // select plate 0 as default q->select_plate(0); } - } - else { - //set to 3d tab + } else { + // set to 3d tab q->select_view_3D("3D"); - //select plate 0 as default + // select plate 0 as default q->select_plate(0); } - } - else { - //always set to 3D after loading files + } else { + // always set to 3D after loading files q->select_view_3D("3D"); wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor); } if (load_model) { - if (!silence) wxGetApp().app_config->update_skein_dir(input_files[input_files.size() - 1].parent_path().make_preferred().string()); + if (!silence) + wxGetApp().app_config->update_skein_dir(input_files[input_files.size() - 1].parent_path().make_preferred().string()); // XXX: Plater.pm had @loaded_files, but didn't seem to fill them with the filenames... } @@ -3728,10 +4047,10 @@ std::vector Plater::priv::load_files(const std::vector& input_ wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs); if (!load_config) { - Selection& selection = view3D->get_canvas3d()->get_selection(); + Selection &selection = view3D->get_canvas3d()->get_selection(); selection.clear(); for (size_t idx : obj_idxs) { - selection.add_object((unsigned int)idx, false); + selection.add_object((unsigned int) idx, false); } } // BBS: update object list selection @@ -3742,32 +4061,36 @@ std::vector Plater::priv::load_files(const std::vector& input_ view3D->get_canvas3d()->update_gizmos_on_off_state(); } - GLGizmoSimplify::add_simplify_suggestion_notification( - obj_idxs, model.objects, *notification_manager); + GLGizmoSimplify::add_simplify_suggestion_notification(obj_idxs, model.objects, *notification_manager); + // set designer_model_id + if (!designer_model_id.empty() && q->model().stl_design_id.empty()) { + q->model().stl_design_id = designer_model_id; + } if (tolal_model_count <= 0 && !q->m_exported_file) { dlg.Hide(); if (!is_user_cancel) { - MessageDialog msg(wxGetApp().mainframe, _L("The file does not contain any geometry data."), _L("Warning"), wxYES | wxICON_WARNING); + MessageDialog msg(wxGetApp().mainframe, _L("The file does not contain any geometry data."), _L("Warning"), + wxYES | wxICON_WARNING); if (msg.ShowModal() == wxID_YES) {} } } return obj_idxs; } - #define AUTOPLACEMENT_ON_LOAD +#define AUTOPLACEMENT_ON_LOAD -std::vector Plater::priv::load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z, bool split_object) +std::vector Plater::priv::load_model_objects(const ModelObjectPtrs &model_objects, bool allow_negative_z, bool split_object) { const Vec3d bed_size = Slic3r::to_3d(this->bed.build_volume().bounding_volume2d().size(), 1.0) - 2.0 * Vec3d::Ones(); #ifndef AUTOPLACEMENT_ON_LOAD // bool need_arrange = false; #endif /* AUTOPLACEMENT_ON_LOAD */ - bool scaled_down = false; + bool scaled_down = false; std::vector obj_idxs; - unsigned int obj_count = model.objects.size(); + unsigned int obj_count = model.objects.size(); #ifdef AUTOPLACEMENT_ON_LOAD ModelInstancePtrs new_instances; @@ -3782,29 +4105,30 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs& mode #ifdef AUTOPLACEMENT_ON_LOAD object->center_around_origin(); new_instances.emplace_back(object->add_instance()); -#else /* AUTOPLACEMENT_ON_LOAD */ +#else /* AUTOPLACEMENT_ON_LOAD */ // if object has no defined position(s) we need to rearrange everything after loading // need_arrange = true; - // add a default instance and center object around origin - object->center_around_origin(); // also aligns object to Z = 0 - ModelInstance* instance = object->add_instance(); + // add a default instance and center object around origin + object->center_around_origin(); // also aligns object to Z = 0 + ModelInstance *instance = object->add_instance(); - //BBS calc transformation + // BBS calc transformation Geometry::Transformation t = instance->get_transformation(); instance->set_offset(Slic3r::to_3d(this->bed.build_volume().bed_center(), -object->origin_translation(2))); #endif /* AUTOPLACEMENT_ON_LOAD */ } - //BBS: when the object is too large, let the user choose whether to scale it down + // BBS: when the object is too large, let the user choose whether to scale it down for (size_t i = 0; i < object->instances.size(); ++i) { - ModelInstance* instance = object->instances[i]; - const Vec3d size = object->instance_bounding_box(i).size(); - const Vec3d ratio = size.cwiseQuotient(bed_size); - const double max_ratio = std::max(ratio(0), ratio(1)); + ModelInstance *instance = object->instances[i]; + const Vec3d size = object->instance_bounding_box(i).size(); + const Vec3d ratio = size.cwiseQuotient(bed_size); + const double max_ratio = std::max(ratio(0), ratio(1)); if (max_ratio > 10000) { - MessageDialog dlg(q, _L("Your object appears to be too large, Do you want to scale it down to fit the heat bed automatically?"), _L("Object too large"), - wxICON_QUESTION | wxYES); - int answer = dlg.ShowModal(); + MessageDialog + dlg(q, _L("Your object appears to be too large, Do you want to scale it down to fit the heat bed automatically?"), + _L("Object too large"), wxICON_QUESTION | wxYES); + int answer = dlg.ShowModal(); // the size of the object is too big -> this could lead to overflow when moving to clipper coordinates, // so scale down the mesh object->scale_mesh_after_creation(1. / max_ratio); @@ -3812,11 +4136,11 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs& mode object->center_around_origin(); scaled_down = true; break; - } - else if (max_ratio > 10) { - MessageDialog dlg(q, _L("Your object appears to be too large, Do you want to scale it down to fit the heat bed automatically?"), _L("Object too large"), - wxICON_QUESTION | wxYES_NO); - int answer = dlg.ShowModal(); + } else if (max_ratio > 10) { + MessageDialog + dlg(q, _L("Your object appears to be too large, Do you want to scale it down to fit the heat bed automatically?"), + _L("Object too large"), wxICON_QUESTION | wxYES_NO); + int answer = dlg.ShowModal(); if (answer == wxID_YES) { instance->set_scaling_factor(instance->get_scaling_factor() / max_ratio); scaled_down = true; @@ -3826,9 +4150,9 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs& mode object->ensure_on_bed(allow_negative_z); if (!split_object) { - //BBS initial assemble transformation - for (ModelObject* model_object : model.objects) { - //BBS initialize assemble transformation + // BBS initial assemble transformation + for (ModelObject *model_object : model.objects) { + // BBS initialize assemble transformation for (int i = 0; i < model_object->instances.size(); i++) { if (!model_object->instances[i]->is_assemble_initialized()) { model_object->instances[i]->set_assemble_transformation(model_object->instances[i]->get_transformation()); @@ -3858,10 +4182,10 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs& mode view3D->get_canvas3d()->arrange_wipe_tower(wti); #else // BBS: find an empty cell to put the copied object - for (auto& instance : new_instances) { - auto offset = instance->get_offset(); - auto start_point = this->bed.build_volume().bounding_volume2d().center(); - bool plate_empty = partplate_list.get_curr_plate()->empty(); + for (auto &instance : new_instances) { + auto offset = instance->get_offset(); + auto start_point = this->bed.build_volume().bounding_volume2d().center(); + bool plate_empty = partplate_list.get_curr_plate()->empty(); Vec3d displacement; if (plate_empty) displacement = {start_point(0), start_point(1), offset(2)}; @@ -3875,12 +4199,12 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs& mode #endif /* AUTOPLACEMENT_ON_LOAD */ - //BBS: remove the auto scaled_down logic when load models - //if (scaled_down) { - // GUI::show_info(q, - // _L("Your object appears to be too large, so it was automatically scaled down to fit your print bed."), - // _L("Object too large?")); - //} + // BBS: remove the auto scaled_down logic when load models + // if (scaled_down) { + // GUI::show_info(q, + // _L("Your object appears to be too large, so it was automatically scaled down to fit your print bed."), + // _L("Object too large?")); + // } notification_manager->close_notification_of_type(NotificationType::UpdatedItemsInfo); wxGetApp().obj_list()->add_objects_to_list(obj_idxs); @@ -3902,7 +4226,7 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs& mode void Plater::priv::load_auxiliary_files() { std::string auxiliary_path = encode_path(q->model().get_auxiliary_file_temp_path().c_str()); - //wxGetApp().mainframe->m_project->Reload(auxiliary_path); + // wxGetApp().mainframe->m_project->Reload(auxiliary_path); } fs::path Plater::priv::get_export_file_path(GUI::FileType file_type) @@ -3910,25 +4234,24 @@ fs::path Plater::priv::get_export_file_path(GUI::FileType file_type) // Update printbility state of each of the ModelInstances. this->update_print_volume_state(); - const Selection& selection = get_selection(); - int obj_idx = selection.get_object_idx(); + const Selection &selection = get_selection(); + int obj_idx = selection.get_object_idx(); fs::path output_file; if (file_type == FT_3MF) // for 3mf take the path from the project filename, if any output_file = into_path(get_project_filename(".3mf")); - //bbs name the project using the part name + // bbs name the project using the part name if (output_file.empty()) { if (get_project_name() != _L("Untitled")) { output_file = into_path(get_project_name() + ".3mf"); } } - if (output_file.empty()) - { + if (output_file.empty()) { // first try to get the file name from the current selection - if ((0 <= obj_idx) && (obj_idx < (int)this->model.objects.size())) + if ((0 <= obj_idx) && (obj_idx < (int) this->model.objects.size())) output_file = this->model.objects[obj_idx]->get_export_filename(); if (output_file.empty()) @@ -3950,55 +4273,47 @@ wxString Plater::priv::get_export_file(GUI::FileType file_type) { wxString wildcard; switch (file_type) { - case FT_STL: - case FT_AMF: - case FT_3MF: - case FT_GCODE: - case FT_OBJ: - wildcard = file_wildcards(file_type); - break; - default: - wildcard = file_wildcards(FT_MODEL); - break; + case FT_STL: + case FT_AMF: + case FT_3MF: + case FT_GCODE: + case FT_OBJ: wildcard = file_wildcards(file_type); break; + default: wildcard = file_wildcards(FT_MODEL); break; } fs::path output_file = get_export_file_path(file_type); wxString dlg_title; switch (file_type) { - case FT_STL: - { - output_file.replace_extension("stl"); - dlg_title = _L("Export STL file:"); - break; - } - case FT_AMF: - { - // XXX: Problem on OS X with double extension? - output_file.replace_extension("zip.amf"); - dlg_title = _L("Export AMF file:"); - break; - } - case FT_3MF: - { - output_file.replace_extension("3mf"); - dlg_title = _L("Save file as:"); - break; - } - case FT_OBJ: - { - output_file.replace_extension("obj"); - dlg_title = _L("Export OBJ file:"); - break; - } - default: break; + case FT_STL: { + output_file.replace_extension("stl"); + dlg_title = _L("Export STL file:"); + break; + } + case FT_AMF: { + // XXX: Problem on OS X with double extension? + output_file.replace_extension("zip.amf"); + dlg_title = _L("Export AMF file:"); + break; + } + case FT_3MF: { + output_file.replace_extension("3mf"); + dlg_title = _L("Save file as:"); + break; + } + case FT_OBJ: { + output_file.replace_extension("obj"); + dlg_title = _L("Export OBJ file:"); + break; + } + default: break; } std::string out_dir = (boost::filesystem::path(output_file).parent_path()).string(); wxFileDialog dlg(q, dlg_title, - is_shapes_dir(out_dir) ? from_u8(wxGetApp().app_config->get_last_dir()) : from_path(output_file.parent_path()), from_path(output_file.filename()), - wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxPD_APP_MODAL); + is_shapes_dir(out_dir) ? from_u8(wxGetApp().app_config->get_last_dir()) : from_path(output_file.parent_path()), + from_path(output_file.filename()), wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxPD_APP_MODAL); int result = dlg.ShowModal(); if (result == wxID_CANCEL) @@ -4008,25 +4323,29 @@ wxString Plater::priv::get_export_file(GUI::FileType file_type) wxString out_path = dlg.GetPath(); fs::path path(into_path(out_path)); +#ifdef __WXMSW__ + if (path.extension() != output_file.extension()) { + out_path += output_file.extension().string(); + boost::system::error_code ec; + if (boost::filesystem::exists(into_u8(out_path), ec)) { + auto result = MessageBox(q->GetHandle(), + wxString::Format(_L("The file %s already exists\nDo you want to replace it?"), out_path), + _L("Comfirm Save As"), MB_YESNO | MB_ICONWARNING); + if (result != IDYES) + return wxEmptyString; + } + } +#endif wxGetApp().app_config->update_last_output_dir(path.parent_path().string()); return out_path; } -const Selection& Plater::priv::get_selection() const -{ - return view3D->get_canvas3d()->get_selection(); -} +const Selection &Plater::priv::get_selection() const { return view3D->get_canvas3d()->get_selection(); } -Selection& Plater::priv::get_selection() -{ - return view3D->get_canvas3d()->get_selection(); -} +Selection &Plater::priv::get_selection() { return view3D->get_canvas3d()->get_selection(); } -Selection& Plater::priv::get_curr_selection() -{ - return get_current_canvas3D()->get_selection(); -} +Selection &Plater::priv::get_curr_selection() { return get_current_canvas3D()->get_selection(); } int Plater::priv::get_selected_object_idx() const { @@ -4036,11 +4355,11 @@ int Plater::priv::get_selected_object_idx() const int Plater::priv::get_selected_volume_idx() const { - auto& selection = get_selection(); - int idx = selection.get_object_idx(); + auto &selection = get_selection(); + int idx = selection.get_object_idx(); if ((0 > idx) || (idx > 1000)) - return-1; - const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin()); + return -1; + const GLVolume *v = selection.get_first_volume(); if (model.objects[idx]->volumes.size() > 1) return v->volume_idx(); return -1; @@ -4062,15 +4381,17 @@ void Plater::priv::object_list_changed() { const bool export_in_progress = this->background_process.is_export_scheduled(); // || ! send_gcode_file.empty()); // XXX: is this right? - //const bool model_fits = view3D->get_canvas3d()->check_volumes_outside_state() == ModelInstancePVS_Inside; + // const bool model_fits = view3D->get_canvas3d()->check_volumes_outside_state() == ModelInstancePVS_Inside; const bool model_fits = view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; - PartPlate* part_plate = partplate_list.get_curr_plate(); + PartPlate *part_plate = partplate_list.get_curr_plate(); // BBS - //sidebar->enable_buttons(!model.objects.empty() && !export_in_progress && model_fits && part_plate->has_printable_instances()); + // sidebar->enable_buttons(!model.objects.empty() && !export_in_progress && model_fits && part_plate->has_printable_instances()); bool can_slice = !model.objects.empty() && !export_in_progress && model_fits && part_plate->has_printable_instances(); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": can_slice %1%, model_fits= %2%, export_in_progress %3%, has_printable_instances %4% ")%can_slice %model_fits %export_in_progress %part_plate->has_printable_instances(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": can_slice %1%, model_fits= %2%, export_in_progress %3%, has_printable_instances %4% ") % + can_slice % model_fits % export_in_progress % part_plate->has_printable_instances(); main_frame->update_slice_print_status(MainFrame::eEventObjectUpdate, can_slice); wxGetApp().params_panel()->notify_object_config_changed(); @@ -4095,10 +4416,7 @@ void Plater::priv::select_all() this->sidebar->obj_list()->update_selections(); } -void Plater::priv::deselect_all() -{ - view3D->deselect_all(); -} +void Plater::priv::deselect_all() { view3D->deselect_all(); } void Plater::priv::remove(size_t obj_idx) { @@ -4107,7 +4425,7 @@ void Plater::priv::remove(size_t obj_idx) m_ui_jobs.cancel_all(); model.delete_object(obj_idx); - //BBS: notify partplate the instance removed + // BBS: notify partplate the instance removed partplate_list.notify_instance_removed(obj_idx, -1); update(); // Delete object from Sidebar list. Do it after update, so that the GLScene selection is updated with the modified model. @@ -4115,7 +4433,6 @@ void Plater::priv::remove(size_t obj_idx) object_list_changed(); } - bool Plater::priv::delete_object_from_model(size_t obj_idx, bool refresh_immediately) { // check if object isn't cut @@ -4142,10 +4459,10 @@ bool Plater::priv::delete_object_from_model(size_t obj_idx, bool refresh_immedia sidebar->obj_list()->invalidate_cut_info_for_object(obj_idx); model.delete_object(obj_idx); - //BBS: notify partplate the instance removed + // BBS: notify partplate the instance removed partplate_list.notify_instance_removed(obj_idx, -1); - //BBS + // BBS if (refresh_immediately) { update(); object_list_changed(); @@ -4171,7 +4488,7 @@ void Plater::priv::delete_all_objects_from_model() // Stop and reset the Print content. background_process.reset(); - //BBS: update partplate + // BBS: update partplate partplate_list.clear(); model.clear_objects(); @@ -4180,7 +4497,7 @@ void Plater::priv::delete_all_objects_from_model() sidebar->obj_list()->delete_all_objects_from_list(); object_list_changed(); - //BBS + // BBS model.calib_pa_pattern.reset(); model.plates_custom_gcodes.clear(); } @@ -4192,22 +4509,23 @@ void Plater::priv::reset(bool apply_presets_change) clear_warnings(); set_project_filename(""); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " call set_project_filename: empty"; if (view3D->is_layers_editing_enabled()) view3D->get_canvas3d()->force_main_toolbar_left_action(view3D->get_canvas3d()->get_main_toolbar_item_id("layersediting")); view3D->get_canvas3d()->reset_all_gizmos(); reset_gcode_toolpaths(); - //BBS: update gcode to current partplate's - //GCodeProcessorResult* current_result = this->background_process.get_current_plate()->get_slice_result(); - //current_result->reset(); - //gcode_result.reset(); + // BBS: update gcode to current partplate's + // GCodeProcessorResult* current_result = this->background_process.get_current_plate()->get_slice_result(); + // current_result->reset(); + // gcode_result.reset(); view3D->get_canvas3d()->reset_sequential_print_clearance(); m_ui_jobs.cancel_all(); - //BBS: clear the partplate list's object before object cleared + // BBS: clear the partplate list's object before object cleared partplate_list.reinit(); partplate_list.update_slice_context_to_current_plate(background_process); preview->update_gcode_result(partplate_list.get_current_slice_result()); @@ -4218,7 +4536,7 @@ void Plater::priv::reset(bool apply_presets_change) assemble_view->get_canvas3d()->reset_explosion_ratio(); update(); - //BBS + // BBS if (wxGetApp().is_editor()) { // Delete object from Sidebar list. Do it after update, so that the GLScene selection is updated with the modified model. sidebar->obj_list()->delete_all_objects_from_list(); @@ -4227,14 +4545,14 @@ void Plater::priv::reset(bool apply_presets_change) project.reset(); - //BBS: reset all project embedded presets + // BBS: reset all project embedded presets wxGetApp().preset_bundle->reset_project_embedded_presets(); if (apply_presets_change) wxGetApp().apply_keeped_preset_modifications(); else wxGetApp().load_current_presets(false, false); - //BBS + // BBS model.calib_pa_pattern.reset(); model.plates_custom_gcodes.clear(); @@ -4242,24 +4560,18 @@ void Plater::priv::reset(bool apply_presets_change) m_saved_timestamp = m_backup_timestamp = size_t(-1); } -void Plater::priv::center_selection() -{ - view3D->center_selected(); -} +void Plater::priv::center_selection() { view3D->center_selected(); } -void Plater::priv::mirror(Axis axis) -{ - view3D->mirror_selection(axis); -} +void Plater::priv::mirror(Axis axis) { view3D->mirror_selection(axis); } void Plater::find_new_position(const ModelInstancePtrs &instances) { arrangement::ArrangePolygons movable, fixed; - arrangement::ArrangeParams arr_params = init_arrange_params(this); + arrangement::ArrangeParams arr_params = init_arrange_params(this); for (const ModelObject *mo : p->model.objects) for (ModelInstance *inst : mo->instances) { - auto it = std::find(instances.begin(), instances.end(), inst); + auto it = std::find(instances.begin(), instances.end(), inst); arrangement::ArrangePolygon arrpoly; inst->get_arrange_polygon(&arrpoly); @@ -4281,7 +4593,7 @@ void Plater::find_new_position(const ModelInstancePtrs &instances) arrangement::arrange(movable, fixed, this->build_volume().polygon(), arr_params); - for (auto & m : movable) + for (auto &m : movable) m.apply(); } @@ -4293,20 +4605,19 @@ void Plater::priv::split_object() // we clone model object because split_object() adds the split volumes // into the same model object, thus causing duplicates when we call load_model_objects() - Model new_model = model; - ModelObject* current_model_object = new_model.objects[obj_idx]; + Model new_model = model; + ModelObject *current_model_object = new_model.objects[obj_idx]; - wxBusyCursor wait; + wxBusyCursor wait; ModelObjectPtrs new_objects; current_model_object->split(&new_objects); if (new_objects.size() == 1) // #ysFIXME use notification Slic3r::GUI::warning_catcher(q, _L("The selected object couldn't be split.")); - else - { + else { // BBS no solid parts removed // If we splited object which is contain some parts/modifiers then all non-solid parts (modifiers) were deleted - //if (current_model_object->volumes.size() > 1 && current_model_object->volumes.size() != new_objects.size()) + // if (current_model_object->volumes.size() > 1 && current_model_object->volumes.size() != new_objects.size()) // notification_manager->push_notification(NotificationType::CustomNotification, // NotificationManager::NotificationLevel::PrintInfoNotificationLevel, // _u8L("All non-solid parts (modifiers) were deleted")); @@ -4317,21 +4628,17 @@ void Plater::priv::split_object() // load all model objects at once, otherwise the plate would be rearranged after each one // causing original positions not to be kept - //BBS: set split_object to true to avoid re-compute assemble matrix + // BBS: set split_object to true to avoid re-compute assemble matrix std::vector idxs = load_model_objects(new_objects, false, true); // select newly added objects - for (size_t idx : idxs) - { - get_selection().add_object((unsigned int)idx, false); + for (size_t idx : idxs) { + get_selection().add_object((unsigned int) idx, false); } } } -void Plater::priv::split_volume() -{ - wxGetApp().obj_list()->split(); -} +void Plater::priv::split_volume() { wxGetApp().obj_list()->split(); } void Plater::priv::scale_selection_to_fit_print_volume() { @@ -4353,8 +4660,8 @@ void Plater::priv::schedule_background_process() void Plater::priv::update_print_volume_state() { - //BBS: use the plate's bounding box instead of the bed's - PartPlate* pp = partplate_list.get_curr_plate(); + // BBS: use the plate's bounding box instead of the bed's + PartPlate *pp = partplate_list.get_curr_plate(); BuildVolume build_volume(pp->get_shape(), this->bed.build_volume().printable_height()); this->model.update_print_volume_state(build_volume); } @@ -4364,29 +4671,34 @@ void Plater::priv::process_validation_warning(StringObjectException const &warni if (warning.string.empty()) notification_manager->close_notification_of_type(NotificationType::ValidateWarning); else { - std::string text = warning.string; - auto po = dynamic_cast(warning.object); - auto mo = po ? po->model_object() : dynamic_cast(warning.object); - auto action_fn = (mo || !warning.opt_key.empty()) ? [id = mo ? mo->id() : 0, opt = warning.opt_key](wxEvtHandler *) { - auto & objects = wxGetApp().model().objects; - auto iter = id.id ? std::find_if(objects.begin(), objects.end(), [id](auto o) { return o->id() == id; }) : objects.end(); - if (iter != objects.end()) { - wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor); - wxGetApp().obj_list()->select_items({{*iter, nullptr}}); - } - if (!opt.empty()) { - if (iter != objects.end()) - wxGetApp().params_panel()->switch_to_object(); - wxGetApp().sidebar().jump_to_option(opt, Preset::TYPE_PRINT, L""); - } - return false; - } : std::function(); - auto hypertext = (mo || !warning.opt_key.empty()) ? _u8L("Jump to") : ""; - if (mo) hypertext += std::string(" [") + mo->name + "]"; - if (!warning.opt_key.empty()) hypertext += std::string(" (") + warning.opt_key + ")"; + std::string text = warning.string; + auto po = dynamic_cast(warning.object); + auto mo = po ? po->model_object() : dynamic_cast(warning.object); + auto action_fn = (mo || !warning.opt_key.empty()) ? + [id = mo ? mo->id() : 0, opt = warning.opt_key](wxEvtHandler *) { + auto &objects = wxGetApp().model().objects; + auto iter = id.id ? std::find_if(objects.begin(), objects.end(), [id](auto o) { return o->id() == id; }) : + objects.end(); + if (iter != objects.end()) { + wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor); + wxGetApp().obj_list()->select_items({{*iter, nullptr}}); + } + if (!opt.empty()) { + if (iter != objects.end()) + wxGetApp().params_panel()->switch_to_object(); + wxGetApp().sidebar().jump_to_option(opt, Preset::TYPE_PRINT, L""); + } + return false; + } : + std::function(); + auto hypertext = (mo || !warning.opt_key.empty()) ? _u8L("Jump to") : ""; + if (mo) + hypertext += std::string(" [") + mo->name + "]"; + if (!warning.opt_key.empty()) + hypertext += std::string(" (") + warning.opt_key + ")"; // BBS disable support enforcer - //if (text == "_SUPPORTS_OFF") { + // if (text == "_SUPPORTS_OFF") { // text = _u8L("An object has custom support enforcers which will not be used " // "because supports are disabled.")+"\n"; // hypertext = _u8L("Enable supports for enforcers only"); @@ -4403,15 +4715,12 @@ void Plater::priv::process_validation_warning(StringObjectException const &warni // }; //} - notification_manager->push_notification( - NotificationType::ValidateWarning, - NotificationManager::NotificationLevel::WarningNotificationLevel, - _u8L("WARNING:") + "\n" + text, hypertext, action_fn - ); + notification_manager->push_notification(NotificationType::ValidateWarning, + NotificationManager::NotificationLevel::WarningNotificationLevel, + _u8L("WARNING:") + "\n" + text, hypertext, action_fn); } } - // Update background processing thread from the current config and Model. // Returns a bitmask of UpdateBackgroundProcessReturnState. unsigned int Plater::priv::update_background_process(bool force_validation, bool postpone_error_messages, bool switch_print) @@ -4425,14 +4734,16 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool // Update the "out of print bed" state of ModelInstances. update_print_volume_state(); // Apply new config to the possibly running background task. - bool was_running = background_process.running(); - //BBS: add the switch print logic before Print::Apply - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": enter, force_validation=%1% postpone_error_messages=%2%, switch_print=%3%, was_running=%4%")%force_validation %postpone_error_messages %switch_print %was_running; - if (switch_print) - { + bool was_running = background_process.running(); + // BBS: add the switch print logic before Print::Apply + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format( + ": enter, force_validation=%1% postpone_error_messages=%2%, switch_print=%3%, was_running=%4%") % + force_validation % postpone_error_messages % switch_print % was_running; + if (switch_print) { // Update the "out of print bed" state of ModelInstances. this->update_print_volume_state(); - //BBS: update the current print to the current plate + // BBS: update the current print to the current plate this->partplate_list.update_slice_context_to_current_plate(background_process); this->preview->update_gcode_result(partplate_list.get_current_slice_result()); } @@ -4442,19 +4753,19 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool // BBS: add only gcode mode q->set_only_gcode(false); - //BBS: add slicing related logs - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": background process apply result=%1%")%invalidated; + // BBS: add slicing related logs + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": background process apply result=%1%") % invalidated; if (background_process.empty()) view3D->get_canvas3d()->reset_sequential_print_clearance(); if (invalidated == Print::APPLY_STATUS_INVALIDATED) { - //BBS: update current plater's slicer result to invalid + // BBS: update current plater's slicer result to invalid this->background_process.get_current_plate()->update_slice_result_valid_state(false); - //no need, should be done in background_process.apply - //this->background_process.get_current_gcode_result()->reset(); - // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. - // Otherwise they will be just refreshed. + // no need, should be done in background_process.apply + // this->background_process.get_current_gcode_result()->reset(); + // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. + // Otherwise they will be just refreshed. if (preview != nullptr) { // If the preview is not visible, the following line just invalidates the preview, // but the G-code paths or SLA preview are calculated first once the preview is made visible. @@ -4469,20 +4780,20 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool notification_manager->set_slicing_progress_hidden(); } - if ((invalidated != Print::APPLY_STATUS_UNCHANGED || force_validation) && ! background_process.empty()) { + if ((invalidated != Print::APPLY_STATUS_UNCHANGED || force_validation) && !background_process.empty()) { // The delayed error message is no more valid. delayed_error_message.clear(); // The state of the Print changed, and it is non-zero. Let's validate it and give the user feedback on errors. - //BBS: add is_warning logic + // BBS: add is_warning logic StringObjectException warning; - //BBS: refine seq-print logic - Polygons polygons; + // BBS: refine seq-print logic + Polygons polygons; std::vector> height_polygons; - StringObjectException err = background_process.validate(&warning, &polygons, &height_polygons); + StringObjectException err = background_process.validate(&warning, &polygons, &height_polygons); // update string by type q->post_process_string_object_exception(err); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": validate err=%1%, warning=%2%")%err.string%warning.string; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": validate err=%1%, warning=%2%") % err.string % warning.string; if (err.string.empty()) { this->partplate_list.get_curr_plate()->update_apply_result_invalid(false); @@ -4499,92 +4810,88 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool view3D->get_canvas3d()->set_as_dirty(); view3D->get_canvas3d()->request_extra_frame(); } - } - else { + } else { this->partplate_list.get_curr_plate()->update_apply_result_invalid(true); // The print is not valid. // Show error as notification. notification_manager->push_validate_error_notification(err); - //also update the warnings + // also update the warnings process_validation_warning(warning); return_state |= UPDATE_BACKGROUND_PROCESS_INVALID; if (printer_technology == ptFFF) { - const Print* print = background_process.fff_print(); - //Polygons polygons; - //if (print->config().print_sequence == PrintSequence::ByObject) - // Print::sequential_print_clearance_valid(*print, &polygons); + const Print *print = background_process.fff_print(); + // Polygons polygons; + // if (print->config().print_sequence == PrintSequence::ByObject) + // Print::sequential_print_clearance_valid(*print, &polygons); view3D->get_canvas3d()->set_sequential_print_clearance_visible(true); view3D->get_canvas3d()->set_sequential_print_clearance_render_fill(true); view3D->get_canvas3d()->set_sequential_print_clearance_polygons(polygons, height_polygons); } } - } - else if (! this->delayed_error_message.empty()) { + } else if (!this->delayed_error_message.empty()) { // Reusing the old state. return_state |= UPDATE_BACKGROUND_PROCESS_INVALID; } - //actualizate warnings + // actualizate warnings if (invalidated != Print::APPLY_STATUS_UNCHANGED || background_process.empty()) { if (background_process.empty()) process_validation_warning({}); actualize_slicing_warnings(*this->background_process.current_print()); actualize_object_warnings(*this->background_process.current_print()); - show_warning_dialog = false; + show_warning_dialog = false; process_completed_with_error = -1; } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: was_running = %2%, running %3%, invalidated=%4%, return_state=%5%, internal_cancel=%6%") - % __LINE__ % was_running % this->background_process.running() % invalidated % return_state % this->background_process.is_internal_cancelled(); - if (was_running && ! this->background_process.running() && (return_state & UPDATE_BACKGROUND_PROCESS_RESTART) == 0) { - if (invalidated != Print::APPLY_STATUS_UNCHANGED || this->background_process.is_internal_cancelled()) - { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format( + ", Line %1%: was_running = %2%, running %3%, invalidated=%4%, return_state=%5%, internal_cancel=%6%") % + __LINE__ % was_running % this->background_process.running() % invalidated % return_state % + this->background_process.is_internal_cancelled(); + if (was_running && !this->background_process.running() && (return_state & UPDATE_BACKGROUND_PROCESS_RESTART) == 0) { + if (invalidated != Print::APPLY_STATUS_UNCHANGED || this->background_process.is_internal_cancelled()) { // The background processing was killed and it will not be restarted. // Post the "canceled" callback message, so that it will be processed after any possible pending status bar update messages. - SlicingProcessCompletedEvent evt(EVT_PROCESS_COMPLETED, 0, - SlicingProcessCompletedEvent::Cancelled, nullptr); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%, post an EVT_PROCESS_COMPLETED to main, status %2%")%__LINE__ %evt.status(); + SlicingProcessCompletedEvent evt(EVT_PROCESS_COMPLETED, 0, SlicingProcessCompletedEvent::Cancelled, nullptr); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(" %1%, post an EVT_PROCESS_COMPLETED to main, status %2%") % __LINE__ % evt.status(); wxQueueEvent(q, evt.Clone()); } } - if ((return_state & UPDATE_BACKGROUND_PROCESS_INVALID) != 0) - { + if ((return_state & UPDATE_BACKGROUND_PROCESS_INVALID) != 0) { // Validation of the background data failed. - //BBS: add slice&&print status update logic + // BBS: add slice&&print status update logic this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, false); process_completed_with_error = partplate_list.get_curr_plate_index(); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: set to process_completed_with_error, return_state=%2%")%__LINE__%return_state; - } - else - { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(", Line %1%: set to process_completed_with_error, return_state=%2%") % __LINE__ % + return_state; + } else { // Background data is valid. - if ((return_state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 || - (return_state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0 ) + if ((return_state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 || (return_state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0) notification_manager->set_slicing_progress_hidden(); - //BBS: add slice&&print status update logic - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: background data valid, return_state=%2%")%__LINE__%return_state; - PartPlate* cur_plate = background_process.get_current_plate(); - if (background_process.finished() && cur_plate && cur_plate->is_slice_result_valid()) - { - //ready_to_slice = false; + // BBS: add slice&&print status update logic + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(", Line %1%: background data valid, return_state=%2%") % __LINE__ % return_state; + PartPlate *cur_plate = background_process.get_current_plate(); + if (background_process.finished() && cur_plate && cur_plate->is_slice_result_valid()) { + // ready_to_slice = false; this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, false); - } - else if (!background_process.empty() && - !background_process.running()) /* Do not update buttons if background process is running - * This condition is important for SLA mode especially, - * when this function is called several times during calculations - * */ + } else if (!background_process.empty() && + !background_process.running()) /* Do not update buttons if background process is running + * This condition is important for SLA mode especially, + * when this function is called several times during calculations + * */ { if (cur_plate->can_slice()) { - //ready_to_slice = true; + // ready_to_slice = true; this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, true); process_completed_with_error = -1; - } - else { - //ready_to_slice = false; + } else { + // ready_to_slice = false; this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, false); process_completed_with_error = partplate_list.get_curr_plate_index(); } @@ -4608,7 +4915,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool #endif } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: exit, return_state=%2%")%__LINE__%return_state; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: exit, return_state=%2%") % __LINE__ % return_state; return return_state; } @@ -4617,36 +4924,33 @@ bool Plater::priv::restart_background_process(unsigned int state) { if (m_ui_jobs.is_any_running()) { // Avoid a race condition - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: ui jobs running, return false")%__LINE__; + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: ui jobs running, return false") % __LINE__; return false; } - if ( ! this->background_process.empty() && - (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) == 0 && - ( ((state & UPDATE_BACKGROUND_PROCESS_FORCE_RESTART) != 0 && ! this->background_process.finished()) || - (state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) != 0 || - (state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ) ) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: print is valid, try to start it now")%__LINE__; + if (!this->background_process.empty() && (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) == 0 && + (((state & UPDATE_BACKGROUND_PROCESS_FORCE_RESTART) != 0 && !this->background_process.finished()) || + (state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) != 0 || (state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0)) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: print is valid, try to start it now") % __LINE__; // The print is valid and it can be started. if (this->background_process.start()) { if (!show_warning_dialog) on_slicing_began(); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: start successfully")%__LINE__; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: start successfully") % __LINE__; return true; } - } - else if (this->background_process.empty()) { - PartPlate* cur_plate = background_process.get_current_plate(); + } else if (this->background_process.empty()) { + PartPlate *cur_plate = background_process.get_current_plate(); if (cur_plate->is_slice_result_valid() && ((state & UPDATE_BACKGROUND_PROCESS_FORCE_RESTART) != 0)) { if (this->background_process.start()) { if (!show_warning_dialog) on_slicing_began(); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: start successfully")%__LINE__; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: start successfully") % __LINE__; return true; } } } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: not started")%__LINE__; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: not started") % __LINE__; return false; } @@ -4654,7 +4958,7 @@ void Plater::priv::export_gcode(fs::path output_path, bool output_path_on_remova { wxCHECK_RET(!(output_path.empty()), "export_gcode: output_path and upload_job empty"); - BOOST_LOG_TRIVIAL(info) << boost::format("export_gcode: output_path %1%")%output_path.string(); + BOOST_LOG_TRIVIAL(info) << boost::format("export_gcode: output_path %1%") % output_path.string(); if (model.objects.empty()) return; @@ -4672,9 +4976,10 @@ void Plater::priv::export_gcode(fs::path output_path, bool output_path_on_remova return; show_warning_dialog = true; - if (! output_path.empty()) { + if (!output_path.empty()) { background_process.schedule_export(output_path.string(), output_path_on_removable_media); - notification_manager->push_delayed_notification(NotificationType::ExportOngoing, []() {return true; }, 1000, 0); + notification_manager->push_delayed_notification( + NotificationType::ExportOngoing, []() { return true; }, 1000, 0); } else { BOOST_LOG_TRIVIAL(info) << "output_path is empty"; } @@ -4704,9 +5009,10 @@ void Plater::priv::export_gcode(fs::path output_path, bool output_path_on_remova return; show_warning_dialog = true; - if (! output_path.empty()) { + if (!output_path.empty()) { background_process.schedule_export(output_path.string(), output_path_on_removable_media); - notification_manager->push_delayed_notification(NotificationType::ExportOngoing, []() {return true; }, 1000, 0); + notification_manager->push_delayed_notification( + NotificationType::ExportOngoing, []() { return true; }, 1000, 0); } else { background_process.schedule_upload(std::move(upload_job)); } @@ -4718,10 +5024,9 @@ void Plater::priv::export_gcode(fs::path output_path, bool output_path_on_remova unsigned int Plater::priv::update_restart_background_process(bool force_update_scene, bool force_update_preview) { bool switch_print = true; - //BBS: judge whether can switch print or not - if ((partplate_list.get_plate_count() > 1) && !this->background_process.can_switch_print()) - { - //can not switch print currently + // BBS: judge whether can switch print or not + if ((partplate_list.get_plate_count() > 1) && !this->background_process.can_switch_print()) { + // can not switch print currently BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": plate count %1%, can not switch") % partplate_list.get_plate_count(); switch_print = false; } @@ -4742,19 +5047,17 @@ void Plater::priv::update_fff_scene() this->preview->reload_print(); // In case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: view3D->reload_scene(true); - //BBS: add assemble view related logic + // BBS: add assemble view related logic assemble_view->reload_scene(true); } -//BBS: add print project related logic +// BBS: add print project related logic void Plater::priv::update_fff_scene_only_shells(bool only_shells) { - if (this->preview != nullptr) - { - const Print* current_print = this->background_process.fff_print(); - if (current_print) - { - //this->preview->reset_shells(); + if (this->preview != nullptr) { + const Print *current_print = this->background_process.fff_print(); + if (current_print) { + // this->preview->reset_shells(); this->preview->load_shells(*current_print); } } @@ -4773,48 +5076,50 @@ void Plater::priv::update_sla_scene() this->update_restart_background_process(true, true); } -bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const fs::path& new_path, const std::string& snapshot) +bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const fs::path &new_path, const std::string &snapshot) { const std::string path = new_path.string(); - wxBusyCursor wait; - wxBusyInfo info(_L("Replace from:") + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas()); + wxBusyCursor wait; Model new_model; try { new_model = Model::read_from_file(path, nullptr, nullptr, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel); - for (ModelObject* model_object : new_model.objects) { + for (ModelObject *model_object : new_model.objects) { model_object->center_around_origin(); model_object->ensure_on_bed(); } - } - catch (std::exception&) { + } catch (std::exception &) { // error while loading return false; } if (new_model.objects.size() > 1 || new_model.objects.front()->volumes.size() > 1) { - MessageDialog dlg(q, _L("Unable to replace with more than one volume"), _L("Error during replace"), wxOK | wxOK_DEFAULT | wxICON_WARNING); + MessageDialog dlg(q, _L("Unable to replace with more than one volume"), _L("Error during replace"), + wxOK | wxOK_DEFAULT | wxICON_WARNING); dlg.ShowModal(); return false; } + wxBusyInfo info(_L("Replace from:") + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas()); + if (!snapshot.empty()) q->take_snapshot(snapshot); - ModelObject* old_model_object = model.objects[object_idx]; - ModelVolume* old_volume = old_model_object->volumes[volume_idx]; + ModelObject *old_model_object = model.objects[object_idx]; + ModelVolume *old_volume = old_model_object->volumes[volume_idx]; bool sinking = old_model_object->bounding_box().min.z() < SINKING_Z_THRESHOLD; - ModelObject* new_model_object = new_model.objects.front(); + ModelObject *new_model_object = new_model.objects.front(); old_model_object->add_volume(*new_model_object->volumes.front()); - ModelVolume* new_volume = old_model_object->volumes.back(); + ModelVolume *new_volume = old_model_object->volumes.back(); new_volume->set_new_unique_id(); new_volume->config.apply(old_volume->config); new_volume->set_type(old_volume->type()); new_volume->set_material_id(old_volume->material_id()); new_volume->set_transformation(old_volume->get_transformation()); - new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); + new_volume->translate(new_volume->get_transformation().get_matrix(true) * + (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); assert(!old_volume->source.is_converted_from_inches || !old_volume->source.is_converted_from_meters); if (old_volume->source.is_converted_from_inches) new_volume->convert_from_imperial_units(); @@ -4843,22 +5148,22 @@ bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const void Plater::priv::replace_with_stl() { - if (! q->get_view3D_canvas3D()->get_gizmos_manager().check_gizmos_closed_except(GLGizmosManager::EType::Undefined)) + if (!q->get_view3D_canvas3D()->get_gizmos_manager().check_gizmos_closed_except(GLGizmosManager::EType::Undefined)) return; - const Selection& selection = get_selection(); + const Selection &selection = get_selection(); if (selection.is_wipe_tower() || get_selection().get_volume_idxs().size() != 1) return; - const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin()); - int object_idx = v->object_idx(); - int volume_idx = v->volume_idx(); + const GLVolume *v = selection.get_first_volume(); + int object_idx = v->object_idx(); + int volume_idx = v->volume_idx(); // collects paths of files to load - const ModelObject* object = model.objects[object_idx]; - const ModelVolume* volume = object->volumes[volume_idx]; + const ModelObject *object = model.objects[object_idx]; + const ModelVolume *volume = object->volumes[volume_idx]; fs::path input_path; if (!volume->source.input_file.empty() && fs::exists(volume->source.input_file)) @@ -4893,7 +5198,7 @@ void Plater::priv::replace_with_stl() static std::vector> reloadable_volumes(const Model &model, const Selection &selection) { std::vector> ret; - const std::set & selected_volumes_idxs = selection.get_volume_idxs(); + const std::set &selected_volumes_idxs = selection.get_volume_idxs(); for (unsigned int idx : selected_volumes_idxs) { const GLVolume &v = *selection.get_volume(idx); const int o_idx = v.object_idx(); @@ -4902,7 +5207,8 @@ static std::vector> reloadable_volumes(const Model &model, c const int v_idx = v.volume_idx(); if (0 <= v_idx && v_idx < int(obj->volumes.size())) { const ModelVolume *vol = obj->volumes[v_idx]; - if (!vol->source.is_from_builtin_objects && !vol->source.input_file.empty() && !fs::path(vol->source.input_file).extension().string().empty()) + if (!vol->source.is_from_builtin_objects && !vol->source.input_file.empty() && + !fs::path(vol->source.input_file).extension().string().empty()) ret.push_back({o_idx, v_idx}); } } @@ -4916,21 +5222,23 @@ void Plater::priv::reload_from_disk() #if ENABLE_RELOAD_FROM_DISK_REWORK // collect selected reloadable ModelVolumes std::vector> selected_volumes = reloadable_volumes(model, get_selection()); - + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " entry, and reloadable volumes number is: " << selected_volumes.size(); // nothing to reload, return if (selected_volumes.empty()) return; std::sort(selected_volumes.begin(), selected_volumes.end(), [](const std::pair &v1, const std::pair &v2) { return (v1.first < v2.first) || (v1.first == v2.first && v1.second < v2.second); - }); - selected_volumes.erase(std::unique(selected_volumes.begin(), selected_volumes.end(), [](const std::pair &v1, const std::pair &v2) { - return (v1.first == v2.first) && (v1.second == v2.second); - }), selected_volumes.end()); + }); + selected_volumes.erase(std::unique(selected_volumes.begin(), selected_volumes.end(), + [](const std::pair &v1, const std::pair &v2) { + return (v1.first == v2.first) && (v1.second == v2.second); + }), + selected_volumes.end()); #else Plater::TakeSnapshot snapshot(q, "Reload from disk"); - const Selection& selection = get_selection(); + const Selection &selection = get_selection(); if (selection.is_wipe_tower()) return; @@ -4942,20 +5250,23 @@ void Plater::priv::reload_from_disk() int volume_idx; // operators needed by std::algorithms - bool operator < (const SelectedVolume& other) const { return object_idx < other.object_idx || (object_idx == other.object_idx && volume_idx < other.volume_idx); } - bool operator == (const SelectedVolume& other) const { return object_idx == other.object_idx && volume_idx == other.volume_idx; } + bool operator<(const SelectedVolume &other) const + { + return object_idx < other.object_idx || (object_idx == other.object_idx && volume_idx < other.volume_idx); + } + bool operator==(const SelectedVolume &other) const { return object_idx == other.object_idx && volume_idx == other.volume_idx; } }; std::vector selected_volumes; // collects selected ModelVolumes - const std::set& selected_volumes_idxs = selection.get_volume_idxs(); + const std::set &selected_volumes_idxs = selection.get_volume_idxs(); for (unsigned int idx : selected_volumes_idxs) { - const GLVolume* v = selection.get_volume(idx); - int v_idx = v->volume_idx(); + const GLVolume *v = selection.get_volume(idx); + int v_idx = v->volume_idx(); if (v_idx >= 0) { int o_idx = v->object_idx(); - if (0 <= o_idx && o_idx < (int)model.objects.size()) - selected_volumes.push_back({ o_idx, v_idx }); + if (0 <= o_idx && o_idx < (int) model.objects.size()) + selected_volumes.push_back({o_idx, v_idx}); } } std::sort(selected_volumes.begin(), selected_volumes.end()); @@ -4991,9 +5302,9 @@ void Plater::priv::reload_from_disk() } #else std::vector replace_paths; - for (const SelectedVolume& v : selected_volumes) { - const ModelObject* object = model.objects[v.object_idx]; - const ModelVolume* volume = object->volumes[v.volume_idx]; + for (const SelectedVolume &v : selected_volumes) { + const ModelObject *object = model.objects[v.object_idx]; + const ModelVolume *volume = object->volumes[v.volume_idx]; if (!volume->source.input_file.empty()) { if (fs::exists(volume->source.input_file)) @@ -5015,8 +5326,8 @@ void Plater::priv::reload_from_disk() if (!found) missing_input_paths.push_back(volume->source.input_file); } - } - else if (!object->input_file.empty() && volume->is_model_part() && !volume->name.empty() && !volume->source.is_from_builtin_objects) + } else if (!object->input_file.empty() && volume->is_model_part() && !volume->name.empty() && + !volume->source.is_from_builtin_objects) missing_input_paths.push_back(volume->name); } #endif // ENABLE_RELOAD_FROM_DISK_REWORK @@ -5027,7 +5338,7 @@ void Plater::priv::reload_from_disk() while (!missing_input_paths.empty()) { // ask user to select the missing file fs::path search = missing_input_paths.back(); - wxString title = _L("Please select a file"); + wxString title = _L("Please select a file"); #if defined(__APPLE__) title += " (" + from_u8(search.filename().string()) + ")"; #endif // __APPLE__ @@ -5037,7 +5348,7 @@ void Plater::priv::reload_from_disk() return; std::string sel_filename_path = dialog.GetPath().ToUTF8().data(); - std::string sel_filename = fs::path(sel_filename_path).filename().string(); + std::string sel_filename = fs::path(sel_filename_path).filename().string(); if (boost::algorithm::iequals(search.filename().string(), sel_filename)) { input_paths.push_back(sel_filename_path); missing_input_paths.pop_back(); @@ -5052,12 +5363,10 @@ void Plater::priv::reload_from_disk() if (fs::exists(repathed_filename)) { input_paths.push_back(repathed_filename.string()); it = missing_input_paths.erase(it); - } - else + } else ++it; } - } - else { + } else { wxString message = _L("Do you want to replace it") + " ?"; MessageDialog dlg(q, message, _L("Message"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION); if (dlg.ShowModal() == wxID_YES) @@ -5084,38 +5393,34 @@ void Plater::priv::reload_from_disk() // load one file at a time for (size_t i = 0; i < input_paths.size(); ++i) { - const auto& path = input_paths[i].string(); + const auto &path = input_paths[i].string(); wxBusyCursor wait; - wxBusyInfo info(_L("Reload from:") + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas()); + wxBusyInfo info(_L("Reload from:") + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas()); Model new_model; - try - { - //BBS: add plate data related logic + try { + // BBS: add plate data related logic PlateDataPtrs plate_data; - //BBS: project embedded settings - std::vector project_presets; + // BBS: project embedded settings + std::vector project_presets; // BBS: backup - new_model = Model::read_from_file(path, nullptr, nullptr, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel, &plate_data, &project_presets); - for (ModelObject* model_object : new_model.objects) - { + new_model = Model::read_from_file(path, nullptr, nullptr, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel, + &plate_data, &project_presets); + for (ModelObject *model_object : new_model.objects) { model_object->center_around_origin(); model_object->ensure_on_bed(); } - if (plate_data.size() > 0) - { - //partplate_list.load_from_3mf_structure(plate_data); + if (plate_data.size() > 0) { + // partplate_list.load_from_3mf_structure(plate_data); partplate_list.update_slice_context_to_current_plate(background_process); this->preview->update_gcode_result(partplate_list.get_current_slice_result()); release_PlateData_list(plate_data); sidebar->obj_list()->reload_all_plates(); } - } - catch (std::exception&) - { + } catch (std::exception &) { // error while loading return; } @@ -5128,7 +5433,8 @@ void Plater::priv::reload_from_disk() bool sinking = old_model_object->bounding_box().min.z() < SINKING_Z_THRESHOLD; bool has_source = !old_volume->source.input_file.empty() && - boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(), fs::path(path).filename().string()); + boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(), + fs::path(path).filename().string()); bool has_name = !old_volume->name.empty() && boost::algorithm::iequals(old_volume->name, fs::path(path).filename().string()); if (has_source || has_name) { int new_volume_idx = -1; @@ -5159,7 +5465,8 @@ void Plater::priv::reload_from_disk() break; } } - if (found) break; + if (found) + break; } } @@ -5182,8 +5489,9 @@ void Plater::priv::reload_from_disk() Transform3d transform = Transform3d::Identity(); transform.translate(new_volume->source.mesh_offset - old_volume->source.mesh_offset); - new_volume->set_transformation(old_volume->get_transformation().get_matrix() * old_volume->source.transform.get_matrix(true) * - transform * new_volume->source.transform.get_matrix(true).inverse()); + new_volume->set_transformation(old_volume->get_transformation().get_matrix() * + old_volume->source.transform.get_matrix(true) * transform * + new_volume->source.transform.get_matrix(true).inverse()); new_volume->source.object_idx = old_volume->source.object_idx; new_volume->source.volume_idx = old_volume->source.volume_idx; @@ -5194,7 +5502,8 @@ void Plater::priv::reload_from_disk() new_volume->convert_from_meters(); std::swap(old_model_object->volumes[vol_idx], old_model_object->volumes.back()); old_model_object->delete_volume(old_model_object->volumes.size() - 1); - if (!sinking) old_model_object->ensure_on_bed(); + if (!sinking) + old_model_object->ensure_on_bed(); old_model_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1"); sla::reproject_points_and_holes(old_model_object); @@ -5205,61 +5514,64 @@ void Plater::priv::reload_from_disk() } #else // update the selected volumes whose source is the current file - for (const SelectedVolume& sel_v : selected_volumes) { - ModelObject* old_model_object = model.objects[sel_v.object_idx]; - ModelVolume* old_volume = old_model_object->volumes[sel_v.volume_idx]; + for (const SelectedVolume &sel_v : selected_volumes) { + ModelObject *old_model_object = model.objects[sel_v.object_idx]; + ModelVolume *old_volume = old_model_object->volumes[sel_v.volume_idx]; bool sinking = old_model_object->bounding_box().min.z() < SINKING_Z_THRESHOLD; - bool has_source = !old_volume->source.input_file.empty() && boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(), fs::path(path).filename().string()); + bool has_source = !old_volume->source.input_file.empty() && + boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(), + fs::path(path).filename().string()); bool has_name = !old_volume->name.empty() && boost::algorithm::iequals(old_volume->name, fs::path(path).filename().string()); if (has_source || has_name) { int new_volume_idx = -1; int new_object_idx = -1; -// if (has_source) { -// // take idxs from source -// new_volume_idx = old_volume->source.volume_idx; -// new_object_idx = old_volume->source.object_idx; -// } -// else { - // take idxs from the 1st matching volume - for (size_t o = 0; o < new_model.objects.size(); ++o) { - ModelObject* obj = new_model.objects[o]; - bool found = false; - for (size_t v = 0; v < obj->volumes.size(); ++v) { - if (obj->volumes[v]->name == old_volume->name) { - new_volume_idx = (int)v; - new_object_idx = (int)o; - found = true; - break; - } - } - if (found) + // if (has_source) { + // // take idxs from source + // new_volume_idx = old_volume->source.volume_idx; + // new_object_idx = old_volume->source.object_idx; + // } + // else { + // take idxs from the 1st matching volume + for (size_t o = 0; o < new_model.objects.size(); ++o) { + ModelObject *obj = new_model.objects[o]; + bool found = false; + for (size_t v = 0; v < obj->volumes.size(); ++v) { + if (obj->volumes[v]->name == old_volume->name) { + new_volume_idx = (int) v; + new_object_idx = (int) o; + found = true; break; + } } -// } + if (found) + break; + } + // } if (new_object_idx < 0 || int(new_model.objects.size()) <= new_object_idx) { fail_list.push_back(from_u8(has_source ? old_volume->source.input_file : old_volume->name)); continue; } - ModelObject* new_model_object = new_model.objects[new_object_idx]; + ModelObject *new_model_object = new_model.objects[new_object_idx]; if (new_volume_idx < 0 || int(new_model_object->volumes.size()) <= new_volume_idx) { fail_list.push_back(from_u8(has_source ? old_volume->source.input_file : old_volume->name)); continue; } old_model_object->add_volume(*new_model_object->volumes[new_volume_idx]); - ModelVolume* new_volume = old_model_object->volumes.back(); + ModelVolume *new_volume = old_model_object->volumes.back(); new_volume->set_new_unique_id(); new_volume->config.apply(old_volume->config); new_volume->set_type(old_volume->type()); new_volume->set_material_id(old_volume->material_id()); new_volume->set_transformation(old_volume->get_transformation()); - new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); + new_volume->translate(new_volume->get_transformation().get_matrix(true) * + (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); new_volume->source.object_idx = old_volume->source.object_idx; new_volume->source.volume_idx = old_volume->source.volume_idx; - assert(! old_volume->source.is_converted_from_inches || ! old_volume->source.is_converted_from_meters); + assert(!old_volume->source.is_converted_from_inches || !old_volume->source.is_converted_from_meters); if (old_volume->source.is_converted_from_inches) new_volume->convert_from_imperial_units(); else if (old_volume->source.is_converted_from_meters) @@ -5285,11 +5597,13 @@ void Plater::priv::reload_from_disk() } #else for (size_t i = 0; i < replace_paths.size(); ++i) { - const auto& path = replace_paths[i].string(); - for (const SelectedVolume& sel_v : selected_volumes) { - ModelObject* old_model_object = model.objects[sel_v.object_idx]; - ModelVolume* old_volume = old_model_object->volumes[sel_v.volume_idx]; - bool has_source = !old_volume->source.input_file.empty() && boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(), fs::path(path).filename().string()); + const auto &path = replace_paths[i].string(); + for (const SelectedVolume &sel_v : selected_volumes) { + ModelObject *old_model_object = model.objects[sel_v.object_idx]; + ModelVolume *old_volume = old_model_object->volumes[sel_v.volume_idx]; + bool has_source = !old_volume->source.input_file.empty() && + boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(), + fs::path(path).filename().string()); if (!replace_volume_with_stl(sel_v.object_idx, sel_v.volume_idx, path, "")) { fail_list.push_back(from_u8(has_source ? old_volume->source.input_file : old_volume->name)); } @@ -5299,7 +5613,7 @@ void Plater::priv::reload_from_disk() if (!fail_list.empty()) { wxString message = _L("Unable to reload:") + "\n"; - for (const wxString& s : fail_list) { + for (const wxString &s : fail_list) { message += s + "\n"; } MessageDialog dlg(q, message, _L("Error during reload"), wxOK | wxOK_DEFAULT | wxICON_WARNING); @@ -5313,6 +5627,8 @@ void Plater::priv::reload_from_disk() for (size_t i = 0; i < model.objects.size(); ++i) { view3D->get_canvas3d()->update_instance_printable_state_for_object(i); } + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " finish."; } void Plater::priv::reload_all_from_disk() @@ -5320,10 +5636,10 @@ void Plater::priv::reload_all_from_disk() if (model.objects.empty()) return; - Plater::TakeSnapshot snapshot(q, "Reload all"); + Plater::TakeSnapshot snapshot(q, "Reload all"); Plater::SuppressSnapshots suppress(q); - Selection& selection = get_selection(); + Selection &selection = get_selection(); Selection::IndicesList curr_idxs = selection.get_volume_idxs(); // reload from disk uses selection select_all(); @@ -5335,105 +5651,97 @@ void Plater::priv::reload_all_from_disk() } } -//BBS: add no_slice logic -void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) +// BBS: add no_slice logic +void Plater::priv::set_current_panel(wxPanel *panel, bool no_slice) { if (std::find(panels.begin(), panels.end(), panel) == panels.end()) return; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": current_panel %1%, new_panel %2%")%current_panel%panel; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": current_panel %1%, new_panel %2%") % current_panel % panel; #ifdef __WXMAC__ bool force_render = (current_panel != nullptr); #endif // __WXMAC__ - //BBS: add slice logic when switch to preview page + // BBS: add slice logic when switch to preview page auto do_reslice = [this, no_slice]() { - // see: Plater::priv::object_list_changed() - // FIXME: it may be better to have a single function making this check and let it be called wherever needed - bool export_in_progress = this->background_process.is_export_scheduled(); - bool model_fits = this->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; - //BBS: add partplate logic - PartPlate * current_plate = this->partplate_list.get_curr_plate(); - bool only_has_gcode_need_preview = false; - bool current_has_print_instances = current_plate->has_printable_instances(); - if (current_plate->is_slice_result_valid() && this->model.objects.empty() && !current_has_print_instances) - only_has_gcode_need_preview = true; - - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": from set_current_panel, no_slice %1%, export_in_progress %2%, model_fits %3%, m_is_slicing %4%")%no_slice%export_in_progress%model_fits%m_is_slicing; - - if (!no_slice && !this->model.objects.empty() && !export_in_progress && model_fits && current_has_print_instances) - { - //if already running in background, not relice here - //BBS: add more judge for slicing - if (!this->background_process.running() && !this->m_is_slicing) - { - this->m_slice_all = false; - this->q->reslice(); - } - else { - //reset current plate to the slicing plate - int plate_index = this->background_process.get_current_plate()->get_index(); - this->partplate_list.select_plate(plate_index); - } - } - else if (only_has_gcode_need_preview) - { + // see: Plater::priv::object_list_changed() + // FIXME: it may be better to have a single function making this check and let it be called wherever needed + bool export_in_progress = this->background_process.is_export_scheduled(); + bool model_fits = this->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; + // BBS: add partplate logic + PartPlate *current_plate = this->partplate_list.get_curr_plate(); + bool only_has_gcode_need_preview = false; + bool current_has_print_instances = current_plate->has_printable_instances(); + if (current_plate->is_slice_result_valid() && this->model.objects.empty() && !current_has_print_instances) + only_has_gcode_need_preview = true; + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format( + ": from set_current_panel, no_slice %1%, export_in_progress %2%, model_fits %3%, m_is_slicing %4%") % + no_slice % export_in_progress % model_fits % m_is_slicing; + + if (!no_slice && !this->model.objects.empty() && !export_in_progress && model_fits && current_has_print_instances) { + // if already running in background, not relice here + // BBS: add more judge for slicing + if (!this->background_process.running() && !this->m_is_slicing) { this->m_slice_all = false; this->q->reslice(); + } else { + // reset current plate to the slicing plate + int plate_index = this->background_process.get_current_plate()->get_index(); + this->partplate_list.select_plate(plate_index); } - //BBS: process empty plate, reset previous toolpath - else - { - //if (!this->m_slice_all) - if (!current_has_print_instances) - reset_gcode_toolpaths(); - //this->q->refresh_print(); - if (!preview->get_canvas3d()->is_initialized()) - { - preview->get_canvas3d()->render(true); - } + } else if (only_has_gcode_need_preview) { + this->m_slice_all = false; + this->q->reslice(); + } + // BBS: process empty plate, reset previous toolpath + else { + // if (!this->m_slice_all) + if (!current_has_print_instances) + reset_gcode_toolpaths(); + // this->q->refresh_print(); + if (!preview->get_canvas3d()->is_initialized()) { + preview->get_canvas3d()->render(true); } - //TODO: turn off this switch currently - /*auto canvas_w = float(preview->get_canvas3d()->get_canvas_size().get_width()); - auto canvas_h = float(preview->get_canvas3d()->get_canvas_size().get_height()); - Point screen_center(canvas_w/2, canvas_h/2); - auto center_point = preview->get_canvas3d()->_mouse_to_3d(screen_center); - center_point(2) = 0.f; - if (!current_plate->contains(center_point)) - this->partplate_list.select_plate_view();*/ - - // keeps current gcode preview, if any - if (this->m_slice_all) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": slicing all, just reload shells"); + } + // TODO: turn off this switch currently + /*auto canvas_w = float(preview->get_canvas3d()->get_canvas_size().get_width()); + auto canvas_h = float(preview->get_canvas3d()->get_canvas_size().get_height()); + Point screen_center(canvas_w/2, canvas_h/2); + auto center_point = preview->get_canvas3d()->_mouse_to_3d(screen_center); + center_point(2) = 0.f; + if (!current_plate->contains(center_point)) + this->partplate_list.select_plate_view();*/ + + // keeps current gcode preview, if any + if (this->m_slice_all) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": slicing all, just reload shells"); + this->update_fff_scene_only_shells(); + } else { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": single slice, reload print"); + if (model_fits) + this->preview->reload_print(true); + else this->update_fff_scene_only_shells(); - } - else { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": single slice, reload print"); - if (model_fits) - this->preview->reload_print(true); - else - this->update_fff_scene_only_shells(); - } + } - preview->set_as_dirty(); - }; + preview->set_as_dirty(); + }; - //BBS: add the collapse logic + // BBS: add the collapse logic if (panel == preview && q->only_gcode_mode()) { this->sidebar->collapse(true); preview->get_canvas3d()->enable_select_plate_toolbar(false); - } - else if (panel == preview && q->using_exported_file() && (q->m_valid_plates_count <= 1)) { + } else if (panel == preview && q->using_exported_file() && (q->m_valid_plates_count <= 1)) { preview->get_canvas3d()->enable_select_plate_toolbar(false); - } - else { + } else { preview->get_canvas3d()->enable_select_plate_toolbar(true); } - if (current_panel == panel) - { - //BBS: add slice logic when switch to preview page - //BBS: add only gcode mode + if (current_panel == panel) { + // BBS: add slice logic when switch to preview page + // BBS: add only gcode mode if (!q->only_gcode_mode() && (current_panel == preview) && (wxGetApp().is_editor())) { do_reslice(); } @@ -5441,38 +5749,38 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) return; } - //BBS: wish to reset all plates stats item selected state when back to View3D Tab + // BBS: wish to reset all plates stats item selected state when back to View3D Tab preview->get_canvas3d()->reset_select_plate_toolbar_selection(); - wxPanel* old_panel = current_panel; -//#if BBL_HAS_FIRST_PAGE + wxPanel *old_panel = current_panel; + // #if BBL_HAS_FIRST_PAGE if (!old_panel) { - //BBS: only switch to the first panel when visible + // BBS: only switch to the first panel when visible panel->Show(); - //dynamic_cast(panel)->get_canvas3d()->render(); + // dynamic_cast(panel)->get_canvas3d()->render(); if (!panel->IsShownOnScreen()) return; } -//#endif + // #endif current_panel = panel; // to reduce flickering when changing view, first set as visible the new current panel - for (wxPanel* p : panels) { + for (wxPanel *p : panels) { if (p == current_panel) { #ifdef __WXMAC__ // On Mac we need also to force a render to avoid flickering when changing view if (force_render) { if (p == view3D) - dynamic_cast(p)->get_canvas3d()->render(); + dynamic_cast(p)->get_canvas3d()->render(); else if (p == preview) - dynamic_cast(p)->get_canvas3d()->render(); + dynamic_cast(p)->get_canvas3d()->render(); } #endif // __WXMAC__ p->Show(); } } // then set to invisible the other - for (wxPanel* p : panels) { + for (wxPanel *p : panels) { if (p != current_panel) p->Hide(); } @@ -5480,7 +5788,7 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) panel_sizer->Layout(); if (wxGetApp().plater()) { - Camera& cam = wxGetApp().plater()->get_camera(); + Camera &cam = wxGetApp().plater()->get_camera(); if (old_panel == preview || old_panel == view3D) { view3D->get_canvas3d()->get_camera().load_camera_view(cam); } else if (old_panel == assemble_view) { @@ -5488,8 +5796,7 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) } if (current_panel == view3D || current_panel == preview) { cam.load_camera_view(view3D->get_canvas3d()->get_camera()); - } - else if (current_panel == assemble_view) { + } else if (current_panel == assemble_view) { cam.load_camera_view(assemble_view->get_canvas3d()->get_camera()); } } @@ -5517,11 +5824,10 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) // reset cached size to force a resize on next call to render() to keep imgui in synch with canvas size view3D->get_canvas3d()->reset_old_size(); // BBS - //view_toolbar.select_item("3D"); + // view_toolbar.select_item("3D"); if (notification_manager != nullptr) notification_manager->set_in_preview(false); - } - else if (current_panel == preview) { + } else if (current_panel == preview) { q->invalid_all_plate_thumbnails(); if (old_panel == view3D) view3D->get_canvas3d()->unbind_event_handlers(); @@ -5530,7 +5836,7 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) preview->get_canvas3d()->bind_event_handlers(); - GLGizmosManager& gizmos = view3D->get_canvas3d()->get_gizmos_manager(); + GLGizmosManager &gizmos = view3D->get_canvas3d()->get_gizmos_manager(); if (gizmos.is_running()) { gizmos.reset_all_states(); gizmos.update_data(); @@ -5564,15 +5870,13 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) // reset cached size to force a resize on next call to render() to keep imgui in synch with canvas size preview->get_canvas3d()->reset_old_size(); // BBS - //view_toolbar.select_item("Preview"); + // view_toolbar.select_item("Preview"); if (notification_manager != nullptr) notification_manager->set_in_preview(true); - } - else if (current_panel == assemble_view) { + } else if (current_panel == assemble_view) { if (old_panel == view3D) { view3D->get_canvas3d()->unbind_event_handlers(); - } - else if (old_panel == preview) + } else if (old_panel == preview) preview->get_canvas3d()->unbind_event_handlers(); assemble_view->get_canvas3d()->bind_event_handlers(); @@ -5581,12 +5885,12 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) // BBS set default view and zoom if (first_enter_assemble) { wxGetApp().plater()->get_camera().requires_zoom_to_volumes = true; - first_enter_assemble = false; + first_enter_assemble = false; } assemble_view->set_as_dirty(); // BBS - //view_toolbar.select_item("Assemble"); + // view_toolbar.select_item("Assemble"); } current_panel->SetFocusFromKbd(); @@ -5597,30 +5901,29 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) // BBS void Plater::priv::on_combobox_select(wxCommandEvent &evt) { - PlaterPresetComboBox* preset_combo_box = dynamic_cast(evt.GetEventObject()); + PlaterPresetComboBox *preset_combo_box = dynamic_cast(evt.GetEventObject()); if (preset_combo_box) { this->on_select_preset(evt); - } - else { + } else { this->on_select_bed_type(evt); } } void Plater::priv::on_select_bed_type(wxCommandEvent &evt) { - ComboBox* combo = static_cast(evt.GetEventObject()); - int selection = combo->GetSelection(); + ComboBox *combo = static_cast(evt.GetEventObject()); + int selection = combo->GetSelection(); std::string bed_type_name = print_config_def.get("curr_bed_type")->enum_values[selection]; - PresetBundle& preset_bundle = *wxGetApp().preset_bundle; - DynamicPrintConfig& proj_config = wxGetApp().preset_bundle->project_config; - const t_config_enum_values* keys_map = print_config_def.get("curr_bed_type")->enum_keys_map; + PresetBundle &preset_bundle = *wxGetApp().preset_bundle; + DynamicPrintConfig &proj_config = wxGetApp().preset_bundle->project_config; + const t_config_enum_values *keys_map = print_config_def.get("curr_bed_type")->enum_keys_map; if (keys_map) { BedType new_bed_type = btCount; for (auto item : *keys_map) { if (item.first == bed_type_name) { - new_bed_type = (BedType)item.second; + new_bed_type = (BedType) item.second; break; } } @@ -5636,12 +5939,12 @@ void Plater::priv::on_select_bed_type(wxCommandEvent &evt) q->on_config_change(wxGetApp().preset_bundle->full_config()); // update app_config - AppConfig* app_config = wxGetApp().app_config; + AppConfig *app_config = wxGetApp().app_config; app_config->set("curr_bed_type", std::to_string(int(new_bed_type))); - app_config->set_printer_setting(wxGetApp().preset_bundle->printers.get_selected_preset_name(), - "curr_bed_type", std::to_string(int(new_bed_type))); + app_config->set_printer_setting(wxGetApp().preset_bundle->printers.get_selected_preset_name(), "curr_bed_type", + std::to_string(int(new_bed_type))); - //update slice status + // update slice status auto plate_list = partplate_list.get_plate_list(); for (auto plate : plate_list) { if (plate->get_bed_type() == btDefault) { @@ -5659,16 +5962,41 @@ void Plater::priv::on_select_bed_type(wxCommandEvent &evt) void Plater::priv::on_select_preset(wxCommandEvent &evt) { - PlaterPresetComboBox* combo = static_cast(evt.GetEventObject()); - Preset::Type preset_type = combo->get_type(); + PlaterPresetComboBox *combo = static_cast(evt.GetEventObject()); + Preset::Type preset_type = combo->get_type(); // Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender"), // m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive. // So, use GetSelection() from event parameter int selection = evt.GetSelection(); + auto marker = reinterpret_cast(combo->GetClientData(selection)); + if (PresetComboBox::LabelItemType::LABEL_ITEM_WIZARD_ADD_PRINTERS == marker) { + sidebar->create_printer_preset(); + return; + } + auto idx = combo->get_filament_idx(); + // BBS:Save the plate parameters before switching + PartPlateList &old_plate_list = this->partplate_list; + PartPlate *old_plate = old_plate_list.get_selected_plate(); + Vec3d old_plate_pos = old_plate->get_center_origin(); + + // BBS: Save the model in the current platelist + std::vector> plate_object; + for (size_t i = 0; i < old_plate_list.get_plate_count(); ++i) { + PartPlate *plate = old_plate_list.get_plate(i); + std::vector obj_idxs; + for (int obj_idx = 0; obj_idx < model.objects.size(); obj_idx++) { + if (plate && plate->contain_instance(obj_idx, 0)) { + obj_idxs.emplace_back(obj_idx); + } + } + plate_object.emplace_back(obj_idxs); + } + + bool flag = is_support_filament(idx); //! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox, //! but the OSX version derived from wxOwnerDrawnCombo. //! So, to get selected string we do @@ -5677,31 +6005,34 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) //! combo->GetStringSelection().ToUTF8().data()); std::string preset_name = wxGetApp().preset_bundle->get_preset_name_by_alias(preset_type, - Preset::remove_suffix_modified(combo->GetString(selection).ToUTF8().data())); + Preset::remove_suffix_modified( + combo->GetString(selection).ToUTF8().data())); if (preset_type == Preset::TYPE_FILAMENT) { wxGetApp().preset_bundle->set_filament_preset(idx, preset_name); wxGetApp().plater()->update_project_dirty_from_presets(); wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); dynamic_filament_list.update(); + bool flag_is_change = is_support_filament(idx); + if (flag != flag_is_change) { + sidebar->auto_calc_flushing_volumes(idx); + } } - bool select_preset = !combo->selection_is_changed_according_to_physical_printers(); // TODO: ? if (preset_type == Preset::TYPE_FILAMENT && sidebar->is_multifilament()) { // Only update the plater UI for the 2nd and other filaments. combo->update(); - } - else if (select_preset) { + } else if (select_preset) { if (preset_type == Preset::TYPE_PRINTER) { - PhysicalPrinterCollection& physical_printers = wxGetApp().preset_bundle->physical_printers; - if(combo->is_selected_physical_printer()) + PhysicalPrinterCollection &physical_printers = wxGetApp().preset_bundle->physical_printers; + if (combo->is_selected_physical_printer()) preset_name = physical_printers.get_selected_printer_preset_name(); else physical_printers.unselect_printer(); } - //BBS - //wxWindowUpdateLocker noUpdates1(sidebar->print_panel()); + // BBS + // wxWindowUpdateLocker noUpdates1(sidebar->print_panel()); wxWindowUpdateLocker noUpdates2(sidebar->filament_panel()); wxGetApp().get_tab(preset_type)->select_preset(preset_name); } @@ -5709,12 +6040,27 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) // update plater with new config q->on_config_change(wxGetApp().preset_bundle->full_config()); if (preset_type == Preset::TYPE_PRINTER) { - /* Settings list can be changed after printer preset changing, so - * update all settings items for all item had it. - * Furthermore, Layers editing is implemented only for FFF printers - * and for SLA presets they should be deleted - */ + /* Settings list can be changed after printer preset changing, so + * update all settings items for all item had it. + * Furthermore, Layers editing is implemented only for FFF printers + * and for SLA presets they should be deleted + */ wxGetApp().obj_list()->update_object_list_by_printer_technology(); + + // BBS:Model reset by plate center + PartPlateList &cur_plate_list = this->partplate_list; + PartPlate *cur_plate = cur_plate_list.get_curr_plate(); + Vec3d cur_plate_pos = cur_plate->get_center_origin(); + + if (old_plate_pos.x() != cur_plate_pos.x() || old_plate_pos.y() != cur_plate_pos.y()) { + for (int i = 0; i < plate_object.size(); ++i) { + view3D->select_object_from_idx(plate_object[i]); + this->sidebar->obj_list()->update_selections(); + view3D->center_selected_plate(i); + } + + view3D->deselect_all(); + } } #ifdef __WXMSW__ @@ -5729,27 +6075,29 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) // update slice state and set bedtype default for 3rd-party printer auto plate_list = partplate_list.get_plate_list(); for (auto plate : plate_list) { - plate->update_slice_result_valid_state(false); + plate->update_slice_result_valid_state(false); } } void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": event_type %1%, percent %2%, text %3%") % evt.GetEventType() % evt.status.percent % evt.status.text; - //BBS: add slice project logic + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ + << boost::format(": event_type %1%, percent %2%, text %3%") % evt.GetEventType() % evt.status.percent % + evt.status.text; + // BBS: add slice project logic std::string title_text = _u8L("Slicing"); - evt.status.text = title_text + evt.status.text; + evt.status.text = title_text + evt.status.text; if (evt.status.percent >= 0) { if (m_ui_jobs.is_any_running()) { // Avoid a race condition return; } - notification_manager->set_slicing_progress_percentage(evt.status.text, (float)evt.status.percent / 100.0f); + notification_manager->set_slicing_progress_percentage(evt.status.text, (float) evt.status.percent / 100.0f); // update slicing percent - PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list(); - //slicing parallel, only update if percent is greater than before + PartPlateList &plate_list = wxGetApp().plater()->get_partplate_list(); + // slicing parallel, only update if percent is greater than before if (evt.status.percent > plate_list.get_curr_plate()->get_slicing_percent()) plate_list.get_curr_plate()->update_slicing_percent(evt.status.percent); } @@ -5757,9 +6105,9 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) if (evt.status.flags & (PrintBase::SlicingStatus::RELOAD_SCENE | PrintBase::SlicingStatus::RELOAD_SLA_SUPPORT_POINTS)) { switch (this->printer_technology) { case ptFFF: - //BBS: add slice project logic, only display shells at the beginning + // BBS: add slice project logic, only display shells at the beginning if (!m_slice_all || (m_cur_slice_plate == (partplate_list.get_plate_count() - 1))) - //this->update_fff_scene(); + // this->update_fff_scene(); this->update_fff_scene_only_shells(); break; case ptSLA: @@ -5776,39 +6124,42 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) this->preview->reload_print(); } - if (evt.status.flags & (PrintBase::SlicingStatus::UPDATE_PRINT_STEP_WARNINGS | PrintBase::SlicingStatus::UPDATE_PRINT_OBJECT_STEP_WARNINGS)) { + if (evt.status.flags & + (PrintBase::SlicingStatus::UPDATE_PRINT_STEP_WARNINGS | PrintBase::SlicingStatus::UPDATE_PRINT_OBJECT_STEP_WARNINGS)) { // Update notification center with warnings of object_id and its warning_step. - ObjectID object_id = evt.status.warning_object_id; - int warning_step = evt.status.warning_step; + ObjectID object_id = evt.status.warning_object_id; + int warning_step = evt.status.warning_step; PrintStateBase::StateWithWarnings state; - ModelObject const * model_object = nullptr; + ModelObject const *model_object = nullptr; - //BBS: add partplate related logic, use the print in background process + // BBS: add partplate related logic, use the print in background process if (evt.status.flags & PrintBase::SlicingStatus::UPDATE_PRINT_STEP_WARNINGS) { state = this->printer_technology == ptFFF ? - this->background_process.m_fff_print->step_state_with_warnings(static_cast(warning_step)) : - this->background_process.m_sla_print->step_state_with_warnings(static_cast(warning_step)); + this->background_process.m_fff_print->step_state_with_warnings(static_cast(warning_step)) : + this->background_process.m_sla_print->step_state_with_warnings(static_cast(warning_step)); } else if (this->printer_technology == ptFFF) { const PrintObject *print_object = this->background_process.m_fff_print->get_object(object_id); if (print_object) { - state = print_object->step_state_with_warnings(static_cast(warning_step)); + state = print_object->step_state_with_warnings(static_cast(warning_step)); model_object = print_object->model_object(); } } else { const SLAPrintObject *print_object = this->background_process.m_sla_print->get_object(object_id); if (print_object) { - state = print_object->step_state_with_warnings(static_cast(warning_step)); + state = print_object->step_state_with_warnings(static_cast(warning_step)); model_object = print_object->model_object(); } } // Now process state.warnings. - for (auto const& warning : state.warnings) { + for (auto const &warning : state.warnings) { if (warning.current) { NotificationManager::NotificationLevel notif_level = NotificationManager::NotificationLevel::WarningNotificationLevel; - if (evt.status.message_type == PrintStateBase::SlicingNotificationType::SlicingReplaceInitEmptyLayers | PrintStateBase::SlicingNotificationType::SlicingEmptyGcodeLayers) { + if (evt.status.message_type == PrintStateBase::SlicingNotificationType::SlicingReplaceInitEmptyLayers | + PrintStateBase::SlicingNotificationType::SlicingEmptyGcodeLayers) { notif_level = NotificationManager::NotificationLevel::SeriousWarningNotificationLevel; } - notification_manager->push_slicing_warning_notification(warning.message, false, model_object, object_id, warning_step, warning.message_id, notif_level); + notification_manager->push_slicing_warning_notification(warning.message, false, model_object, object_id, warning_step, + warning.message_id, notif_level); add_warning(warning, object_id.id); } } @@ -5816,12 +6167,13 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format("exit."); } -void Plater::priv::on_slicing_completed(wxCommandEvent & evt) +void Plater::priv::on_slicing_completed(wxCommandEvent &evt) { BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": event_type %1%, string %2%") % evt.GetEventType() % evt.GetString(); - //BBS: add slice project logic + // BBS: add slice project logic if (m_slice_all && (m_cur_slice_plate < (partplate_list.get_plate_count() - 1))) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format("slicing all, finished plate %1%, will continue next.")%m_cur_slice_plate; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ + << boost::format("slicing all, finished plate %1%, will continue next.") % m_cur_slice_plate; return; } @@ -5829,23 +6181,22 @@ void Plater::priv::on_slicing_completed(wxCommandEvent & evt) delayed_scene_refresh = true; else { if (this->printer_technology == ptFFF) { - //BBS: only reload shells + // BBS: only reload shells this->update_fff_scene_only_shells(false); - //this->update_fff_scene(); - } - else + // this->update_fff_scene(); + } else this->update_sla_scene(); } BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format("exit."); } -void Plater::priv::on_export_began(wxCommandEvent& evt) +void Plater::priv::on_export_began(wxCommandEvent &evt) { if (show_warning_dialog) warnings_dialog(); } -void Plater::priv::on_export_finished(wxCommandEvent& evt) +void Plater::priv::on_export_finished(wxCommandEvent &evt) { #if 0 //BBS: also export 3mf to the same directory for debugging @@ -5863,14 +6214,17 @@ void Plater::priv::on_slicing_began() clear_warnings(); notification_manager->close_notification_of_type(NotificationType::SignDetected); notification_manager->close_notification_of_type(NotificationType::ExportFinished); + bool is_first_plate = m_cur_slice_plate == 0; + bool slice_all = q->m_only_gcode ? m_slice_all_only_has_gcode : m_slice_all; + bool need_change_dailytips = !(slice_all && !is_first_plate); notification_manager->set_slicing_progress_began(); + notification_manager->update_slicing_notif_dailytips(need_change_dailytips); } -void Plater::priv::add_warning(const Slic3r::PrintStateBase::Warning& warning, size_t oid) +void Plater::priv::add_warning(const Slic3r::PrintStateBase::Warning &warning, size_t oid) { - for (auto& it : current_warnings) { + for (auto &it : current_warnings) { if (warning.message_id == it.first.message_id) { - if (warning.message_id != 0 || (warning.message_id == 0 && warning.message == it.first.message)) - { + if (warning.message_id != 0 || (warning.message_id == 0 && warning.message == it.first.message)) { if (warning.message_id != 0) it.first.message = warning.message; return; @@ -5891,11 +6245,10 @@ void Plater::priv::actualize_slicing_warnings(const PrintBase &print) notification_manager->remove_slicing_warnings_of_released_objects(ids); notification_manager->set_all_slicing_warnings_gray(true); } -void Plater::priv::actualize_object_warnings(const PrintBase& print) +void Plater::priv::actualize_object_warnings(const PrintBase &print) { std::vector ids; - for (const ModelObject* object : print.model().objects ) - { + for (const ModelObject *object : print.model().objects) { ids.push_back(object->id()); } std::sort(ids.begin(), ids.end()); @@ -5911,7 +6264,7 @@ bool Plater::priv::warnings_dialog() if (current_warnings.empty()) return true; std::string text = _u8L("There are warnings after slicing models:") + "\n"; - for (auto const& it : current_warnings) { + for (auto const &it : current_warnings) { size_t next_n = it.first.message.find_first_of('\n', 0); text += "\n"; if (next_n != std::string::npos) @@ -5919,31 +6272,29 @@ bool Plater::priv::warnings_dialog() else text += it.first.message; } - //text += "\n\nDo you still wish to export?"; + // text += "\n\nDo you still wish to export?"; MessageDialog msg_window(this->q, from_u8(text), _L("warnings"), wxOK); const auto res = msg_window.ShowModal(); return res == wxID_OK; - } -//BBS: add project slice logic +// BBS: add project slice logic void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": enter, m_ignore_event %1%, status %2%")%m_ignore_event %evt.status(); - //BBS:ignore cancel event for some special case - if (m_ignore_event) - { + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": enter, m_ignore_event %1%, status %2%") % m_ignore_event % evt.status(); + // BBS:ignore cancel event for some special case + if (m_ignore_event) { m_ignore_event = false; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": ignore this event %1%") % evt.status(); return; } - //BBS: add project slice logic + // BBS: add project slice logic bool is_finished = !m_slice_all || (m_cur_slice_plate == (partplate_list.get_plate_count() - 1)); - //BBS: slice .gcode.3mf file related logic, assign is_finished again + // BBS: slice .gcode.3mf file related logic, assign is_finished again bool only_has_gcode_need_preview = false; - auto plate_list = this->partplate_list.get_plate_list(); - bool has_print_instances = false; + auto plate_list = this->partplate_list.get_plate_list(); + bool has_print_instances = false; for (auto plate : plate_list) has_print_instances = has_print_instances || plate->has_printable_instances(); if (this->model.objects.empty() && !has_print_instances) @@ -5977,24 +6328,25 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) } } else { std::vector ptrs; - for (auto oid : message.second) - { + for (auto oid : message.second) { const PrintObject *print_object = this->background_process.m_fff_print->get_object(ObjectID(oid)); - if (print_object) { ptrs.push_back(print_object->model_object()); } + if (print_object) { + ptrs.push_back(print_object->model_object()); + } } notification_manager->push_slicing_error_notification(message.first, ptrs); } - if (evt.invalidate_plater()) - { + if (evt.invalidate_plater()) { // BBS #if 0 const wxString invalid_str = _L("Invalid data"); for (auto btn : { ActionButtonType::abReslice, ActionButtonType::abSendGCode, ActionButtonType::abExport }) sidebar->set_btn_label(btn, invalid_str); #endif - process_completed_with_error = partplate_list.get_curr_plate_index();; + process_completed_with_error = partplate_list.get_curr_plate_index(); + ; } - has_error = true; + has_error = true; is_finished = true; } if (evt.cancelled()) { @@ -6003,11 +6355,11 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) is_finished = true; } - //BBS: set the current plater's slice result to valid + // BBS: set the current plater's slice result to valid if (!this->background_process.empty()) this->background_process.get_current_plate()->update_slice_result_valid_state(evt.success()); - //BBS: update the action button according to the current plate's status + // BBS: update the action button according to the current plate's status bool ready_to_slice = !this->partplate_list.get_curr_plate()->is_slice_result_valid(); // BBS @@ -6018,8 +6370,8 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) // This updates the "Slice now", "Export G-code", "Arrange" buttons status. // Namely, it refreshes the "Out of print bed" property of all the ModelObjects, and it enables // the "Slice now" and "Export G-code" buttons based on their "out of bed" status. - //BBS: remove this update here, will be updated in update_fff_scene later - //this->object_list_changed(); + // BBS: remove this update here, will be updated in update_fff_scene later + // this->object_list_changed(); // refresh preview if (view3D->is_dragging()) // updating scene now would interfere with the gizmo dragging @@ -6028,28 +6380,27 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) if (this->printer_technology == ptFFF) { if (is_finished) this->update_fff_scene(); - } - else + } else this->update_sla_scene(); } - //BBS: add slice&&print status update logic + // BBS: add slice&&print status update logic if (evt.cancelled()) { /*if (wxGetApp().get_mode() == comSimple) sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now"); show_action_buttons(true);*/ ready_to_slice = true; - //this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, true, true); + // this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, true, true); - //BBS + // BBS if (m_is_publishing) { m_publish_dlg->cancel(); } } else { - if((ready_to_slice) || (wxGetApp().get_mode() == comSimple)) { - //this means the current plate is not the slicing plate - //show_action_buttons(ready_to_slice); - //this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, ready_to_slice, true); + if ((ready_to_slice) || (wxGetApp().get_mode() == comSimple)) { + // this means the current plate is not the slicing plate + // show_action_buttons(ready_to_slice); + // this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, ready_to_slice, true); } if (exporting_status != ExportingStatus::NOT_EXPORTING && !has_error) { notification_manager->stop_delayed_notifications_of_type(NotificationType::ExportOngoing); @@ -6057,14 +6408,14 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) } // If writing to removable drive was scheduled, show notification with eject button if (exporting_status == ExportingStatus::EXPORTING_TO_REMOVABLE && !has_error) { - //show_action_buttons(ready_to_slice); + // show_action_buttons(ready_to_slice); this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, ready_to_slice, true); - notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path, - // Don't offer the "Eject" button on ChromeOS, the Linux side has no control over it. - platform_flavor() != PlatformFlavor::LinuxOnChromium); + notification_manager + ->push_exporting_finished_notification(last_output_path, last_output_dir_path, + // Don't offer the "Eject" button on ChromeOS, the Linux side has no control over it. + platform_flavor() != PlatformFlavor::LinuxOnChromium); wxGetApp().removable_drive_manager()->set_exporting_finished(true); - }else - if (exporting_status == ExportingStatus::EXPORTING_TO_LOCAL && !has_error) + } else if (exporting_status == ExportingStatus::EXPORTING_TO_LOCAL && !has_error) notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path, false); // BBS, Generate calibration thumbnail for current plate @@ -6074,20 +6425,19 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) preview->reload_print(); ThumbnailData* calibration_data = &partplate_list.get_curr_plate()->cali_thumbnail_data; const ThumbnailsParams calibration_params = { {}, false, true, true, true, partplate_list.get_curr_plate_index() }; - generate_calibration_thumbnail(*calibration_data, PartPlate::cali_thumbnail_width, PartPlate::cali_thumbnail_height, calibration_params); - preview->get_canvas3d()->reset_gcode_toolpaths();*/ + generate_calibration_thumbnail(*calibration_data, PartPlate::cali_thumbnail_width, PartPlate::cali_thumbnail_height, + calibration_params); preview->get_canvas3d()->reset_gcode_toolpaths();*/ // generate bbox data - PlateBBoxData* plate_bbox_data = &partplate_list.get_curr_plate()->cali_bboxes_data; - *plate_bbox_data = generate_first_layer_bbox(); + PlateBBoxData *plate_bbox_data = &partplate_list.get_curr_plate()->cali_bboxes_data; + *plate_bbox_data = generate_first_layer_bbox(); } } exporting_status = ExportingStatus::NOT_EXPORTING; - // BBS stop publishing if error occur - //if (m_is_publishing) { + // if (m_is_publishing) { // GCodeProcessorResult *gcode_result = background_process.get_current_gcode_result(); // m_publish_dlg->UpdateStatus(_L("Error occurred during slicing"), -1, false); // // if toolpath is outside @@ -6096,9 +6446,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) // } //} - - if (is_finished) - { + if (is_finished) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":finished, reload print soon"); m_is_slicing = false; this->preview->reload_print(false); @@ -6113,10 +6461,9 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) } } q->SetDropTarget(new PlaterDropTarget(q)); - } - else - { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":slicing all, plate %1% finished, start next slice...")%m_cur_slice_plate; + } else { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(":slicing all, plate %1% finished, start next slice...") % m_cur_slice_plate; m_cur_slice_plate++; q->Freeze(); @@ -6124,16 +6471,17 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) partplate_list.select_plate_view(); int ret = q->start_next_slice(); if (ret) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":slicing all, plate %1% can not be sliced, will stop")%m_cur_slice_plate; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(":slicing all, plate %1% can not be sliced, will stop") % m_cur_slice_plate; m_is_slicing = false; } - //not the last plate + // not the last plate update_fff_scene_only_shells(); q->Thaw(); if (m_is_publishing) { if (m_publish_dlg && !m_publish_dlg->was_cancelled()) { - wxString msg = wxString::Format(_L("Slicing Plate %d"), m_cur_slice_plate + 1); - int percent = 70 * m_cur_slice_plate / partplate_list.get_plate_count(); + wxString msg = wxString::Format(_L("Slicing Plate %d"), m_cur_slice_plate + 1); + int percent = 70 * m_cur_slice_plate / partplate_list.get_plate_count(); m_publish_dlg->UpdateStatus(msg, percent, false); } } @@ -6141,17 +6489,17 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(", exit."); } -void Plater::priv::on_action_add(SimpleEvent&) +void Plater::priv::on_action_add(SimpleEvent &) { if (q != nullptr) { - //q->add_model(); - //BBS open file in toolbar add + // q->add_model(); + // BBS open file in toolbar add q->add_file(); } } -//BBS: add plate from toolbar -void Plater::priv::on_action_add_plate(SimpleEvent&) +// BBS: add plate from toolbar +void Plater::priv::on_action_add_plate(SimpleEvent &) { if (q != nullptr) { take_snapshot("add partplate"); @@ -6161,39 +6509,39 @@ void Plater::priv::on_action_add_plate(SimpleEvent&) update(); // BBS set default view - //q->get_camera().select_view("topfront"); + // q->get_camera().select_view("topfront"); q->get_camera().requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE; } } -//BBS: remove plate from toolbar -void Plater::priv::on_action_del_plate(SimpleEvent&) +// BBS: remove plate from toolbar +void Plater::priv::on_action_del_plate(SimpleEvent &) { if (q != nullptr) { q->delete_plate(); - //q->get_camera().select_view("topfront"); - //q->get_camera().requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE; + // q->get_camera().select_view("topfront"); + // q->get_camera().requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE; } } -//BBS: GUI refactor: GLToolbar -void Plater::priv::on_action_open_project(SimpleEvent&) +// BBS: GUI refactor: GLToolbar +void Plater::priv::on_action_open_project(SimpleEvent &) { if (q != nullptr) { q->load_project(); } } -//BBS: GUI refactor: slice plate -void Plater::priv::on_action_slice_plate(SimpleEvent&) +// BBS: GUI refactor: slice plate +void Plater::priv::on_action_slice_plate(SimpleEvent &) { if (q != nullptr) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received slice plate event\n" ; - //BBS update extruder params and speed table before slicing - const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config(); - auto& print = q->get_partplate_list().get_current_fff_print(); - auto print_config = print.config(); - int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received slice plate event\n"; + // BBS update extruder params and speed table before slicing + const Slic3r::DynamicPrintConfig &config = wxGetApp().preset_bundle->full_config(); + auto &print = q->get_partplate_list().get_current_fff_print(); + auto print_config = print.config(); + int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); Model::setExtruderParams(config, numExtruders); Model::setPrintSpeedTable(config, print_config); @@ -6203,28 +6551,28 @@ void Plater::priv::on_action_slice_plate(SimpleEvent&) } } -//BBS: GUI refactor: slice all -void Plater::priv::on_action_slice_all(SimpleEvent&) +// BBS: GUI refactor: slice all +void Plater::priv::on_action_slice_all(SimpleEvent &) { if (q != nullptr) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received slice project event\n" ; - //BBS update extruder params and speed table before slicing - const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config(); - auto& print = q->get_partplate_list().get_current_fff_print(); - auto print_config = print.config(); - int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received slice project event\n"; + // BBS update extruder params and speed table before slicing + const Slic3r::DynamicPrintConfig &config = wxGetApp().preset_bundle->full_config(); + auto &print = q->get_partplate_list().get_current_fff_print(); + auto print_config = print.config(); + int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); Model::setExtruderParams(config, numExtruders); Model::setPrintSpeedTable(config, print_config); - m_slice_all = true; + m_slice_all = true; m_slice_all_only_has_gcode = true; - m_cur_slice_plate = 0; - //select plate + m_cur_slice_plate = 0; + // select plate q->select_plate(m_cur_slice_plate); q->reslice(); if (!m_is_publishing) q->select_view_3D("Preview"); - //BBS: wish to select all plates stats item + // BBS: wish to select all plates stats item preview->get_canvas3d()->_update_select_plate_toolbar_stats_item(true); } } @@ -6256,94 +6604,102 @@ void Plater::priv::on_action_publish(wxCommandEvent &event) } } -void Plater::priv::on_action_print_plate(SimpleEvent&) +void Plater::priv::on_action_print_plate(SimpleEvent &) { if (q != nullptr) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received print plate event\n" ; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received print plate event\n"; } - //BBS - if (!m_select_machine_dlg) m_select_machine_dlg = new SelectMachineDialog(q); + // BBS + if (!m_select_machine_dlg) + m_select_machine_dlg = new SelectMachineDialog(q); m_select_machine_dlg->set_print_type(PrintFromType::FROM_NORMAL); m_select_machine_dlg->prepare(partplate_list.get_curr_plate_index()); m_select_machine_dlg->ShowModal(); record_start_print_preset("print_plate"); } -void Plater::priv::on_action_print_plate_from_sdcard(SimpleEvent&) +void Plater::priv::on_action_print_plate_from_sdcard(SimpleEvent &) { if (q != nullptr) { BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received print plate event\n"; } - //BBS - if (!m_select_machine_dlg) m_select_machine_dlg = new SelectMachineDialog(q); + // BBS + if (!m_select_machine_dlg) + m_select_machine_dlg = new SelectMachineDialog(q); m_select_machine_dlg->set_print_type(PrintFromType::FROM_SDCARD_VIEW); m_select_machine_dlg->prepare(0); m_select_machine_dlg->ShowModal(); } -int Plater::priv::update_print_required_data(Slic3r::DynamicPrintConfig config, Slic3r::Model model, Slic3r::PlateDataPtrs plate_data_list, std::string file_name, std::string file_path) +int Plater::priv::update_print_required_data(Slic3r::DynamicPrintConfig config, + Slic3r::Model model, + Slic3r::PlateDataPtrs plate_data_list, + std::string file_name, + std::string file_path) { - if (!m_select_machine_dlg) m_select_machine_dlg = new SelectMachineDialog(q); + if (!m_select_machine_dlg) + m_select_machine_dlg = new SelectMachineDialog(q); return m_select_machine_dlg->update_print_required_data(config, model, plate_data_list, file_name, file_path); } void Plater::priv::on_action_send_to_printer(bool isall) { - if (!m_send_to_sdcard_dlg) m_send_to_sdcard_dlg = new SendToPrinterDialog(q); + if (!m_send_to_sdcard_dlg) + m_send_to_sdcard_dlg = new SendToPrinterDialog(q); if (isall) { m_send_to_sdcard_dlg->prepare(PLATE_ALL_IDX); - } - else { + } else { m_send_to_sdcard_dlg->prepare(partplate_list.get_curr_plate_index()); } - m_send_to_sdcard_dlg->ShowModal(); + m_send_to_sdcard_dlg->ShowModal(); } void Plater::priv::on_action_select_sliced_plate(wxCommandEvent &evt) { if (q != nullptr) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received select sliced plate event\n" ; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received select sliced plate event\n"; } q->select_sliced_plate(evt.GetInt()); } -void Plater::priv::on_action_print_all(SimpleEvent&) +void Plater::priv::on_action_print_all(SimpleEvent &) { if (q != nullptr) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received print all event\n" ; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received print all event\n"; } - //BBS - if (!m_select_machine_dlg) m_select_machine_dlg = new SelectMachineDialog(q); + // BBS + if (!m_select_machine_dlg) + m_select_machine_dlg = new SelectMachineDialog(q); m_select_machine_dlg->set_print_type(PrintFromType::FROM_NORMAL); m_select_machine_dlg->prepare(PLATE_ALL_IDX); m_select_machine_dlg->ShowModal(); record_start_print_preset("print_all"); } -void Plater::priv::on_action_export_gcode(SimpleEvent&) +void Plater::priv::on_action_export_gcode(SimpleEvent &) { if (q != nullptr) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n" ; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n"; q->export_gcode(false); } } -void Plater::priv::on_action_send_gcode(SimpleEvent&) +void Plater::priv::on_action_send_gcode(SimpleEvent &) { if (q != nullptr) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n" ; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n"; q->send_gcode_legacy(); } } -void Plater::priv::on_action_export_sliced_file(SimpleEvent&) +void Plater::priv::on_action_export_sliced_file(SimpleEvent &) { if (q != nullptr) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export sliced file event\n" ; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export sliced file event\n"; q->export_gcode_3mf(); } } @@ -6356,15 +6712,15 @@ void Plater::priv::on_action_export_all_sliced_file(SimpleEvent &) } } -void Plater::priv::on_action_export_to_sdcard(SimpleEvent&) +void Plater::priv::on_action_export_to_sdcard(SimpleEvent &) { - if (q != nullptr) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export sliced file event\n"; - q->send_to_printer(); - } + if (q != nullptr) { + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export sliced file event\n"; + q->send_to_printer(); + } } -void Plater::priv::on_action_export_to_sdcard_all(SimpleEvent&) +void Plater::priv::on_action_export_to_sdcard_all(SimpleEvent &) { if (q != nullptr) { BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export sliced file event\n"; @@ -6372,64 +6728,58 @@ void Plater::priv::on_action_export_to_sdcard_all(SimpleEvent&) } } - -//BBS: add plate select logic -void Plater::priv::on_plate_selected(SimpleEvent&) +// BBS: add plate select logic +void Plater::priv::on_plate_selected(SimpleEvent &) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received plate selected event\n" ; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received plate selected event\n"; sidebar->obj_list()->on_plate_selected(partplate_list.get_curr_plate_index()); } -void Plater::priv::on_action_request_model_id(wxCommandEvent& evt) +void Plater::priv::on_action_request_model_id(wxCommandEvent &evt) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received import model id event\n" ; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received import model id event\n"; if (q != nullptr) { q->import_model_id(evt.GetString()); } } -void Plater::priv::on_action_download_project(wxCommandEvent& evt) +void Plater::priv::on_action_download_project(wxCommandEvent &evt) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received download project event\n" ; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received download project event\n"; if (q != nullptr) { q->download_project(evt.GetString()); } } -//BBS: add slice button status update logic +// BBS: add slice button status update logic void Plater::priv::on_slice_button_status(bool enable) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ": enable = "<update_slice_print_status(MainFrame::eEventObjectUpdate, enable); } -void Plater::priv::on_action_split_objects(SimpleEvent&) -{ - split_object(); -} +void Plater::priv::on_action_split_objects(SimpleEvent &) { split_object(); } -void Plater::priv::on_action_split_volumes(SimpleEvent&) -{ - split_volume(); -} +void Plater::priv::on_action_split_volumes(SimpleEvent &) { split_volume(); } -void Plater::priv::on_object_select(SimpleEvent& evt) +void Plater::priv::on_object_select(SimpleEvent &evt) { wxGetApp().obj_list()->update_selections(); selection_changed(); } -//BBS: repair model through netfabb -void Plater::priv::on_repair_model(wxCommandEvent &event) -{ - wxGetApp().obj_list()->fix_through_netfabb(); -} +// BBS: repair model through netfabb +void Plater::priv::on_repair_model(wxCommandEvent &event) { wxGetApp().obj_list()->fix_through_netfabb(); } void Plater::priv::on_filament_color_changed(wxCommandEvent &event) { - //q->update_all_plate_thumbnails(true); - //q->get_preview_canvas3D()->update_plate_thumbnails(); + // q->update_all_plate_thumbnails(true); + // q->get_preview_canvas3D()->update_plate_thumbnails(); + if (wxGetApp().app_config->get("auto_calculate") == "true") { + int modify_id = event.GetInt(); + sidebar->auto_calc_flushing_volumes(modify_id); + } } void Plater::priv::install_network_plugin(wxCommandEvent &event) @@ -6440,37 +6790,40 @@ void Plater::priv::install_network_plugin(wxCommandEvent &event) void Plater::priv::update_plugin_when_launch(wxCommandEvent &event) { - std::string data_dir_str = data_dir(); + std::string data_dir_str = data_dir(); boost::filesystem::path data_dir_path(data_dir_str); - auto cache_folder = data_dir_path / "ota"; - std::string changelog_file = cache_folder.string() + "/network_plugins.json"; + auto cache_folder = data_dir_path / "ota"; + std::string changelog_file = cache_folder.string() + "/network_plugins.json"; UpdatePluginDialog dlg(wxGetApp().mainframe); dlg.update_info(changelog_file); auto result = dlg.ShowModal(); auto app_config = wxGetApp().app_config; - if (!app_config) return; + if (!app_config) + return; if (result == wxID_OK) { app_config->set("update_network_plugin", "true"); - } - else if (result == wxID_NO) { + } else if (result == wxID_NO) { app_config->set("update_network_plugin", "false"); } } void Plater::priv::show_install_plugin_hint(wxCommandEvent &event) { - notification_manager->bbl_show_plugin_install_notification(into_u8(_L("Network Plug-in is not detected. Network related features are unavailable."))); + notification_manager->bbl_show_plugin_install_notification( + into_u8(_L("Network Plug-in is not detected. Network related features are unavailable."))); } void Plater::priv::show_preview_only_hint(wxCommandEvent &event) { - notification_manager->bbl_show_preview_only_notification(into_u8(_L("Preview only mode:\nThe loaded file contains gcode only, Can not enter the Prepare page"))); + notification_manager->bbl_show_preview_only_notification( + into_u8(_L("Preview only mode:\nThe loaded file contains gcode only, Can not enter the Prepare page"))); } -void Plater::priv::on_apple_change_color_mode(wxSysColourChangedEvent& evt) { +void Plater::priv::on_apple_change_color_mode(wxSysColourChangedEvent &evt) +{ m_is_dark = wxSystemSettings::GetAppearance().IsDark(); if (view3D->get_canvas3d() && view3D->get_canvas3d()->is_initialized()) { view3D->get_canvas3d()->on_change_color_mode(m_is_dark); @@ -6479,36 +6832,35 @@ void Plater::priv::on_apple_change_color_mode(wxSysColourChangedEvent& evt) { } } -void Plater::priv::on_change_color_mode(SimpleEvent& evt) { +void Plater::priv::on_change_color_mode(SimpleEvent &evt) +{ m_is_dark = wxGetApp().app_config->get("dark_color_mode") == "1"; view3D->get_canvas3d()->on_change_color_mode(m_is_dark); preview->get_canvas3d()->on_change_color_mode(m_is_dark); assemble_view->get_canvas3d()->on_change_color_mode(m_is_dark); - if (m_send_to_sdcard_dlg) m_send_to_sdcard_dlg->on_change_color_mode(); + if (m_send_to_sdcard_dlg) + m_send_to_sdcard_dlg->on_change_color_mode(); } -void Plater::priv::on_right_click(RBtnEvent& evt) +void Plater::priv::on_right_click(RBtnEvent &evt) { int obj_idx = get_selected_object_idx(); - wxMenu* menu = nullptr; + wxMenu *menu = nullptr; - if (obj_idx == -1) { // no one or several object are selected - if (evt.data.second) { // right button was clicked on empty space + if (obj_idx == -1) { // no one or several object are selected + if (evt.data.second) { // right button was clicked on empty space if (!get_selection().is_empty()) // several objects are selected in 3DScene return; menu = menus.default_menu(); - } - else { + } else { if (current_panel == assemble_view) { menu = menus.assemble_multi_selection_menu(); - } - else { + } else { menu = menus.multi_selection_menu(); } } - } - else { + } else { // If in 3DScene is(are) selected volume(s), but right button was clicked on empty space if (evt.data.second) return; @@ -6520,20 +6872,19 @@ void Plater::priv::on_right_click(RBtnEvent& evt) if (printer_technology == ptSLA) menu = menus.sla_object_menu(); else { - const Selection& selection = get_selection(); + const Selection &selection = get_selection(); // show "Object menu" for each one or several FullInstance instead of FullObject - const bool is_some_full_instances = selection.is_single_full_instance() || - selection.is_single_full_object() || + const bool is_some_full_instances = selection.is_single_full_instance() || selection.is_single_full_object() || selection.is_multiple_full_instance(); const bool is_part = selection.is_single_volume() || selection.is_single_modifier(); - //BBS get assemble view menu + // BBS get assemble view menu if (current_panel == assemble_view) { - menu = is_some_full_instances ? menus.assemble_object_menu() : - is_part ? menus.assemble_part_menu() : menus.assemble_multi_selection_menu(); + menu = is_some_full_instances ? menus.assemble_object_menu() : + is_part ? menus.assemble_part_menu() : + menus.assemble_multi_selection_menu(); } else { - menu = is_some_full_instances ? menus.object_menu() : - is_part ? menus.part_menu() : menus.multi_selection_menu(); + menu = is_some_full_instances ? menus.object_menu() : is_part ? menus.part_menu() : menus.multi_selection_menu(); } } } @@ -6544,65 +6895,67 @@ void Plater::priv::on_right_click(RBtnEvent& evt) // (even though the position is sane). q->PopupMenu(menu); #else - //BBS: GUI refactor: move sidebar to the left + // BBS: GUI refactor: move sidebar to the left int x, y; current_panel->GetPosition(&x, &y); - q->PopupMenu(menu, (int)evt.data.first.x() + x, (int)evt.data.first.y()); - //q->PopupMenu(menu); + q->PopupMenu(menu, (int) evt.data.first.x() + x, (int) evt.data.first.y()); + // q->PopupMenu(menu); #endif } } -//BBS: add part plate related logic -void Plater::priv::on_plate_right_click(RBtnPlateEvent& evt) +// BBS: add part plate related logic +void Plater::priv::on_plate_right_click(RBtnPlateEvent &evt) { - wxMenu* menu = menus.plate_menu(); + wxMenu *menu = menus.plate_menu(); #ifdef __linux__ q->PopupMenu(menu); #else - //BBS: GUI refactor: move sidebar to the left + // BBS: GUI refactor: move sidebar to the left int x, y; current_panel->GetPosition(&x, &y); - q->PopupMenu(menu, (int)evt.data.first.x() + x, (int)evt.data.first.y()); - //q->PopupMenu(menu); + q->PopupMenu(menu, (int) evt.data.first.x() + x, (int) evt.data.first.y()); + // q->PopupMenu(menu); #endif } -void Plater::priv::on_update_geometry(Vec3dsEvent<2>&) +void Plater::priv::on_update_geometry(Vec3dsEvent<2> &) { // TODO } -void Plater::priv::on_3dcanvas_mouse_dragging_started(SimpleEvent&) -{ - view3D->get_canvas3d()->reset_sequential_print_clearance(); -} +void Plater::priv::on_3dcanvas_mouse_dragging_started(SimpleEvent &) { view3D->get_canvas3d()->reset_sequential_print_clearance(); } // Update the scene from the background processing, // if the update message was received during mouse manipulation. -void Plater::priv::on_3dcanvas_mouse_dragging_finished(SimpleEvent&) +void Plater::priv::on_3dcanvas_mouse_dragging_finished(SimpleEvent &) { if (delayed_scene_refresh) { delayed_scene_refresh = false; update_sla_scene(); } - //partplate_list.reload_all_objects(); + // partplate_list.reload_all_objects(); } -//BBS: add plate id for thumbnail generate param -void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - Camera::EType camera_type, bool use_top_view, bool for_picking) +// BBS: add plate id for thumbnail generate param +void Plater::priv::generate_thumbnail(ThumbnailData &data, + unsigned int w, + unsigned int h, + const ThumbnailsParams &thumbnail_params, + Camera::EType camera_type, + bool use_top_view, + bool for_picking) { view3D->get_canvas3d()->render_thumbnail(data, w, h, thumbnail_params, camera_type, use_top_view, for_picking); } -//BBS: add plate id for thumbnail generate param -ThumbnailsList Plater::priv::generate_thumbnails(const ThumbnailsParams& params, Camera::EType camera_type) +// BBS: add plate id for thumbnail generate param +ThumbnailsList Plater::priv::generate_thumbnails(const ThumbnailsParams ¶ms, Camera::EType camera_type) { ThumbnailsList thumbnails; - for (const Vec2d& size : params.sizes) { + for (const Vec2d &size : params.sizes) { thumbnails.push_back(ThumbnailData()); Point isize(size); // round to ints generate_thumbnail(thumbnails.back(), isize.x(), isize.y(), params, camera_type); @@ -6612,54 +6965,56 @@ ThumbnailsList Plater::priv::generate_thumbnails(const ThumbnailsParams& params, return thumbnails; } -void Plater::priv::generate_calibration_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params) +void Plater::priv::generate_calibration_thumbnail(ThumbnailData &data, + unsigned int w, + unsigned int h, + const ThumbnailsParams &thumbnail_params) { preview->get_canvas3d()->render_calibration_thumbnail(data, w, h, thumbnail_params); } PlateBBoxData Plater::priv::generate_first_layer_bbox() { - PlateBBoxData bboxdata; - std::vector& id_bboxes = bboxdata.bbox_objs; - BoundingBoxf bbox_all; - auto print = this->background_process.m_fff_print; - auto curr_plate = this->partplate_list.get_curr_plate(); - auto curr_plate_seq = curr_plate->get_real_print_seq(); - bboxdata.is_seq_print = (curr_plate_seq == PrintSequence::ByObject); - bboxdata.first_extruder = print->get_tool_ordering().first_extruder(); - bboxdata.bed_type = bed_type_to_gcode_string(print->config().curr_bed_type.value); + PlateBBoxData bboxdata; + std::vector &id_bboxes = bboxdata.bbox_objs; + BoundingBoxf bbox_all; + auto print = this->background_process.m_fff_print; + auto curr_plate = this->partplate_list.get_curr_plate(); + auto curr_plate_seq = curr_plate->get_real_print_seq(); + bboxdata.is_seq_print = (curr_plate_seq == PrintSequence::ByObject); + bboxdata.first_extruder = print->get_tool_ordering().first_extruder(); + bboxdata.bed_type = bed_type_to_gcode_string(print->config().curr_bed_type.value); // get nozzle diameter auto opt_nozzle_diameters = print->config().option("nozzle_diameter"); if (opt_nozzle_diameters != nullptr) bboxdata.nozzle_diameter = float(opt_nozzle_diameters->get_at(bboxdata.first_extruder)); - //PrintObjectPtrs objects; - //if (this->printer_technology == ptFFF) { - // objects = this->background_process.m_fff_print->objects().vector(); - //} - //else { - // objects = this->background_process.m_sla_print->objects(); - //} - auto objects = print->objects(); - auto orig = this->partplate_list.get_curr_plate()->get_origin(); - Vec2d orig2d = { orig[0], orig[1] }; + // PrintObjectPtrs objects; + // if (this->printer_technology == ptFFF) { + // objects = this->background_process.m_fff_print->objects().vector(); + // } + // else { + // objects = this->background_process.m_sla_print->objects(); + // } + auto objects = print->objects(); + auto orig = this->partplate_list.get_curr_plate()->get_origin(); + Vec2d orig2d = {orig[0], orig[1]}; BBoxData data; - for (auto obj : objects) - { + for (auto obj : objects) { auto bb_scaled = obj->get_first_layer_bbox(data.area, data.layer_height, data.name); - auto bb = unscaled(bb_scaled); + auto bb = unscaled(bb_scaled); bb.min -= orig2d; bb.max -= orig2d; bbox_all.merge(bb); data.area *= (SCALING_FACTOR * SCALING_FACTOR); // unscale area - data.id = obj->id().id; - data.bbox = { bb.min.x(),bb.min.y(),bb.max.x(),bb.max.y() }; + data.id = obj->id().id; + data.bbox = {bb.min.x(), bb.min.y(), bb.max.x(), bb.max.y()}; id_bboxes.emplace_back(data); } // add wipe tower bounding box if (print->has_wipe_tower()) { - auto wt_corners = print->first_layer_wipe_tower_corners(); + auto wt_corners = print->first_layer_wipe_tower_corners(); // when loading gcode.3mf, wipe tower info may not be correct if (!wt_corners.empty()) { BoundingBox bb_scaled = {wt_corners[0], wt_corners[2]}; @@ -6674,11 +7029,11 @@ PlateBBoxData Plater::priv::generate_first_layer_bbox() } } - bboxdata.bbox_all = { bbox_all.min.x(),bbox_all.min.y(),bbox_all.max.x(),bbox_all.max.y() }; + bboxdata.bbox_all = {bbox_all.min.x(), bbox_all.min.y(), bbox_all.max.x(), bbox_all.max.y()}; return bboxdata; } -wxString Plater::priv::get_project_filename(const wxString& extension) const +wxString Plater::priv::get_project_filename(const wxString &extension) const { if (m_project_name.empty()) return ""; @@ -6688,10 +7043,10 @@ wxString Plater::priv::get_project_filename(const wxString& extension) const } } -wxString Plater::priv::get_export_gcode_filename(const wxString& extension, bool only_filename, bool export_all) const +wxString Plater::priv::get_export_gcode_filename(const wxString &extension, bool only_filename, bool export_all) const { std::string plate_index_str; - auto plate_name = partplate_list.get_curr_plate()->get_plate_name(); + auto plate_name = partplate_list.get_curr_plate()->get_plate_name(); if (!plate_name.empty()) plate_index_str = (boost::format("_%1%") % plate_name).str(); else if (partplate_list.get_plate_count() > 1) @@ -6703,7 +7058,8 @@ wxString Plater::priv::get_export_gcode_filename(const wxString& extension, bool auto full_filename = m_project_folder / std::string((m_project_name + extension).mb_str(wxConvUTF8)); return from_path(full_filename); } else { - auto full_filename = m_project_folder / std::string((m_project_name + from_u8(plate_index_str) + extension).mb_str(wxConvUTF8)); + auto full_filename = m_project_folder / + std::string((m_project_name + from_u8(plate_index_str) + extension).mb_str(wxConvUTF8)); return from_path(full_filename); } } else { @@ -6714,29 +7070,26 @@ wxString Plater::priv::get_export_gcode_filename(const wxString& extension, bool } } else { if (only_filename) { - if(m_project_name == _L("Untitled")) + if (m_project_name == _L("Untitled")) return wxString(fs::path(model.objects.front()->name).replace_extension().c_str()) + from_u8(plate_index_str) + extension; if (export_all) return m_project_name + extension; else return m_project_name + from_u8(plate_index_str) + extension; - } - else + } else return ""; } } -wxString Plater::priv::get_project_name() -{ - return m_project_name; -} +wxString Plater::priv::get_project_name() { return m_project_name; } -//BBS -void Plater::priv::set_project_name(const wxString& project_name) +// BBS +void Plater::priv::set_project_name(const wxString &project_name) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " project is:" << project_name; m_project_name = project_name; - //update topbar title + // update topbar title wxGetApp().mainframe->SetTitle(m_project_name); #ifdef __WINDOWS__ wxGetApp().mainframe->topbar()->SetTitle(m_project_name); @@ -6746,26 +7099,27 @@ void Plater::priv::set_project_name(const wxString& project_name) #endif } -void Plater::priv::set_project_filename(const wxString& filename) +void Plater::priv::set_project_filename(const wxString &filename) { boost::filesystem::path full_path = into_path(filename); - boost::filesystem::path ext = full_path.extension(); - //if (boost::iequals(ext.string(), ".amf")) { - // // Remove the first extension. - // full_path.replace_extension(""); - // // It may be ".zip.amf". - // if (boost::iequals(full_path.extension().string(), ".zip")) - // // Remove the 2nd extension. - // full_path.replace_extension(""); - //} else { - // // Remove just one extension. - // full_path.replace_extension(""); - //} + boost::filesystem::path ext = full_path.extension(); + // if (boost::iequals(ext.string(), ".amf")) { + // // Remove the first extension. + // full_path.replace_extension(""); + // // It may be ".zip.amf". + // if (boost::iequals(full_path.extension().string(), ".zip")) + // // Remove the 2nd extension. + // full_path.replace_extension(""); + // } else { + // // Remove just one extension. + // full_path.replace_extension(""); + // } full_path.replace_extension(""); m_project_folder = full_path.parent_path(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " project folder is:" << m_project_folder.string(); - //BBS + // BBS wxString project_name = from_u8(full_path.filename().string()); set_project_name(project_name); // record filename for hint when open exported file/.gcode @@ -6797,50 +7151,29 @@ void Plater::priv::init_notification_manager() notification_manager->init_progress_indicator(); } -void Plater::orient() -{ - p->m_ui_jobs.orient(); -} +void Plater::orient() { p->m_ui_jobs.orient(); } -//BBS: add job state related functions -void Plater::set_prepare_state(int state) -{ - p->m_job_prepare_state = state; -} +// BBS: add job state related functions +void Plater::set_prepare_state(int state) { p->m_job_prepare_state = state; } -int Plater::get_prepare_state() -{ - return p->m_job_prepare_state; -} +int Plater::get_prepare_state() { return p->m_job_prepare_state; } -void Plater::get_print_job_data(PrintPrepareData* data) +void Plater::get_print_job_data(PrintPrepareData *data) { if (data) { - data->plate_idx = p->m_print_job_data.plate_idx; - data->_3mf_path = p->m_print_job_data._3mf_path; + data->plate_idx = p->m_print_job_data.plate_idx; + data->_3mf_path = p->m_print_job_data._3mf_path; data->_3mf_config_path = p->m_print_job_data._3mf_config_path; } } -int Plater::get_send_calibration_finished_event() -{ - return EVT_SEND_CALIBRATION_FINISHED; -} +int Plater::get_send_calibration_finished_event() { return EVT_SEND_CALIBRATION_FINISHED; } -int Plater::get_print_finished_event() -{ - return EVT_PRINT_FINISHED; -} +int Plater::get_print_finished_event() { return EVT_PRINT_FINISHED; } -int Plater::get_send_finished_event() -{ - return EVT_SEND_FINISHED; -} +int Plater::get_send_finished_event() { return EVT_SEND_FINISHED; } -int Plater::get_publish_finished_event() -{ - return EVT_PUBLISH_FINISHED; -} +int Plater::get_publish_finished_event() { return EVT_PUBLISH_FINISHED; } void Plater::priv::set_current_canvas_as_dirty() { @@ -6852,7 +7185,7 @@ void Plater::priv::set_current_canvas_as_dirty() assemble_view->set_as_dirty(); } -GLCanvas3D* Plater::priv::get_current_canvas3D(bool exclude_preview) +GLCanvas3D *Plater::priv::get_current_canvas3D(bool exclude_preview) { if (current_panel == view3D) return view3D->get_canvas3d(); @@ -6860,10 +7193,10 @@ GLCanvas3D* Plater::priv::get_current_canvas3D(bool exclude_preview) return preview->get_canvas3d(); else if (current_panel == assemble_view) return assemble_view->get_canvas3d(); - else //BBS default set to view3D + else // BBS default set to view3D return view3D->get_canvas3d(); - //return (current_panel == view3D) ? view3D->get_canvas3d() : ((current_panel == preview) ? preview->get_canvas3d() : nullptr); + // return (current_panel == view3D) ? view3D->get_canvas3d() : ((current_panel == preview) ? preview->get_canvas3d() : nullptr); } void Plater::priv::unbind_canvas_event_handlers() @@ -6898,10 +7231,10 @@ bool Plater::priv::init_collapse_toolbar() BackgroundTexture::Metadata background_data; background_data.filename = m_is_dark ? "toolbar_background_dark.png" : "toolbar_background.png"; - background_data.left = 16; - background_data.top = 16; - background_data.right = 16; - background_data.bottom = 16; + background_data.left = 16; + background_data.top = 16; + background_data.right = 16; + background_data.bottom = 16; if (!collapse_toolbar.init(background_data)) return false; @@ -6919,11 +7252,9 @@ bool Plater::priv::init_collapse_toolbar() item.name = "collapse_sidebar"; // set collapse svg name - item.icon_filename = "*.svg"; - item.sprite_id = 0; - item.left.action_callback = []() { - wxGetApp().plater()->collapse_sidebar(!wxGetApp().plater()->is_sidebar_collapsed()); - }; + item.icon_filename = "*.svg"; + item.sprite_id = 0; + item.left.action_callback = []() { wxGetApp().plater()->collapse_sidebar(!wxGetApp().plater()->is_sidebar_collapsed()); }; if (!collapse_toolbar.add_item(item)) return false; @@ -6934,10 +7265,7 @@ bool Plater::priv::init_collapse_toolbar() return true; } -void Plater::priv::update_preview_bottom_toolbar() -{ - ; -} +void Plater::priv::update_preview_bottom_toolbar() { ; } #if 0 void Plater::update_partplate() @@ -6946,32 +7274,25 @@ void Plater::update_partplate() } #endif -void Plater::priv::reset_gcode_toolpaths() -{ - preview->get_canvas3d()->reset_gcode_toolpaths(); -} +void Plater::priv::reset_gcode_toolpaths() { preview->get_canvas3d()->reset_gcode_toolpaths(); } bool Plater::priv::can_set_instance_to_object() const { const int obj_idx = get_selected_object_idx(); - return 0 <= obj_idx && obj_idx < (int)model.objects.size() && model.objects[obj_idx]->instances.size() > 1; + return 0 <= obj_idx && obj_idx < (int) model.objects.size() && model.objects[obj_idx]->instances.size() > 1; } -bool Plater::priv::can_split(bool to_objects) const -{ - return sidebar->obj_list()->is_splittable(to_objects); -} +bool Plater::priv::can_split(bool to_objects) const { return sidebar->obj_list()->is_splittable(to_objects); } bool Plater::priv::can_fillcolor() const { - //BBS TODO + // BBS TODO return true; } bool Plater::priv::has_assemble_view() const { - for (auto object: model.objects) - { + for (auto object : model.objects) { for (auto instance : object->instances) if (instance->is_assemble_initialized()) return true; @@ -6992,22 +7313,19 @@ bool Plater::priv::has_assemble_view() const bool Plater::priv::can_scale_to_print_volume() const { const BuildVolume_Type type = this->bed.build_volume().type(); - return !sidebar->obj_list()->has_selected_cut_object() - && !view3D->get_canvas3d()->get_selection().is_empty() - && (type == BuildVolume_Type::Rectangle || type == BuildVolume_Type::Circle); + return !sidebar->obj_list()->has_selected_cut_object() && !view3D->get_canvas3d()->get_selection().is_empty() && + (type == BuildVolume_Type::Rectangle || type == BuildVolume_Type::Circle); } #endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT bool Plater::priv::can_mirror() const { - return !sidebar->obj_list()->has_selected_cut_object() - && get_selection().is_from_single_instance(); + return !sidebar->obj_list()->has_selected_cut_object() && get_selection().is_from_single_instance(); } bool Plater::priv::can_replace_with_stl() const { - return !sidebar->obj_list()->has_selected_cut_object() - && get_selection().get_volume_idxs().size() == 1; + return !sidebar->obj_list()->has_selected_cut_object() && get_selection().get_volume_idxs().size() == 1; } bool Plater::priv::can_reload_from_disk() const @@ -7029,22 +7347,25 @@ bool Plater::priv::can_reload_from_disk() const int volume_idx; // operators needed by std::algorithms - bool operator < (const SelectedVolume& other) const { return (object_idx < other.object_idx) || ((object_idx == other.object_idx) && (volume_idx < other.volume_idx)); } - bool operator == (const SelectedVolume& other) const { return (object_idx == other.object_idx) && (volume_idx == other.volume_idx); } + bool operator<(const SelectedVolume &other) const + { + return (object_idx < other.object_idx) || ((object_idx == other.object_idx) && (volume_idx < other.volume_idx)); + } + bool operator==(const SelectedVolume &other) const { return (object_idx == other.object_idx) && (volume_idx == other.volume_idx); } }; std::vector selected_volumes; - const Selection& selection = get_selection(); + const Selection &selection = get_selection(); // collects selected ModelVolumes - const std::set& selected_volumes_idxs = selection.get_volume_idxs(); + const std::set &selected_volumes_idxs = selection.get_volume_idxs(); for (unsigned int idx : selected_volumes_idxs) { - const GLVolume* v = selection.get_volume(idx); - int v_idx = v->volume_idx(); + const GLVolume *v = selection.get_volume(idx); + int v_idx = v->volume_idx(); if (v_idx >= 0) { int o_idx = v->object_idx(); - if (0 <= o_idx && o_idx < (int)model.objects.size()) - selected_volumes.push_back({ o_idx, v_idx }); + if (0 <= o_idx && o_idx < (int) model.objects.size()) + selected_volumes.push_back({o_idx, v_idx}); } } #endif // ENABLE_RELOAD_FROM_DISK_REWORK @@ -7052,10 +7373,12 @@ bool Plater::priv::can_reload_from_disk() const #if ENABLE_RELOAD_FROM_DISK_REWORK std::sort(selected_volumes.begin(), selected_volumes.end(), [](const std::pair &v1, const std::pair &v2) { return (v1.first < v2.first) || (v1.first == v2.first && v1.second < v2.second); - }); - selected_volumes.erase(std::unique(selected_volumes.begin(), selected_volumes.end(), [](const std::pair &v1, const std::pair &v2) { - return (v1.first == v2.first) && (v1.second == v2.second); - }), selected_volumes.end()); + }); + selected_volumes.erase(std::unique(selected_volumes.begin(), selected_volumes.end(), + [](const std::pair &v1, const std::pair &v2) { + return (v1.first == v2.first) && (v1.second == v2.second); + }), + selected_volumes.end()); // collects paths of files to load std::vector paths; @@ -7068,9 +7391,9 @@ bool Plater::priv::can_reload_from_disk() const // collects paths of files to load std::vector paths; - for (const SelectedVolume& v : selected_volumes) { - const ModelObject* object = model.objects[v.object_idx]; - const ModelVolume* volume = object->volumes[v.volume_idx]; + for (const SelectedVolume &v : selected_volumes) { + const ModelObject *object = model.objects[v.object_idx]; + const ModelVolume *volume = object->volumes[v.volume_idx]; if (!volume->source.input_file.empty()) paths.push_back(volume->source.input_file); else if (!object->input_file.empty() && !volume->name.empty() && !volume->source.is_from_builtin_objects) @@ -7091,50 +7414,61 @@ void Plater::priv::update_publish_dialog_status(wxString &msg, int percent) bool Plater::priv::show_publish_dlg(bool show) { - if (q != nullptr) { BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":recevied publish event\n"; } + if (q != nullptr) { + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":recevied publish event\n"; + } - if (!m_publish_dlg) m_publish_dlg = new PublishDialog(q); + if (!m_publish_dlg) + m_publish_dlg = new PublishDialog(q); if (show) { m_publish_dlg->reset(); m_publish_dlg->start_slicing(); - //m_publish_dlg->Show(); + // m_publish_dlg->Show(); m_publish_dlg->ShowModal(); } else { m_publish_dlg->EndModal(wxID_OK); - //cancel the slicing + // cancel the slicing if (this->background_process.running()) this->background_process.stop(); } return true; } -//BBS: add bed exclude area -void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_areas, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) +// BBS: add bed exclude area +void Plater::priv::set_bed_shape(const Pointfs &shape, + const Pointfs &exclude_areas, + const double printable_height, + const std::string &custom_texture, + const std::string &custom_model, + bool force_as_custom) { - //BBS: add shape position + // BBS: add shape position Vec2d shape_position = partplate_list.get_current_shape_position(); - bool new_shape = bed.set_shape(shape, printable_height, custom_model, force_as_custom, shape_position); + bool new_shape = bed.set_shape(shape, printable_height, custom_model, force_as_custom, shape_position); float prev_height_lid, prev_height_rod; partplate_list.get_height_limits(prev_height_lid, prev_height_rod); - auto prev_logo = partplate_list.get_logo_texture_filename(); - double height_to_lid = config->opt_float("extruder_clearance_height_to_lid"); - double height_to_rod = config->opt_float("extruder_clearance_height_to_rod"); - auto custom_bed_texture = config->opt_string("bed_custom_texture"); + auto prev_logo = partplate_list.get_logo_texture_filename(); + double height_to_lid = config->opt_float("extruder_clearance_height_to_lid"); + double height_to_rod = config->opt_float("extruder_clearance_height_to_rod"); + auto custom_bed_texture = config->opt_string("bed_custom_texture"); Pointfs prev_exclude_areas = partplate_list.get_exclude_area(); - new_shape |= (height_to_lid != prev_height_lid) || (height_to_rod != prev_height_rod) || (prev_exclude_areas != exclude_areas) || (prev_logo != custom_bed_texture); + new_shape |= (height_to_lid != prev_height_lid) || (height_to_rod != prev_height_rod) || (prev_exclude_areas != exclude_areas) || + (prev_logo != custom_bed_texture); if (new_shape) { - if (view3D) view3D->bed_shape_changed(); - if (preview) preview->bed_shape_changed(); - - //BBS: update part plate's size - // BBS: to be checked - Vec3d max = bed.extended_bounding_box().max; - Vec3d min = bed.extended_bounding_box().min; - double z = config->opt_float("printable_height"); - - //Pointfs& exclude_areas = config->option("bed_exclude_area")->values; + if (view3D) + view3D->bed_shape_changed(); + if (preview) + preview->bed_shape_changed(); + + // BBS: update part plate's size + // BBS: to be checked + Vec3d max = bed.extended_bounding_box().max; + Vec3d min = bed.extended_bounding_box().min; + double z = config->opt_float("printable_height"); + + // Pointfs& exclude_areas = config->option("bed_exclude_area")->values; partplate_list.reset_size(max.x() - min.x() - Bed3D::Axes::DefaultTipRadius, max.y() - min.y() - Bed3D::Axes::DefaultTipRadius, z); partplate_list.set_shapes(shape, exclude_areas, custom_texture, height_to_lid, height_to_rod); @@ -7144,15 +7478,9 @@ void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_ar } } -bool Plater::priv::can_delete() const -{ - return !get_selection().is_empty() && !get_selection().is_wipe_tower(); -} +bool Plater::priv::can_delete() const { return !get_selection().is_empty() && !get_selection().is_wipe_tower(); } -bool Plater::priv::can_delete_all() const -{ - return !model.objects.empty(); -} +bool Plater::priv::can_delete_all() const { return !model.objects.empty(); } bool Plater::priv::can_edit_text() const { @@ -7161,26 +7489,20 @@ bool Plater::priv::can_edit_text() const return true; if (selection.is_single_volume()) { - const GLVolume *gl_volume = selection.get_volume(*selection.get_volume_idxs().begin()); + const GLVolume *gl_volume = selection.get_first_volume(); int out_object_idx = gl_volume->object_idx(); - ModelObject * model_object = selection.get_model()->objects[out_object_idx]; + ModelObject *model_object = selection.get_model()->objects[out_object_idx]; int out_volume_idx = gl_volume->volume_idx(); - ModelVolume * model_volume = model_object->volumes[out_volume_idx]; + ModelVolume *model_volume = model_object->volumes[out_volume_idx]; if (model_volume) return !model_volume->get_text_info().m_text.empty(); } return false; } -bool Plater::priv::can_add_plate() const -{ - return q->get_partplate_list().get_plate_count() < PartPlateList::MAX_PLATES_COUNT; -} +bool Plater::priv::can_add_plate() const { return q->get_partplate_list().get_plate_count() < PartPlateList::MAX_PLATES_COUNT; } -bool Plater::priv::can_delete_plate() const -{ - return q->get_partplate_list().get_plate_count() > 1; -} +bool Plater::priv::can_delete_plate() const { return q->get_partplate_list().get_plate_count() > 1; } bool Plater::priv::can_fix_through_netfabb() const { @@ -7189,8 +7511,8 @@ bool Plater::priv::can_fix_through_netfabb() const #if FIX_THROUGH_NETFABB_ALWAYS // Fixing always. - return ! obj_idxs.empty() || ! vol_idxs.empty(); -#else // FIX_THROUGH_NETFABB_ALWAYS + return !obj_idxs.empty() || !vol_idxs.empty(); +#else // FIX_THROUGH_NETFABB_ALWAYS // Fixing only if the model is not manifold. if (vol_idxs.empty()) { for (auto obj_idx : obj_idxs) @@ -7210,50 +7532,40 @@ bool Plater::priv::can_fix_through_netfabb() const bool Plater::priv::can_simplify() const { // is object for simplification selected - if (get_selected_object_idx() < 0) return false; + if (get_selected_object_idx() < 0) + return false; // is already opened? - if (q->get_view3D_canvas3D()->get_gizmos_manager().get_current_type() == - GLGizmosManager::EType::Simplify) + if (q->get_view3D_canvas3D()->get_gizmos_manager().get_current_type() == GLGizmosManager::EType::Simplify) return false; return true; } bool Plater::priv::can_increase_instances() const { - if (m_ui_jobs.is_any_running() - || q->get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode()) - return false; + if (m_ui_jobs.is_any_running() || q->get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode()) + return false; int obj_idx = get_selected_object_idx(); - return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) - && !sidebar->obj_list()->has_selected_cut_object(); + return (0 <= obj_idx) && (obj_idx < (int) model.objects.size()) && !sidebar->obj_list()->has_selected_cut_object() && + std::all_of(model.objects[obj_idx]->instances.begin(), model.objects[obj_idx]->instances.end(), + [](auto &inst) { return inst->printable; }); } bool Plater::priv::can_decrease_instances() const { - if (m_ui_jobs.is_any_running() - || q->get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode()) - return false; + if (m_ui_jobs.is_any_running() || q->get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode()) + return false; int obj_idx = get_selected_object_idx(); - return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && (model.objects[obj_idx]->instances.size() > 1) - && !sidebar->obj_list()->has_selected_cut_object(); + return (0 <= obj_idx) && (obj_idx < (int) model.objects.size()) && (model.objects[obj_idx]->instances.size() > 1) && + !sidebar->obj_list()->has_selected_cut_object(); } -bool Plater::priv::can_split_to_objects() const -{ - return q->can_split(true); -} +bool Plater::priv::can_split_to_objects() const { return q->can_split(true); } -bool Plater::priv::can_split_to_volumes() const -{ - return (printer_technology != ptSLA) && q->can_split(false); -} +bool Plater::priv::can_split_to_volumes() const { return (printer_technology != ptSLA) && q->can_split(false); } -bool Plater::priv::can_arrange() const -{ - return !model.objects.empty() && !m_ui_jobs.is_any_running(); -} +bool Plater::priv::can_arrange() const { return !model.objects.empty() && !m_ui_jobs.is_any_running(); } bool Plater::priv::layers_height_allowed() const { @@ -7261,20 +7573,47 @@ bool Plater::priv::layers_height_allowed() const return false; int obj_idx = get_selected_object_idx(); - return 0 <= obj_idx && obj_idx < (int)model.objects.size() && model.objects[obj_idx]->bounding_box().max.z() > SINKING_Z_THRESHOLD && view3D->is_layers_editing_allowed(); + return 0 <= obj_idx && obj_idx < (int) model.objects.size() && model.objects[obj_idx]->bounding_box().max.z() > SINKING_Z_THRESHOLD && + view3D->is_layers_editing_allowed(); } -bool Plater::priv::can_layers_editing() const -{ - return layers_height_allowed(); -} +bool Plater::priv::can_layers_editing() const { return layers_height_allowed(); } -void Plater::priv::on_action_layersediting(SimpleEvent&) +void Plater::priv::on_action_layersediting(SimpleEvent &) { view3D->enable_layers_editing(!view3D->is_layers_editing_enabled()); notification_manager->set_move_from_overlay(view3D->is_layers_editing_enabled()); } +void Plater::priv::on_create_filament(SimpleEvent &) +{ + CreateFilamentPresetDialog dlg(wxGetApp().mainframe); + int res = dlg.ShowModal(); + if (wxID_OK == res) { + wxGetApp().mainframe->update_side_preset_ui(); + update_ui_from_settings(); + sidebar->update_all_preset_comboboxes(); + CreatePresetSuccessfulDialog success_dlg(wxGetApp().mainframe, SuccessType::FILAMENT); + int res = success_dlg.ShowModal(); + } +} + +void Plater::priv::on_modify_filament(SimpleEvent &evt) +{ + FilamentInfomation *filament_info = static_cast(evt.GetEventObject()); + int res; + { + EditFilamentPresetDialog dlg(wxGetApp().mainframe, filament_info); + res = dlg.ShowModal(); + } + wxGetApp().mainframe->update_side_preset_ui(); + update_ui_from_settings(); + sidebar->update_all_preset_comboboxes(); + if (wxID_EDIT == res) { + wxGetApp().params_dialog()->Popup(true); + } +} + void Plater::priv::enter_gizmos_stack() { assert(m_undo_redo_stack_active == &m_undo_redo_stack_main); @@ -7292,7 +7631,7 @@ bool Plater::priv::leave_gizmos_stack() bool changed = false; assert(m_undo_redo_stack_active == &m_undo_redo_stack_gizmos); if (m_undo_redo_stack_active == &m_undo_redo_stack_gizmos) { - assert(! m_undo_redo_stack_active->empty()); + assert(!m_undo_redo_stack_active->empty()); changed = m_undo_redo_stack_gizmos.has_undo_snapshot(); m_undo_redo_stack_active->clear(); m_undo_redo_stack_active = &m_undo_redo_stack_main; @@ -7302,13 +7641,13 @@ bool Plater::priv::leave_gizmos_stack() int Plater::priv::get_active_snapshot_index() { - const size_t active_snapshot_time = this->undo_redo_stack().active_snapshot_time(); - const std::vector& ss_stack = this->undo_redo_stack().snapshots(); + const size_t active_snapshot_time = this->undo_redo_stack().active_snapshot_time(); + const std::vector &ss_stack = this->undo_redo_stack().snapshots(); const auto it = std::lower_bound(ss_stack.begin(), ss_stack.end(), UndoRedo::Snapshot(active_snapshot_time)); return it - ss_stack.begin(); } -void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRedo::SnapshotType snapshot_type) +void Plater::priv::take_snapshot(const std::string &snapshot_name, const UndoRedo::SnapshotType snapshot_type) { if (m_prevent_snapshots > 0) return; @@ -7324,12 +7663,10 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed if (this->sidebar->obj_list()->is_selected(itSettings)) { snapshot_data.flags |= UndoRedo::SnapshotData::SELECTED_SETTINGS_ON_SIDEBAR; snapshot_data.layer_range_idx = this->sidebar->obj_list()->get_selected_layers_range_idx(); - } - else if (this->sidebar->obj_list()->is_selected(itLayer)) { + } else if (this->sidebar->obj_list()->is_selected(itLayer)) { snapshot_data.flags |= UndoRedo::SnapshotData::SELECTED_LAYER_ON_SIDEBAR; snapshot_data.layer_range_idx = this->sidebar->obj_list()->get_selected_layers_range_idx(); - } - else if (this->sidebar->obj_list()->is_selected(itLayerRoot)) + } else if (this->sidebar->obj_list()->is_selected(itLayerRoot)) snapshot_data.flags |= UndoRedo::SnapshotData::SELECTED_LAYERROOT_ON_SIDEBAR; // If SLA gizmo is active, ask it if it wants to trigger support generation @@ -7337,33 +7674,39 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed if (view3D->get_canvas3d()->get_gizmos_manager().wants_reslice_supports_on_undo()) snapshot_data.flags |= UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS; - //FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config. - // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config. - // BBS: add partplate logic + // FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config. + // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print + // config. BBS: add partplate logic if (this->printer_technology == ptFFF) { - const DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config; - const DynamicPrintConfig& proj_cfg = wxGetApp().preset_bundle->project_config; - const ConfigOptionFloats* tower_x_opt = proj_cfg.option("wipe_tower_x"); - const ConfigOptionFloats* tower_y_opt = proj_cfg.option("wipe_tower_y"); + const DynamicPrintConfig &config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + const DynamicPrintConfig &proj_cfg = wxGetApp().preset_bundle->project_config; + const ConfigOptionFloats *tower_x_opt = proj_cfg.option("wipe_tower_x"); + const ConfigOptionFloats *tower_y_opt = proj_cfg.option("wipe_tower_y"); assert(tower_x_opt->values.size() == tower_y_opt->values.size()); model.wipe_tower.positions.clear(); model.wipe_tower.positions.resize(tower_x_opt->values.size()); for (int plate_idx = 0; plate_idx < tower_x_opt->values.size(); plate_idx++) { - ModelWipeTower& tower = model.wipe_tower; + ModelWipeTower &tower = model.wipe_tower; tower.positions[plate_idx] = Vec2d(tower_x_opt->get_at(plate_idx), tower_y_opt->get_at(plate_idx)); - tower.rotation = proj_cfg.opt_float("wipe_tower_rotation_angle"); + tower.rotation = proj_cfg.opt_float("wipe_tower_rotation_angle"); } } - const GLGizmosManager& gizmos = get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : view3D->get_canvas3d()->get_gizmos_manager(); + const GLGizmosManager &gizmos = get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? + assemble_view->get_canvas3d()->get_gizmos_manager() : + view3D->get_canvas3d()->get_gizmos_manager(); if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator) this->undo_redo_stack().clear(); - this->undo_redo_stack().take_snapshot(snapshot_name, model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection() : view3D->get_canvas3d()->get_selection(), gizmos, partplate_list, snapshot_data); + this->undo_redo_stack().take_snapshot(snapshot_name, model, + get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? + assemble_view->get_canvas3d()->get_selection() : + view3D->get_canvas3d()->get_selection(), + gizmos, partplate_list, snapshot_data); if (snapshot_type == UndoRedo::SnapshotType::LeavingGizmoWithAction) { - // Filter all but the last UndoRedo::SnapshotType::GizmoAction in a row between the last UndoRedo::SnapshotType::EnteringGizmo and UndoRedo::SnapshotType::LeavingGizmoWithAction. - // The remaining snapshot will be renamed to a more generic name, - // depending on what gizmo is being left. + // Filter all but the last UndoRedo::SnapshotType::GizmoAction in a row between the last UndoRedo::SnapshotType::EnteringGizmo and + // UndoRedo::SnapshotType::LeavingGizmoWithAction. The remaining snapshot will be renamed to a more generic name, depending on what + // gizmo is being left. if (gizmos.get_current() != nullptr) { std::string new_name = gizmos.get_current()->get_action_snapshot_name(); this->undo_redo_stack().reduce_noisy_snapshots(new_name); @@ -7372,23 +7715,29 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed // Reset the "dirty project" flag. m_undo_redo_stack_main.mark_current_as_saved(); } - //BBS: add PartPlateList as the paremeter for take_snapshot + // BBS: add PartPlateList as the paremeter for take_snapshot this->undo_redo_stack().release_least_recently_used(); dirty_state.update_from_undo_redo_stack(m_undo_redo_stack_main.project_modified()); // Save the last active preset name of a particular printer technology. - ((this->printer_technology == ptFFF) ? m_last_fff_printer_profile_name : m_last_sla_printer_profile_name) = wxGetApp().preset_bundle->printers.get_selected_preset_name(); - BOOST_LOG_TRIVIAL(info) << "Undo / Redo snapshot taken: " << snapshot_name << ", Undo / Redo stack memory: " << Slic3r::format_memsize_MB(this->undo_redo_stack().memsize()) << log_memory_info(); + ((this->printer_technology == ptFFF) ? m_last_fff_printer_profile_name : + m_last_sla_printer_profile_name) = wxGetApp().preset_bundle->printers.get_selected_preset_name(); + BOOST_LOG_TRIVIAL(info) << "Undo / Redo snapshot taken: " << snapshot_name + << ", Undo / Redo stack memory: " << Slic3r::format_memsize_MB(this->undo_redo_stack().memsize()) + << log_memory_info(); } void Plater::priv::undo() { - const std::vector &snapshots = this->undo_redo_stack().snapshots(); - auto it_current = std::lower_bound(snapshots.begin(), snapshots.end(), UndoRedo::Snapshot(this->undo_redo_stack().active_snapshot_time())); + const std::vector &snapshots = this->undo_redo_stack().snapshots(); + auto it_current = std::lower_bound(snapshots.begin(), snapshots.end(), + UndoRedo::Snapshot(this->undo_redo_stack().active_snapshot_time())); // BBS: undo-redo until modify record - while (--it_current != snapshots.begin() && !snapshot_modifies_project(*it_current)); - if (it_current == snapshots.begin()) return; + while (--it_current != snapshots.begin() && !snapshot_modifies_project(*it_current)) + ; + if (it_current == snapshots.begin()) + return; if (get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView) { if (it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::GizmoAction && it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::EnteringGizmo && @@ -7401,12 +7750,15 @@ void Plater::priv::undo() void Plater::priv::redo() { - const std::vector &snapshots = this->undo_redo_stack().snapshots(); - auto it_current = std::lower_bound(snapshots.begin(), snapshots.end(), UndoRedo::Snapshot(this->undo_redo_stack().active_snapshot_time())); + const std::vector &snapshots = this->undo_redo_stack().snapshots(); + auto it_current = std::lower_bound(snapshots.begin(), snapshots.end(), + UndoRedo::Snapshot(this->undo_redo_stack().active_snapshot_time())); // BBS: undo-redo until modify record - while (it_current != snapshots.end() && !snapshot_modifies_project(*it_current++)); + while (it_current != snapshots.end() && !snapshot_modifies_project(*it_current++)) + ; if (it_current != snapshots.end()) { - while (it_current != snapshots.end() && !snapshot_modifies_project(*it_current++)); + while (it_current != snapshots.end() && !snapshot_modifies_project(*it_current++)) + ; this->undo_redo_to(--it_current); } } @@ -7422,14 +7774,13 @@ void Plater::priv::undo_redo_to(size_t time_to_load) // BBS: check need save or backup bool Plater::priv::up_to_date(bool saved, bool backup) { - size_t& last_time = backup ? m_backup_timestamp : m_saved_timestamp; + size_t &last_time = backup ? m_backup_timestamp : m_saved_timestamp; if (saved) { last_time = undo_redo_stack_main().active_snapshot_time(); if (!backup) undo_redo_stack_main().mark_current_as_saved(); return true; - } - else { + } else { return !undo_redo_stack_main().has_real_change_from(last_time); } } @@ -7439,35 +7790,36 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator // Make sure that no updating function calls take_snapshot until we are done. SuppressSnapshots snapshot_supressor(q); - bool temp_snapshot_was_taken = this->undo_redo_stack().temp_snapshot_active(); - PrinterTechnology new_printer_technology = it_snapshot->snapshot_data.printer_technology; - bool printer_technology_changed = this->printer_technology != new_printer_technology; + bool temp_snapshot_was_taken = this->undo_redo_stack().temp_snapshot_active(); + PrinterTechnology new_printer_technology = it_snapshot->snapshot_data.printer_technology; + bool printer_technology_changed = this->printer_technology != new_printer_technology; if (printer_technology_changed) { - //BBS do not support SLA + // BBS do not support SLA } // Save the last active preset name of a particular printer technology. - ((this->printer_technology == ptFFF) ? m_last_fff_printer_profile_name : m_last_sla_printer_profile_name) = wxGetApp().preset_bundle->printers.get_selected_preset_name(); - //FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config. - // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config. - // BBS: add partplate logic + ((this->printer_technology == ptFFF) ? m_last_fff_printer_profile_name : + m_last_sla_printer_profile_name) = wxGetApp().preset_bundle->printers.get_selected_preset_name(); + // FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config. + // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print + // config. BBS: add partplate logic if (this->printer_technology == ptFFF) { - const DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config; - const DynamicPrintConfig& proj_cfg = wxGetApp().preset_bundle->project_config; - const ConfigOptionFloats* tower_x_opt = proj_cfg.option("wipe_tower_x"); - const ConfigOptionFloats* tower_y_opt = proj_cfg.option("wipe_tower_y"); + const DynamicPrintConfig &config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + const DynamicPrintConfig &proj_cfg = wxGetApp().preset_bundle->project_config; + const ConfigOptionFloats *tower_x_opt = proj_cfg.option("wipe_tower_x"); + const ConfigOptionFloats *tower_y_opt = proj_cfg.option("wipe_tower_y"); assert(tower_x_opt->values.size() == tower_y_opt->values.size()); model.wipe_tower.positions.clear(); model.wipe_tower.positions.resize(tower_x_opt->values.size()); for (int plate_idx = 0; plate_idx < tower_x_opt->values.size(); plate_idx++) { - ModelWipeTower& tower = model.wipe_tower; + ModelWipeTower &tower = model.wipe_tower; tower.positions[plate_idx] = Vec2d(tower_x_opt->get_at(plate_idx), tower_y_opt->get_at(plate_idx)); - tower.rotation = proj_cfg.opt_float("wipe_tower_rotation_angle"); + tower.rotation = proj_cfg.opt_float("wipe_tower_rotation_angle"); } } const int layer_range_idx = it_snapshot->snapshot_data.layer_range_idx; // Flags made of Snapshot::Flags enum values. - unsigned int new_flags = it_snapshot->snapshot_data.flags; + unsigned int new_flags = it_snapshot->snapshot_data.flags; UndoRedo::SnapshotData top_snapshot_data; top_snapshot_data.printer_technology = this->printer_technology; if (this->view3D->is_layers_editing_enabled()) @@ -7475,17 +7827,15 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator if (this->sidebar->obj_list()->is_selected(itSettings)) { top_snapshot_data.flags |= UndoRedo::SnapshotData::SELECTED_SETTINGS_ON_SIDEBAR; top_snapshot_data.layer_range_idx = this->sidebar->obj_list()->get_selected_layers_range_idx(); - } - else if (this->sidebar->obj_list()->is_selected(itLayer)) { + } else if (this->sidebar->obj_list()->is_selected(itLayer)) { top_snapshot_data.flags |= UndoRedo::SnapshotData::SELECTED_LAYER_ON_SIDEBAR; top_snapshot_data.layer_range_idx = this->sidebar->obj_list()->get_selected_layers_range_idx(); - } - else if (this->sidebar->obj_list()->is_selected(itLayerRoot)) + } else if (this->sidebar->obj_list()->is_selected(itLayerRoot)) top_snapshot_data.flags |= UndoRedo::SnapshotData::SELECTED_LAYERROOT_ON_SIDEBAR; - bool new_variable_layer_editing_active = (new_flags & UndoRedo::SnapshotData::VARIABLE_LAYER_EDITING_ACTIVE) != 0; - bool new_selected_settings_on_sidebar = (new_flags & UndoRedo::SnapshotData::SELECTED_SETTINGS_ON_SIDEBAR) != 0; - bool new_selected_layer_on_sidebar = (new_flags & UndoRedo::SnapshotData::SELECTED_LAYER_ON_SIDEBAR) != 0; - bool new_selected_layerroot_on_sidebar = (new_flags & UndoRedo::SnapshotData::SELECTED_LAYERROOT_ON_SIDEBAR) != 0; + bool new_variable_layer_editing_active = (new_flags & UndoRedo::SnapshotData::VARIABLE_LAYER_EDITING_ACTIVE) != 0; + bool new_selected_settings_on_sidebar = (new_flags & UndoRedo::SnapshotData::SELECTED_SETTINGS_ON_SIDEBAR) != 0; + bool new_selected_layer_on_sidebar = (new_flags & UndoRedo::SnapshotData::SELECTED_LAYER_ON_SIDEBAR) != 0; + bool new_selected_layerroot_on_sidebar = (new_flags & UndoRedo::SnapshotData::SELECTED_LAYERROOT_ON_SIDEBAR) != 0; if (this->view3D->get_canvas3d()->get_gizmos_manager().wants_reslice_supports_on_undo()) top_snapshot_data.flags |= UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS; @@ -7498,32 +7848,45 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator const UndoRedo::Snapshot snapshot_copy = *it_snapshot; // Do the jump in time. if (it_snapshot->timestamp < this->undo_redo_stack().active_snapshot_time() ? - this->undo_redo_stack().undo(model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection() : this->view3D->get_canvas3d()->get_selection(), get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, top_snapshot_data, it_snapshot->timestamp) : - this->undo_redo_stack().redo(model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, it_snapshot->timestamp)) { + this->undo_redo_stack().undo(model, + get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? + assemble_view->get_canvas3d()->get_selection() : + this->view3D->get_canvas3d()->get_selection(), + get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? + assemble_view->get_canvas3d()->get_gizmos_manager() : + this->view3D->get_canvas3d()->get_gizmos_manager(), + this->partplate_list, top_snapshot_data, it_snapshot->timestamp) : + this->undo_redo_stack().redo(model, + get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? + assemble_view->get_canvas3d()->get_gizmos_manager() : + this->view3D->get_canvas3d()->get_gizmos_manager(), + this->partplate_list, it_snapshot->timestamp)) { if (printer_technology_changed) { // Switch to the other printer technology. Switch to the last printer active for that particular technology. AppConfig *app_config = wxGetApp().app_config; - app_config->set("presets", PRESET_PRINTER_NAME, (new_printer_technology == ptFFF) ? m_last_fff_printer_profile_name : m_last_sla_printer_profile_name); - //FIXME Why are we reloading the whole preset bundle here? Please document. This is fishy and it is unnecessarily expensive. - // Anyways, don't report any config value substitutions, they have been already reported to the user at application start up. + app_config->set("presets", PRESET_PRINTER_NAME, + (new_printer_technology == ptFFF) ? m_last_fff_printer_profile_name : m_last_sla_printer_profile_name); + // FIXME Why are we reloading the whole preset bundle here? Please document. This is fishy and it is unnecessarily expensive. + // Anyways, don't report any config value substitutions, they have been already reported to the user at application start up. wxGetApp().preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilent); - // load_current_presets() calls Tab::load_current_preset() -> TabPrint::update() -> Object_list::update_and_show_object_settings_item(), - // but the Object list still keeps pointer to the old Model. Avoid a crash by removing selection first. + // load_current_presets() calls Tab::load_current_preset() -> TabPrint::update() -> + // Object_list::update_and_show_object_settings_item(), but the Object list still keeps pointer to the old Model. Avoid a crash + // by removing selection first. this->sidebar->obj_list()->unselect_objects(); // Load the currently selected preset into the GUI, update the preset selection box. // This also switches the printer technology based on the printer technology of the active printer profile. wxGetApp().load_current_presets(); } - //FIXME updating the Print config from the Wipe tower config values at the ModelWipeTower. - // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config. - // BBS: add partplate logic + // FIXME updating the Print config from the Wipe tower config values at the ModelWipeTower. + // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print + // config. BBS: add partplate logic if (this->printer_technology == ptFFF) { - const DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config; - const DynamicPrintConfig& proj_cfg = wxGetApp().preset_bundle->project_config; - ConfigOptionFloats* tower_x_opt = const_cast(proj_cfg.option("wipe_tower_x")); - ConfigOptionFloats* tower_y_opt = const_cast(proj_cfg.option("wipe_tower_y")); + const DynamicPrintConfig &config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + const DynamicPrintConfig &proj_cfg = wxGetApp().preset_bundle->project_config; + ConfigOptionFloats *tower_x_opt = const_cast(proj_cfg.option("wipe_tower_x")); + ConfigOptionFloats *tower_y_opt = const_cast(proj_cfg.option("wipe_tower_y")); // BBS: don't support wipe tower rotation - //double current_rotation = proj_cfg.opt_float("wipe_tower_rotation_angle"); + // double current_rotation = proj_cfg.opt_float("wipe_tower_rotation_angle"); bool need_update = false; if (tower_x_opt->values.size() != model.wipe_tower.positions.size()) { tower_x_opt->clear(); @@ -7574,20 +7937,30 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator dirty_state.update_from_undo_redo_stack(m_undo_redo_stack_main.project_modified()); } -void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool /* temp_snapshot_was_taken */) +void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot &snapshot, bool /* temp_snapshot_was_taken */) { - get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection().clear() : this->view3D->get_canvas3d()->get_selection().clear(); + get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection().clear() : + this->view3D->get_canvas3d()->get_selection().clear(); // Update volumes from the deserializd model, always stop / update the background processing (for both the SLA and FFF technologies). - this->update((unsigned int)UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE | (unsigned int)UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE); - // Release old snapshots if the memory allocated is excessive. This may remove the top most snapshot if jumping to the very first snapshot. - //if (temp_snapshot_was_taken) - // Release the old snapshots always, as it may have happened, that some of the triangle meshes got deserialized from the snapshot, while some - // triangle meshes may have gotten released from the scene or the background processing, therefore now being calculated into the Undo / Redo stack size. - this->undo_redo_stack().release_least_recently_used(); - //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time) - get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? - assemble_view->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances) : - this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances); + this->update((unsigned int) UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE | + (unsigned int) UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE); + // Release old snapshots if the memory allocated is excessive. This may remove the top most snapshot if jumping to the very first + // snapshot. + // if (temp_snapshot_was_taken) + // Release the old snapshots always, as it may have happened, that some of the triangle meshes got deserialized from the snapshot, while + // some triangle meshes may have gotten released from the scene or the background processing, therefore now being calculated into the + // Undo / Redo stack size. + this->undo_redo_stack().release_least_recently_used(); + // YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time) + get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? + assemble_view->get_canvas3d() + ->get_selection() + .set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), + this->undo_redo_stack().selection_deserialized().volumes_and_instances) : + this->view3D->get_canvas3d() + ->get_selection() + .set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), + this->undo_redo_stack().selection_deserialized().volumes_and_instances); get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot) : this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot); @@ -7596,34 +7969,37 @@ void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bo if (wxGetApp().get_mode() == comSimple && model_has_advanced_features(this->model)) { // If the user jumped to a snapshot that require user interface with advanced features, switch to the advanced mode without asking. - // There is a little risk of surprising the user, as he already must have had the advanced or advanced mode active for such a snapshot to be taken. + // There is a little risk of surprising the user, as he already must have had the advanced or advanced mode active for such a + // snapshot to be taken. Slic3r::GUI::wxGetApp().save_mode(comAdvanced); view3D->set_as_dirty(); } - // this->update() above was called with POSTPONE_VALIDATION_ERROR_MESSAGE, so that if an error message was generated when updating the back end, it would not open immediately, - // but it would be saved to be show later. Let's do it now. We do not want to display the message box earlier, because on Windows & OSX the message box takes over the message - // queue pump, which in turn executes the rendering function before a full update after the Undo / Redo jump. + // this->update() above was called with POSTPONE_VALIDATION_ERROR_MESSAGE, so that if an error message was generated when updating the + // back end, it would not open immediately, but it would be saved to be show later. Let's do it now. We do not want to display the + // message box earlier, because on Windows & OSX the message box takes over the message queue pump, which in turn executes the rendering + // function before a full update after the Undo / Redo jump. this->show_delayed_error_message(); - //FIXME what about the state of the manipulators? - //FIXME what about the focus? Cursor in the side panel? + // FIXME what about the state of the manipulators? + // FIXME what about the focus? Cursor in the side panel? - BOOST_LOG_TRIVIAL(info) << "Undo / Redo snapshot reloaded. Undo / Redo stack memory: " << Slic3r::format_memsize_MB(this->undo_redo_stack().memsize()) << log_memory_info(); + BOOST_LOG_TRIVIAL(info) << "Undo / Redo snapshot reloaded. Undo / Redo stack memory: " + << Slic3r::format_memsize_MB(this->undo_redo_stack().memsize()) << log_memory_info(); } void Plater::priv::bring_instance_forward() const { -/*#ifdef __APPLE__ - wxGetApp().other_instance_message_handler()->bring_instance_forward(); - return; -#endif //__APPLE__*/ + /*#ifdef __APPLE__ + wxGetApp().other_instance_message_handler()->bring_instance_forward(); + return; + #endif //__APPLE__*/ if (main_frame == nullptr) { BOOST_LOG_TRIVIAL(debug) << "Couldnt bring instance forward - mainframe is null"; return; } BOOST_LOG_TRIVIAL(debug) << "Orca Slicer window going forward"; - //this code maximize app window on Fedora + // this code maximize app window on Fedora { main_frame->Iconize(false); if (main_frame->IsMaximized()) @@ -7631,28 +8007,28 @@ void Plater::priv::bring_instance_forward() const else main_frame->Maximize(false); } - //this code maximize window on Ubuntu + // this code maximize window on Ubuntu { main_frame->Restore(); - wxGetApp().GetTopWindow()->SetFocus(); // focus on my window - wxGetApp().GetTopWindow()->Raise(); // bring window to front + wxGetApp().GetTopWindow()->SetFocus(); // focus on my window + wxGetApp().GetTopWindow()->Raise(); // bring window to front wxGetApp().GetTopWindow()->Show(true); // show the window } } -//BBS: popup object table -bool Plater::priv::PopupObjectTable(int object_id, int volume_id, const wxPoint& position) +// BBS: popup object table +bool Plater::priv::PopupObjectTable(int object_id, int volume_id, const wxPoint &position) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" enter, create ObjectTableDialog"); int max_width{1920}, max_height{1080}; - max_width = q->GetMaxWidth(); + max_width = q->GetMaxWidth(); max_height = q->GetMaxHeight(); ObjectTableDialog table_dialog(q, q, &model, wxSize(max_width, max_height)); - //m_popup_table = new ObjectTableDialog(q, q, &model); + // m_popup_table = new ObjectTableDialog(q, q, &model); - wxRect rect = sidebar->GetRect(); - wxPoint pos = sidebar->ClientToScreen(wxPoint(rect.x, rect.y)); + wxRect rect = sidebar->GetRect(); + wxPoint pos = sidebar->ClientToScreen(wxPoint(rect.x, rect.y)); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": show ObjectTableDialog"); table_dialog.Popup(object_id, volume_id, pos); @@ -7661,20 +8037,19 @@ bool Plater::priv::PopupObjectTable(int object_id, int volume_id, const wxPoint& return true; } - -void Plater::priv::record_start_print_preset(std::string action) { +void Plater::priv::record_start_print_preset(std::string action) +{ // record start print preset try { json j; - int plate_count = partplate_list.get_plate_count(); - j["plate_count"] = plate_count; + int plate_count = partplate_list.get_plate_count(); + j["plate_count"] = plate_count; unsigned int obj_count = model.objects.size(); - j["obj_count"] = obj_count; - auto printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset_with_vendor_profile().preset; + j["obj_count"] = obj_count; + auto printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset_with_vendor_profile().preset; if (printer_preset.is_system) { j["printer_preset_name"] = printer_preset.name; - } - else { + } else { j["printer_preset_name"] = printer_preset.config.opt_string("inherits"); } auto filament_presets = wxGetApp().preset_bundle->filament_presets; @@ -7682,47 +8057,41 @@ void Plater::priv::record_start_print_preset(std::string action) { auto filament_preset = wxGetApp().preset_bundle->filaments.find_preset(filament_presets[i]); if (filament_preset->is_system) { j["filament_preset_" + std::to_string(i)] = filament_preset->name; - } - else { + } else { j["filament_preset_" + std::to_string(i)] = filament_preset->config.opt_string("inherits"); } } - Preset& print_preset = wxGetApp().preset_bundle->prints.get_edited_preset(); + Preset &print_preset = wxGetApp().preset_bundle->prints.get_edited_preset(); if (print_preset.is_system) { j["process_preset"] = print_preset.name; - } - else { + } else { j["process_preset"] = print_preset.config.opt_string("inherits"); } - j["record_event"] = action; - NetworkAgent* agent = wxGetApp().getAgent(); - } - catch (...) { + j["record_event"] = action; + NetworkAgent *agent = wxGetApp().getAgent(); + } catch (...) { return; } - } -void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString& label) const +void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString &label) const { - switch (btn_type) - { - case ActionButtonType::abReslice: p->btn_reslice->SetLabelText(label); break; - case ActionButtonType::abExport: p->btn_export_gcode->SetLabelText(label); break; - case ActionButtonType::abSendGCode: /*p->btn_send_gcode->SetLabelText(label);*/ break; + switch (btn_type) { + case ActionButtonType::abReslice: p->btn_reslice->SetLabelText(label); break; + case ActionButtonType::abExport: p->btn_export_gcode->SetLabelText(label); break; + case ActionButtonType::abSendGCode: /*p->btn_send_gcode->SetLabelText(label);*/ break; } } // Plater / Public Plater::Plater(wxWindow *parent, MainFrame *main_frame) - : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxGetApp().get_min_size()) - , p(new priv(this, main_frame)) + : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxGetApp().get_min_size()), p(new priv(this, main_frame)) { // Initialization performed in the private c-tor - enable_wireframe(false); + enable_wireframe(true); } bool Plater::Show(bool show) @@ -7736,30 +8105,31 @@ bool Plater::is_project_dirty() const { return p->is_project_dirty(); } bool Plater::is_presets_dirty() const { return p->is_presets_dirty(); } void Plater::set_plater_dirty(bool is_dirty) { p->set_plater_dirty(is_dirty); } void Plater::update_project_dirty_from_presets() { p->update_project_dirty_from_presets(); } -int Plater::save_project_if_dirty(const wxString& reason) { return p->save_project_if_dirty(reason); } +int Plater::save_project_if_dirty(const wxString &reason) { return p->save_project_if_dirty(reason); } void Plater::reset_project_dirty_after_save() { p->reset_project_dirty_after_save(); } void Plater::reset_project_dirty_initial_presets() { p->reset_project_dirty_initial_presets(); } #if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW void Plater::render_project_state_debug_window() const { p->render_project_state_debug_window(); } #endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW -Sidebar& Plater::sidebar() { return *p->sidebar; } -const Model& Plater::model() const { return p->model; } -Model& Plater::model() { return p->model; } -const Print& Plater::fff_print() const { return p->fff_print; } -Print& Plater::fff_print() { return p->fff_print; } -const SLAPrint& Plater::sla_print() const { return p->sla_print; } -SLAPrint& Plater::sla_print() { return p->sla_print; } +Sidebar &Plater::sidebar() { return *p->sidebar; } +const Model &Plater::model() const { return p->model; } +Model &Plater::model() { return p->model; } +const Print &Plater::fff_print() const { return p->fff_print; } +Print &Plater::fff_print() { return p->fff_print; } +const SLAPrint &Plater::sla_print() const { return p->sla_print; } +SLAPrint &Plater::sla_print() { return p->sla_print; } -int Plater::new_project(bool skip_confirm, bool silent, const wxString& project_name) +int Plater::new_project(bool skip_confirm, bool silent, const wxString &project_name) { bool transfer_preset_changes = false; // BBS: save confirm auto check = [&transfer_preset_changes](bool yes_or_no) { wxString header = _L("Some presets are modified.") + "\n" + - (yes_or_no ? _L("You can keep the modified presets to the new project or discard them") : - _L("You can keep the modifield presets to the new project, discard or save changes as new presets.")); - using ab = UnsavedChangesDialog::ActionButtons; + (yes_or_no ? + _L("You can keep the modified presets to the new project or discard them") : + _L("You can keep the modifield presets to the new project, discard or save changes as new presets.")); + using ab = UnsavedChangesDialog::ActionButtons; int act_buttons = ab::KEEP | ab::REMEMBER_CHOISE; if (!yes_or_no) act_buttons |= ab::SAVE; @@ -7769,11 +8139,11 @@ int Plater::new_project(bool skip_confirm, bool silent, const wxString& project_ if (!skip_confirm && (result = close_with_confirm(check)) == wxID_CANCEL) return wxID_CANCEL; - //BBS: add only gcode mode + // BBS: add only gcode mode bool previous_gcode = m_only_gcode; - m_only_gcode = false; - m_exported_file = false; + m_only_gcode = false; + m_exported_file = false; m_loading_project = false; get_notification_manager()->bbl_close_plateinfo_notification(); get_notification_manager()->bbl_close_preview_only_notification(); @@ -7782,18 +8152,18 @@ int Plater::new_project(bool skip_confirm, bool silent, const wxString& project_ if (!silent) wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor); - //get_partplate_list().reinit(); - //get_partplate_list().update_slice_context_to_current_plate(p->background_process); - //p->preview->update_gcode_result(p->partplate_list.get_current_slice_result()); + // get_partplate_list().reinit(); + // get_partplate_list().update_slice_context_to_current_plate(p->background_process); + // p->preview->update_gcode_result(p->partplate_list.get_current_slice_result()); reset(transfer_preset_changes); reset_project_dirty_after_save(); reset_project_dirty_initial_presets(); wxGetApp().update_saved_preset_from_current_preset(); update_project_dirty_from_presets(); - //reset project + // reset project p->project.reset(); - //set project name + // set project name if (project_name.empty()) p->set_project_name(_L("Untitled")); else @@ -7804,7 +8174,7 @@ int Plater::new_project(bool skip_confirm, bool silent, const wxString& project_ Model m; model().load_from(m); // new id avoid same path name - //select first plate + // select first plate get_partplate_list().select_plate(0); SimpleEvent event(EVT_GLCANVAS_PLATE_SELECT); p->on_plate_selected(event); @@ -7824,16 +8194,13 @@ int Plater::new_project(bool skip_confirm, bool silent, const wxString& project_ return wxID_YES; } - - // BBS: FIXME, missing resotre logic -void Plater::load_project(wxString const& filename2, - wxString const& originfile) +void Plater::load_project(wxString const &filename2, wxString const &originfile) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "filename is: " << filename2 << "and originfile is: " << originfile; auto filename = filename2; - auto check = [&filename, this] (bool yes_or_no) { - if (!yes_or_no && !wxGetApp().check_and_save_current_preset_changes(_L("Load project"), - _L("Some presets are modified."))) + auto check = [&filename, this](bool yes_or_no) { + if (!yes_or_no && !wxGetApp().check_and_save_current_preset_changes(_L("Load project"), _L("Some presets are modified."))) return false; if (filename.empty()) { // Ask user for a project file name. @@ -7848,26 +8215,25 @@ void Plater::load_project(wxString const& filename2, return; } - //BBS: add only gcode mode + // BBS: add only gcode mode bool previous_gcode = m_only_gcode; // BBS if (m_loading_project) { - //some error cases happens - //return directly + // some error cases happens + // return directly BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": current loading other project, return directly"); return; - } - else + } else m_loading_project = true; - m_only_gcode = false; + m_only_gcode = false; m_exported_file = false; get_notification_manager()->bbl_close_plateinfo_notification(); get_notification_manager()->bbl_close_preview_only_notification(); get_notification_manager()->bbl_close_3mf_warn_notification(); - auto path = into_path(filename); + auto path = into_path(filename); auto strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig; if (originfile == "") { @@ -7895,23 +8261,26 @@ void Plater::load_project(wxString const& filename2, // if res is empty no data has been loaded if (!res.empty() && (load_restore || !(strategy & LoadStrategy::Silence))) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " call set_project_filename: " << load_restore ? originfile : filename; p->set_project_filename(load_restore ? originfile : filename); - if (load_restore && originfile.IsEmpty()) + if (load_restore && originfile.IsEmpty()) { p->set_project_name(_L("Untitled")); + } + } else { - if (using_exported_file()) + if (using_exported_file()) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " using ecported set project filename: " << filename; p->set_project_filename(filename); + } } - // BBS set default 3D view and direction after loading project - //p->select_view_3D("3D"); + // p->select_view_3D("3D"); if (!m_exported_file) { p->select_view("topfront"); p->camera.requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE; wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor); - } - else { + } else { p->partplate_list.select_plate_view(); } @@ -7932,14 +8301,15 @@ void Plater::load_project(wxString const& filename2, wxGetApp().params_panel()->switch_to_object_if_has_object_configs(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " load project done"; m_loading_project = false; } // BBS: save logic int Plater::save_project(bool saveAs) { - //if (up_to_date(false, false)) // should we always save - // return; + // if (up_to_date(false, false)) // should we always save + // return; auto filename = get_project_filename(".3mf"); if (!saveAs && filename.IsEmpty()) saveAs = true; @@ -7950,16 +8320,20 @@ int Plater::save_project(bool saveAs) if (filename == "") return wxID_CANCEL; - //BBS export 3mf without gcode - if (export_3mf(into_path(filename), SaveStrategy::SplitModel | SaveStrategy::ShareMesh) < 0) { - MessageDialog(this, _L("Failed to save the project.\nPlease check whether the folder exists online or if other programs open the project file."), - _L("Save project"), wxOK | wxICON_WARNING).ShowModal(); + // BBS export 3mf without gcode + if (export_3mf(into_path(filename), SaveStrategy::SplitModel | SaveStrategy::ShareMesh | SaveStrategy::FullPathSources) < 0) { + MessageDialog( + this, + _L("Failed to save the project.\nPlease check whether the folder exists online or if other programs open the project file."), + _L("Save project"), wxOK | wxICON_WARNING) + .ShowModal(); return wxID_CANCEL; } Slic3r::remove_backup(model(), false); p->set_project_filename(filename); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " call set_project_filename: " << filename; up_to_date(true, false); up_to_date(true, true); @@ -7967,189 +8341,174 @@ int Plater::save_project(bool saveAs) wxGetApp().update_saved_preset_from_current_preset(); reset_project_dirty_after_save(); try { - json j; + json j; boost::uintmax_t size = boost::filesystem::file_size(into_path(filename)); - j["file_size"] = size; - j["file_name"] = std::string(filename.mb_str()); + j["file_size"] = size; + j["file_name"] = std::string(filename.mb_str()); - NetworkAgent* agent = wxGetApp().getAgent(); - } - catch (...) {} + NetworkAgent *agent = wxGetApp().getAgent(); + } catch (...) {} return wxID_YES; } -//BBS import model by model id +// BBS import model by model id void Plater::import_model_id(wxString download_info) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " download info: " << download_info; + wxString download_origin_url = download_info; wxString download_url; wxString filename; wxString separator = "&name="; - try - { + try { size_t namePos = download_info.Find(separator); if (namePos != wxString::npos) { download_url = download_info.Mid(0, namePos); - filename = download_info.Mid(namePos + separator.Length()); + filename = download_info.Mid(namePos + separator.Length()); - } - else { + } else { fs::path download_path = fs::path(download_origin_url.wx_str()); - download_url = download_origin_url; - filename = download_path.filename().string(); + download_url = download_origin_url; + filename = download_path.filename().string(); } - } - catch (const std::exception& error) - { - //wxString sError = error.what(); + } catch (const std::exception &error) { + // wxString sError = error.what(); } - bool download_ok = false; - int retry_count = 0; + bool download_ok = false; + int retry_count = 0; const int max_retries = 3; /* jump to 3D eidtor */ - wxGetApp().mainframe->select_tab((size_t)MainFrame::TabPosition::tp3DEditor); + wxGetApp().mainframe->select_tab((size_t) MainFrame::TabPosition::tp3DEditor); /* prepare progress dialog */ - bool cont = true; - bool cont_dlg = true; - bool cancel = false; + bool cont = true; + bool cont_dlg = true; + bool cancel = false; wxString msg; wxString dlg_title = _L("Importing Model"); - int percent = 1; - ProgressDialog dlg(dlg_title, - wxString(' ', 100) + "\n\n\n\n", - 100, // range - this, // parent - wxPD_CAN_ABORT | - wxPD_APP_MODAL | - wxPD_AUTO_HIDE | - wxPD_SMOOTH); + int percent = 0; + ProgressDialog dlg(dlg_title, wxString(' ', 100) + "\n\n\n\n", + 100, // range + this, // parent + wxPD_CAN_ABORT | wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_SMOOTH); boost::filesystem::path target_path; - //reset params + // reset params p->project.reset(); /* prepare project and profile */ - boost::thread import_thread = Slic3r::create_thread([&percent, &cont, &cancel, &retry_count, max_retries, &msg, &target_path, &download_ok, download_url, &filename] { - - NetworkAgent* m_agent = Slic3r::GUI::wxGetApp().getAgent(); - if (!m_agent) return; + boost::thread import_thread = Slic3r::create_thread( + [&percent, &cont, &cancel, &retry_count, max_retries, &msg, &target_path, &download_ok, download_url, &filename] { + NetworkAgent *m_agent = Slic3r::GUI::wxGetApp().getAgent(); + if (!m_agent) + return; - int res = 0; - unsigned int http_code; - std::string http_body; + int res = 0; + unsigned int http_code; + std::string http_body; - msg = _L("prepare 3mf file..."); + msg = _L("prepare 3mf file..."); - //gets the number of files with the same name - std::vector vecFiles; - bool is_already_exist = false; + // gets the number of files with the same name + std::vector vecFiles; + bool is_already_exist = false; + target_path = fs::path(wxGetApp().app_config->get("download_path")); - target_path = fs::path(wxGetApp().app_config->get("download_path")); + try { + vecFiles.clear(); + wxString extension = fs::path(filename.wx_str()).extension().c_str(); + auto name = filename.substr(0, filename.length() - extension.length() - 1); - try - { - vecFiles.clear(); - wxString extension = fs::path(filename.wx_str()).extension().c_str(); - auto name = filename.substr(0, filename.length() - extension.length() - 1); + for (const auto &iter : boost::filesystem::directory_iterator(target_path)) { + if (boost::filesystem::is_directory(iter.path())) + continue; - for (const auto& iter : boost::filesystem::directory_iterator(target_path)) - { - if (boost::filesystem::is_directory(iter.path())) - continue; + wxString sFile = iter.path().filename().string().c_str(); + if (strstr(sFile.c_str(), name.c_str()) != NULL) { + vecFiles.push_back(sFile); + } - wxString sFile = iter.path().filename().string().c_str(); - if (strstr(sFile.c_str(), name.c_str()) != NULL) { - vecFiles.push_back(sFile); + if (sFile == filename) + is_already_exist = true; } - - if (sFile == filename) is_already_exist = true; + } catch (const std::exception &error) { + // wxString sError = error.what(); } - } - catch (const std::exception& error) - { - //wxString sError = error.what(); - } - //update filename - if (is_already_exist && vecFiles.size() >= 1) { - wxString extension = fs::path(filename.wx_str()).extension().c_str(); - wxString name = filename.substr(0, filename.length() - extension.length()); - filename = wxString::Format("%s(%d)%s", name, vecFiles.size() + 1, extension).ToStdString(); - } - - - msg = _L("downloading project ..."); - - //target_path = wxStandardPaths::Get().GetTempDir().utf8_str().data(); + // update filename + if (is_already_exist && vecFiles.size() >= 1) { + wxString extension = fs::path(filename.wx_str()).extension().c_str(); + wxString name = filename.substr(0, filename.length() - extension.length()); + filename = wxString::Format("%s(%d)%s", name, vecFiles.size() + 1, extension).ToStdString(); + } + msg = _L("downloading project ..."); - //target_path = wxGetApp().get_local_models_path().c_str(); - boost::uuids::uuid uuid = boost::uuids::random_generator()(); - std::string unique = to_string(uuid).substr(0, 6); + // target_path = wxStandardPaths::Get().GetTempDir().utf8_str().data(); - if (filename.empty()) { - filename = "untitled.3mf"; - } + // target_path = wxGetApp().get_local_models_path().c_str(); + boost::uuids::uuid uuid = boost::uuids::random_generator()(); + std::string unique = to_string(uuid).substr(0, 6); - //target_path /= (boost::format("%1%_%2%.3mf") % filename % unique).str(); - target_path /= fs::path(filename.wc_str()); + if (filename.empty()) { + filename = "untitled.3mf"; + } - fs::path tmp_path = target_path; - tmp_path += format(".%1%", ".download"); + // target_path /= (boost::format("%1%_%2%.3mf") % filename % unique).str(); + target_path /= fs::path(filename.wc_str()); + fs::path tmp_path = target_path; + tmp_path += format(".%1%", ".download"); - auto http = Http::get(download_url.ToStdString()); + auto http = Http::get(download_url.ToStdString()); - while (cont && retry_count < max_retries) { - retry_count++; - http.on_progress([&percent, &cont, &msg](Http::Progress progress, bool& cancel) { - if (!cont) cancel = true; - if (progress.dltotal != 0) { - percent = progress.dlnow * 100 / progress.dltotal; - } - msg = wxString::Format(_L("Project downloaded %d%%"), percent); - }) - .on_error([&msg, &cont, &retry_count, max_retries](std::string body, std::string error, unsigned http_status) { - (void)body; - BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%", - body, - http_status, - error); - - if (retry_count == max_retries) { - msg = _L("Importing to Orca Slicer failed. Please download the file and manually import it."); - cont = false; - } - }) - .on_complete([&cont, &download_ok, tmp_path, target_path](std::string body, unsigned /* http_status */) { + while (cont && retry_count < max_retries) { + retry_count++; + http.on_progress([&percent, &cont, &msg](Http::Progress progress, bool &cancel) { + if (!cont) + cancel = true; + if (progress.dltotal != 0) { + percent = progress.dlnow * 100 / progress.dltotal; + } + msg = wxString::Format(_L("Project downloaded %d%%"), percent); + }) + .on_error([&msg, &cont, &retry_count, max_retries](std::string body, std::string error, unsigned http_status) { + (void) body; + BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%", body, http_status, error); + + if (retry_count == max_retries) { + msg = _L("Importing to Orca Slicer failed. Please download the file and manually import it."); + cont = false; + } + }) + .on_complete([&cont, &download_ok, tmp_path, target_path](std::string body, unsigned /* http_status */) { fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc); file.write(body.c_str(), body.size()); file.close(); fs::rename(tmp_path, target_path); - cont = false; + cont = false; download_ok = true; - }).perform_sync(); + }) + .perform_sync(); // for break while - //cont = false; - } - - }); + // cont = false; + } + }); while (cont && cont_dlg) { wxMilliSleep(50); cont_dlg = dlg.Update(percent, msg); if (!cont_dlg) { - cont = cont_dlg; + cont = cont_dlg; cancel = true; } @@ -8167,9 +8526,9 @@ void Plater::import_model_id(wxString download_info) /* load project */ this->load_project(target_path.wstring()); /*BBS set project info after load project, project info is reset in load project */ - //p->project.project_model_id = model_id; - //p->project.project_design_id = design_id; - AppConfig* config = wxGetApp().app_config; + // p->project.project_model_id = model_id; + // p->project.project_design_id = design_id; + AppConfig *config = wxGetApp().app_config; if (config) { p->project.project_country_code = config->get_country_code(); } @@ -8177,8 +8536,7 @@ void Plater::import_model_id(wxString download_info) // show save new project p->set_project_filename(filename); p->notification_manager->push_import_finished_notification(target_path.string(), target_path.parent_path().string(), false); - } - else { + } else { if (!msg.empty()) { MessageDialog msg_wingow(nullptr, msg, wxEmptyString, wxICON_WARNING | wxOK); msg_wingow.SetSize(wxSize(FromDIP(480), -1)); @@ -8188,22 +8546,19 @@ void Plater::import_model_id(wxString download_info) } } -//BBS download project by project id -void Plater::download_project(const wxString& project_id) -{ - return; -} +// BBS download project by project id +void Plater::download_project(const wxString &project_id) { return; } void Plater::request_model_download(wxString url) { - wxCommandEvent* event = new wxCommandEvent(EVT_IMPORT_MODEL_ID); + wxCommandEvent *event = new wxCommandEvent(EVT_IMPORT_MODEL_ID); event->SetString(url); wxQueueEvent(this, event); } void Plater::request_download_project(std::string project_id) { - wxCommandEvent* event = new wxCommandEvent(EVT_DOWNLOAD_PROJECT); + wxCommandEvent *event = new wxCommandEvent(EVT_DOWNLOAD_PROJECT); event->SetString(project_id); wxQueueEvent(this, event); } @@ -8215,8 +8570,7 @@ bool Plater::up_to_date(bool saved, bool backup) Slic3r::clear_other_changes(backup); return p->up_to_date(saved, backup); } - return p->model.objects.empty() || (p->up_to_date(saved, backup) && - !Slic3r::has_other_changes(backup)); + return p->model.objects.empty() || (p->up_to_date(saved, backup) && !Slic3r::has_other_changes(backup)); } void Plater::add_model(bool imperial_units, std::string fname) @@ -8229,15 +8583,14 @@ void Plater::add_model(bool imperial_units, std::string fname) if (input_files.empty()) return; - for (const auto& file : input_files) + for (const auto &file : input_files) paths.emplace_back(into_path(file)); - } - else { + } else { paths.emplace_back(fname); } std::string snapshot_label; - assert(! paths.empty()); + assert(!paths.empty()); if (paths.size() == 1) { snapshot_label = "Import Object"; snapshot_label += ": "; @@ -8246,7 +8599,7 @@ void Plater::add_model(bool imperial_units, std::string fname) snapshot_label = "Import Objects"; snapshot_label += ": "; snapshot_label += paths.front().filename().string().c_str(); - for (size_t i = 1; i < paths.size(); ++ i) { + for (size_t i = 1; i < paths.size(); ++i) { snapshot_label += ", "; snapshot_label += encode_path(paths[i].filename().string().c_str()); } @@ -8258,11 +8611,21 @@ void Plater::add_model(bool imperial_units, std::string fname) auto loadfiles_type = LoadFilesType::NoFile; auto amf_files_count = get_3mf_file_count(paths); - if (paths.size() > 1 && amf_files_count < paths.size()) { loadfiles_type = LoadFilesType::Multiple3MFOther; } - if (paths.size() > 1 && amf_files_count == paths.size()) { loadfiles_type = LoadFilesType::Multiple3MF; } - if (paths.size() > 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::MultipleOther; } - if (paths.size() == 1 && amf_files_count == 1) { loadfiles_type = LoadFilesType::Single3MF; }; - if (paths.size() == 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::SingleOther; }; + if (paths.size() > 1 && amf_files_count < paths.size()) { + loadfiles_type = LoadFilesType::Multiple3MFOther; + } + if (paths.size() > 1 && amf_files_count == paths.size()) { + loadfiles_type = LoadFilesType::Multiple3MF; + } + if (paths.size() > 1 && amf_files_count == 0) { + loadfiles_type = LoadFilesType::MultipleOther; + } + if (paths.size() == 1 && amf_files_count == 1) { + loadfiles_type = LoadFilesType::Single3MF; + }; + if (paths.size() == 1 && amf_files_count == 0) { + loadfiles_type = LoadFilesType::SingleOther; + }; bool ask_multi = false; @@ -8270,9 +8633,9 @@ void Plater::add_model(bool imperial_units, std::string fname) ask_multi = true; auto strategy = LoadStrategy::LoadModel; - if (imperial_units) strategy = strategy | LoadStrategy::ImperialUnits; + if (imperial_units) + strategy = strategy | LoadStrategy::ImperialUnits; if (!load_files(paths, strategy, ask_multi).empty()) { - if (get_project_name() == _L("Untitled") && paths.size() > 0) { p->set_project_filename(wxString::FromUTF8(paths[0].string())); } @@ -8280,153 +8643,116 @@ void Plater::add_model(bool imperial_units, std::string fname) wxGetApp().mainframe->update_title(); } } -std::array get_cut_plane(const BoundingBoxf3& bbox, const double& cut_height) { - std::array plane_pts; - plane_pts[0] = Vec3d(bbox.min(0), bbox.min(1), cut_height); - plane_pts[1] = Vec3d(bbox.max(0), bbox.min(1), cut_height); - plane_pts[2] = Vec3d(bbox.max(0), bbox.max(1), cut_height); - plane_pts[3] = Vec3d(bbox.min(0), bbox.max(1), cut_height); - return plane_pts; -} -void Plater::calib_pa(const Calib_Params& params) +void Plater::calib_pa(const Calib_Params ¶ms) { const auto calib_pa_name = wxString::Format(L"Pressure Advance Test"); new_project(false, false, calib_pa_name); wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); - switch (params.mode) { - case CalibMode::Calib_PA_Line: - add_model(false, Slic3r::resources_dir() + "/calib/pressure_advance/pressure_advance_test.stl"); - break; - case CalibMode::Calib_PA_Pattern: - _calib_pa_pattern(params); - break; - case CalibMode::Calib_PA_Tower: - _calib_pa_tower(params); - break; - default: break; + case CalibMode::Calib_PA_Line: add_model(false, Slic3r::resources_dir() + "/calib/pressure_advance/pressure_advance_test.stl"); break; + case CalibMode::Calib_PA_Pattern: _calib_pa_pattern(params); break; + case CalibMode::Calib_PA_Tower: _calib_pa_tower(params); break; + default: break; } p->background_process.fff_print()->set_calib_params(params); } -void Plater::_calib_pa_pattern(const Calib_Params& params) +void Plater::_calib_pa_pattern(const Calib_Params ¶ms) { // add "handle" cube sidebar().obj_list()->load_generic_subobject("Cube", ModelVolumeType::INVALID); orient(); - changed_objects({ 0 }); + changed_objects({0}); _calib_pa_select_added_objects(); - const DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config; - DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; - double nozzle_diameter = printer_config.option("nozzle_diameter")->get_at(0); + const DynamicPrintConfig &printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + DynamicPrintConfig &print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + double nozzle_diameter = printer_config.option("nozzle_diameter")->get_at(0); for (const auto opt : SuggestedConfigCalibPAPattern().float_pairs) { - print_config.set_key_value( - opt.first, - new ConfigOptionFloat(opt.second) - ); + print_config.set_key_value(opt.first, new ConfigOptionFloat(opt.second)); } - print_config.set_key_value( - "outer_wall_speed", - new ConfigOptionFloat(CalibPressureAdvance::find_optimal_PA_speed( - wxGetApp().preset_bundle->full_config(), print_config.get_abs_value("line_width", nozzle_diameter), - print_config.get_abs_value("layer_height"), 0))); + print_config.set_key_value("outer_wall_speed", + new ConfigOptionFloat( + CalibPressureAdvance::find_optimal_PA_speed(wxGetApp().preset_bundle->full_config(), + print_config.get_abs_value("line_width", nozzle_diameter), + print_config.get_abs_value("layer_height"), 0))); for (const auto opt : SuggestedConfigCalibPAPattern().nozzle_ratio_pairs) { - print_config.set_key_value( - opt.first, - new ConfigOptionFloatOrPercent(nozzle_diameter * opt.second / 100, false) - ); + print_config.set_key_value(opt.first, new ConfigOptionFloatOrPercent(nozzle_diameter * opt.second / 100, false)); } for (const auto opt : SuggestedConfigCalibPAPattern().int_pairs) { - print_config.set_key_value( - opt.first, - new ConfigOptionInt(opt.second) - ); + print_config.set_key_value(opt.first, new ConfigOptionInt(opt.second)); } - print_config.set_key_value( - SuggestedConfigCalibPAPattern().brim_pair.first, - new ConfigOptionEnum(SuggestedConfigCalibPAPattern().brim_pair.second) - ); + print_config.set_key_value(SuggestedConfigCalibPAPattern().brim_pair.first, + new ConfigOptionEnum(SuggestedConfigCalibPAPattern().brim_pair.second)); wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config(); - const DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config(); - PresetBundle* preset_bundle = wxGetApp().preset_bundle; - const bool is_bbl_machine = preset_bundle->is_bbl_vendor(); - const Vec3d plate_origin = get_partplate_list().get_current_plate_origin(); - CalibPressureAdvancePattern pa_pattern( - params, - full_config, - is_bbl_machine, - model(), - plate_origin - ); + const DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config(); + PresetBundle *preset_bundle = wxGetApp().preset_bundle; + const bool is_bbl_machine = preset_bundle->is_bbl_vendor(); + const Vec3d plate_origin = get_partplate_list().get_current_plate_origin(); + CalibPressureAdvancePattern pa_pattern(params, full_config, is_bbl_machine, model(), plate_origin); // scale cube to suit test - GizmoObjectManipulation& giz_obj_manip = p->view3D->get_canvas3d()-> - get_gizmos_manager().get_object_manipulation(); + GizmoObjectManipulation &giz_obj_manip = p->view3D->get_canvas3d()->get_gizmos_manager().get_object_manipulation(); giz_obj_manip.set_uniform_scaling(true); - giz_obj_manip.on_change( - "size", - 0, - pa_pattern.handle_xy_size() - ); + giz_obj_manip.on_change("size", 0, pa_pattern.handle_xy_size()); giz_obj_manip.set_uniform_scaling(false); - giz_obj_manip.on_change( - "size", - 2, - pa_pattern.max_layer_z() - ); + giz_obj_manip.on_change("size", 2, pa_pattern.max_layer_z()); // start with pattern centered on plate center_selection(); const Vec3d plate_center = get_partplate_list().get_curr_plate()->get_center_origin(); - giz_obj_manip.on_change( - "position", - 0, - plate_center.x() - (pa_pattern.print_size_x() / 2) - ); - giz_obj_manip.on_change( - "position", - 1, - plate_center.y() - - (pa_pattern.print_size_y() / 2) - - pa_pattern.handle_spacing() - ); - - pa_pattern.generate_custom_gcodes( - full_config, - is_bbl_machine, - model(), - plate_origin - ); + giz_obj_manip.on_change("position", 0, plate_center.x() - (pa_pattern.print_size_x() / 2)); + giz_obj_manip.on_change("position", 1, plate_center.y() - (pa_pattern.print_size_y() / 2) - pa_pattern.handle_spacing()); + + pa_pattern.generate_custom_gcodes(full_config, is_bbl_machine, model(), plate_origin); model().calib_pa_pattern = std::make_unique(pa_pattern); - changed_objects({ 0 }); + changed_objects({0}); +} + +void Plater::cut_horizontal(size_t obj_idx, size_t instance_idx, double z, ModelObjectCutAttributes attributes) +{ + wxCHECK_RET(obj_idx < p->model.objects.size(), "obj_idx out of bounds"); + auto *object = p->model.objects[obj_idx]; + + wxCHECK_RET(instance_idx < object->instances.size(), "instance_idx out of bounds"); + + if (!attributes.has(ModelObjectCutAttribute::KeepUpper) && !attributes.has(ModelObjectCutAttribute::KeepLower)) + return; + + wxBusyCursor wait; + + const Vec3d instance_offset = object->instances[instance_idx]->get_offset(); + Cut cut(object, instance_idx, Geometry::translation_transform(z * Vec3d::UnitZ() - instance_offset), attributes); + const auto new_objects = cut.perform_with_plane(); + + apply_cut_object_to_model(obj_idx, new_objects); } -void Plater::_calib_pa_tower(const Calib_Params& params) { +void Plater::_calib_pa_tower(const Calib_Params ¶ms) +{ add_model(false, Slic3r::resources_dir() + "/calib/pressure_advance/tower_with_seam.stl"); - auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; - auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; const double nozzle_diameter = printer_config->option("nozzle_diameter")->get_at(0); - filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{ 1.0f }); + filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{1.0f}); print_config->set_key_value("default_jerk", new ConfigOptionFloat(1.0f)); print_config->set_key_value("outer_wall_jerk", new ConfigOptionFloat(1.0f)); print_config->set_key_value("inner_wall_jerk", new ConfigOptionFloat(1.0f)); auto full_config = wxGetApp().preset_bundle->full_config(); - auto wall_speed = CalibPressureAdvance::find_optimal_PA_speed( - full_config, full_config.get_abs_value("line_width", nozzle_diameter), - full_config.get_abs_value("layer_height"), 0); + auto wall_speed = CalibPressureAdvance::find_optimal_PA_speed(full_config, full_config.get_abs_value("line_width", nozzle_diameter), + full_config.get_abs_value("layer_height"), 0); print_config->set_key_value("outer_wall_speed", new ConfigOptionFloat(wall_speed)); print_config->set_key_value("inner_wall_speed", new ConfigOptionFloat(wall_speed)); // print_config->set_key_value("wall_generator", new ConfigOptionEnum(PerimeterGeneratorType::Classic)); @@ -8435,7 +8761,7 @@ void Plater::_calib_pa_tower(const Calib_Params& params) { print_config->set_key_value("wall_transition_angle", new ConfigOptionFloat(25)); model().objects[0]->config.set_key_value("seam_position", new ConfigOptionEnum(spRear)); - changed_objects({ 0 }); + changed_objects({0}); wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty(); @@ -8444,20 +8770,20 @@ void Plater::_calib_pa_tower(const Calib_Params& params) { wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); auto new_height = std::ceil((params.end - params.start) / params.step) + 1; - auto obj_bb = model().objects[0]->bounding_box(); + auto obj_bb = model().objects[0]->bounding_box(); if (new_height < obj_bb.size().z()) { - std::array plane_pts = get_cut_plane(obj_bb, new_height); - cut(0, 0, plane_pts, ModelObjectCutAttribute::KeepLower); + cut_horizontal(0, 0, new_height, ModelObjectCutAttribute::KeepLower); } _calib_pa_select_added_objects(); } -void Plater::_calib_pa_select_added_objects() { +void Plater::_calib_pa_select_added_objects() +{ // update printable state for new volumes on canvas3D wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects({0}); - Selection& selection = p->view3D->get_canvas3d()->get_selection(); + Selection &selection = p->view3D->get_canvas3d()->get_selection(); selection.clear(); selection.add_object(0, false); @@ -8470,50 +8796,52 @@ void Plater::_calib_pa_select_added_objects() { } } -void Plater::calib_flowrate(int pass) { +void Plater::calib_flowrate(int pass) +{ if (pass != 1 && pass != 2) return; const auto calib_name = wxString::Format(L"Flowrate Test - Pass%d", pass); new_project(false, false, calib_name); wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); - - if(pass == 1) - add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass1.3mf").string()); + + if (pass == 1) + add_model(false, + (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass1.3mf").string()); else - add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass2.3mf").string()); + add_model(false, + (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass2.3mf").string()); - auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; - auto printerConfig = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; + auto printerConfig = &wxGetApp().preset_bundle->printers.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; /// --- scale --- // model is created for a 0.4 nozzle, scale z with nozzle size. - const ConfigOptionFloats* nozzle_diameter_config = printerConfig->option("nozzle_diameter"); + const ConfigOptionFloats *nozzle_diameter_config = printerConfig->option("nozzle_diameter"); assert(nozzle_diameter_config->values.size() > 0); float nozzle_diameter = nozzle_diameter_config->values[0]; - float xyScale = nozzle_diameter / 0.6; - //scale z to have 7 layers + float xyScale = nozzle_diameter / 0.6; + // scale z to have 7 layers double first_layer_height = print_config->option("initial_layer_print_height")->value; - double layer_height = nozzle_diameter / 2.0; // prefer 0.2 layer height for 0.4 nozzle - first_layer_height = std::max(first_layer_height, layer_height); + double layer_height = nozzle_diameter / 2.0; // prefer 0.2 layer height for 0.4 nozzle + first_layer_height = std::max(first_layer_height, layer_height); float zscale = (first_layer_height + 6 * layer_height) / 1.4; // only enlarge if (xyScale > 1.2) { for (auto _obj : model().objects) - _obj->scale(xyScale, xyScale, zscale); - } - else { + _obj->scale(xyScale, xyScale, zscale); + } else { for (auto _obj : model().objects) _obj->scale(1, 1, zscale); } - Flow infill_flow = Flow(nozzle_diameter * 1.2f, layer_height, nozzle_diameter); + Flow infill_flow = Flow(nozzle_diameter * 1.2f, layer_height, nozzle_diameter); double filament_max_volumetric_speed = filament_config->option("filament_max_volumetric_speed")->get_at(0); - double max_infill_speed = filament_max_volumetric_speed / (infill_flow.mm3_per_mm() * (pass == 1 ? 1.2 : 1)); - double internal_solid_speed = std::floor(std::min(print_config->opt_float("internal_solid_infill_speed"), max_infill_speed)); - double top_surface_speed = std::floor(std::min(print_config->opt_float("top_surface_speed"), max_infill_speed)); + double max_infill_speed = filament_max_volumetric_speed / (infill_flow.mm3_per_mm() * (pass == 1 ? 1.2 : 1)); + double internal_solid_speed = std::floor(std::min(print_config->opt_float("internal_solid_infill_speed"), max_infill_speed)); + double top_surface_speed = std::floor(std::min(print_config->opt_float("top_surface_speed"), max_infill_speed)); // adjust parameters for (auto _obj : model().objects) { @@ -8521,6 +8849,7 @@ void Plater::calib_flowrate(int pass) { _obj->config.set_key_value("wall_loops", new ConfigOptionInt(3)); _obj->config.set_key_value("only_one_wall_top", new ConfigOptionBool(true)); _obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(35)); + _obj->config.set_key_value("min_width_top_surface", new ConfigOptionPercent(100)); _obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(1)); _obj->config.set_key_value("top_shell_layers", new ConfigOptionInt(5)); _obj->config.set_key_value("detect_thin_wall", new ConfigOptionBool(true)); @@ -8543,13 +8872,13 @@ void Plater::calib_flowrate(int pass) { if (obj_name[0] == 'm') obj_name[0] = '-'; auto modifier = stof(obj_name); - _obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f + modifier/100.f)); + _obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f + modifier / 100.f)); } print_config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); print_config->set_key_value("initial_layer_print_height", new ConfigOptionFloat(first_layer_height)); print_config->set_key_value("reduce_crossing_wall", new ConfigOptionBool(true)); - //filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{ 9. }); + // filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{ 9. }); wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); @@ -8559,55 +8888,54 @@ void Plater::calib_flowrate(int pass) { wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); } -void Plater::calib_temp(const Calib_Params& params) { +void Plater::calib_temp(const Calib_Params ¶ms) +{ const auto calib_temp_name = wxString::Format(L"Nozzle temperature test"); new_project(false, false, calib_temp_name); wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); if (params.mode != CalibMode::Calib_Temp_Tower) return; - + add_model(false, Slic3r::resources_dir() + "/calib/temperature_tower/temperature_tower.stl"); auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; - auto start_temp = lround(params.start); - filament_config->set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(1,(int)start_temp)); - filament_config->set_key_value("nozzle_temperature", new ConfigOptionInts(1,(int)start_temp)); + auto start_temp = lround(params.start); + filament_config->set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(1, (int) start_temp)); + filament_config->set_key_value("nozzle_temperature", new ConfigOptionInts(1, (int) start_temp)); model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(5.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); - changed_objects({ 0 }); + changed_objects({0}); wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config(); // cut upper - auto obj_bb = model().objects[0]->bounding_box(); + auto obj_bb = model().objects[0]->bounding_box(); auto block_count = lround((350 - params.end) / 5 + 1); - if(block_count > 0){ + if (block_count > 0) { // add EPSILON offset to avoid cutting at the exact location where the flat surface is auto new_height = block_count * 10.0 + EPSILON; if (new_height < obj_bb.size().z()) { - std::array plane_pts = get_cut_plane(obj_bb, new_height); - cut(0, 0, plane_pts, ModelObjectCutAttribute::KeepLower); + cut_horizontal(0, 0, new_height, ModelObjectCutAttribute::KeepLower); } } - + // cut bottom - obj_bb = model().objects[0]->bounding_box(); + obj_bb = model().objects[0]->bounding_box(); block_count = lround((350 - params.start) / 5); - if(block_count > 0){ + if (block_count > 0) { auto new_height = block_count * 10.0 + EPSILON; if (new_height < obj_bb.size().z()) { - std::array plane_pts = get_cut_plane(obj_bb, new_height); - cut(0, 0, plane_pts, ModelObjectCutAttribute::KeepUpper); + cut_horizontal(0, 0, new_height, ModelObjectCutAttribute::KeepUpper); } } - + p->background_process.fff_print()->set_calib_params(params); } -void Plater::calib_max_vol_speed(const Calib_Params& params) +void Plater::calib_max_vol_speed(const Calib_Params ¶ms) { const auto calib_vol_speed_name = wxString::Format(L"Max volumetric speed test"); new_project(false, false, calib_vol_speed_name); @@ -8617,31 +8945,31 @@ void Plater::calib_max_vol_speed(const Calib_Params& params) add_model(false, Slic3r::resources_dir() + "/calib/volumetric_speed/SpeedTestStructure.step"); - auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; - auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; - auto obj = model().objects[0]; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + auto obj = model().objects[0]; - auto bed_shape = printer_config->option("printable_area")->values; - BoundingBoxf bed_ext = get_extents(bed_shape); - auto scale_obj = (bed_ext.size().x() - 10) / obj->bounding_box().size().x(); + auto bed_shape = printer_config->option("printable_area")->values; + BoundingBoxf bed_ext = get_extents(bed_shape); + auto scale_obj = (bed_ext.size().x() - 10) / obj->bounding_box().size().x(); if (scale_obj < 1.0) obj->scale(scale_obj, 1, 1); - const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter"); + const ConfigOptionFloats *nozzle_diameter_config = printer_config->option("nozzle_diameter"); assert(nozzle_diameter_config->values.size() > 0); double nozzle_diameter = nozzle_diameter_config->values[0]; - double line_width = nozzle_diameter * 1.75; - double layer_height = nozzle_diameter * 0.8; + double line_width = nozzle_diameter * 1.75; + double layer_height = nozzle_diameter * 0.8; auto max_lh = printer_config->option("max_layer_height"); if (max_lh->values[0] < layer_height) - max_lh->values[0] = { layer_height }; + max_lh->values[0] = {layer_height}; - filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats { 200 }); + filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{200}); filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{0.0}); - - print_config->set_key_value("enable_overhang_speed", new ConfigOptionBool { false }); + + print_config->set_key_value("enable_overhang_speed", new ConfigOptionBool{false}); print_config->set_key_value("timelapse_type", new ConfigOptionEnum(tlTraditional)); print_config->set_key_value("wall_loops", new ConfigOptionInt(1)); print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0)); @@ -8656,7 +8984,7 @@ void Plater::calib_max_vol_speed(const Calib_Params& params) obj->config.set_key_value("brim_width", new ConfigOptionFloat(5.0)); obj->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); - changed_objects({ 0 }); + changed_objects({0}); wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty(); @@ -8668,22 +8996,20 @@ void Plater::calib_max_vol_speed(const Calib_Params& params) auto obj_bb = obj->bounding_box(); auto height = (params.end - params.start + 1) / params.step; if (height < obj_bb.size().z()) { - std::array plane_pts = get_cut_plane(obj_bb, height); - cut(0, 0, plane_pts, ModelObjectCutAttribute::KeepLower); + cut_horizontal(0, 0, height, ModelObjectCutAttribute::KeepLower); } auto new_params = params; auto mm3_per_mm = Flow(line_width, layer_height, nozzle_diameter).mm3_per_mm() * filament_config->option("filament_flow_ratio")->get_at(0); - new_params.end = params.end / mm3_per_mm; + new_params.end = params.end / mm3_per_mm; new_params.start = params.start / mm3_per_mm; - new_params.step = params.step / mm3_per_mm; - + new_params.step = params.step / mm3_per_mm; p->background_process.fff_print()->set_calib_params(new_params); } -void Plater::calib_retraction(const Calib_Params& params) +void Plater::calib_retraction(const Calib_Params ¶ms) { const auto calib_retraction_name = wxString::Format(L"Retraction test"); new_project(false, false, calib_retraction_name); @@ -8693,16 +9019,16 @@ void Plater::calib_retraction(const Calib_Params& params) add_model(false, Slic3r::resources_dir() + "/calib/retraction/retraction_tower.stl"); - auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; - auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; - auto obj = model().objects[0]; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + auto obj = model().objects[0]; double layer_height = 0.2; auto max_lh = printer_config->option("max_layer_height"); if (max_lh->values[0] < layer_height) - max_lh->values[0] = { layer_height }; + max_lh->values[0] = {layer_height}; obj->config.set_key_value("wall_loops", new ConfigOptionInt(2)); obj->config.set_key_value("top_shell_layers", new ConfigOptionInt(0)); @@ -8711,20 +9037,19 @@ void Plater::calib_retraction(const Calib_Params& params) obj->config.set_key_value("initial_layer_print_height", new ConfigOptionFloat(layer_height)); obj->config.set_key_value("layer_height", new ConfigOptionFloat(layer_height)); - changed_objects({ 0 }); + changed_objects({0}); // cut upper auto obj_bb = obj->bounding_box(); auto height = 1.0 + 0.4 + ((params.end - params.start)) / params.step; if (height < obj_bb.size().z()) { - std::array plane_pts = get_cut_plane(obj_bb, height); - cut(0, 0, plane_pts, ModelObjectCutAttribute::KeepLower); + cut_horizontal(0, 0, height, ModelObjectCutAttribute::KeepLower); } p->background_process.fff_print()->set_calib_params(params); } -void Plater::calib_VFA(const Calib_Params& params) +void Plater::calib_VFA(const Calib_Params ¶ms) { const auto calib_vfa_name = wxString::Format(L"VFA test"); new_project(false, false, calib_vfa_name); @@ -8733,11 +9058,11 @@ void Plater::calib_VFA(const Calib_Params& params) return; add_model(false, Slic3r::resources_dir() + "/calib/vfa/VFA.stl"); - auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; - filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 0.0 }); - filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats { 200 }); - print_config->set_key_value("enable_overhang_speed", new ConfigOptionBool { false }); + filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{0.0}); + filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{200}); + print_config->set_key_value("enable_overhang_speed", new ConfigOptionBool{false}); print_config->set_key_value("timelapse_type", new ConfigOptionEnum(tlTraditional)); print_config->set_key_value("wall_loops", new ConfigOptionInt(1)); print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0)); @@ -8749,7 +9074,7 @@ void Plater::calib_VFA(const Calib_Params& params) model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); - changed_objects({ 0 }); + changed_objects({0}); wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings(); @@ -8759,14 +9084,13 @@ void Plater::calib_VFA(const Calib_Params& params) auto obj_bb = model().objects[0]->bounding_box(); auto height = 5 * ((params.end - params.start) / params.step + 1); if (height < obj_bb.size().z()) { - std::array plane_pts = get_cut_plane(obj_bb, height); - cut(0, 0, plane_pts, ModelObjectCutAttribute::KeepLower); + cut_horizontal(0, 0, height, ModelObjectCutAttribute::KeepLower); } p->background_process.fff_print()->set_calib_params(params); } BuildVolume_Type Plater::get_build_volume_type() const { return p->bed.get_build_volume_type(); } -void Plater::import_sl1_archive() +void Plater::import_sl1_archive() { if (!p->m_ui_jobs.is_any_running()) p->m_ui_jobs.import_sla_arch(); @@ -8777,8 +9101,8 @@ void Plater::extract_config_from_project() wxString input_file; wxGetApp().load_project(this, input_file); - if (! input_file.empty()) - load_files({ into_path(input_file) }, LoadStrategy::LoadConfig); + if (!input_file.empty()) + load_files({into_path(input_file)}, LoadStrategy::LoadConfig); } void Plater::load_gcode() @@ -8790,12 +9114,11 @@ void Plater::load_gcode() load_gcode(input_file); } -//BBS: remove GCodeViewer as seperate APP logic -void Plater::load_gcode(const wxString& filename) +// BBS: remove GCodeViewer as seperate APP logic +void Plater::load_gcode(const wxString &filename) { - if (! is_gcode_file(into_u8(filename)) - || (m_last_loaded_gcode == filename && m_only_gcode) - ) + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " entry and filename: " << filename; + if (!is_gcode_file(into_u8(filename)) || (m_last_loaded_gcode == filename && m_only_gcode)) return; m_last_loaded_gcode = filename; @@ -8807,34 +9130,31 @@ void Plater::load_gcode(const wxString& filename) m_only_gcode = true; // cleanup view before to start loading/processing - //BBS: update gcode to current partplate's - GCodeProcessorResult* current_result = p->partplate_list.get_current_slice_result(); - Print& current_print = p->partplate_list.get_current_fff_print(); - //BBS:already reset in new_project - //current_result->reset(); - //p->gcode_result.reset(); - //reset_gcode_toolpaths(); + // BBS: update gcode to current partplate's + GCodeProcessorResult *current_result = p->partplate_list.get_current_slice_result(); + Print ¤t_print = p->partplate_list.get_current_fff_print(); + // BBS:already reset in new_project + // current_result->reset(); + // p->gcode_result.reset(); + // reset_gcode_toolpaths(); p->preview->reload_print(false, m_only_gcode); wxGetApp().mainframe->select_tab(MainFrame::tpPreview); p->set_current_panel(p->preview, true); p->get_current_canvas3D()->render(); - //p->notification_manager->bbl_show_plateinfo_notification(into_u8(_L("Preview only mode for gcode file."))); + // p->notification_manager->bbl_show_plateinfo_notification(into_u8(_L("Preview only mode for gcode file."))); wxBusyCursor wait; // process gcode GCodeProcessor processor; - try - { + try { processor.process_file(filename.ToUTF8().data()); - } - catch (const std::exception& ex) - { + } catch (const std::exception &ex) { show_error(this, ex.what()); return; } *current_result = std::move(processor.extract_result()); - //current_result->filename = filename; + // current_result->filename = filename; BedType bed_type = current_result->bed_type; if (bed_type != BedType::btCount) { @@ -8845,21 +9165,37 @@ void Plater::load_gcode(const wxString& filename) current_print.apply(this->model(), wxGetApp().preset_bundle->full_config()); + // BBS: add cost info when drag in gcode + auto &ps = current_result->print_statistics; + double total_cost = 0.0; + for (auto &volumes_map : {ps.volumes_per_extruder, ps.flush_per_filament, ps.wipe_tower_volumes_per_extruder}) { + for (auto volume : volumes_map) { + size_t extruder_id = volume.first; + double density = current_result->filament_densities.at(extruder_id); + double cost = current_result->filament_costs.at(extruder_id); + double weight = volume.second * density * 0.001; + total_cost += weight * cost * 0.001; + } + } + current_print.print_statistics().total_cost = total_cost; + current_print.set_gcode_file_ready(); // show results p->preview->reload_print(false, m_only_gcode); - //BBS: zoom to bed 0 for gcode preview - //p->preview->get_canvas3d()->zoom_to_gcode(); + // BBS: zoom to bed 0 for gcode preview + // p->preview->get_canvas3d()->zoom_to_gcode(); p->preview->get_canvas3d()->zoom_to_plate(0); if (p->preview->get_canvas3d()->get_gcode_layers_zs().empty()) { MessageDialog(this, _L("The selected file") + ":\n" + filename + "\n" + _L("does not contain valid gcode."), - wxString(GCODEVIEWER_APP_NAME) + " - " + _L("Error occurs while loading G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); + wxString(GCODEVIEWER_APP_NAME) + " - " + _L("Error occurs while loading G-code file"), + wxCLOSE | wxICON_WARNING | wxCENTRE) + .ShowModal(); set_project_filename(DEFAULT_PROJECT_NAME); - } - else + } else { set_project_filename(filename); + } } void Plater::reload_gcode_from_disk() @@ -8869,36 +9205,31 @@ void Plater::reload_gcode_from_disk() load_gcode(filename); } -void Plater::refresh_print() -{ - p->preview->refresh_print(); -} +void Plater::refresh_print() { p->preview->refresh_print(); } // BBS -wxString Plater::get_project_name() -{ - return p->get_project_name(); -} +wxString Plater::get_project_name() { return p->get_project_name(); } void Plater::update_all_plate_thumbnails(bool force_update) { for (int i = 0; i < get_partplate_list().get_plate_count(); i++) { - PartPlate* plate = get_partplate_list().get_plate(i); - ThumbnailsParams thumbnail_params = { {}, false, true, true, true, i}; + PartPlate *plate = get_partplate_list().get_plate(i); + ThumbnailsParams thumbnail_params = {{}, false, true, true, true, i}; if (force_update || !plate->thumbnail_data.is_valid()) { - get_view3D_canvas3D()->render_thumbnail(plate->thumbnail_data, plate->plate_thumbnail_width, plate->plate_thumbnail_height, thumbnail_params, Camera::EType::Ortho); + get_view3D_canvas3D()->render_thumbnail(plate->thumbnail_data, plate->plate_thumbnail_width, plate->plate_thumbnail_height, + thumbnail_params, Camera::EType::Ortho); } } } -//invalid all plate's thumbnails +// invalid all plate's thumbnails void Plater::invalid_all_plate_thumbnails() { if (using_exported_file() || skip_thumbnail_invalid) return; BOOST_LOG_TRIVIAL(info) << "thumb: invalid all"; for (int i = 0; i < get_partplate_list().get_plate_count(); i++) { - PartPlate* plate = get_partplate_list().get_plate(i); + PartPlate *plate = get_partplate_list().get_plate(i); plate->thumbnail_data.reset(); } } @@ -8906,8 +9237,7 @@ void Plater::invalid_all_plate_thumbnails() void Plater::force_update_all_plate_thumbnails() { if (using_exported_file() || skip_thumbnail_invalid) { - } - else { + } else { invalid_all_plate_thumbnails(); update_all_plate_thumbnails(true); } @@ -8915,20 +9245,21 @@ void Plater::force_update_all_plate_thumbnails() } // BBS: backup -std::vector Plater::load_files(const std::vector& input_files, LoadStrategy strategy, bool ask_multi) { - //BBS: wish to reset state when load a new file +std::vector Plater::load_files(const std::vector &input_files, LoadStrategy strategy, bool ask_multi) +{ + // BBS: wish to reset state when load a new file p->m_slice_all_only_has_gcode = false; - //BBS: wish to reset all plates stats item selected state when load a new file + // BBS: wish to reset all plates stats item selected state when load a new file p->preview->get_canvas3d()->reset_select_plate_toolbar_selection(); return p->load_files(input_files, strategy, ask_multi); } // To be called when providing a list of files to the GUI slic3r on command line. -std::vector Plater::load_files(const std::vector& input_files, LoadStrategy strategy, bool ask_multi) +std::vector Plater::load_files(const std::vector &input_files, LoadStrategy strategy, bool ask_multi) { std::vector paths; paths.reserve(input_files.size()); - for (const std::string& path : input_files) + for (const std::string &path : input_files) paths.emplace_back(path); return p->load_files(paths, strategy, ask_multi); } @@ -8957,23 +9288,22 @@ class ProjectDropDialog : public DPIDialog public: ProjectDropDialog(const std::string &filename); - wxPanel * m_top_line; + wxPanel *m_top_line; wxStaticText *m_fname_title; wxStaticText *m_fname_f; wxStaticText *m_fname_s; - StaticBox * m_panel_select; - Button * m_confirm; - Button * m_cancel; - + StaticBox *m_panel_select; + Button *m_confirm; + Button *m_cancel; - void select_radio(int index); - void on_select_radio(wxMouseEvent &event); - void on_select_ok(wxMouseEvent &event); - void on_select_cancel(wxMouseEvent &event); + void select_radio(int index); + void on_select_radio(wxMouseEvent &event); + void on_select_ok(wxMouseEvent &event); + void on_select_cancel(wxMouseEvent &event); - int get_select_radio(int groupid); - int get_action() const { return m_action; } - void set_action(int index) { m_action = index; } + int get_select_radio(int groupid); + int get_action() const { return m_action; } + void set_action(int index) { m_action = index; } wxBoxSizer *create_item_checkbox(wxString title, wxWindow *parent, wxString tooltip, std::string param); wxBoxSizer *create_item_radiobox(wxString title, wxWindow *parent, int select_id, int groupid); @@ -9006,7 +9336,7 @@ ProjectDropDialog::ProjectDropDialog(const std::string &filename) m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, 20); - wxBoxSizer *m_sizer_name = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *m_sizer_name = new wxBoxSizer(wxVERTICAL); wxBoxSizer *m_sizer_fline = new wxBoxSizer(wxHORIZONTAL); m_fname_title = new wxStaticText(this, wxID_ANY, _L("Please select an action"), wxDefaultPosition, wxDefaultSize, 0); @@ -9050,14 +9380,13 @@ ProjectDropDialog::ProjectDropDialog(const std::string &filename) wxBoxSizer *m_sizer_select_v = new wxBoxSizer(wxVERTICAL); - auto select_f = create_item_radiobox(_L("Open as project"), m_panel_select, 1, 0); auto select_s = create_item_radiobox(_L("Import geometry only"), m_panel_select, 2, 0); - //auto select_t = create_item_radiobox(_L("Import presets only"), m_panel_select,3, 0); + // auto select_t = create_item_radiobox(_L("Import presets only"), m_panel_select,3, 0); m_sizer_select_v->Add(select_f, 0, wxEXPAND, 5); m_sizer_select_v->Add(select_s, 0, wxEXPAND, 5); - //m_sizer_select_v->Add(select_t, 0, wxEXPAND, 5); + // m_sizer_select_v->Add(select_t, 0, wxEXPAND, 5); select_radio(2); m_sizer_select_h->Add(m_sizer_select_v, 0, wxALIGN_CENTER | wxLEFT, 22); @@ -9070,19 +9399,20 @@ ProjectDropDialog::ProjectDropDialog(const std::string &filename) wxBoxSizer *m_sizer_bottom = new wxBoxSizer(wxHORIZONTAL); // hide the "Don't show again" checkbox - //wxBoxSizer *m_sizer_left = new wxBoxSizer(wxHORIZONTAL); + // wxBoxSizer *m_sizer_left = new wxBoxSizer(wxHORIZONTAL); - //auto dont_show_again = create_item_checkbox(_L("Don't show again"), this, _L("Don't show again"), "show_drop_project_dialog"); - //m_sizer_left->Add(dont_show_again, 0, wxALL, 5); + // auto dont_show_again = create_item_checkbox(_L("Don't show again"), this, _L("Don't show again"), "show_drop_project_dialog"); + // m_sizer_left->Add(dont_show_again, 0, wxALL, 5); - //m_sizer_bottom->Add(m_sizer_left, 0, wxEXPAND, 5); + // m_sizer_bottom->Add(m_sizer_left, 0, wxEXPAND, 5); m_sizer_bottom->Add(0, 0, 1, wxEXPAND, 5); - wxBoxSizer *m_sizer_right = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *m_sizer_right = new wxBoxSizer(wxHORIZONTAL); m_confirm = new Button(this, _L("OK")); - StateColor btn_bg_green(std::pair(wxColour(0, 137, 123), StateColor::Pressed), std::pair(wxColour(38, 166, 154), StateColor::Hovered), + StateColor btn_bg_green(std::pair(wxColour(0, 137, 123), StateColor::Pressed), + std::pair(wxColour(38, 166, 154), StateColor::Hovered), std::pair(wxColour(0, 150, 136), StateColor::Normal)); m_confirm->SetBackgroundColor(btn_bg_green); @@ -9102,7 +9432,7 @@ ProjectDropDialog::ProjectDropDialog(const std::string &filename) m_cancel->Bind(wxEVT_LEFT_DOWN, &ProjectDropDialog::on_select_cancel, this); m_sizer_right->Add(m_cancel, 0, wxALL, 5); - m_sizer_bottom->Add( m_sizer_right, 0, wxEXPAND, 5 ); + m_sizer_bottom->Add(m_sizer_right, 0, wxEXPAND, 5); m_sizer_main->Add(m_sizer_bottom, 0, wxEXPAND | wxLEFT | wxRIGHT, 40); m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, 20); @@ -9111,14 +9441,13 @@ ProjectDropDialog::ProjectDropDialog(const std::string &filename) Fit(); Centre(wxBOTH); - auto limit_width = m_fname_f->GetSize().GetWidth() - 2; auto current_width = 0; auto cut_index = 0; auto fstring = wxString(""); auto bstring = wxString(""); - //auto file_name = from_u8(filename.c_str()); + // auto file_name = from_u8(filename.c_str()); auto file_name = wxString(filename); for (int x = 0; x < file_name.length(); x++) { current_width += m_fname_s->GetTextExtent(file_name[x]).GetWidth(); @@ -9139,16 +9468,16 @@ ProjectDropDialog::ProjectDropDialog(const std::string &filename) wxBoxSizer *ProjectDropDialog ::create_item_radiobox(wxString title, wxWindow *parent, int select_id, int groupid) { - wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); - auto radiobox = new RadioBox(parent); + wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); + auto radiobox = new RadioBox(parent); - radiobox->SetBackgroundColour(wxColour(248,248,248)); + radiobox->SetBackgroundColour(wxColour(248, 248, 248)); sizer->Add(radiobox, 0, wxALL, 5); sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, 5); auto text = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, 0); text->Wrap(-1); text->SetForegroundColour(wxColour(107, 107, 107)); - text->SetBackgroundColour(wxColour(248,248,248)); + text->SetBackgroundColour(wxColour(248, 248, 248)); sizer->Add(text, 0, wxALL, 5); radiobox->Bind(wxEVT_LEFT_DOWN, &ProjectDropDialog::on_select_radio, this); @@ -9176,12 +9505,12 @@ wxBoxSizer *ProjectDropDialog::create_item_checkbox(wxString title, wxWindow *pa m_sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, 8); auto checkbox_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxSize(-1, -1), 0); - checkbox_title->SetForegroundColour(wxColour(144,144,144)); + checkbox_title->SetForegroundColour(wxColour(144, 144, 144)); checkbox_title->SetFont(::Label::Body_13); checkbox_title->Wrap(-1); m_sizer_checkbox->Add(checkbox_title, 0, wxALIGN_CENTER | wxALL, 3); - m_show_again = wxGetApp().app_config->get(param) == "true" ? true : false; + m_show_again = wxGetApp().app_config->get(param) == "true" ? true : false; checkbox->SetValue(m_show_again); checkbox->Bind(wxEVT_TOGGLEBUTTON, [this, checkbox, param](wxCommandEvent &e) { @@ -9194,21 +9523,24 @@ wxBoxSizer *ProjectDropDialog::create_item_checkbox(wxString title, wxWindow *pa void ProjectDropDialog::select_radio(int index) { - m_action = index; - RadioSelectorList::compatibility_iterator it = m_radio_group.GetFirst(); - auto groupid = 0; + m_action = index; + RadioSelectorList::compatibility_iterator it = m_radio_group.GetFirst(); + auto groupid = 0; while (it) { RadioSelector *rs = it->GetData(); - if (rs->m_select_id == index) groupid = rs->m_groupid; + if (rs->m_select_id == index) + groupid = rs->m_groupid; it = it->GetNext(); } it = m_radio_group.GetFirst(); while (it) { RadioSelector *rs = it->GetData(); - if (rs->m_groupid == groupid && rs->m_select_id == index) rs->m_radiobox->SetValue(true); - if (rs->m_groupid == groupid && rs->m_select_id != index) rs->m_radiobox->SetValue(false); + if (rs->m_groupid == groupid && rs->m_select_id == index) + rs->m_radiobox->SetValue(true); + if (rs->m_groupid == groupid && rs->m_select_id != index) + rs->m_radiobox->SetValue(false); it = it->GetNext(); } } @@ -9218,7 +9550,9 @@ int ProjectDropDialog::get_select_radio(int groupid) RadioSelectorList::compatibility_iterator it = m_radio_group.GetFirst(); while (it) { RadioSelector *rs = it->GetData(); - if (rs->m_groupid == groupid && rs->m_radiobox->GetValue()) { return rs->m_select_id; } + if (rs->m_groupid == groupid && rs->m_radiobox->GetValue()) { + return rs->m_select_id; + } it = it->GetNext(); } @@ -9226,12 +9560,13 @@ int ProjectDropDialog::get_select_radio(int groupid) } void ProjectDropDialog::on_select_radio(wxMouseEvent &event) { - RadioSelectorList::compatibility_iterator it = m_radio_group.GetFirst(); - auto groupid = 0; + RadioSelectorList::compatibility_iterator it = m_radio_group.GetFirst(); + auto groupid = 0; while (it) { RadioSelector *rs = it->GetData(); - if (rs->m_radiobox->GetId() == event.GetId()) groupid = rs->m_groupid; + if (rs->m_radiobox->GetId() == event.GetId()) + groupid = rs->m_groupid; it = it->GetNext(); } @@ -9243,8 +9578,8 @@ void ProjectDropDialog::on_select_radio(wxMouseEvent &event) rs->m_radiobox->SetValue(true); } - - if (rs->m_groupid == groupid && rs->m_radiobox->GetId() != event.GetId()) rs->m_radiobox->SetValue(false); + if (rs->m_groupid == groupid && rs->m_radiobox->GetId() != event.GetId()) + rs->m_radiobox->SetValue(false); it = it->GetNext(); } } @@ -9255,12 +9590,9 @@ void ProjectDropDialog::on_select_ok(wxMouseEvent &event) EndModal(wxID_OK); } -void ProjectDropDialog::on_select_cancel(wxMouseEvent &event) -{ - EndModal(wxID_CANCEL); -} +void ProjectDropDialog::on_select_cancel(wxMouseEvent &event) { EndModal(wxID_CANCEL); } -void ProjectDropDialog::on_dpi_changed(const wxRect& suggested_rect) +void ProjectDropDialog::on_dpi_changed(const wxRect &suggested_rect) { m_confirm->SetMinSize(PROJECT_DROP_DIALOG_BUTTON_SIZE); m_cancel->SetMinSize(PROJECT_DROP_DIALOG_BUTTON_SIZE); @@ -9268,8 +9600,8 @@ void ProjectDropDialog::on_dpi_changed(const wxRect& suggested_rect) Refresh(); } -//BBS: remove GCodeViewer as seperate APP logic -bool Plater::load_files(const wxArrayString& filenames) +// BBS: remove GCodeViewer as seperate APP logic +bool Plater::load_files(const wxArrayString &filenames) { const std::regex pattern_drop(".*[.](stp|step|stl|obj|amf|3mf|svg)", std::regex::icase); const std::regex pattern_gcode_drop(".*[.](gcode|g)", std::regex::icase); @@ -9277,7 +9609,7 @@ bool Plater::load_files(const wxArrayString& filenames) std::vector normal_paths; std::vector gcode_paths; - for (const auto& filename : filenames) { + for (const auto &filename : filenames) { fs::path path(into_path(filename)); if (std::regex_match(path.string(), pattern_drop)) normal_paths.push_back(std::move(path)); @@ -9287,14 +9619,14 @@ bool Plater::load_files(const wxArrayString& filenames) continue; } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": normal_paths %1%, gcode_paths %2%")%normal_paths.size() %gcode_paths.size(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": normal_paths %1%, gcode_paths %2%") % normal_paths.size() % gcode_paths.size(); if (normal_paths.empty() && gcode_paths.empty()) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": can not find valid path, return directly"); // Likely no supported files return false; - } - else if (normal_paths.empty()){ - //only gcode files + } else if (normal_paths.empty()) { + // only gcode files if (gcode_paths.size() > 1) { show_info(this, _L("Only one G-code file can be opened at the same time."), _L("G-code loading")); return false; @@ -9309,12 +9641,12 @@ bool Plater::load_files(const wxArrayString& filenames) } //// searches for project files - //for (std::vector::const_reverse_iterator it = normal_paths.rbegin(); it != normal_paths.rend(); ++it) { - // std::string filename = (*it).filename().string(); - // ////BBS: only 3mf will be treated as project file - // if (open_3mf_file((*it))) - // return true; - //} + // for (std::vector::const_reverse_iterator it = normal_paths.rbegin(); it != normal_paths.rend(); ++it) { + // std::string filename = (*it).filename().string(); + // ////BBS: only 3mf will be treated as project file + // if (open_3mf_file((*it))) + // return true; + // } //// other files std::string snapshot_label; @@ -9333,20 +9665,31 @@ bool Plater::load_files(const wxArrayString& filenames) } } - //Plater::TakeSnapshot snapshot(this, snapshot_label); - //load_files(normal_paths, LoadStrategy::LoadModel); + // Plater::TakeSnapshot snapshot(this, snapshot_label); + // load_files(normal_paths, LoadStrategy::LoadModel); // BBS: check file types - std::sort(normal_paths.begin(), normal_paths.end(), [](fs::path obj1, fs::path obj2) { return obj1.filename().string() < obj2.filename().string(); }); + std::sort(normal_paths.begin(), normal_paths.end(), + [](fs::path obj1, fs::path obj2) { return obj1.filename().string() < obj2.filename().string(); }); auto loadfiles_type = LoadFilesType::NoFile; auto amf_files_count = get_3mf_file_count(normal_paths); - if (normal_paths.size() > 1 && amf_files_count < normal_paths.size()) { loadfiles_type = LoadFilesType::Multiple3MFOther; } - if (normal_paths.size() > 1 && amf_files_count == normal_paths.size()) { loadfiles_type = LoadFilesType::Multiple3MF; } - if (normal_paths.size() > 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::MultipleOther; } - if (normal_paths.size() == 1 && amf_files_count == 1) { loadfiles_type = LoadFilesType::Single3MF; }; - if (normal_paths.size() == 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::SingleOther; }; + if (normal_paths.size() > 1 && amf_files_count < normal_paths.size()) { + loadfiles_type = LoadFilesType::Multiple3MFOther; + } + if (normal_paths.size() > 1 && amf_files_count == normal_paths.size()) { + loadfiles_type = LoadFilesType::Multiple3MF; + } + if (normal_paths.size() > 1 && amf_files_count == 0) { + loadfiles_type = LoadFilesType::MultipleOther; + } + if (normal_paths.size() == 1 && amf_files_count == 1) { + loadfiles_type = LoadFilesType::Single3MF; + }; + if (normal_paths.size() == 1 && amf_files_count == 0) { + loadfiles_type = LoadFilesType::SingleOther; + }; auto first_file = std::vector{}; auto tmf_file = std::vector{}; @@ -9354,36 +9697,41 @@ bool Plater::load_files(const wxArrayString& filenames) auto res = true; if (this->m_only_gcode || this->m_exported_file) { - if ((loadfiles_type == LoadFilesType::SingleOther) - || (loadfiles_type == LoadFilesType::MultipleOther)) { + if ((loadfiles_type == LoadFilesType::SingleOther) || (loadfiles_type == LoadFilesType::MultipleOther)) { show_info(this, _L("Can not add models when in preview mode!"), _L("Add Models")); return false; } } switch (loadfiles_type) { - case LoadFilesType::Single3MF: - open_3mf_file(normal_paths[0]); - break; + case LoadFilesType::Single3MF: open_3mf_file(normal_paths[0]); break; case LoadFilesType::SingleOther: { Plater::TakeSnapshot snapshot(this, snapshot_label); - if (load_files(normal_paths, LoadStrategy::LoadModel, false).empty()) { res = false; } + if (load_files(normal_paths, LoadStrategy::LoadModel, false).empty()) { + res = false; + } break; } case LoadFilesType::Multiple3MF: first_file = std::vector{normal_paths[0]}; for (auto i = 0; i < normal_paths.size(); i++) { - if (i > 0) { other_file.push_back(normal_paths[i]); } + if (i > 0) { + other_file.push_back(normal_paths[i]); + } }; open_3mf_file(first_file[0]); - if (load_files(other_file, LoadStrategy::LoadModel).empty()) { res = false; } + if (load_files(other_file, LoadStrategy::LoadModel).empty()) { + res = false; + } break; case LoadFilesType::MultipleOther: { Plater::TakeSnapshot snapshot(this, snapshot_label); - if (load_files(normal_paths, LoadStrategy::LoadModel, true).empty()) { res = false; } + if (load_files(normal_paths, LoadStrategy::LoadModel, true).empty()) { + res = false; + } break; } @@ -9400,8 +9748,12 @@ bool Plater::load_files(const wxArrayString& filenames) } open_3mf_file(first_file[0]); - if (load_files(tmf_file, LoadStrategy::LoadModel).empty()) { res = false; } - if (load_files(other_file, LoadStrategy::LoadModel, false).empty()) { res = false; } + if (load_files(tmf_file, LoadStrategy::LoadModel).empty()) { + res = false; + } + if (load_files(other_file, LoadStrategy::LoadModel, false).empty()) { + res = false; + } break; default: break; } @@ -9409,7 +9761,6 @@ bool Plater::load_files(const wxArrayString& filenames) return res; } - bool Plater::open_3mf_file(const fs::path &file_path) { std::string filename = encode_path(file_path.filename().string().c_str()); @@ -9431,32 +9782,33 @@ bool Plater::open_3mf_file(const fs::path &file_path) wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor); } } else - load_type = static_cast( - std::clamp(std::stoi(wxGetApp().app_config->get("import_project_action")), static_cast(LoadType::OpenProject), static_cast(LoadType::LoadConfig))); + load_type = static_cast(std::clamp(std::stoi(wxGetApp().app_config->get("import_project_action")), + static_cast(LoadType::OpenProject), static_cast(LoadType::LoadConfig))); } else load_type = LoadType::OpenProject; - if (load_type == LoadType::Unknown) return false; + if (load_type == LoadType::Unknown) + return false; switch (load_type) { - case LoadType::OpenProject: { - if (wxGetApp().can_load_project()) - load_project(from_path(file_path)); - break; - } - case LoadType::LoadGeometry: { - Plater::TakeSnapshot snapshot(this, "Import Object"); - load_files({file_path}, LoadStrategy::LoadModel); - break; - } - case LoadType::LoadConfig: { - load_files({file_path}, LoadStrategy::LoadConfig); - break; - } - case LoadType::Unknown: { - assert(false); - break; - } + case LoadType::OpenProject: { + if (wxGetApp().can_load_project()) + load_project(from_path(file_path)); + break; + } + case LoadType::LoadGeometry: { + Plater::TakeSnapshot snapshot(this, "Import Object"); + load_files({file_path}, LoadStrategy::LoadModel); + break; + } + case LoadType::LoadConfig: { + load_files({file_path}, LoadStrategy::LoadConfig); + break; + } + case LoadType::Unknown: { + assert(false); + break; + } } return true; @@ -9466,19 +9818,23 @@ int Plater::get_3mf_file_count(std::vector paths) { auto count = 0; for (const auto &path : paths) { - if (wxString(encode_path(path.filename().string().c_str())).EndsWith("3mf")) count++; + if (wxString(encode_path(path.filename().string().c_str())).EndsWith("3mf")) + count++; } return count; } void Plater::add_file() { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " entry"; wxArrayString input_files; wxGetApp().import_model(this, input_files); - if (input_files.empty()) return; + if (input_files.empty()) + return; std::vector paths; - for (const auto &file : input_files) paths.emplace_back(into_path(file)); + for (const auto &file : input_files) + paths.emplace_back(into_path(file)); std::string snapshot_label; assert(!paths.empty()); @@ -9495,40 +9851,59 @@ void Plater::add_file() auto loadfiles_type = LoadFilesType::NoFile; auto amf_files_count = get_3mf_file_count(paths); - if (paths.size() > 1 && amf_files_count < paths.size()) { loadfiles_type = LoadFilesType::Multiple3MFOther; } - if (paths.size() > 1 && amf_files_count == paths.size()) { loadfiles_type = LoadFilesType::Multiple3MF; } - if (paths.size() > 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::MultipleOther; } - if (paths.size() == 1 && amf_files_count == 1) { loadfiles_type = LoadFilesType::Single3MF; }; - if (paths.size() == 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::SingleOther; }; + if (paths.size() > 1 && amf_files_count < paths.size()) { + loadfiles_type = LoadFilesType::Multiple3MFOther; + } + if (paths.size() > 1 && amf_files_count == paths.size()) { + loadfiles_type = LoadFilesType::Multiple3MF; + } + if (paths.size() > 1 && amf_files_count == 0) { + loadfiles_type = LoadFilesType::MultipleOther; + } + if (paths.size() == 1 && amf_files_count == 1) { + loadfiles_type = LoadFilesType::Single3MF; + }; + if (paths.size() == 1 && amf_files_count == 0) { + loadfiles_type = LoadFilesType::SingleOther; + }; auto first_file = std::vector{}; auto tmf_file = std::vector{}; auto other_file = std::vector{}; - switch (loadfiles_type) - { - case LoadFilesType::Single3MF: - open_3mf_file(paths[0]); - break; + switch (loadfiles_type) { + case LoadFilesType::Single3MF: open_3mf_file(paths[0]); break; case LoadFilesType::SingleOther: { Plater::TakeSnapshot snapshot(this, snapshot_label); - if (!load_files(paths, LoadStrategy::LoadModel, false).empty()) { wxGetApp().mainframe->update_title(); } + if (!load_files(paths, LoadStrategy::LoadModel, false).empty()) { + if (get_project_name() == _L("Untitled") && paths.size() > 0) { + p->set_project_filename(wxString::FromUTF8(paths[0].string())); + } + wxGetApp().mainframe->update_title(); + } break; } case LoadFilesType::Multiple3MF: first_file = std::vector{paths[0]}; for (auto i = 0; i < paths.size(); i++) { - if (i > 0) { other_file.push_back(paths[i]); } + if (i > 0) { + other_file.push_back(paths[i]); + } }; open_3mf_file(first_file[0]); - if (!load_files(other_file, LoadStrategy::LoadModel).empty()) { wxGetApp().mainframe->update_title(); } + if (!load_files(other_file, LoadStrategy::LoadModel).empty()) { + wxGetApp().mainframe->update_title(); + } break; case LoadFilesType::MultipleOther: { Plater::TakeSnapshot snapshot(this, snapshot_label); if (!load_files(paths, LoadStrategy::LoadModel, true).empty()) { + if (get_project_name() == _L("Untitled") && paths.size() > 0) { + p->set_project_filename(wxString::FromUTF8(paths[0].string())); + } wxGetApp().mainframe->update_title(); } break; @@ -9547,22 +9922,24 @@ void Plater::add_file() open_3mf_file(first_file[0]); load_files(tmf_file, LoadStrategy::LoadModel); - if (!load_files(other_file, LoadStrategy::LoadModel, false).empty()) { wxGetApp().mainframe->update_title(); } + if (!load_files(other_file, LoadStrategy::LoadModel, false).empty()) { + wxGetApp().mainframe->update_title(); + } break; - default:break; + default: break; } } void Plater::update(bool conside_update_flag, bool force_background_processing_update) { - unsigned int flag = force_background_processing_update ? (unsigned int)Plater::priv::UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE : 0; + unsigned int flag = force_background_processing_update ? (unsigned int) Plater::priv::UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE : + 0; if (conside_update_flag) { if (need_update()) { p->update(flag); p->set_need_update(false); } - } - else + } else p->update(flag); } @@ -9570,17 +9947,14 @@ void Plater::object_list_changed() { p->object_list_changed(); } void Plater::stop_jobs() { p->m_ui_jobs.stop_all(); } -bool Plater::is_any_job_running() const -{ - return p->m_ui_jobs.is_any_running(); -} +bool Plater::is_any_job_running() const { return p->m_ui_jobs.is_any_running(); } void Plater::update_ui_from_settings() { p->update_ui_from_settings(); } -void Plater::select_view(const std::string& direction) { p->select_view(direction); } +void Plater::select_view(const std::string &direction) { p->select_view(direction); } -//BBS: add no_slice logic -void Plater::select_view_3D(const std::string& name, bool no_slice) { p->select_view_3D(name, no_slice); } +// BBS: add no_slice logic +void Plater::select_view_3D(const std::string &name, bool no_slice) { p->select_view_3D(name, no_slice); } bool Plater::is_preview_shown() const { return p->is_preview_shown(); } bool Plater::is_preview_loaded() const { return p->is_preview_loaded(); } @@ -9590,12 +9964,12 @@ bool Plater::are_view3D_labels_shown() const { return p->are_view3D_labels_shown void Plater::show_view3D_labels(bool show) { p->show_view3D_labels(show); } bool Plater::is_view3D_overhang_shown() const { return p->is_view3D_overhang_shown(); } -void Plater::show_view3D_overhang(bool show) { p->show_view3D_overhang(show); } +void Plater::show_view3D_overhang(bool show) { p->show_view3D_overhang(show); } bool Plater::is_sidebar_collapsed() const { return p->is_sidebar_collapsed(); } void Plater::collapse_sidebar(bool show) { p->collapse_sidebar(show); } -//BBS +// BBS void Plater::select_curr_plate_all() { p->select_curr_plate_all(); } void Plater::remove_curr_plate_all() { p->remove_curr_plate_all(); } @@ -9606,9 +9980,10 @@ void Plater::remove(size_t obj_idx) { p->remove(obj_idx); } void Plater::reset(bool apply_presets_change) { p->reset(apply_presets_change); } void Plater::reset_with_confirm() { - if (p->model.objects.empty() || MessageDialog(static_cast(this), _L("All objects will be removed, continue?"), - wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Delete all"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE) - .ShowModal() == wxID_YES) { + if (p->model.objects.empty() || + MessageDialog(static_cast(this), _L("All objects will be removed, continue?"), + wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Delete all"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE) + .ShowModal() == wxID_YES) { reset(); // BBS: jump to plater panel wxGetApp().mainframe->select_tab(size_t(0)); @@ -9619,13 +9994,14 @@ void Plater::reset_with_confirm() int GUI::Plater::close_with_confirm(std::function second_check) { if (up_to_date(false, false)) { - if (second_check && !second_check(false)) return wxID_CANCEL; + if (second_check && !second_check(false)) + return wxID_CANCEL; model().set_backup_path(""); return wxID_NO; } - MessageDialog dlg(static_cast(this), _L("The current project has unsaved changes, save it before continue?"), - wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Save"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE); + MessageDialog dlg(static_cast(this), _L("The current project has unsaved changes, save it before continue?"), + wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Save"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE); dlg.show_dsa_button(_L("Remember my choice.")); auto choise = wxGetApp().app_config->get("save_project_choise"); auto result = choise.empty() ? dlg.ShowModal() : choise == "yes" ? wxID_YES : wxID_NO; @@ -9645,7 +10021,8 @@ int GUI::Plater::close_with_confirm(std::function second_check) } } - if (second_check && !second_check(result == wxID_YES)) return wxID_CANCEL; + if (second_check && !second_check(result == wxID_YES)) + return wxID_CANCEL; model().set_backup_path(""); up_to_date(true, false); @@ -9654,24 +10031,24 @@ int GUI::Plater::close_with_confirm(std::function second_check) return result; } -//BBS: trigger a restore project event +// BBS: trigger a restore project event void Plater::trigger_restore_project(int skip_confirm) { auto evt = new wxCommandEvent(EVT_RESTORE_PROJECT, this->GetId()); evt->SetInt(skip_confirm); wxQueueEvent(this, evt); - //wxPostEvent(this, *evt); + // wxPostEvent(this, *evt); } -//BBS -bool Plater::delete_object_from_model(size_t obj_idx, bool refresh_immediately) { return p->delete_object_from_model(obj_idx, refresh_immediately); } - -//BBS: delete all from model -void Plater::delete_all_objects_from_model() +// BBS +bool Plater::delete_object_from_model(size_t obj_idx, bool refresh_immediately) { - p->delete_all_objects_from_model(); + return p->delete_object_from_model(obj_idx, refresh_immediately); } +// BBS: delete all from model +void Plater::delete_all_objects_from_model() { p->delete_all_objects_from_model(); } + void Plater::set_selected_visible(bool visible) { if (p->get_curr_selection().is_empty()) @@ -9683,7 +10060,6 @@ void Plater::set_selected_visible(bool visible) p->get_current_canvas3D()->set_selected_visible(visible); } - void Plater::remove_selected() { /*if (p->get_selection().is_empty()) @@ -9698,8 +10074,8 @@ void Plater::remove_selected() Plater::TakeSnapshot snapshot(this, "Delete Selected Objects"); p->m_ui_jobs.cancel_all(); - //BBS delete current selected - // p->view3D->delete_selected(); + // BBS delete current selected + // p->view3D->delete_selected(); p->get_current_canvas3D()->delete_selected(); } @@ -9772,13 +10148,8 @@ void Plater::decrease_instances(size_t num) #endif } -static long GetNumberFromUser( const wxString& msg, - const wxString& prompt, - const wxString& title, - long value, - long min, - long max, - wxWindow* parent) +static long GetNumberFromUser( + const wxString &msg, const wxString &prompt, const wxString &title, long value, long min, long max, wxWindow *parent) { #ifdef _WIN32 wxNumberEntryDialog dialog(parent, msg, prompt, title, value, min, max, wxDefaultPosition); @@ -9798,16 +10169,16 @@ void Plater::set_number_of_copies(/*size_t num*/) if (obj_idx == -1) return; - ModelObject* model_object = p->model.objects[obj_idx]; + ModelObject *model_object = p->model.objects[obj_idx]; - const int num = GetNumberFromUser( " ", _L("Number of copies:"), - _L("Copies of the selected object"), model_object->instances.size(), 0, 1000, this ); + const int num = GetNumberFromUser(" ", _L("Number of copies:"), _L("Copies of the selected object"), model_object->instances.size(), 0, + 1000, this); if (num < 0) return; - Plater::TakeSnapshot snapshot(this, (boost::format("Set numbers of copies to %1%")%num).str()); + Plater::TakeSnapshot snapshot(this, (boost::format("Set numbers of copies to %1%") % num).str()); - int diff = num - (int)model_object->instances.size(); + int diff = num - (int) model_object->instances.size(); if (diff > 0) increase_instances(diff); else if (diff < 0) @@ -9820,15 +10191,9 @@ void Plater::fill_bed_with_instances() p->m_ui_jobs.fill_bed(); } -bool Plater::is_selection_empty() const -{ - return p->get_selection().is_empty() || p->get_selection().is_wipe_tower(); -} +bool Plater::is_selection_empty() const { return p->get_selection().is_empty() || p->get_selection().is_wipe_tower(); } -void Plater::scale_selection_to_fit_print_volume() -{ - p->scale_selection_to_fit_print_volume(); -} +void Plater::scale_selection_to_fit_print_volume() { p->scale_selection_to_fit_print_volume(); } void Plater::convert_unit(ConversionType conv_type) { @@ -9839,7 +10204,8 @@ void Plater::convert_unit(ConversionType conv_type) TakeSnapshot snapshot(this, conv_type == ConversionType::CONV_FROM_INCH ? "Convert from imperial units" : conv_type == ConversionType::CONV_TO_INCH ? "Revert conversion from imperial units" : - conv_type == ConversionType::CONV_FROM_METER ? "Convert from meters" : "Revert conversion from meters"); + conv_type == ConversionType::CONV_FROM_METER ? "Convert from meters" : + "Revert conversion from meters"); wxBusyCursor wait; ModelObjectPtrs objects; @@ -9852,105 +10218,41 @@ void Plater::convert_unit(ConversionType conv_type) std::reverse(objects.begin(), objects.end()); p->load_model_objects(objects); - Selection& selection = p->view3D->get_canvas3d()->get_selection(); - size_t last_obj_idx = p->model.objects.size() - 1; + Selection &selection = p->view3D->get_canvas3d()->get_selection(); + size_t last_obj_idx = p->model.objects.size() - 1; if (volume_idxs.empty()) { for (size_t i = 0; i < objects.size(); ++i) - selection.add_object((unsigned int)(last_obj_idx - i), i == 0); - } - else { + selection.add_object((unsigned int) (last_obj_idx - i), i == 0); + } else { for (int vol_idx : volume_idxs) selection.add_volume(last_obj_idx, vol_idx, 0, false); } } -// BBS: replace z with plane_points -void Plater::cut(size_t obj_idx, size_t instance_idx, std::array plane_points, ModelObjectCutAttributes attributes) +void Plater::apply_cut_object_to_model(size_t obj_idx, const ModelObjectPtrs &new_objects) { - wxCHECK_RET(obj_idx < p->model.objects.size(), "obj_idx out of bounds"); - auto *object = p->model.objects[obj_idx]; - - wxCHECK_RET(instance_idx < object->instances.size(), "instance_idx out of bounds"); - - if (! attributes.has(ModelObjectCutAttribute::KeepUpper) && ! attributes.has(ModelObjectCutAttribute::KeepLower)) - return; - - wxBusyCursor wait; - // BBS: replace z with plane_points - const auto new_objects = object->cut(instance_idx, plane_points, attributes); + model().delete_object(obj_idx); + sidebar().obj_list()->delete_object_from_list(obj_idx); - remove(obj_idx); - p->load_model_objects(new_objects); + // suppress to call selection update for Object List to avoid call of early Gizmos on/off update + p->load_model_objects(new_objects, false, false); // now process all updates of the 3d scene update(); - // Update InfoItems in ObjectList after update() to use of a correct value of the GLCanvas3D::is_sinking(), // which is updated after a view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH) call for (size_t idx = 0; idx < p->model.objects.size(); idx++) wxGetApp().obj_list()->update_info_items(idx); - Selection& selection = p->get_selection(); - size_t last_id = p->model.objects.size() - 1; - for (size_t i = 0; i < new_objects.size(); ++i) - selection.add_object((unsigned int)(last_id - i), i == 0); -} - -// BBS -void Plater::segment(size_t obj_idx, size_t instance_idx, double smoothing_alpha, int segment_number) -{ - wxCHECK_RET(obj_idx < p->model.objects.size(), "obj_idx out of bounds"); - auto* object = p->model.objects[obj_idx]; - - wxCHECK_RET(instance_idx < object->instances.size(), "instance_idx out of bounds"); - - Plater::TakeSnapshot snapshot(this, "Segment"); - - wxBusyCursor wait; - // real process - PresetBundle& preset_bundle = *wxGetApp().preset_bundle; - const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); - const size_t filament_cnt = print_tech != ptFFF ? 1 : preset_bundle.filament_presets.size(); - const auto new_objects = object->segment(instance_idx, filament_cnt, smoothing_alpha, segment_number); - - remove(obj_idx); - p->load_model_objects(new_objects); - - Selection& selection = p->get_selection(); - size_t last_id = p->model.objects.size() - 1; + Selection &selection = p->get_selection(); + size_t last_id = p->model.objects.size() - 1; for (size_t i = 0; i < new_objects.size(); ++i) - { - selection.add_object((unsigned int)(last_id - i), i == 0); - } -} - -// BBS -void Plater::merge(size_t obj_idx, std::vector& vol_indeces) -{ - wxCHECK_RET(obj_idx < p->model.objects.size(), "obj_idx out of bounds"); - auto* object = p->model.objects[obj_idx]; + selection.add_object((unsigned int) (last_id - i), i == 0); - Plater::TakeSnapshot snapshot(this, "Merge"); - - wxBusyCursor wait; - // real process - PresetBundle& preset_bundle = *wxGetApp().preset_bundle; - const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology(); - // BBS - const size_t filament_cnt = print_tech != ptFFF ? 1 : preset_bundle.filament_presets.size(); - - const auto new_objects = object->merge_volumes(vol_indeces); - - remove(obj_idx); - p->load_model_objects(new_objects); - - Selection& selection = p->get_selection(); - size_t last_id = p->model.objects.size() - 1; - for (size_t i = 0; i < new_objects.size(); ++i) - { - selection.add_object((unsigned int)(last_id - i), i == 0); - } + // UIThreadWorker w; + // arrange(w, true); + // w.wait_for_idle(); } void Plater::export_gcode(bool prefer_removable) @@ -9958,8 +10260,8 @@ void Plater::export_gcode(bool prefer_removable) if (p->model.objects.empty()) return; - //if (get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode(true)) - // return; + // if (get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode(true)) + // return; if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index()) return; @@ -9982,11 +10284,11 @@ void Plater::export_gcode(bool prefer_removable) show_error(this, ex.what(), false); return; } - default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); - AppConfig &appconfig = *wxGetApp().app_config; - RemovableDriveManager &removable_drive_manager = *wxGetApp().removable_drive_manager(); + default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); + AppConfig &appconfig = *wxGetApp().app_config; + RemovableDriveManager &removable_drive_manager = *wxGetApp().removable_drive_manager(); // Get a last save path, either to removable media or to an internal media. - std::string start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), prefer_removable); + std::string start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), prefer_removable); if (prefer_removable) { // Returns a path to a removable media if it exists, prefering start_dir. Update the internal removable drives database. start_dir = removable_drive_manager.get_removable_drive_path(start_dir); @@ -9997,18 +10299,15 @@ void Plater::export_gcode(bool prefer_removable) fs::path output_path; { - std::string ext = default_output_file.extension().string(); - wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _L("Save G-code file as:") : _L("Save SLA file as:"), - start_dir, - from_path(default_output_file.filename()), - GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_SL1, ext), - wxFD_SAVE | wxFD_OVERWRITE_PROMPT - ); + std::string ext = default_output_file.extension().string(); + wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _L("Save G-code file as:") : _L("Save SLA file as:"), start_dir, + from_path(default_output_file.filename()), + GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_SL1, ext), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if (dlg.ShowModal() == wxID_OK) { output_path = into_path(dlg.GetPath()); while (has_illegal_filename_characters(output_path.filename().string())) { show_error(this, _L("The provided file name is not valid.") + "\n" + - _L("The following characters are not allowed by a FAT file system:") + " <>:/\\|?*\""); + _L("The following characters are not allowed by a FAT file system:") + " <>:/\\|?*\""); dlg.SetFilename(from_path(output_path.filename())); if (dlg.ShowModal() == wxID_OK) output_path = into_path(dlg.GetPath()); @@ -10020,17 +10319,17 @@ void Plater::export_gcode(bool prefer_removable) } } - if (! output_path.empty()) { + if (!output_path.empty()) { bool path_on_removable_media = removable_drive_manager.set_and_verify_last_save_path(output_path.string()); - //bool path_on_removable_media = false; + // bool path_on_removable_media = false; p->notification_manager->new_export_began(path_on_removable_media); - p->exporting_status = path_on_removable_media ? ExportingStatus::EXPORTING_TO_REMOVABLE : ExportingStatus::EXPORTING_TO_LOCAL; - p->last_output_path = output_path.string(); + p->exporting_status = path_on_removable_media ? ExportingStatus::EXPORTING_TO_REMOVABLE : ExportingStatus::EXPORTING_TO_LOCAL; + p->last_output_path = output_path.string(); p->last_output_dir_path = output_path.parent_path().string(); p->export_gcode(output_path, path_on_removable_media); // Storing a path to AppConfig either as path to removable media or a path to internal media. - // is_path_on_removable_drive() is called with the "true" parameter to update its internal database as the user may have shuffled the external drives - // while the dialog was open. + // is_path_on_removable_drive() is called with the "true" parameter to update its internal database as the user may have shuffled + // the external drives while the dialog was open. appconfig.update_last_output_dir(output_path.parent_path().string(), path_on_removable_media); try { @@ -10048,16 +10347,12 @@ void Plater::export_gcode(bool prefer_removable) } NetworkAgent *agent = wxGetApp().getAgent(); } catch (...) {} - } } -void Plater::send_to_printer(bool isall) -{ - p->on_action_send_to_printer(isall); -} +void Plater::send_to_printer(bool isall) { p->on_action_send_to_printer(isall); } -//BBS export gcode 3mf to file +// BBS export gcode 3mf to file void Plater::export_gcode_3mf(bool export_all) { if (p->model.objects.empty()) @@ -10066,9 +10361,9 @@ void Plater::export_gcode_3mf(bool export_all) if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index()) return; - //calc default_output_file, get default output file from background process - fs::path default_output_file; - AppConfig& appconfig = *wxGetApp().app_config; + // calc default_output_file, get default output file from background process + fs::path default_output_file; + AppConfig &appconfig = *wxGetApp().app_config; std::string start_dir; try { // Update the background processing, so that the placeholder parser will get the correct values for the ouput file template. @@ -10077,58 +10372,51 @@ void Plater::export_gcode_3mf(bool export_all) if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) return; default_output_file = this->p->background_process.output_filepath_for_project(""); - } - catch (const Slic3r::PlaceholderParserError& ex) { + } catch (const Slic3r::PlaceholderParserError &ex) { // Show the error with monospaced font. show_error(this, ex.what(), true); return; - } - catch (const std::exception& ex) { + } catch (const std::exception &ex) { show_error(this, ex.what(), false); return; } default_output_file.replace_extension(".3mf"); default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string())); - //Get a last save path + // Get a last save path start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), false); fs::path output_path; { - std::string ext = default_output_file.extension().string(); - wxFileDialog dlg(this, _L("Save Sliced file as:"), - start_dir, - from_path(default_output_file.filename()), - GUI::file_wildcards(FT_3MF, ext), - wxFD_SAVE | wxFD_OVERWRITE_PROMPT - ); + std::string ext = default_output_file.extension().string(); + wxFileDialog dlg(this, _L("Save Sliced file as:"), start_dir, from_path(default_output_file.filename()), + GUI::file_wildcards(FT_3MF, ext), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if (dlg.ShowModal() == wxID_OK) { output_path = into_path(dlg.GetPath()); - ext = output_path.extension().string(); + ext = output_path.extension().string(); if (ext != ".3mf") output_path = output_path.string() + ".3mf"; } } if (!output_path.empty()) { - //BBS do not set to removable media path + // BBS do not set to removable media path bool path_on_removable_media = false; p->notification_manager->new_export_began(path_on_removable_media); p->exporting_status = path_on_removable_media ? ExportingStatus::EXPORTING_TO_REMOVABLE : ExportingStatus::EXPORTING_TO_LOCAL; - //BBS do not save last output path - p->last_output_path = output_path.string(); + // BBS do not save last output path + p->last_output_path = output_path.string(); p->last_output_dir_path = output_path.parent_path().string(); - int plate_idx = get_partplate_list().get_curr_plate_index(); + int plate_idx = get_partplate_list().get_curr_plate_index(); if (export_all) plate_idx = PLATE_ALL_IDX; - export_3mf(output_path, SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithGcode | SaveStrategy::SkipModel, plate_idx); // BBS: silence - - RemovableDriveManager& removable_drive_manager = *wxGetApp().removable_drive_manager(); + export_3mf(output_path, SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithGcode | SaveStrategy::SkipModel, + plate_idx); // BBS: silence + RemovableDriveManager &removable_drive_manager = *wxGetApp().removable_drive_manager(); bool on_removable = removable_drive_manager.is_path_on_removable_drive(p->last_output_dir_path); - // update last output dir appconfig.update_last_output_dir(output_path.parent_path().string(), false); p->notification_manager->push_exporting_finished_notification(output_path.string(), p->last_output_dir_path, on_removable); @@ -10144,27 +10432,28 @@ void Plater::send_gcode_finish(wxString name) void Plater::export_core_3mf() { wxString path = p->get_export_file(FT_3MF); - if (path.empty()) { return; } + if (path.empty()) { + return; + } const std::string path_u8 = into_u8(path); export_3mf(path_u8, SaveStrategy::Silence); } // Following lambda generates a combined mesh for export with normals pointing outwards. -TriangleMesh Plater::combine_mesh_fff(const ModelObject& mo, int instance_id, std::function notify_func) +TriangleMesh Plater::combine_mesh_fff(const ModelObject &mo, int instance_id, std::function notify_func) { TriangleMesh mesh; std::vector csgmesh; csgmesh.reserve(2 * mo.volumes.size()); bool has_splitable_volume = csg::model_to_csgmesh(mo, Transform3d::Identity(), std::back_inserter(csgmesh), - csg::mpartsPositive | csg::mpartsNegative | csg::mpartsDoSplits); + csg::mpartsPositive | csg::mpartsNegative | csg::mpartsDoSplits); - if (csg::check_csgmesh_booleans(Range{ std::begin(csgmesh), std::end(csgmesh) }) == csgmesh.end()) { + if (csg::check_csgmesh_booleans(Range{std::begin(csgmesh), std::end(csgmesh)}) == csgmesh.end()) { try { - MeshBoolean::mcut::McutMeshPtr meshPtr = csg::perform_csgmesh_booleans_mcut(Range{ std::begin(csgmesh), std::end(csgmesh) }); - mesh = MeshBoolean::mcut::mcut_to_triangle_mesh(*meshPtr); - } - catch (...) {} + MeshBoolean::mcut::McutMeshPtr meshPtr = csg::perform_csgmesh_booleans_mcut(Range{std::begin(csgmesh), std::end(csgmesh)}); + mesh = MeshBoolean::mcut::mcut_to_triangle_mesh(*meshPtr); + } catch (...) {} #if 0 // if mcut fails, try again with CGAL if (mesh.empty()) { @@ -10180,9 +10469,9 @@ TriangleMesh Plater::combine_mesh_fff(const ModelObject& mo, int instance_id, st if (mesh.empty()) { if (notify_func) notify_func(_u8L("Unable to perform boolean operation on model meshes. " - "Only positive parts will be exported.")); + "Only positive parts will be exported.")); - for (const ModelVolume* v : mo.volumes) + for (const ModelVolume *v : mo.volumes) if (v->is_model_part()) { TriangleMesh vol_mesh(v->mesh()); vol_mesh.transform(v->get_matrix(), true); @@ -10193,42 +10482,56 @@ TriangleMesh Plater::combine_mesh_fff(const ModelObject& mo, int instance_id, st if (instance_id == -1) { TriangleMesh vols_mesh(mesh); mesh = TriangleMesh(); - for (const ModelInstance* i : mo.instances) { + for (const ModelInstance *i : mo.instances) { TriangleMesh m = vols_mesh; m.transform(i->get_matrix(), true); mesh.merge(m); } - } - else if (0 <= instance_id && instance_id < int(mo.instances.size())) + } else if (0 <= instance_id && instance_id < int(mo.instances.size())) mesh.transform(mo.instances[instance_id]->get_matrix(), true); return mesh; } // BBS export with/without boolean, however, stil merge mesh #define EXPORT_WITH_BOOLEAN 0 -void Plater::export_stl(bool extended, bool selection_only) +void Plater::export_stl(bool extended, bool selection_only, bool multi_stls) { - if (p->model.objects.empty()) { return; } + if (p->model.objects.empty()) { + return; + } - wxString path = p->get_export_file(FT_STL); - if (path.empty()) { return; } + wxString path; + if (multi_stls) { + wxDirDialog dlg(this, _L("Choose a directory"), from_u8(wxGetApp().app_config->get_last_dir()), + wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); + if (dlg.ShowModal() == wxID_OK) { + path = dlg.GetPath() + "/"; + } + } else { + path = p->get_export_file(FT_STL); + } + if (path.empty()) { + return; + } const std::string path_u8 = into_u8(path); wxBusyCursor wait; - const auto& selection = p->get_selection(); - const auto obj_idx = selection.get_object_idx(); + const auto &selection = p->get_selection(); + const auto obj_idx = selection.get_object_idx(); #if EXPORT_WITH_BOOLEAN if (selection_only && (obj_idx == -1 || selection.is_wipe_tower())) return; #else // BBS support selecting multiple objects - if (selection_only && selection.is_wipe_tower()) return; + if (selection_only && selection.is_wipe_tower()) + return; // BBS if (selection_only) { // only support selection single full object and mulitiple full object - if (!selection.is_single_full_object() && !selection.is_multiple_full_object()) return; + if (!selection.is_single_full_object() && !selection.is_multiple_full_object()) + return; } // Following lambda generates a combined mesh for export with normals pointing outwards. @@ -10253,36 +10556,38 @@ void Plater::export_stl(bool extended, bool selection_only) return mesh; }; #endif - auto mesh_to_export_sla = [&, this](const ModelObject& mo, int instance_id) { + auto mesh_to_export_sla = [&, this](const ModelObject &mo, int instance_id) { TriangleMesh mesh; const SLAPrintObject *object = this->p->sla_print.get_print_object_by_model_object_id(mo.id()); if (auto m = object->get_mesh_to_print(); m.empty()) - mesh = combine_mesh_fff(mo, instance_id, [this](const std::string& msg) {return get_notification_manager()->push_plater_error_notification(msg); }); + mesh = combine_mesh_fff(mo, instance_id, [this](const std::string &msg) { + return get_notification_manager()->push_plater_error_notification(msg); + }); else { const Transform3d mesh_trafo_inv = object->trafo().inverse(); - const bool is_left_handed = object->is_left_handed(); + const bool is_left_handed = object->is_left_handed(); - auto pad_mesh = extended? object->pad_mesh() : TriangleMesh{}; + auto pad_mesh = extended ? object->pad_mesh() : TriangleMesh{}; pad_mesh.transform(mesh_trafo_inv); auto supports_mesh = extended ? object->support_mesh() : TriangleMesh{}; supports_mesh.transform(mesh_trafo_inv); - const std::vector& obj_instances = object->instances(); - for (const SLAPrintObject::Instance& obj_instance : obj_instances) { + const std::vector &obj_instances = object->instances(); + for (const SLAPrintObject::Instance &obj_instance : obj_instances) { auto it = std::find_if(object->model_object()->instances.begin(), object->model_object()->instances.end(), [&obj_instance](const ModelInstance *mi) { return mi->id() == obj_instance.instance_id; }); assert(it != object->model_object()->instances.end()); if (it != object->model_object()->instances.end()) { - const bool one_inst_only = selection_only && ! selection.is_single_full_object(); + const bool one_inst_only = selection_only && !selection.is_single_full_object(); - const int instance_idx = it - object->model_object()->instances.begin(); - const Transform3d& inst_transform = one_inst_only - ? Transform3d::Identity() - : object->model_object()->instances[instance_idx]->get_transformation().get_matrix(); + const int instance_idx = it - object->model_object()->instances.begin(); + const Transform3d &inst_transform = + one_inst_only ? Transform3d::Identity() : + object->model_object()->instances[instance_idx]->get_transformation().get_matrix(); TriangleMesh inst_mesh; @@ -10305,10 +10610,10 @@ void Plater::export_stl(bool extended, bool selection_only) inst_mesh.merge(inst_object_mesh); - // ensure that the instance lays on the bed + // ensure that the instance lays on the bed inst_mesh.translate(0.0f, 0.0f, -inst_mesh.bounding_box().min.z()); - // merge instance with global mesh + // merge instance with global mesh mesh.merge(inst_mesh); if (one_inst_only) @@ -10320,52 +10625,78 @@ void Plater::export_stl(bool extended, bool selection_only) return mesh; }; - std::function - mesh_to_export; + std::function mesh_to_export; if (p->printer_technology == ptFFF) #if EXPORT_WITH_BOOLEAN - mesh_to_export = [this](const ModelObject& mo, int instance_id) {return Plater::combine_mesh_fff(mo, instance_id, - [this](const std::string& msg) {return get_notification_manager()->push_plater_error_notification(msg); }); }; + mesh_to_export = [this](const ModelObject &mo, int instance_id) { + return Plater::combine_mesh_fff(mo, instance_id, [this](const std::string &msg) { + return get_notification_manager()->push_plater_error_notification(msg); + }); + }; #else mesh_to_export = mesh_to_export_fff_no_boolean; #endif else mesh_to_export = mesh_to_export_sla; + auto get_save_file = [](std::string const &dir, std::string const &name) { + auto path = dir + name + ".stl"; + int n = 1; + while (boost::filesystem::exists(path)) + path = dir + name + "(" + std::to_string(n++) + ").stl"; + return path; + }; + TriangleMesh mesh; if (selection_only) { if (selection.is_single_full_object()) { - const auto obj_idx = selection.get_object_idx(); - const ModelObject* model_object = p->model.objects[obj_idx]; + const auto obj_idx = selection.get_object_idx(); + const ModelObject *model_object = p->model.objects[obj_idx]; if (selection.get_mode() == Selection::Instance) mesh = mesh_to_export(*model_object, (model_object->instances.size() > 1) ? -1 : selection.get_instance_idx()); else { - const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); - mesh = model_object->volumes[volume->volume_idx()]->mesh(); + const GLVolume *volume = selection.get_first_volume(); + mesh = model_object->volumes[volume->volume_idx()]->mesh(); mesh.transform(volume->get_volume_transformation().get_matrix(), true); } - if (model_object->instances.size() == 1) mesh.translate(-model_object->origin_translation.cast()); - } - else if (selection.is_multiple_full_object()) { - const std::set>& instances_idxs = p->get_selection().get_selected_object_instances(); - for (const std::pair& i : instances_idxs) { - ModelObject* object = p->model.objects[i.first]; + if (model_object->instances.size() == 1) + mesh.translate(-model_object->origin_translation.cast()); + } else if (selection.is_multiple_full_object() && !multi_stls) { + const std::set> &instances_idxs = p->get_selection().get_selected_object_instances(); + for (const std::pair &i : instances_idxs) { + ModelObject *object = p->model.objects[i.first]; mesh.merge(mesh_to_export(*object, i.second)); } + } else if (selection.is_multiple_full_object() && multi_stls) { + const std::set> &instances_idxs = p->get_selection().get_selected_object_instances(); + for (const std::pair &i : instances_idxs) { + ModelObject *object = p->model.objects[i.first]; + auto mesh = mesh_to_export(*object, i.second); + mesh.translate(-object->origin_translation.cast()); + + Slic3r::store_stl(get_save_file(path_u8, object->name).c_str(), &mesh, true); + } + return; } - } - else { - for (const ModelObject* o : p->model.objects) { + } else if (!multi_stls) { + for (const ModelObject *o : p->model.objects) { mesh.merge(mesh_to_export(*o, -1)); } + } else { + for (const ModelObject *o : p->model.objects) { + auto mesh = mesh_to_export(*o, -1); + mesh.translate(-o->origin_translation.cast()); + Slic3r::store_stl(get_save_file(path_u8, o->name).c_str(), &mesh, true); + } + return; } Slic3r::store_stl(path_u8.c_str(), &mesh, true); } -//BBS: remove amf export +// BBS: remove amf export /*void Plater::export_amf() { if (p->model.objects.empty()) { return; } @@ -10386,130 +10717,142 @@ void Plater::export_stl(bool extended, bool selection_only) }*/ // BBS: backup -int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy strategy, int export_plate_idx, Export3mfProgressFn proFn) +int Plater::export_3mf(const boost::filesystem::path &output_path, SaveStrategy strategy, int export_plate_idx, Export3mfProgressFn proFn) { int ret = 0; - //if (p->model.objects.empty()) { - // MessageDialog dialog(nullptr, _L("No objects to export."), _L("Save project"), wxYES); - // if (dialog.ShowModal() == wxYES) - // return -1; - //} + // if (p->model.objects.empty()) { + // MessageDialog dialog(nullptr, _L("No objects to export."), _L("Save project"), wxYES); + // if (dialog.ShowModal() == wxYES) + // return -1; + // } if (output_path.empty()) return -1; - bool export_config = true; - wxString path = from_path(output_path); + bool export_config = true; + wxString path = from_path(output_path); if (!path.Lower().EndsWith(".3mf")) return -1; - DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); - const std::string path_u8 = into_u8(path); - wxBusyCursor wait; + DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); + const std::string path_u8 = into_u8(path); + wxBusyCursor wait; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": path=%1%, backup=%2%, export_plate_idx=%3%, SaveStrategy=%4%") - %output_path.string()%(strategy & SaveStrategy::Backup)%export_plate_idx %(unsigned int)strategy; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": path=%1%, backup=%2%, export_plate_idx=%3%, SaveStrategy=%4%") % output_path.string() % + (strategy & SaveStrategy::Backup) % export_plate_idx % (unsigned int) strategy; - //BBS: add plate logic for thumbnail generate - std::vector thumbnails; - std::vector calibration_thumbnails; - std::vector top_thumbnails; - std::vector picking_thumbnails; - std::vector plate_bboxes; + // BBS: add plate logic for thumbnail generate + std::vector thumbnails; + std::vector calibration_thumbnails; + std::vector top_thumbnails; + std::vector picking_thumbnails; + std::vector plate_bboxes; // BBS: backup if (!(strategy & SaveStrategy::Backup)) { for (int i = 0; i < p->partplate_list.get_plate_count(); i++) { - ThumbnailData* thumbnail_data = &p->partplate_list.get_plate(i)->thumbnail_data; - if (p->partplate_list.get_plate(i)->thumbnail_data.is_valid() && using_exported_file()) { - //no need to generate thumbnail - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate thumbnail for gcode/exported mode of plate %1%")%i; - } - else { + ThumbnailData *thumbnail_data = &p->partplate_list.get_plate(i)->thumbnail_data; + if (p->partplate_list.get_plate(i)->thumbnail_data.is_valid() && using_exported_file()) { + // no need to generate thumbnail + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": non need to re-generate thumbnail for gcode/exported mode of plate %1%") % i; + } else { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate thumbnail for plate %1%") % i; - const ThumbnailsParams thumbnail_params = { {}, false, true, true, true, i }; + const ThumbnailsParams thumbnail_params = {{}, false, true, true, true, i}; p->generate_thumbnail(p->partplate_list.get_plate(i)->thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, - thumbnail_params, Camera::EType::Ortho); + thumbnail_params, Camera::EType::Ortho); } thumbnails.push_back(thumbnail_data); - //ThumbnailData* calibration_data = &p->partplate_list.get_plate(i)->cali_thumbnail_data; - //calibration_thumbnails.push_back(calibration_data); - PlateBBoxData* plate_bbox_data = &p->partplate_list.get_plate(i)->cali_bboxes_data; + // ThumbnailData* calibration_data = &p->partplate_list.get_plate(i)->cali_thumbnail_data; + // calibration_thumbnails.push_back(calibration_data); + PlateBBoxData *plate_bbox_data = &p->partplate_list.get_plate(i)->cali_bboxes_data; plate_bboxes.push_back(plate_bbox_data); - //generate top and picking thumbnails - ThumbnailData* top_thumbnail = &p->partplate_list.get_plate(i)->top_thumbnail_data; - if (top_thumbnail->is_valid() && using_exported_file()) { - //no need to generate thumbnail - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate top_thumbnail for gcode/exported mode of plate %1%")%i; - } - else { + // generate top and picking thumbnails + ThumbnailData *top_thumbnail = &p->partplate_list.get_plate(i)->top_thumbnail_data; + if (top_thumbnail->is_valid() && using_exported_file()) { + // no need to generate thumbnail + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": non need to re-generate top_thumbnail for gcode/exported mode of plate %1%") % + i; + } else { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate top_thumbnail for plate %1%") % i; - const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i }; - p->generate_thumbnail(p->partplate_list.get_plate(i)->top_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, - thumbnail_params, Camera::EType::Ortho, true, false); + const ThumbnailsParams thumbnail_params = {{}, false, true, false, true, i}; + p->generate_thumbnail(p->partplate_list.get_plate(i)->top_thumbnail_data, THUMBNAIL_SIZE_3MF.first, + THUMBNAIL_SIZE_3MF.second, thumbnail_params, Camera::EType::Ortho, true, false); } top_thumbnails.push_back(top_thumbnail); - ThumbnailData* picking_thumbnail = &p->partplate_list.get_plate(i)->pick_thumbnail_data; - if (picking_thumbnail->is_valid() && using_exported_file()) { - //no need to generate thumbnail - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate pick_thumbnail for gcode/exported mode of plate %1%")%i; - } - else { + ThumbnailData *picking_thumbnail = &p->partplate_list.get_plate(i)->pick_thumbnail_data; + if (picking_thumbnail->is_valid() && using_exported_file()) { + // no need to generate thumbnail + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": non need to re-generate pick_thumbnail for gcode/exported mode of plate %1%") % + i; + } else { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate pick_thumbnail for plate %1%") % i; - const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i }; - p->generate_thumbnail(p->partplate_list.get_plate(i)->pick_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, - thumbnail_params, Camera::EType::Ortho, true, true); + const ThumbnailsParams thumbnail_params = {{}, false, true, false, true, i}; + p->generate_thumbnail(p->partplate_list.get_plate(i)->pick_thumbnail_data, THUMBNAIL_SIZE_3MF.first, + THUMBNAIL_SIZE_3MF.second, thumbnail_params, Camera::EType::Ortho, true, true); } picking_thumbnails.push_back(picking_thumbnail); } if (p->partplate_list.get_curr_plate()->is_slice_result_valid()) { - //BBS generate BBS calibration thumbnails + // BBS generate BBS calibration thumbnails int index = p->partplate_list.get_curr_plate_index(); - //ThumbnailData* calibration_data = calibration_thumbnails[index]; - //const ThumbnailsParams calibration_params = { {}, false, true, true, true, p->partplate_list.get_curr_plate_index() }; - //p->generate_calibration_thumbnail(*calibration_data, PartPlate::cali_thumbnail_width, PartPlate::cali_thumbnail_height, calibration_params); + // ThumbnailData* calibration_data = calibration_thumbnails[index]; + // const ThumbnailsParams calibration_params = { {}, false, true, true, true, p->partplate_list.get_curr_plate_index() }; + // p->generate_calibration_thumbnail(*calibration_data, PartPlate::cali_thumbnail_width, PartPlate::cali_thumbnail_height, + // calibration_params); if (using_exported_file()) { - //do nothing - } - else + // do nothing + } else *plate_bboxes[index] = p->generate_first_layer_bbox(); } } - //BBS: add bbs 3mf logic + // BBS: add bbs 3mf logic PlateDataPtrs plate_data_list; - p->partplate_list.store_to_3mf_structure(plate_data_list, (strategy & SaveStrategy::WithGcode || strategy & SaveStrategy::WithSliceInfo), export_plate_idx); + p->partplate_list.store_to_3mf_structure(plate_data_list, + (strategy & SaveStrategy::WithGcode || strategy & SaveStrategy::WithSliceInfo), + export_plate_idx); // BBS: backup - PresetBundle& preset_bundle = *wxGetApp().preset_bundle; - std::vector project_presets = preset_bundle.get_current_project_embedded_presets(); + PresetBundle &preset_bundle = *wxGetApp().preset_bundle; + std::vector project_presets = preset_bundle.get_current_project_embedded_presets(); StoreParams store_params; - store_params.path = path_u8.c_str(); - store_params.model = &p->model; - store_params.plate_data_list = plate_data_list; - store_params.export_plate_idx = export_plate_idx; - store_params.project_presets = project_presets; - store_params.config = export_config ? &cfg : nullptr; - store_params.thumbnail_data = thumbnails; - store_params.top_thumbnail_data = top_thumbnails; - store_params.pick_thumbnail_data = picking_thumbnails; + store_params.path = path_u8.c_str(); + store_params.model = &p->model; + store_params.plate_data_list = plate_data_list; + store_params.export_plate_idx = export_plate_idx; + store_params.project_presets = project_presets; + store_params.config = export_config ? &cfg : nullptr; + store_params.thumbnail_data = thumbnails; + store_params.top_thumbnail_data = top_thumbnails; + store_params.pick_thumbnail_data = picking_thumbnails; store_params.calibration_thumbnail_data = calibration_thumbnails; - store_params.proFn = proFn; - store_params.id_bboxes = plate_bboxes;//BBS - store_params.project = &p->project; - store_params.strategy = strategy | SaveStrategy::Zip64; - + store_params.proFn = proFn; + store_params.id_bboxes = plate_bboxes; // BBS + store_params.project = &p->project; + store_params.strategy = strategy | SaveStrategy::Zip64; // get type and color for platedata - auto* filament_color = dynamic_cast(cfg.option("filament_colour")); + auto *filament_color = dynamic_cast(cfg.option("filament_colour")); + auto *nozzle_diameter_option = dynamic_cast(cfg.option("nozzle_diameter")); + std::string nozzle_diameter_str; + if (nozzle_diameter_option) + nozzle_diameter_str = nozzle_diameter_option->serialize(); + + std::string printer_model_id = preset_bundle.printers.get_edited_preset().get_printer_type(&preset_bundle); for (int i = 0; i < plate_data_list.size(); i++) { - PlateData *plate_data = plate_data_list[i]; + PlateData *plate_data = plate_data_list[i]; + plate_data->printer_model_id = printer_model_id; + plate_data->nozzle_diameters = nozzle_diameter_str; for (auto it = plate_data->slice_filaments_info.begin(); it != plate_data->slice_filaments_info.end(); it++) { std::string display_filament_type; it->type = cfg.get_filament_type(display_filament_type, it->id); @@ -10524,7 +10867,7 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy } // handle Design Info - bool has_design_info = false; + bool has_design_info = false; ModelDesignInfo designInfo; if (p->model.design_info != nullptr) { if (!p->model.design_info->Designer.empty()) { @@ -10537,11 +10880,12 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy if (p->model.design_info == nullptr) { // set designInfo before export and reset after export if (wxGetApp().is_user_login()) { - p->model.design_info = std::make_shared(); - //p->model.design_info->Designer = wxGetApp().getAgent()->get_user_nickanme(); + p->model.design_info = std::make_shared(); + // p->model.design_info->Designer = wxGetApp().getAgent()->get_user_nickanme(); p->model.design_info->Designer = ""; p->model.design_info->DesignerUserId = wxGetApp().getAgent()->get_user_id(); - BOOST_LOG_TRIVIAL(trace) << "design_info prepare, designer = "<< ""; + BOOST_LOG_TRIVIAL(trace) << "design_info prepare, designer = " + << ""; BOOST_LOG_TRIVIAL(trace) << "design_info prepare, designer_user_id = " << p->model.design_info->DesignerUserId; } } @@ -10556,16 +10900,14 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy if (!(store_params.strategy & SaveStrategy::Silence)) { // Success p->set_project_filename(path); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " call set_project_filename: " << path; } - } - else { + } else { ret = -1; } - if (project_presets.size() > 0) - { - for (unsigned int i = 0; i < project_presets.size(); i++) - { + if (project_presets.size() > 0) { + for (unsigned int i = 0; i < project_presets.size(); i++) { delete project_presets[i]; } project_presets.clear(); @@ -10573,52 +10915,34 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy release_PlateData_list(plate_data_list); - for (unsigned int i = 0; i < calibration_thumbnails.size(); i++) - { - //release the data here, as it will always be generated when export + for (unsigned int i = 0; i < calibration_thumbnails.size(); i++) { + // release the data here, as it will always be generated when export calibration_thumbnails[i]->reset(); } - for (unsigned int i = 0; i < top_thumbnails.size(); i++) - { - //release the data here, as it will always be generated when export + for (unsigned int i = 0; i < top_thumbnails.size(); i++) { + // release the data here, as it will always be generated when export top_thumbnails[i]->reset(); } top_thumbnails.clear(); - for (unsigned int i = 0; i < picking_thumbnails.size(); i++) - { - //release the data here, as it will always be generated when export - picking_thumbnails[i]->reset();; + for (unsigned int i = 0; i < picking_thumbnails.size(); i++) { + // release the data here, as it will always be generated when export + picking_thumbnails[i]->reset(); + ; } picking_thumbnails.clear(); return ret; } -void Plater::publish_project() -{ - return; -} - +void Plater::publish_project() { return; } -void Plater::reload_from_disk() -{ - p->reload_from_disk(); -} +void Plater::reload_from_disk() { p->reload_from_disk(); } -void Plater::replace_with_stl() -{ - p->replace_with_stl(); -} +void Plater::replace_with_stl() { p->replace_with_stl(); } -void Plater::reload_all_from_disk() -{ - p->reload_all_from_disk(); -} +void Plater::reload_all_from_disk() { p->reload_all_from_disk(); } -bool Plater::has_toolpaths_to_export() const -{ - return p->preview->get_canvas3d()->has_toolpaths_to_export(); -} +bool Plater::has_toolpaths_to_export() const { return p->preview->get_canvas3d()->has_toolpaths_to_export(); } void Plater::export_toolpaths_to_obj() const { @@ -10633,13 +10957,14 @@ void Plater::export_toolpaths_to_obj() const p->preview->get_canvas3d()->export_toolpaths_to_obj(into_u8(path).c_str()); } -//BBS: add multiple plate reslice logic +// BBS: add multiple plate reslice logic void Plater::reslice() { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: enter, process_completed_with_error=%2%")%__LINE__ %p->process_completed_with_error; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(", Line %1%: enter, process_completed_with_error=%2%") % __LINE__ % + p->process_completed_with_error; // There is "invalid data" button instead "slice now" - if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index()) - { + if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index()) { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": process_completed_with_error, return directly"); reset_gcode_toolpaths(); return; @@ -10653,49 +10978,46 @@ void Plater::reslice() // Stop arrange and (or) optimize rotation tasks. this->stop_jobs(); - // regenerate CalibPressureAdvancePattern custom G-code to apply changes + // Orca: regenerate CalibPressureAdvancePattern custom G-code to apply changes if (model().calib_pa_pattern) { - PresetBundle* preset_bundle = wxGetApp().preset_bundle; + PresetBundle *preset_bundle = wxGetApp().preset_bundle; - model().calib_pa_pattern->generate_custom_gcodes( - wxGetApp().preset_bundle->full_config(), - preset_bundle->is_bbl_vendor(), - model(), - get_partplate_list().get_current_plate_origin() - ); + model().calib_pa_pattern->generate_custom_gcodes(wxGetApp().preset_bundle->full_config(), preset_bundle->is_bbl_vendor(), model(), + get_partplate_list().get_current_plate_origin()); } if (printer_technology() == ptSLA) { - for (auto& object : model().objects) + for (auto &object : model().objects) if (object->sla_points_status == sla::PointsStatus::NoPoints) object->sla_points_status = sla::PointsStatus::Generating; } - //FIXME Don't reslice if export of G-code or sending to OctoPrint is running. - // bitmask of UpdateBackgroundProcessReturnState + // FIXME Don't reslice if export of G-code or sending to OctoPrint is running. + // bitmask of UpdateBackgroundProcessReturnState unsigned int state = this->p->update_background_process(true); if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) this->p->view3D->reload_scene(false); // If the SLA processing of just a single object's supports is running, restart slicing for the whole object. this->p->background_process.set_task(PrintBase::TaskParams()); // Only restarts if the state is valid. - //BBS: jusdge the result + // BBS: jusdge the result bool result = this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: restart background,state=%2%, result=%3%")%__LINE__%state %result; - if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0) - { - //BBS: add logs - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": state %1% is UPDATE_BACKGROUND_PROCESS_INVALID, can not slice") % state; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(", Line %1%: restart background,state=%2%, result=%3%") % __LINE__ % state % result; + if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0) { + // BBS: add logs + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ + << boost::format(": state %1% is UPDATE_BACKGROUND_PROCESS_INVALID, can not slice") % state; p->update_fff_scene_only_shells(); return; } - if ((!result) && p->m_slice_all && (p->m_cur_slice_plate < (p->partplate_list.get_plate_count() - 1))) - { - //slice next - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": in slicing all, current plate %1% already sliced, skip to next") % p->m_cur_slice_plate ; - SlicingProcessCompletedEvent evt(EVT_PROCESS_COMPLETED, 0, - SlicingProcessCompletedEvent::Finished, nullptr); + if ((!result) && p->m_slice_all && (p->m_cur_slice_plate < (p->partplate_list.get_plate_count() - 1))) { + // slice next + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ + << boost::format(": in slicing all, current plate %1% already sliced, skip to next") % + p->m_cur_slice_plate; + SlicingProcessCompletedEvent evt(EVT_PROCESS_COMPLETED, 0, SlicingProcessCompletedEvent::Finished, nullptr); // Post the "complete" callback message, so that it will slice the next plate soon wxQueueEvent(this, evt.Clone()); p->m_is_slicing = true; @@ -10712,32 +11034,31 @@ void Plater::reslice() bool clean_gcode_toolpaths = true; // BBS - if (p->background_process.running()) - { - //p->ready_to_slice = false; + if (p->background_process.running()) { + // p->ready_to_slice = false; p->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, false); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": background process is running, m_is_slicing is true"); - } - else if (!p->background_process.empty() && !p->background_process.idle()) { - //p->show_action_buttons(true); - //p->ready_to_slice = true; + } else if (!p->background_process.empty() && !p->background_process.idle()) { + // p->show_action_buttons(true); + // p->ready_to_slice = true; p->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, true); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": background process changes to not_idle, set ready_to_slice back to true"); - } - else { - //BBS: add reset logic for empty plate - PartPlate * current_plate = p->background_process.get_current_plate(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": background process changes to not_idle, set ready_to_slice back to true"); + } else { + // BBS: add reset logic for empty plate + PartPlate *current_plate = p->background_process.get_current_plate(); if (!current_plate->has_printable_instances()) { clean_gcode_toolpaths = true; current_plate->update_slice_result_valid_state(false); - } - else { + } else { clean_gcode_toolpaths = false; current_plate->update_slice_result_valid_state(true); } p->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, false); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": background process in idle state, use previous result, clean_gcode_toolpaths=%1%")%clean_gcode_toolpaths; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": background process in idle state, use previous result, clean_gcode_toolpaths=%1%") % + clean_gcode_toolpaths; } if (clean_gcode_toolpaths) @@ -10745,7 +11066,8 @@ void Plater::reslice() p->preview->reload_print(!clean_gcode_toolpaths); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": finished, started slicing for plate %1%") % p->partplate_list.get_curr_plate_index(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": finished, started slicing for plate %1%") % p->partplate_list.get_curr_plate_index(); record_slice_preset("slicing"); } @@ -10753,17 +11075,15 @@ void Plater::reslice() void Plater::record_slice_preset(std::string action) { // record slice preset - try - { + try { json j; auto printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset_with_vendor_profile().preset; if (printer_preset.is_system) { j["printer_preset_name"] = printer_preset.name; - } - else { + } else { j["printer_preset_name"] = printer_preset.config.opt_string("inherits"); } - const t_config_enum_values* keys_map = print_config_def.get("curr_bed_type")->enum_keys_map; + const t_config_enum_values *keys_map = print_config_def.get("curr_bed_type")->enum_keys_map; if (keys_map) { for (auto item : *keys_map) { if (item.second == wxGetApp().preset_bundle->project_config.opt_enum("curr_bed_type")) { @@ -10777,60 +11097,57 @@ void Plater::record_slice_preset(std::string action) auto filament_preset = wxGetApp().preset_bundle->filaments.find_preset(filament_presets[i]); if (filament_preset->is_system) { j["filament_preset_" + std::to_string(i)] = filament_preset->name; - } - else { + } else { j["filament_preset_" + std::to_string(i)] = filament_preset->config.opt_string("inherits"); } } - Preset& print_preset = wxGetApp().preset_bundle->prints.get_edited_preset(); + Preset &print_preset = wxGetApp().preset_bundle->prints.get_edited_preset(); if (print_preset.is_system) { j["process_preset"] = print_preset.name; - } - else { + } else { j["process_preset"] = print_preset.config.opt_string("inherits"); } j["support_type"] = ConfigOptionEnum::get_enum_names().at(print_preset.config.opt_enum("support_type")); - j["sparse_infill_pattern"] = ConfigOptionEnum::get_enum_names().at(print_preset.config.opt_enum("sparse_infill_pattern")); + j["sparse_infill_pattern"] = ConfigOptionEnum::get_enum_names().at( + print_preset.config.opt_enum("sparse_infill_pattern")); j["sparse_infill_density"] = print_preset.config.opt("sparse_infill_density")->value; j["brim_type"] = ConfigOptionEnum::get_enum_names().at(print_preset.config.opt_enum("brim_type")); j["user_mode"] = wxGetApp().get_mode_str(); if (p->background_process.fff_print()) { - const DynamicPrintConfig& full_config = p->background_process.fff_print()->full_print_config(); - json values = json::array(); + const DynamicPrintConfig &full_config = p->background_process.fff_print()->full_print_config(); + json values = json::array(); if (full_config.has("different_settings_to_system")) { std::vector different_values = full_config.option("different_settings_to_system")->values; - for (auto& item : different_values) { + for (auto &item : different_values) { values.push_back(item); } } j["different_settings_to_system"] = values; } - j["record_event"] = action; - NetworkAgent* agent = wxGetApp().getAgent(); - } - catch (...) - { + j["record_event"] = action; + NetworkAgent *agent = wxGetApp().getAgent(); + } catch (...) { return; } } -//BBS: add project slicing related logic +// BBS: add project slicing related logic int Plater::start_next_slice() { // Stop arrange and (or) optimize rotation tasks. - //this->stop_jobs(); + // this->stop_jobs(); - //FIXME Don't reslice if export of G-code or sending to OctoPrint is running. - // bitmask of UpdateBackgroundProcessReturnState + // FIXME Don't reslice if export of G-code or sending to OctoPrint is running. + // bitmask of UpdateBackgroundProcessReturnState unsigned int state = this->p->update_background_process(true, false, false); if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) this->p->view3D->reload_scene(false); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": update_background_process returns %1%")%state; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": update_background_process returns %1%") % state; if (p->partplate_list.get_curr_plate()->is_apply_result_invalid()) { p->process_completed_with_error = p->partplate_list.get_curr_plate_index(); BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": found invalidated apply in update_background_process."); @@ -10839,20 +11156,17 @@ int Plater::start_next_slice() // Only restarts if the state is valid. bool result = this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART); - if (!result) - { - //slice next - SlicingProcessCompletedEvent evt(EVT_PROCESS_COMPLETED, 0, - SlicingProcessCompletedEvent::Finished, nullptr); + if (!result) { + // slice next + SlicingProcessCompletedEvent evt(EVT_PROCESS_COMPLETED, 0, SlicingProcessCompletedEvent::Finished, nullptr); // Post the "complete" callback message, so that it will slice the next plate soon wxQueueEvent(this, evt.Clone()); } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": restart_background_process returns %1%")%result; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": restart_background_process returns %1%") % result; return 0; } - void Plater::reslice_SLA_supports(const ModelObject &object, bool postpone_error_messages) { reslice_SLA_until_step(slaposPad, object, postpone_error_messages); @@ -10865,8 +11179,8 @@ void Plater::reslice_SLA_hollowing(const ModelObject &object, bool postpone_erro void Plater::reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &object, bool postpone_error_messages) { - //FIXME Don't reslice if export of G-code or sending to OctoPrint is running. - // bitmask of UpdateBackgroundProcessReturnState + // FIXME Don't reslice if export of G-code or sending to OctoPrint is running. + // bitmask of UpdateBackgroundProcessReturnState unsigned int state = this->p->update_background_process(true, postpone_error_messages); if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) this->p->view3D->reload_scene(false); @@ -10882,7 +11196,7 @@ void Plater::reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject & // Otherwise calculate everything, but start with the provided object. if (!this->p->background_processing_enabled()) { task.single_model_instance_only = true; - task.to_object_step = step; + task.to_object_step = step; } this->p->background_process.set_task(task); // and let the background processing start. @@ -10892,8 +11206,8 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn) { // if physical_printer is selected, send gcode for this printer // DynamicPrintConfig* physical_printer_config = wxGetApp().preset_bundle->physical_printers.get_selected_printer_config(); - DynamicPrintConfig* physical_printer_config = &Slic3r::GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config; - if (! physical_printer_config || p->model.objects.empty()) + DynamicPrintConfig *physical_printer_config = &Slic3r::GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config; + if (!physical_printer_config || p->model.objects.empty()) return; PrintHostJob upload_job(physical_printer_config); @@ -10909,11 +11223,11 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn) if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) return; default_output_file = this->p->background_process.output_filepath_for_project(""); - } catch (const Slic3r::PlaceholderParserError& ex) { + } catch (const Slic3r::PlaceholderParserError &ex) { // Show the error with monospaced font. show_error(this, ex.what(), true); return; - } catch (const std::exception& ex) { + } catch (const std::exception &ex) { show_error(this, ex.what(), false); return; } @@ -10933,7 +11247,7 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn) wxBusyCursor wait; try { upload_job.printhost->get_storage(storage_paths, storage_names); - } catch (const Slic3r::IOError& ex) { + } catch (const Slic3r::IOError &ex) { show_error(this, ex.what(), false); return; } @@ -10947,8 +11261,10 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn) upload_job.upload_data.storage = dlg.storage(); // Show "Is printer clean" dialog for PrusaConnect - Upload and print. - if (std::string(upload_job.printhost->get_name()) == "PrusaConnect" && upload_job.upload_data.post_action == PrintHostPostUploadAction::StartPrint) { - GUI::MessageDialog dlg(nullptr, _L("Is the printer ready? Is the print sheet in place, empty and clean?"), _L("Upload and Print"), wxOK | wxCANCEL); + if (std::string(upload_job.printhost->get_name()) == "PrusaConnect" && + upload_job.upload_data.post_action == PrintHostPostUploadAction::StartPrint) { + GUI::MessageDialog dlg(nullptr, _L("Is the printer ready? Is the print sheet in place, empty and clean?"), + _L("Upload and Print"), wxOK | wxCANCEL); if (dlg.ShowModal() != wxID_OK) return; } @@ -10962,24 +11278,22 @@ int Plater::send_gcode(int plate_idx, Export3mfProgressFn proFn) /* generate 3mf */ if (plate_idx == PLATE_CURRENT_IDX) { p->m_print_job_data.plate_idx = get_partplate_list().get_curr_plate_index(); - } - else { + } else { p->m_print_job_data.plate_idx = plate_idx; } - PartPlate* plate = get_partplate_list().get_curr_plate(); + PartPlate *plate = get_partplate_list().get_curr_plate(); try { p->m_print_job_data._3mf_path = fs::path(plate->get_tmp_gcode_path()); p->m_print_job_data._3mf_path.replace_extension("3mf"); - } - catch (std::exception& e) { + } catch (std::exception &e) { BOOST_LOG_TRIVIAL(error) << "generate 3mf path failed"; return -1; } SaveStrategy strategy = SaveStrategy::Silence | SaveStrategy::SkipModel | SaveStrategy::WithGcode; #if !BBL_RELEASE_TO_PUBLIC - //only save model in QA environment + // only save model in QA environment std::string sel = get_app_config()->get("iot_environment"); if (sel == ENV_PRE_HOST) strategy = SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithGcode; @@ -10996,33 +11310,31 @@ int Plater::export_config_3mf(int plate_idx, Export3mfProgressFn proFn) /* generate 3mf */ if (plate_idx == PLATE_CURRENT_IDX) { p->m_print_job_data.plate_idx = get_partplate_list().get_curr_plate_index(); - } - else { + } else { p->m_print_job_data.plate_idx = plate_idx; } - PartPlate* plate = get_partplate_list().get_curr_plate(); + PartPlate *plate = get_partplate_list().get_curr_plate(); try { p->m_print_job_data._3mf_config_path = fs::path(plate->get_temp_config_3mf_path()); - } - catch (std::exception& e) { + } catch (std::exception &e) { BOOST_LOG_TRIVIAL(error) << "generate 3mf path failed"; return -1; } SaveStrategy strategy = SaveStrategy::Silence | SaveStrategy::SkipModel | SaveStrategy::WithSliceInfo | SaveStrategy::SkipAuxiliary; - result = export_3mf(p->m_print_job_data._3mf_config_path, strategy, plate_idx, proFn); + result = export_3mf(p->m_print_job_data._3mf_config_path, strategy, plate_idx, proFn); return result; } -//BBS -void Plater::send_calibration_job_finished(wxCommandEvent & evt) +// BBS +void Plater::send_calibration_job_finished(wxCommandEvent &evt) { p->main_frame->request_select_tab(MainFrame::TabPosition::tpCalibration); auto calibration_panel = p->main_frame->m_calibration; if (calibration_panel) { - auto curr_wizard = static_cast(calibration_panel->get_tabpanel()->GetPage(evt.GetInt())); + auto curr_wizard = static_cast(calibration_panel->get_tabpanel()->GetPage(evt.GetInt())); wxCommandEvent event(EVT_CALIBRATION_JOB_FINISHED); event.SetString(evt.GetString()); event.SetEventObject(curr_wizard); @@ -11033,71 +11345,69 @@ void Plater::send_calibration_job_finished(wxCommandEvent & evt) void Plater::print_job_finished(wxCommandEvent &evt) { - //start print failed + // start print failed if (Slic3r::GUI::wxGetApp().get_inf_dialog_contect().empty()) { p->hide_select_machine_dlg(); - } - else { + } else { p->enter_prepare_mode(); } - - Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); - if (!dev) return; + Slic3r::DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager(); + if (!dev) + return; dev->set_selected_machine(evt.GetString().ToStdString()); p->main_frame->request_select_tab(MainFrame::TabPosition::tpMonitor); - //jump to monitor and select device status panel - MonitorPanel* curr_monitor = p->main_frame->m_monitor; - if(curr_monitor) - curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS); + // jump to monitor and select device status panel + MonitorPanel *curr_monitor = p->main_frame->m_monitor; + if (curr_monitor) + curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS); } -void Plater::send_job_finished(wxCommandEvent& evt) +void Plater::send_job_finished(wxCommandEvent &evt) { - Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); - if (!dev) return; - //dev->set_selected_machine(evt.GetString().ToStdString()); + Slic3r::DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager(); + if (!dev) + return; + // dev->set_selected_machine(evt.GetString().ToStdString()); send_gcode_finish(evt.GetString()); p->hide_send_to_printer_dlg(); - //p->main_frame->request_select_tab(MainFrame::TabPosition::tpMonitor); + // p->main_frame->request_select_tab(MainFrame::TabPosition::tpMonitor); ////jump to monitor and select device status panel - //MonitorPanel* curr_monitor = p->main_frame->m_monitor; - //if (curr_monitor) - // curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS); + // MonitorPanel* curr_monitor = p->main_frame->m_monitor; + // if (curr_monitor) + // curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS); } void Plater::publish_job_finished(wxCommandEvent &evt) { p->m_publish_dlg->EndModal(wxID_OK); - // GUI::wxGetApp().load_url(evt.GetString()); - //GUI::wxGetApp().open_publish_page_dialog(evt.GetString()); + // GUI::wxGetApp().load_url(evt.GetString()); + // GUI::wxGetApp().open_publish_page_dialog(evt.GetString()); } // Called when the Eject button is pressed. void Plater::eject_drive() { - wxBusyCursor wait; + wxBusyCursor wait; wxGetApp().removable_drive_manager()->set_and_verify_last_save_path(p->last_output_dir_path); - wxGetApp().removable_drive_manager()->eject_drive(); + wxGetApp().removable_drive_manager()->eject_drive(); } void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot(snapshot_name); } -//void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); } -void Plater::take_snapshot(const std::string &snapshot_name, UndoRedo::SnapshotType snapshot_type) { p->take_snapshot(snapshot_name, snapshot_type); } -//void Plater::take_snapshot(const wxString &snapshot_name, UndoRedo::SnapshotType snapshot_type) { p->take_snapshot(snapshot_name, snapshot_type); } +// void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); } +void Plater::take_snapshot(const std::string &snapshot_name, UndoRedo::SnapshotType snapshot_type) +{ + p->take_snapshot(snapshot_name, snapshot_type); +} +// void Plater::take_snapshot(const wxString &snapshot_name, UndoRedo::SnapshotType snapshot_type) { p->take_snapshot(snapshot_name, +// snapshot_type); } void Plater::suppress_snapshots() { p->suppress_snapshots(); } void Plater::allow_snapshots() { p->allow_snapshots(); } // BBS: single snapshot -void Plater::single_snapshots_enter(SingleSnapshot *single) -{ - p->single_snapshots_enter(single); -} -void Plater::single_snapshots_leave(SingleSnapshot *single) -{ - p->single_snapshots_leave(single); -} +void Plater::single_snapshots_enter(SingleSnapshot *single) { p->single_snapshots_enter(single); } +void Plater::single_snapshots_leave(SingleSnapshot *single) { p->single_snapshots_leave(single); } void Plater::undo() { p->undo(); } void Plater::redo() { p->redo(); } void Plater::undo_to(int selection) @@ -11120,12 +11430,12 @@ void Plater::redo_to(int selection) const int idx = p->get_active_snapshot_index() + selection + 1; p->undo_redo_to(p->undo_redo_stack().snapshots()[idx].timestamp); } -bool Plater::undo_redo_string_getter(const bool is_undo, int idx, const char** out_text) +bool Plater::undo_redo_string_getter(const bool is_undo, int idx, const char **out_text) { - const std::vector& ss_stack = p->undo_redo_stack().snapshots(); - const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -(++idx) : idx); + const std::vector &ss_stack = p->undo_redo_stack().snapshots(); + const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -(++idx) : idx); - if (0 < idx_in_ss_stack && (size_t)idx_in_ss_stack < ss_stack.size() - 1) { + if (0 < idx_in_ss_stack && (size_t) idx_in_ss_stack < ss_stack.size() - 1) { *out_text = ss_stack[idx_in_ss_stack].name.c_str(); return true; } @@ -11133,18 +11443,21 @@ bool Plater::undo_redo_string_getter(const bool is_undo, int idx, const char** o return false; } -int Plater::update_print_required_data(Slic3r::DynamicPrintConfig config, Slic3r::Model model, Slic3r::PlateDataPtrs plate_data_list, std::string file_name, std::string file_path) +int Plater::update_print_required_data(Slic3r::DynamicPrintConfig config, + Slic3r::Model model, + Slic3r::PlateDataPtrs plate_data_list, + std::string file_name, + std::string file_path) { return p->update_print_required_data(config, model, plate_data_list, file_name, file_path); } - -void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text) +void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string &out_text) { - const std::vector& ss_stack = p->undo_redo_stack().snapshots(); - const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -1 : 0); + const std::vector &ss_stack = p->undo_redo_stack().snapshots(); + const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -1 : 0); - if (0 < idx_in_ss_stack && (size_t)idx_in_ss_stack < ss_stack.size() - 1) { + if (0 < idx_in_ss_stack && (size_t) idx_in_ss_stack < ss_stack.size() - 1) { out_text = ss_stack[idx_in_ss_stack].name; return; } @@ -11152,11 +11465,11 @@ void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& ou out_text = ""; } -bool Plater::search_string_getter(int idx, const char** label, const char** tooltip) +bool Plater::search_string_getter(int idx, const char **label, const char **tooltip) { - const Search::OptionsSearcher& search_list = p->sidebar->get_searcher(); + const Search::OptionsSearcher &search_list = p->sidebar->get_searcher(); - if (0 <= idx && (size_t)idx < search_list.size()) { + if (0 <= idx && (size_t) idx < search_list.size()) { search_list[idx].get_marked_label_and_tooltip(label, tooltip); return true; } @@ -11174,43 +11487,39 @@ void Plater::on_filaments_change(size_t num_filaments) Slic3r::GUI::PartPlateList &plate_list = get_partplate_list(); for (int i = 0; i < plate_list.get_plate_count(); ++i) { - PartPlate* part_plate = plate_list.get_plate(i); + PartPlate *part_plate = plate_list.get_plate(i); part_plate->update_first_layer_print_sequence(num_filaments); } - for (ModelObject* mo : wxGetApp().model().objects) { - for (ModelVolume* mv : mo->volumes) { + for (ModelObject *mo : wxGetApp().model().objects) { + for (ModelVolume *mv : mo->volumes) { mv->update_extruder_count(num_filaments); } } } -void Plater::on_bed_type_change(BedType bed_type) -{ - sidebar().on_bed_type_change(bed_type); -} +void Plater::on_bed_type_change(BedType bed_type) { sidebar().on_bed_type_change(bed_type); } bool Plater::update_filament_colors_in_full_config() { - DynamicPrintConfig& project_config = wxGetApp().preset_bundle->project_config; - ConfigOptionStrings* color_opt = project_config.option("filament_colour"); + DynamicPrintConfig &project_config = wxGetApp().preset_bundle->project_config; + ConfigOptionStrings *color_opt = project_config.option("filament_colour"); p->config->option("filament_colour")->values = color_opt->values; return true; } -void Plater::config_change_notification(const DynamicPrintConfig &config, const std::string& key) +void Plater::config_change_notification(const DynamicPrintConfig &config, const std::string &key) { - GLCanvas3D* view3d_canvas = get_view3D_canvas3D(); + GLCanvas3D *view3d_canvas = get_view3D_canvas3D(); if (key == std::string("print_sequence")) { auto seq_print = config.option>("print_sequence"); if (seq_print && view3d_canvas && view3d_canvas->is_initialized() && view3d_canvas->is_rendering_enabled()) { - NotificationManager* notify_manager = get_notification_manager(); + NotificationManager *notify_manager = get_notification_manager(); if (seq_print->value == PrintSequence::ByObject) { std::string info_text = _u8L("Print By Object: \nSuggest to use auto-arrange to avoid collisions when printing."); notify_manager->bbl_show_seqprintinfo_notification(info_text); - } - else + } else notify_manager->bbl_close_seqprintinfo_notification(); } } @@ -11219,9 +11528,9 @@ void Plater::config_change_notification(const DynamicPrintConfig &config, const void Plater::on_config_change(const DynamicPrintConfig &config) { - bool update_scheduled = false; + bool update_scheduled = false; bool bed_shape_changed = false; - //bool print_sequence_changed = false; + // bool print_sequence_changed = false; t_config_option_keys diff_keys = p->config->diff(config); for (auto opt_key : diff_keys) { if (opt_key == "filament_colour") { @@ -11244,51 +11553,41 @@ void Plater::on_config_change(const DynamicPrintConfig &config) p->sidebar->update_searcher(); p->reset_gcode_toolpaths(); p->view3D->get_canvas3d()->reset_sequential_print_clearance(); - //BBS: invalid all the slice results + // BBS: invalid all the slice results p->partplate_list.invalid_all_slice_result(); } - //BBS: add bed_exclude_area - else if (opt_key == "printable_area" || opt_key == "bed_exclude_area" - || opt_key == "bed_custom_texture" || opt_key == "bed_custom_model" - || opt_key == "extruder_clearance_height_to_lid" - || opt_key == "extruder_clearance_height_to_rod") { + // BBS: add bed_exclude_area + else if (opt_key == "printable_area" || opt_key == "bed_exclude_area" || opt_key == "bed_custom_texture" || + opt_key == "bed_custom_model" || opt_key == "extruder_clearance_height_to_lid" || + opt_key == "extruder_clearance_height_to_rod") { bed_shape_changed = true; - update_scheduled = true; - } - else if (opt_key == "bed_shape" || opt_key == "bed_custom_texture" || opt_key == "bed_custom_model") { + update_scheduled = true; + } else if (opt_key == "bed_shape" || opt_key == "bed_custom_texture" || opt_key == "bed_custom_model") { bed_shape_changed = true; + update_scheduled = true; + } else if (boost::starts_with(opt_key, "enable_prime_tower") || boost::starts_with(opt_key, "prime_tower") || + boost::starts_with(opt_key, "wipe_tower") || opt_key == "filament_minimal_purge_on_wipe_tower" || + opt_key == "single_extruder_multi_material" || + // BBS + opt_key == "prime_volume") { update_scheduled = true; - } - else if (boost::starts_with(opt_key, "enable_prime_tower") || - boost::starts_with(opt_key, "prime_tower") || - boost::starts_with(opt_key, "wipe_tower") || - opt_key == "filament_minimal_purge_on_wipe_tower" || - opt_key == "single_extruder_multi_material" || - // BBS - opt_key == "prime_volume") { - update_scheduled = true; - } - else if(opt_key == "extruder_colour") { + } else if (opt_key == "extruder_colour") { update_scheduled = true; - //p->sidebar->obj_list()->update_extruder_colors(); - } - else if (opt_key == "printable_height") { + // p->sidebar->obj_list()->update_extruder_colors(); + } else if (opt_key == "printable_height") { bed_shape_changed = true; + update_scheduled = true; + } else if (opt_key == "print_sequence") { update_scheduled = true; - } - else if (opt_key == "print_sequence") { - update_scheduled = true; - //print_sequence_changed = true; - } - else if (opt_key == "printer_model") { + // print_sequence_changed = true; + } else if (opt_key == "printer_model") { p->reset_gcode_toolpaths(); // update to force bed selection(for texturing) bed_shape_changed = true; - update_scheduled = true; + update_scheduled = true; } // BBS - else if (opt_key == "support_interface_filament" || - opt_key == "support_filament") { + else if (opt_key == "support_interface_filament" || opt_key == "support_filament") { update_scheduled = true; } } @@ -11308,35 +11607,42 @@ void Plater::on_config_change(const DynamicPrintConfig &config) void Plater::set_bed_shape() const { std::string texture_filename; - auto bundle = wxGetApp().preset_bundle; + auto bundle = wxGetApp().preset_bundle; if (bundle != nullptr) { - const Preset* curr = &bundle->printers.get_selected_preset(); + const Preset *curr = &bundle->printers.get_selected_preset(); if (curr->is_system) texture_filename = PresetUtils::system_printer_bed_texture(*curr); else { auto *printer_model = curr->config.opt("printer_model"); - if (printer_model != nullptr && ! printer_model->value.empty()) { + if (printer_model != nullptr && !printer_model->value.empty()) { texture_filename = bundle->get_texture_for_printer_model(printer_model->value); } } } set_bed_shape(p->config->option("printable_area")->values, - //BBS: add bed exclude areas - p->config->option("bed_exclude_area")->values, - p->config->option("printable_height")->value, - p->config->option("bed_custom_texture")->value.empty() ? texture_filename : p->config->option("bed_custom_texture")->value, - p->config->option("bed_custom_model")->value); -} - -//BBS: add bed exclude area -void Plater::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_area, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const + // BBS: add bed exclude areas + p->config->option("bed_exclude_area")->values, + p->config->option("printable_height")->value, + p->config->option("bed_custom_texture")->value.empty() ? + texture_filename : + p->config->option("bed_custom_texture")->value, + p->config->option("bed_custom_model")->value); +} + +// BBS: add bed exclude area +void Plater::set_bed_shape(const Pointfs &shape, + const Pointfs &exclude_area, + const double printable_height, + const std::string &custom_texture, + const std::string &custom_model, + bool force_as_custom) const { p->set_bed_shape(shape, exclude_area, printable_height, custom_texture, custom_model, force_as_custom); } void Plater::force_filament_colors_update() { -//BBS: filament_color logic has been moved out of filament setting +// BBS: filament_color logic has been moved out of filament setting #if 0 bool update_scheduled = false; DynamicPrintConfig* config = p->config; @@ -11369,24 +11675,21 @@ void Plater::force_filament_colors_update() void Plater::force_print_bed_update() { - // Fill in the printer model key with something which cannot possibly be valid, so that Plater::on_config_change() will update the print bed - // once a new Printer profile config is loaded. + // Fill in the printer model key with something which cannot possibly be valid, so that Plater::on_config_change() will update the print + // bed once a new Printer profile config is loaded. p->config->opt_string("printer_model", true) = "bbl_empty"; } -void Plater::on_activate() -{ - this->p->show_delayed_error_message(); -} +void Plater::on_activate() { this->p->show_delayed_error_message(); } // Get vector of extruder colors considering filament color, if extruder color is undefined. -std::vector Plater::get_extruder_colors_from_plater_config(const GCodeProcessorResult* const result) const +std::vector Plater::get_extruder_colors_from_plater_config(const GCodeProcessorResult *const result) const { if (wxGetApp().is_gcode_viewer() && result != nullptr) return result->extruder_colors; else { - const Slic3r::DynamicPrintConfig* config = &wxGetApp().preset_bundle->project_config; - std::vector filament_colors; + const Slic3r::DynamicPrintConfig *config = &wxGetApp().preset_bundle->project_config; + std::vector filament_colors; if (!config->has("filament_colour")) // in case of a SLA print return filament_colors; @@ -11398,20 +11701,19 @@ std::vector Plater::get_extruder_colors_from_plater_config(const GC /* Get vector of colors used for rendering of a Preview scene in "Color print" mode * It consists of extruder colors and colors, saved in model.custom_gcode_per_print_z */ -std::vector Plater::get_colors_for_color_print(const GCodeProcessorResult* const result) const +std::vector Plater::get_colors_for_color_print(const GCodeProcessorResult *const result) const { std::vector colors = get_extruder_colors_from_plater_config(result); if (wxGetApp().is_gcode_viewer() && result != nullptr) { - for (const CustomGCode::Item& code : result->custom_gcode_per_print_z) { + for (const CustomGCode::Item &code : result->custom_gcode_per_print_z) { if (code.type == CustomGCode::ColorChange) colors.emplace_back(code.color); } - } - else { - //BBS + } else { + // BBS colors.reserve(colors.size() + p->model.get_curr_plate_custom_gcodes().gcodes.size()); - for (const CustomGCode::Item& code : p->model.get_curr_plate_custom_gcodes().gcodes) { + for (const CustomGCode::Item &code : p->model.get_curr_plate_custom_gcodes().gcodes) { if (code.type == CustomGCode::ColorChange) colors.emplace_back(code.color); } @@ -11420,10 +11722,7 @@ std::vector Plater::get_colors_for_color_print(const GCodeProcessor return colors; } -wxWindow* Plater::get_select_machine_dialog() -{ - return p->m_select_machine_dlg; -} +wxWindow *Plater::get_select_machine_dialog() { return p->m_select_machine_dlg; } void Plater::update_print_error_info(int code, std::string msg, std::string extra) { @@ -11438,74 +11737,47 @@ void Plater::update_print_error_info(int code, std::string msg, std::string extr p->main_frame->m_calibration->update_print_error_info(code, msg, extra); } -wxString Plater::get_project_filename(const wxString& extension) const -{ - return p->get_project_filename(extension); -} +wxString Plater::get_project_filename(const wxString &extension) const { return p->get_project_filename(extension); } -wxString Plater::get_export_gcode_filename(const wxString & extension, bool only_filename, bool export_all) const +wxString Plater::get_export_gcode_filename(const wxString &extension, bool only_filename, bool export_all) const { return p->get_export_gcode_filename(extension, only_filename, export_all); } -void Plater::set_project_filename(const wxString& filename) -{ - p->set_project_filename(filename); -} +void Plater::set_project_filename(const wxString &filename) { p->set_project_filename(filename); } -bool Plater::is_export_gcode_scheduled() const -{ - return p->background_process.is_export_scheduled(); -} +bool Plater::is_export_gcode_scheduled() const { return p->background_process.is_export_scheduled(); } -const Selection &Plater::get_selection() const -{ - return p->get_selection(); -} +const Selection &Plater::get_selection() const { return p->get_selection(); } -int Plater::get_selected_object_idx() -{ - return p->get_selected_object_idx(); -} +int Plater::get_selected_object_idx() { return p->get_selected_object_idx(); } -bool Plater::is_single_full_object_selection() const -{ - return p->get_selection().is_single_full_object(); -} +bool Plater::is_single_full_object_selection() const { return p->get_selection().is_single_full_object(); } -GLCanvas3D* Plater::canvas3D() +GLCanvas3D *Plater::canvas3D() { // BBS modify view3D->get_canvas3d() to current canvas return p->get_current_canvas3D(); } -const GLCanvas3D* Plater::canvas3D() const +const GLCanvas3D *Plater::canvas3D() const { // BBS modify view3D->get_canvas3d() to current canvas return p->get_current_canvas3D(); } -GLCanvas3D* Plater::get_view3D_canvas3D() -{ - return p->view3D->get_canvas3d(); -} +GLCanvas3D *Plater::get_view3D_canvas3D() { return p->view3D->get_canvas3d(); } -GLCanvas3D* Plater::get_preview_canvas3D() -{ - return p->preview->get_canvas3d(); -} +GLCanvas3D *Plater::get_preview_canvas3D() { return p->preview->get_canvas3d(); } -GLCanvas3D* Plater::get_assmeble_canvas3D() +GLCanvas3D *Plater::get_assmeble_canvas3D() { if (p->assemble_view) return p->assemble_view->get_canvas3d(); return nullptr; } -GLCanvas3D* Plater::get_current_canvas3D(bool exclude_preview) -{ - return p->get_current_canvas3D(exclude_preview); -} +GLCanvas3D *Plater::get_current_canvas3D(bool exclude_preview) { return p->get_current_canvas3D(exclude_preview); } void Plater::arrange() { @@ -11514,46 +11786,34 @@ void Plater::arrange() } } -void Plater::set_current_canvas_as_dirty() -{ - p->set_current_canvas_as_dirty(); -} +void Plater::set_current_canvas_as_dirty() { p->set_current_canvas_as_dirty(); } -void Plater::unbind_canvas_event_handlers() -{ - p->unbind_canvas_event_handlers(); -} +void Plater::unbind_canvas_event_handlers() { p->unbind_canvas_event_handlers(); } -void Plater::reset_canvas_volumes() -{ - p->reset_canvas_volumes(); -} +void Plater::reset_canvas_volumes() { p->reset_canvas_volumes(); } -PrinterTechnology Plater::printer_technology() const -{ - return p->printer_technology; -} +PrinterTechnology Plater::printer_technology() const { return p->printer_technology; } -const DynamicPrintConfig * Plater::config() const { return p->config; } +const DynamicPrintConfig *Plater::config() const { return p->config; } bool Plater::set_printer_technology(PrinterTechnology printer_technology) { p->printer_technology = printer_technology; - bool ret = p->background_process.select_technology(printer_technology); + bool ret = p->background_process.select_technology(printer_technology); if (ret) { // Update the active presets. } - //FIXME for SLA synchronize - //p->background_process.apply(Model)! + // FIXME for SLA synchronize + // p->background_process.apply(Model)! if (printer_technology == ptSLA) { - for (ModelObject* model_object : p->model.objects) { + for (ModelObject *model_object : p->model.objects) { model_object->ensure_on_bed(); } } p->label_btn_export = printer_technology == ptFFF ? L("Export G-code") : L("Export"); - p->label_btn_send = printer_technology == ptFFF ? L("Send G-code") : L("Send to printer"); + p->label_btn_send = printer_technology == ptFFF ? L("Send G-code") : L("Send to printer"); if (wxGetApp().mainframe != nullptr) wxGetApp().mainframe->update_menubar(); @@ -11568,29 +11828,28 @@ bool Plater::set_printer_technology(PrinterTechnology printer_technology) void Plater::clear_before_change_mesh(int obj_idx) { - ModelObject* mo = model().objects[obj_idx]; + ModelObject *mo = model().objects[obj_idx]; // If there are custom supports/seams/mmu segmentation, remove them. Fixed mesh // may be different and they would make no sense. bool paint_removed = false; - for (ModelVolume* mv : mo->volumes) { - paint_removed |= ! mv->supported_facets.empty() || ! mv->seam_facets.empty() || ! mv->mmu_segmentation_facets.empty(); + for (ModelVolume *mv : mo->volumes) { + paint_removed |= !mv->supported_facets.empty() || !mv->seam_facets.empty() || !mv->mmu_segmentation_facets.empty(); mv->supported_facets.reset(); mv->seam_facets.reset(); mv->mmu_segmentation_facets.reset(); } if (paint_removed) { // snapshot_time is captured by copy so the lambda knows where to undo/redo to. - get_notification_manager()->push_notification( - NotificationType::CustomSupportsAndSeamRemovedAfterRepair, - NotificationManager::NotificationLevel::PrintInfoNotificationLevel, - _u8L("Custom supports and color painting were removed before repairing.")); + get_notification_manager()->push_notification(NotificationType::CustomSupportsAndSeamRemovedAfterRepair, + NotificationManager::NotificationLevel::PrintInfoNotificationLevel, + _u8L("Custom supports and color painting were removed before repairing.")); } } void Plater::changed_mesh(int obj_idx) { - ModelObject* mo = model().objects[obj_idx]; + ModelObject *mo = model().objects[obj_idx]; sla::reproject_points_and_holes(mo); update(); p->object_list_changed(); @@ -11607,15 +11866,14 @@ void Plater::changed_object(int obj_idx) // Update the SLAPrint from the current Model, so that the reload_scene() // pulls the correct data, update the 3D scene. this->p->update_restart_background_process(true, false); - } - else + } else p->view3D->reload_scene(false); // update print this->p->schedule_background_process(); } -void Plater::changed_objects(const std::vector& object_idxs) +void Plater::changed_objects(const std::vector &object_idxs) { if (object_idxs.empty()) return; @@ -11631,8 +11889,7 @@ void Plater::changed_objects(const std::vector& object_idxs) // Update the SLAPrint from the current Model, so that the reload_scene() // pulls the correct data, update the 3D scene. this->p->update_restart_background_process(true, false); - } - else { + } else { p->view3D->reload_scene(false); p->view3D->get_canvas3d()->update_instance_printable_state_for_objects(object_idxs); } @@ -11641,7 +11898,7 @@ void Plater::changed_objects(const std::vector& object_idxs) this->p->schedule_background_process(); } -void Plater::schedule_background_process(bool schedule/* = true*/) +void Plater::schedule_background_process(bool schedule /* = true*/) { if (schedule) this->p->schedule_background_process(); @@ -11649,10 +11906,7 @@ void Plater::schedule_background_process(bool schedule/* = true*/) this->p->suppressed_backround_processing_update = false; } -bool Plater::is_background_process_update_scheduled() const -{ - return this->p->background_process_timer.IsRunning(); -} +bool Plater::is_background_process_update_scheduled() const { return this->p->background_process_timer.IsRunning(); } void Plater::suppress_background_process(const bool stop_background_process) { @@ -11662,14 +11916,18 @@ void Plater::suppress_background_process(const bool stop_background_process) this->p->suppressed_backround_processing_update = true; } -void Plater::center_selection() { p->center_selection(); } -void Plater::mirror(Axis axis) { p->mirror(axis); } -void Plater::split_object() { p->split_object(); } -void Plater::split_volume() { p->split_volume(); } -void Plater::optimize_rotation() { if (!p->m_ui_jobs.is_any_running()) p->m_ui_jobs.optimize_rotation(); } -void Plater::update_menus() { p->menus.update(); } +void Plater::center_selection() { p->center_selection(); } +void Plater::mirror(Axis axis) { p->mirror(axis); } +void Plater::split_object() { p->split_object(); } +void Plater::split_volume() { p->split_volume(); } +void Plater::optimize_rotation() +{ + if (!p->m_ui_jobs.is_any_running()) + p->m_ui_jobs.optimize_rotation(); +} +void Plater::update_menus() { p->menus.update(); } // BBS -//void Plater::show_action_buttons(const bool ready_to_slice) const { p->show_action_buttons(ready_to_slice); } +// void Plater::show_action_buttons(const bool ready_to_slice) const { p->show_action_buttons(ready_to_slice); } void Plater::fill_color(int extruder_id) { @@ -11678,7 +11936,7 @@ void Plater::fill_color(int extruder_id) } } -//BBS +// BBS void Plater::cut_selection_to_clipboard() { Plater::TakeSnapshot snapshot(this, "Cut Selected Objects"); @@ -11710,21 +11968,18 @@ void Plater::paste_from_clipboard() p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); } -//BBS: add clone +// BBS: add clone void Plater::clone_selection() { if (is_selection_empty()) return; - long res = wxGetNumberFromUser("", - _L("Clone"), - _L("Number of copies:"), - 1, 0, 100, this); + long res = wxGetNumberFromUser("", _L("Clone"), _L("Number of copies:"), 1, 0, 1000, this); wxString msg; if (res == -1) { msg = _L("Invalid number"); return; } - Selection& selection = p->get_selection(); + Selection &selection = p->get_selection(); selection.clone(res); } @@ -11739,13 +11994,12 @@ void Plater::search(bool plater_is_active, Preset::Type type, wxWindow *tag, Tex wxKeyEvent evt; #ifdef __APPLE__ evt.m_keyCode = 'f'; -#else /* __APPLE__ */ - evt.m_keyCode = WXK_CONTROL_F; +#else /* __APPLE__ */ + evt.m_keyCode = WXK_CONTROL_F; #endif /* __APPLE__ */ evt.SetControlDown(true); canvas3D()->on_char(evt); - } - else + } else p->sidebar->get_searcher().show_dialog(type, tag, etag, stag); } @@ -11757,8 +12011,6 @@ void Plater::msw_rescale() p->sidebar->msw_rescale(); - p->menus.msw_rescale(); - Layout(); GetParent()->Layout(); } @@ -11768,7 +12020,8 @@ void Plater::sys_color_changed() p->preview->sys_color_changed(); p->sidebar->sys_color_changed(); p->menus.sys_color_changed(); - if (p->m_select_machine_dlg) p->m_select_machine_dlg->sys_color_changed(); + if (p->m_select_machine_dlg) + p->m_select_machine_dlg->sys_color_changed(); Layout(); GetParent()->Layout(); @@ -11787,54 +12040,40 @@ void Plater::enable_view_toolbar(bool enable) } #endif -bool Plater::init_collapse_toolbar() -{ - return p->init_collapse_toolbar(); -} +bool Plater::init_collapse_toolbar() { return p->init_collapse_toolbar(); } -void Plater::enable_collapse_toolbar(bool enable) -{ - p->collapse_toolbar.set_enabled(enable); -} +void Plater::enable_collapse_toolbar(bool enable) { p->collapse_toolbar.set_enabled(enable); } -const Camera& Plater::get_camera() const -{ - return p->camera; -} +const Camera &Plater::get_camera() const { return p->camera; } -Camera& Plater::get_camera() -{ - return p->camera; -} +Camera &Plater::get_camera() { return p->camera; } -//BBS: partplate list related functions -PartPlateList& Plater::get_partplate_list() -{ - return p->partplate_list; -} +// BBS: partplate list related functions +PartPlateList &Plater::get_partplate_list() { return p->partplate_list; } void Plater::apply_background_progress() { - PartPlate* part_plate = p->partplate_list.get_curr_plate(); - int plate_index = p->partplate_list.get_curr_plate_index(); - bool result_valid = part_plate->is_slice_result_valid(); - //always apply the current plate's print + PartPlate *part_plate = p->partplate_list.get_curr_plate(); + int plate_index = p->partplate_list.get_curr_plate_index(); + bool result_valid = part_plate->is_slice_result_valid(); + // always apply the current plate's print Print::ApplyStatus invalidated = p->background_process.apply(this->model(), wxGetApp().preset_bundle->full_config()); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, after apply, invalidated= %3%, previous result_valid %4% ") % __LINE__ % plate_index % invalidated % result_valid; - if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED) - { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(" %1%: plate %2%, after apply, invalidated= %3%, previous result_valid %4% ") % __LINE__ % + plate_index % invalidated % result_valid; + if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED) { part_plate->update_slice_result_valid_state(false); - //p->ready_to_slice = true; + // p->ready_to_slice = true; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true); } } -//BBS: select Plate +// BBS: select Plate int Plater::select_plate(int plate_index, bool need_slice) { int ret; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, need_slice %3% ")%__LINE__ %plate_index %need_slice; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, need_slice %3% ") % __LINE__ % plate_index % need_slice; take_snapshot("select partplate!"); ret = p->partplate_list.select_plate(plate_index); if (!ret) { @@ -11842,111 +12081,95 @@ int Plater::select_plate(int plate_index, bool need_slice) wxGetApp().plater()->canvas3D()->render(); } - if ((!ret) && (p->background_process.can_switch_print())) - { - //select successfully + if ((!ret) && (p->background_process.can_switch_print())) { + // select successfully p->partplate_list.update_slice_context_to_current_plate(p->background_process); p->preview->update_gcode_result(p->partplate_list.get_current_slice_result()); p->update_print_volume_state(); - PartPlate* part_plate = p->partplate_list.get_curr_plate(); - bool result_valid = part_plate->is_slice_result_valid(); - PrintBase* print = nullptr; - GCodeResult* gcode_result = nullptr; + PartPlate *part_plate = p->partplate_list.get_curr_plate(); + bool result_valid = part_plate->is_slice_result_valid(); + PrintBase *print = nullptr; + GCodeResult *gcode_result = nullptr; Print::ApplyStatus invalidated; part_plate->get_print(&print, &gcode_result, NULL); - //always apply the current plate's print + // always apply the current plate's print invalidated = p->background_process.apply(this->model(), wxGetApp().preset_bundle->full_config()); bool model_fits, validate_err; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, after apply, invalidated= %3%, previous result_valid %4% ")%__LINE__ %plate_index %invalidated %result_valid; - if (result_valid) - { - if (is_preview_shown()) - { - if (need_slice) { //from preview's thumbnail - if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) || (gcode_result->moves.empty())){ + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(" %1%: plate %2%, after apply, invalidated= %3%, previous result_valid %4% ") % __LINE__ % + plate_index % invalidated % result_valid; + if (result_valid) { + if (is_preview_shown()) { + if (need_slice) { // from preview's thumbnail + if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) || (gcode_result->moves.empty())) { if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED) part_plate->update_slice_result_valid_state(false); p->process_completed_with_error = -1; - p->m_slice_all = false; + p->m_slice_all = false; reset_gcode_toolpaths(); reslice(); - } - else { + } else { validate_current_plate(model_fits, validate_err); - //just refresh_print + // just refresh_print refresh_print(); p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false, true); } + } else { // from multiple slice's next + // do nothing } - else {// from multiple slice's next - //do nothing - } - } - else - { + } else { validate_current_plate(model_fits, validate_err); - if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED) - { + if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED) { part_plate->update_slice_result_valid_state(false); // BBS - //p->show_action_buttons(true); - //p->ready_to_slice = true; + // p->show_action_buttons(true); + // p->ready_to_slice = true; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true); - } - else - { + } else { // BBS - //p->show_action_buttons(false); - //p->ready_to_slice = false; + // p->show_action_buttons(false); + // p->ready_to_slice = false; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); refresh_print(); } } - } - else - { - //check inside status - //model_fits = p->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; - //bool validate_err = false; + } else { + // check inside status + // model_fits = p->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; + // bool validate_err = false; validate_current_plate(model_fits, validate_err); if (model_fits && !validate_err) { p->process_completed_with_error = -1; - } - else { + } else { p->process_completed_with_error = p->partplate_list.get_curr_plate_index(); } - if (is_preview_shown()) - { - if (need_slice) - { - //p->process_completed_with_error = -1; + if (is_preview_shown()) { + if (need_slice) { + // p->process_completed_with_error = -1; p->m_slice_all = false; reset_gcode_toolpaths(); if (model_fits && !validate_err) reslice(); else { p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); - //sometimes the previous print's sliced result is still valid, but the newly added object is laid over the boundary - //then the print toolpath will be shown, so we should not refresh print here, only onload shell - //refresh_print(); + // sometimes the previous print's sliced result is still valid, but the newly added object is laid over the boundary + // then the print toolpath will be shown, so we should not refresh print here, only onload shell + // refresh_print(); p->update_fff_scene_only_shells(); } - } - else { - //p->ready_to_slice = false; + } else { + // p->ready_to_slice = false; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); refresh_print(); } - } - else - { - //validate_current_plate(model_fits, validate_err); - //check inside status + } else { + // validate_current_plate(model_fits, validate_err); + // check inside status /*if (model_fits && !validate_err){ p->process_completed_with_error = -1; } @@ -11955,16 +12178,13 @@ int Plater::select_plate(int plate_index, bool need_slice) }*/ // BBS: don't show action buttons - //p->show_action_buttons(true); - //p->ready_to_slice = true; - if (model_fits && part_plate->has_printable_instances()) - { - //p->view3D->get_canvas3d()->post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, true)); + // p->show_action_buttons(true); + // p->ready_to_slice = true; + if (model_fits && part_plate->has_printable_instances()) { + // p->view3D->get_canvas3d()->post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, true)); p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true); - } - else - { - //p->view3D->get_canvas3d()->post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false)); + } else { + // p->view3D->get_canvas3d()->post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false)); p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); } } @@ -11974,7 +12194,7 @@ int Plater::select_plate(int plate_index, bool need_slice) SimpleEvent event(EVT_GLCANVAS_PLATE_SELECT); p->on_plate_selected(event); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, return %3%")%__LINE__ %plate_index %ret; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, return %3%") % __LINE__ % plate_index % ret; return ret; } @@ -11985,8 +12205,7 @@ int Plater::select_sliced_plate(int plate_index) Freeze(); ret = select_plate(plate_index, true); - if (ret) - { + if (ret) { BOOST_LOG_TRIVIAL(error) << "select_plate error for plate_idx=" << plate_index; Thaw(); return -1; @@ -11997,20 +12216,24 @@ int Plater::select_sliced_plate(int plate_index) return ret; } -void Plater::validate_current_plate(bool& model_fits, bool& validate_error) +void Plater::validate_current_plate(bool &model_fits, bool &validate_error) { - model_fits = p->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; + model_fits = p->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; validate_error = false; if (p->printer_technology == ptFFF) { std::string plater_text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n" - "Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");; - StringObjectException warning; - Polygons polygons; + "Please solve the problem by moving it totally on or off the plate, and confirming that the height " + "is within the build volume."); + ; + StringObjectException warning; + Polygons polygons; std::vector> height_polygons; - StringObjectException err = p->background_process.validate(&warning, &polygons, &height_polygons); + StringObjectException err = p->background_process.validate(&warning, &polygons, &height_polygons); // update string by type post_process_string_object_exception(err); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": validate err=%1%, warning=%2%, model_fits %3%")%err.string%warning.string %model_fits; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": validate err=%1%, warning=%2%, model_fits %3%") % err.string % warning.string % + model_fits; if (err.string.empty()) { p->partplate_list.get_curr_plate()->update_apply_result_invalid(false); @@ -12023,14 +12246,13 @@ void Plater::validate_current_plate(bool& model_fits, bool& validate_error) p->view3D->get_canvas3d()->reset_sequential_print_clearance(); p->view3D->get_canvas3d()->set_as_dirty(); p->view3D->get_canvas3d()->request_extra_frame(); - } - else { + } else { // The print is not valid. p->partplate_list.get_curr_plate()->update_apply_result_invalid(true); // Show error as notification. p->notification_manager->push_validate_error_notification(err); p->process_validation_warning(warning); - //model_fits = false; + // model_fits = false; validate_error = true; p->view3D->get_canvas3d()->set_sequential_print_clearance_visible(true); p->view3D->get_canvas3d()->set_sequential_print_clearance_render_fill(true); @@ -12039,20 +12261,85 @@ void Plater::validate_current_plate(bool& model_fits, bool& validate_error) if (!model_fits) { p->notification_manager->push_plater_error_notification(plater_text); - } - else { + } else { p->notification_manager->close_plater_error_notification(plater_text); } } - PartPlate* part_plate = p->partplate_list.get_curr_plate(); + PartPlate *part_plate = p->partplate_list.get_curr_plate(); part_plate->update_slice_ready_status(model_fits); return; } +void Plater::open_platesettings_dialog(wxCommandEvent &evt) +{ + int plate_index = evt.GetInt(); + PlateSettingsDialog dlg(this, _L("Plate Settings"), evt.GetString() == "only_first_layer_sequence"); + PartPlate *curr_plate = p->partplate_list.get_curr_plate(); + dlg.sync_bed_type(curr_plate->get_bed_type()); -//BBS: select Plate by hover_id + auto curr_print_seq = curr_plate->get_print_seq(); + if (curr_print_seq != PrintSequence::ByDefault) { + dlg.sync_print_seq(int(curr_print_seq) + 1); + } else + dlg.sync_print_seq(0); + + auto first_layer_print_seq = curr_plate->get_first_layer_print_sequence(); + if (first_layer_print_seq.empty()) + dlg.sync_first_layer_print_seq(0); + else + dlg.sync_first_layer_print_seq(1, curr_plate->get_first_layer_print_sequence()); + + dlg.sync_spiral_mode(curr_plate->get_spiral_vase_mode(), !curr_plate->has_spiral_mode_config()); + + dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index, &dlg](wxCommandEvent &e) { + PartPlate *curr_plate = p->partplate_list.get_curr_plate(); + BedType old_bed_type = curr_plate->get_bed_type(); + auto bt_sel = BedType(dlg.get_bed_type_choice()); + if (old_bed_type != bt_sel) { + curr_plate->set_bed_type(bt_sel); + update_project_dirty_from_presets(); + set_plater_dirty(true); + } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side") % bt_sel % plate_index; + + if (dlg.get_first_layer_print_seq_choice() != 0) + curr_plate->set_first_layer_print_sequence(dlg.get_first_layer_print_seq()); + else + curr_plate->set_first_layer_print_sequence({}); + + int ps_sel = dlg.get_print_seq_choice(); + if (ps_sel != 0) + curr_plate->set_print_seq(PrintSequence(ps_sel - 1)); + else + curr_plate->set_print_seq(PrintSequence::ByDefault); + + int spiral_sel = dlg.get_spiral_mode_choice(); + if (spiral_sel == 1) { + curr_plate->set_spiral_vase_mode(true, false); + } else if (spiral_sel == 2) { + curr_plate->set_spiral_vase_mode(false, false); + } else { + curr_plate->set_spiral_vase_mode(false, true); + } + + update_project_dirty_from_presets(); + set_plater_dirty(true); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format("select print sequence %1% for plate %2% at plate side") % ps_sel % plate_index; + auto plate_config = *(curr_plate->config()); + wxGetApp().plater()->config_change_notification(plate_config, std::string("print_sequence")); + update(); + wxGetApp().obj_list()->update_selections(); + }); + dlg.set_plate_name(from_u8(curr_plate->get_plate_name())); + + dlg.ShowModal(); + curr_plate->set_plate_name(dlg.get_plate_name().ToUTF8().data()); +} + +// BBS: select Plate by hover_id int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModidyPlateName) { int ret; @@ -12061,226 +12348,153 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi plate_index = hover_id / PartPlate::GRABBER_COUNT; action = isModidyPlateName ? PartPlate::PLATE_NAME_HOVER_ID : hover_id % PartPlate::GRABBER_COUNT; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": enter, hover_id %1%, plate_index %2%, action %3%")%hover_id % plate_index %action; - if (action == 0) - { - //select plate + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": enter, hover_id %1%, plate_index %2%, action %3%") % hover_id % plate_index % action; + if (action == 0) { + // select plate ret = p->partplate_list.select_plate(plate_index); if (!ret) { SimpleEvent event(EVT_GLCANVAS_PLATE_SELECT); p->on_plate_selected(event); } - if ((!ret)&&(p->background_process.can_switch_print())) - { - //select successfully + if ((!ret) && (p->background_process.can_switch_print())) { + // select successfully p->partplate_list.update_slice_context_to_current_plate(p->background_process); p->preview->update_gcode_result(p->partplate_list.get_current_slice_result()); p->update_print_volume_state(); - PartPlate* part_plate = p->partplate_list.get_curr_plate(); - bool result_valid = part_plate->is_slice_result_valid(); - PrintBase* print = nullptr; - GCodeResult* gcode_result = nullptr; + PartPlate *part_plate = p->partplate_list.get_curr_plate(); + bool result_valid = part_plate->is_slice_result_valid(); + PrintBase *print = nullptr; + GCodeResult *gcode_result = nullptr; Print::ApplyStatus invalidated; part_plate->get_print(&print, &gcode_result, NULL); - //always apply the current plate's print + // always apply the current plate's print invalidated = p->background_process.apply(this->model(), wxGetApp().preset_bundle->full_config()); bool model_fits, validate_err; validate_current_plate(model_fits, validate_err); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: after apply, invalidated= %2%, previous result_valid %3% ")%__LINE__ % invalidated %result_valid; - if (result_valid) - { - if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED) - { - //bool model_fits, validate_err; - //validate_current_plate(model_fits, validate_err); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(" %1%: after apply, invalidated= %2%, previous result_valid %3% ") % __LINE__ % + invalidated % result_valid; + if (result_valid) { + if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED) { + // bool model_fits, validate_err; + // validate_current_plate(model_fits, validate_err); part_plate->update_slice_result_valid_state(false); // BBS - //p->show_action_buttons(true); - //p->ready_to_slice = true; + // p->show_action_buttons(true); + // p->ready_to_slice = true; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true); - } - else - { + } else { // BBS - //p->show_action_buttons(false); - //validate_current_plate(model_fits, validate_err); - //p->ready_to_slice = false; + // p->show_action_buttons(false); + // validate_current_plate(model_fits, validate_err); + // p->ready_to_slice = false; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); refresh_print(); } - } - else - { - //check inside status - if (model_fits && !validate_err){ + } else { + // check inside status + if (model_fits && !validate_err) { p->process_completed_with_error = -1; - } - else { + } else { p->process_completed_with_error = p->partplate_list.get_curr_plate_index(); } // BBS: don't show action buttons - //p->show_action_buttons(true); - //p->ready_to_slice = true; - if (model_fits && part_plate->has_printable_instances()) - { - //p->view3D->get_canvas3d()->post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, true)); + // p->show_action_buttons(true); + // p->ready_to_slice = true; + if (model_fits && part_plate->has_printable_instances()) { + // p->view3D->get_canvas3d()->post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, true)); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": will set can_slice to true"); p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true); - } - else - { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": will set can_slice to false, has_printable_instances %1%")%part_plate->has_printable_instances(); - //p->view3D->get_canvas3d()->post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false)); + } else { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(": will set can_slice to false, has_printable_instances %1%") % + part_plate->has_printable_instances(); + // p->view3D->get_canvas3d()->post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false)); p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); } } } - } - else if ((action == 1)&&(!right_click)) - { - //delete plate + } else if ((action == 1) && (!right_click)) { + // delete plate ret = delete_plate(plate_index); - } - else if ((action == 2)&&(!right_click)) - { - //arrange the plate - //take_snapshot("select_orient partplate"); + } else if ((action == 2) && (!right_click)) { + // arrange the plate + // take_snapshot("select_orient partplate"); ret = select_plate(plate_index); - if (!ret) - { + if (!ret) { set_prepare_state(Job::PREPARE_STATE_MENU); orient(); - } - else - { + } else { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index; ret = -1; } - } - else if ((action == 3)&&(!right_click)) - { - //arrange the plate - //take_snapshot("select_arrange partplate"); + } else if ((action == 3) && (!right_click)) { + // arrange the plate + // take_snapshot("select_arrange partplate"); ret = select_plate(plate_index); - if (!ret) - { + if (!ret) { if (last_arrange_job_is_finished()) { set_prepare_state(Job::PREPARE_STATE_MENU); arrange(); } - } - else - { + } else { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index; ret = -1; } - } - else if ((action == 4)&&(!right_click)) - { - //lock the plate + } else if ((action == 4) && (!right_click)) { + // lock the plate take_snapshot("lock partplate"); ret = p->partplate_list.lock_plate(plate_index, !p->partplate_list.is_locked(plate_index)); - } - else if ((action == 5)&&(!right_click)) - { - //set the plate type + } else if ((action == 5) && (!right_click)) { + // set the plate type ret = select_plate(plate_index); if (!ret) { - PlateSettingsDialog dlg(this, wxID_ANY, _L("Plate Settings")); - PartPlate* curr_plate = p->partplate_list.get_curr_plate(); - dlg.sync_bed_type(curr_plate->get_bed_type()); - - auto curr_print_seq = curr_plate->get_print_seq(); - if (curr_print_seq != PrintSequence::ByDefault) { - dlg.sync_print_seq(int(curr_print_seq) + 1); - } - else - dlg.sync_print_seq(0); - - auto first_layer_print_seq = curr_plate->get_first_layer_print_sequence(); - if (first_layer_print_seq.empty()) - dlg.sync_first_layer_print_seq(0); - else - dlg.sync_first_layer_print_seq(1, curr_plate->get_first_layer_print_sequence()); - - dlg.set_plate_name(from_u8(curr_plate->get_plate_name())); - - dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index, &dlg](wxCommandEvent& e) { - PartPlate *curr_plate = p->partplate_list.get_curr_plate(); - BedType old_bed_type = curr_plate->get_bed_type(); - auto bt_sel = BedType(dlg.get_bed_type_choice()); - if (old_bed_type != bt_sel) { - curr_plate->set_bed_type(bt_sel); - update_project_dirty_from_presets(); - set_plater_dirty(true); - } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side")%bt_sel %plate_index; - - if (dlg.get_first_layer_print_seq_choice() != 0) - curr_plate->set_first_layer_print_sequence(dlg.get_first_layer_print_seq()); - else - curr_plate->set_first_layer_print_sequence({}); - - int ps_sel = dlg.get_print_seq_choice(); - if (ps_sel != 0) - curr_plate->set_print_seq(PrintSequence(ps_sel - 1)); - else - curr_plate->set_print_seq(PrintSequence::ByDefault); - update_project_dirty_from_presets(); - set_plater_dirty(true); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select print sequence %1% for plate %2% at plate side")%ps_sel %plate_index; - auto plate_config = *(curr_plate->config()); - wxGetApp().plater()->config_change_notification(plate_config, std::string("print_sequence")); - update(); - }); - dlg.ShowModal(); - curr_plate->set_plate_name(dlg.get_plate_name().ToUTF8().data()); + wxCommandEvent evt(EVT_OPEN_PLATESETTINGSDIALOG); + evt.SetInt(plate_index); + evt.SetEventObject(this); + wxPostEvent(this, evt); this->schedule_background_process(); - } - else { + } else { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index; ret = -1; } - } - else if ((action == 6) && (!right_click)) { + } else if ((action == 6) && (!right_click)) { // set the plate type ret = select_plate(plate_index); if (!ret) { PlateNameEditDialog dlg(this, wxID_ANY, _L("Edit Plate Name")); - PartPlate * curr_plate = p->partplate_list.get_curr_plate(); + PartPlate *curr_plate = p->partplate_list.get_curr_plate(); wxString curr_plate_name = from_u8(curr_plate->get_plate_name()); dlg.set_plate_name(curr_plate_name); - dlg.ShowModal(); - - wxString dlg_plate_name = dlg.get_plate_name(); - curr_plate->set_plate_name(dlg_plate_name.ToUTF8().data()); - - this->schedule_background_process(); + int result = dlg.ShowModal(); + if (result == wxID_YES) { + wxString dlg_plate_name = dlg.get_plate_name(); + curr_plate->set_plate_name(dlg_plate_name.ToUTF8().data()); + } } else { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index; ret = -1; } - } - else - { + } else { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "invalid action %1%, with right_click=%2%" << action << right_click; ret = -1; } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: return %2%")%__LINE__ % ret; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: return %2%") % __LINE__ % ret; return ret; } -//BBS: delete the plate, index= -1 means the current plate +// BBS: delete the plate, index= -1 means the current plate int Plater::delete_plate(int plate_index) { int index = plate_index, ret; @@ -12291,48 +12505,42 @@ int Plater::delete_plate(int plate_index) take_snapshot("delete partplate"); ret = p->partplate_list.delete_plate(index); - //BBS: update the current print to the current plate + // BBS: update the current print to the current plate p->partplate_list.update_slice_context_to_current_plate(p->background_process); p->preview->update_gcode_result(p->partplate_list.get_current_slice_result()); p->sidebar->obj_list()->reload_all_plates(); // BBS update default view - //get_camera().select_view("topfront"); - //get_camera().requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE; + // get_camera().select_view("topfront"); + // get_camera().requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE; - //need to call update + // need to call update update(); return ret; } -//BBS: set bed positions -void Plater::set_bed_position(Vec2d& pos) -{ - p->bed.set_position(pos); -} +// BBS: set bed positions +void Plater::set_bed_position(Vec2d &pos) { p->bed.set_position(pos); } -//BBS: is the background process slicing currently -bool Plater::is_background_process_slicing() const -{ - return p->m_is_slicing; -} +// BBS: is the background process slicing currently +bool Plater::is_background_process_slicing() const { return p->m_is_slicing; } -//BBS: update slicing context +// BBS: update slicing context void Plater::update_slicing_context_to_current_partplate() { p->partplate_list.update_slice_context_to_current_plate(p->background_process); p->preview->update_gcode_result(p->partplate_list.get_current_slice_result()); } -//BBS: show object info +// BBS: show object info void Plater::show_object_info() { NotificationManager *notify_manager = get_notification_manager(); - const Selection& selection = get_selection(); - int selCount = selection.get_volume_idxs().size(); - ModelObjectPtrs objects = model().objects; - int obj_idx = selection.get_object_idx(); - std::string info_text; + const Selection &selection = get_selection(); + int selCount = selection.get_volume_idxs().size(); + ModelObjectPtrs objects = model().objects; + int obj_idx = selection.get_object_idx(); + std::string info_text; if (selCount > 1 && !selection.is_single_full_object()) { notify_manager->bbl_close_objectsinfo_notification(); @@ -12344,108 +12552,118 @@ void Plater::show_object_info() } notify_manager->bbl_show_objectsinfo_notification(info_text, false, !(p->current_panel == p->view3D)); return; - } - else if (objects.empty() || (obj_idx < 0) || (obj_idx >= objects.size()) || - objects[obj_idx]->volumes.empty() ||// hack to avoid crash when deleting the last object on the bed - (selection.is_single_full_object() && objects[obj_idx]->instances.size()> 1) || - !(selection.is_single_full_instance() || selection.is_single_volume())) - { + } else if (objects.empty() || (obj_idx < 0) || (obj_idx >= objects.size()) || + objects[obj_idx]->volumes.empty() || // hack to avoid crash when deleting the last object on the bed + (selection.is_single_full_object() && objects[obj_idx]->instances.size() > 1) || + !(selection.is_single_full_instance() || selection.is_single_volume())) { notify_manager->bbl_close_objectsinfo_notification(); return; } - const ModelObject* model_object = objects[obj_idx]; - int inst_idx = selection.get_instance_idx(); - if ((inst_idx < 0) || (inst_idx >= model_object->instances.size())) - { + const ModelObject *model_object = objects[obj_idx]; + int inst_idx = selection.get_instance_idx(); + if ((inst_idx < 0) || (inst_idx >= model_object->instances.size())) { notify_manager->bbl_close_objectsinfo_notification(); return; } - bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; - double koef = imperial_units ? GizmoObjectManipulation::mm_to_in : 1.0f; + bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; + double koef = imperial_units ? GizmoObjectManipulation::mm_to_in : 1.0f; - ModelVolume* vol = nullptr; - Transform3d t; - int face_count; - Vec3d size; + ModelVolume *vol = nullptr; + Transform3d t; + int face_count; + Vec3d size; if (selection.is_single_volume()) { std::vector obj_idxs, vol_idxs; wxGetApp().obj_list()->get_selection_indexes(obj_idxs, vol_idxs); - if (vol_idxs.size() != 1) - { - //corner case when merge/split/remove + if (vol_idxs.size() != 1) { + // corner case when merge/split/remove return; } vol = model_object->volumes[vol_idxs[0]]; - t = model_object->instances[inst_idx]->get_matrix() * vol->get_matrix(); + t = model_object->instances[inst_idx]->get_matrix() * vol->get_matrix(); info_text += (boost::format(_utf8(L("Part name: %1%\n"))) % vol->name).str(); face_count = static_cast(vol->mesh().facets_count()); - size = vol->get_convex_hull().transformed_bounding_box(t).size(); - } - else { - //int obj_idx, vol_idx; - //wxGetApp().obj_list()->get_selected_item_indexes(obj_idx, vol_idx); - //if (obj_idx < 0) { - // //corner case when merge/split/remove - // return; - //} + size = vol->get_convex_hull().transformed_bounding_box(t).size(); + } else { + // int obj_idx, vol_idx; + // wxGetApp().obj_list()->get_selected_item_indexes(obj_idx, vol_idx); + // if (obj_idx < 0) { + // //corner case when merge/split/remove + // return; + // } info_text += (boost::format(_utf8(L("Object name: %1%\n"))) % model_object->name).str(); face_count = static_cast(model_object->facets_count()); - size = model_object->instance_convex_hull_bounding_box(inst_idx).size(); + size = model_object->instance_convex_hull_bounding_box(inst_idx).size(); } - //Vec3d size = vol ? vol->mesh().transformed_bounding_box(t).size() : model_object->instance_bounding_box(inst_idx).size(); + // Vec3d size = vol ? vol->mesh().transformed_bounding_box(t).size() : model_object->instance_bounding_box(inst_idx).size(); if (imperial_units) - info_text += (boost::format(_utf8(L("Size: %1% x %2% x %3% in\n"))) %(size(0)*koef) %(size(1)*koef) %(size(2)*koef)).str(); + info_text += (boost::format(_utf8(L("Size: %1% x %2% x %3% in\n"))) % (size(0) * koef) % (size(1) * koef) % (size(2) * koef)).str(); else - info_text += (boost::format(_utf8(L("Size: %1% x %2% x %3% mm\n"))) %size(0) %size(1) %size(2)).str(); + info_text += (boost::format(_utf8(L("Size: %1% x %2% x %3% mm\n"))) % size(0) % size(1) % size(2)).str(); - const TriangleMeshStats& stats = vol ? vol->mesh().stats() : model_object->get_object_stl_stats(); - double volume_val = stats.volume; + const TriangleMeshStats &stats = vol ? vol->mesh().stats() : model_object->get_object_stl_stats(); + double volume_val = stats.volume; if (vol) volume_val *= std::fabs(t.matrix().block(0, 0, 3, 3).determinant()); - volume_val = volume_val * pow(koef,3); + volume_val = volume_val * pow(koef, 3); if (imperial_units) - info_text += (boost::format(_utf8(L("Volume: %1% in³\n"))) %volume_val).str(); + info_text += (boost::format(_utf8(L("Volume: %1% in³\n"))) % volume_val).str(); else - info_text += (boost::format(_utf8(L("Volume: %1% mm³\n"))) %volume_val).str(); - info_text += (boost::format(_utf8(L("Triangles: %1%\n"))) %face_count).str(); + info_text += (boost::format(_utf8(L("Volume: %1% mm³\n"))) % volume_val).str(); + info_text += (boost::format(_utf8(L("Triangles: %1%\n"))) % face_count).str(); wxString info_manifold; - int non_manifold_edges = 0; - auto mesh_errors = p->sidebar->obj_list()->get_mesh_errors_info(&info_manifold, &non_manifold_edges); + int non_manifold_edges = 0; + auto mesh_errors = p->sidebar->obj_list()->get_mesh_errors_info(&info_manifold, &non_manifold_edges); - #ifndef __WINDOWS__ +#ifndef __WINDOWS__ if (non_manifold_edges > 0) { - info_manifold += into_u8("\n" + _L("Tips:") + "\n" +_L("\"Fix Model\" feature is currently only on Windows. Please repair the model on Orca Slicer(windows) or CAD softwares.")); + info_manifold += into_u8( + "\n" + _L("Tips:") + "\n" + + _L("\"Fix Model\" feature is currently only on Windows. Please repair the model on Orca Slicer(windows) or CAD softwares.")); } - #endif //APPLE & LINUX +#endif // APPLE & LINUX info_manifold = "" + info_manifold + ""; info_text += into_u8(info_manifold); - notify_manager->bbl_show_objectsinfo_notification(info_text, is_windows10()&&(non_manifold_edges > 0), !(p->current_panel == p->view3D)); + notify_manager->bbl_show_objectsinfo_notification(info_text, is_windows10() && (non_manifold_edges > 0), + !(p->current_panel == p->view3D)); } -bool Plater::show_publish_dialog(bool show) -{ - return p->show_publish_dlg(show); -} +bool Plater::show_publish_dialog(bool show) { return p->show_publish_dlg(show); } void Plater::post_process_string_object_exception(StringObjectException &err) { + PresetBundle *preset_bundle = wxGetApp().preset_bundle; if (err.type == StringExceptionType::STRING_EXCEPT_FILAMENT_NOT_MATCH_BED_TYPE) { try { int extruder_id = atoi(err.params[2].c_str()) - 1; - if (extruder_id < wxGetApp().preset_bundle->filament_presets.size()) { - std::string filament_name = wxGetApp().preset_bundle->filament_presets[extruder_id]; - for (auto filament : wxGetApp().preset_bundle->filaments) { - if (filament.name == filament_name) { - filament_name = filament.alias; + if (extruder_id < preset_bundle->filament_presets.size()) { + std::string filament_name = preset_bundle->filament_presets[extruder_id]; + for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) { + if (filament_it->name == filament_name) { + if (filament_it->is_system) { + filament_name = filament_it->alias; + } else { + auto preset = preset_bundle->filaments.get_preset_base(*filament_it); + if (!preset->alias.empty()) { + filament_name = preset->alias; + } else { + char target = '@'; + size_t pos = preset->name.find(target); + if (pos != std::string::npos) { + filament_name = preset->name.substr(0, pos - 1); + } + } + } break; } } - err.string = format(_L("Plate% d: %s is not suggested to be used to print filament %s(%s). If you still want to do this printing, please set this filament's bed temperature to non zero."), - err.params[0], err.params[1], err.params[2], filament_name); + err.string = format(_L("Plate% d: %s is not suggested to be used to print filament %s(%s). If you still want to do this " + "printing, please set this filament's bed temperature to non zero."), + err.params[0], err.params[1], err.params[2], filament_name); err.string += "\n"; } } catch (...) { @@ -12463,16 +12681,10 @@ void Plater::init_environment_texture() p->environment_texture.load_from_file(resources_dir() + "/images/Pmetal_001.png", false, GLTexture::SingleThreaded, false); } -unsigned int Plater::get_environment_texture_id() const -{ - return p->environment_texture.get_id(); -} +unsigned int Plater::get_environment_texture_id() const { return p->environment_texture.get_id(); } #endif // ENABLE_ENVIRONMENT_MAP -const BuildVolume& Plater::build_volume() const -{ - return p->bed.build_volume(); -} +const BuildVolume &Plater::build_volume() const { return p->bed.build_volume(); } // BBS #if 0 @@ -12487,57 +12699,36 @@ GLToolbar& Plater::get_view_toolbar() } #endif -const GLToolbar& Plater::get_collapse_toolbar() const -{ - return p->collapse_toolbar; -} +const GLToolbar &Plater::get_collapse_toolbar() const { return p->collapse_toolbar; } -GLToolbar& Plater::get_collapse_toolbar() -{ - return p->collapse_toolbar; -} +GLToolbar &Plater::get_collapse_toolbar() { return p->collapse_toolbar; } -void Plater::update_preview_bottom_toolbar() -{ - p->update_preview_bottom_toolbar(); -} +void Plater::update_preview_bottom_toolbar() { p->update_preview_bottom_toolbar(); } void Plater::reset_gcode_toolpaths() { - //BBS: add some logs + // BBS: add some logs BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": reset the gcode viewer's toolpaths"); p->reset_gcode_toolpaths(); } -const Mouse3DController& Plater::get_mouse3d_controller() const -{ - return p->mouse3d_controller; -} +const Mouse3DController &Plater::get_mouse3d_controller() const { return p->mouse3d_controller; } -Mouse3DController& Plater::get_mouse3d_controller() -{ - return p->mouse3d_controller; -} +Mouse3DController &Plater::get_mouse3d_controller() { return p->mouse3d_controller; } -NotificationManager * Plater::get_notification_manager() -{ - return p->notification_manager.get(); -} +NotificationManager *Plater::get_notification_manager() { return p->notification_manager.get(); } -const NotificationManager * Plater::get_notification_manager() const +DailyTipsWindow *Plater::get_dailytips() const { - return p->notification_manager.get(); + static DailyTipsWindow *dailytips_win = new DailyTipsWindow(); + return dailytips_win; } -void Plater::init_notification_manager() -{ - p->init_notification_manager(); -} +const NotificationManager *Plater::get_notification_manager() const { return p->notification_manager.get(); } -void Plater::show_status_message(std::string s) -{ - BOOST_LOG_TRIVIAL(trace) << "show_status_message:" << s; -} +void Plater::init_notification_manager() { p->init_notification_manager(); } + +void Plater::show_status_message(std::string s) { BOOST_LOG_TRIVIAL(trace) << "show_status_message:" << s; } void Plater::edit_text() { @@ -12563,10 +12754,11 @@ bool Plater::can_arrange() const { return p->can_arrange(); } bool Plater::can_layers_editing() const { return p->can_layers_editing(); } bool Plater::can_paste_from_clipboard() const { - if (!IsShown() || !p->is_view3D_shown()) return false; + if (!IsShown() || !p->is_view3D_shown()) + return false; - const Selection& selection = p->view3D->get_canvas3d()->get_selection(); - const Selection::Clipboard& clipboard = selection.get_clipboard(); + const Selection &selection = p->view3D->get_canvas3d()->get_selection(); + const Selection::Clipboard &clipboard = selection.get_clipboard(); if (clipboard.is_empty() && p->sidebar->obj_list()->clipboard_is_empty()) return false; @@ -12584,7 +12776,7 @@ bool Plater::can_paste_from_clipboard() const return true; } -//BBS support cut +// BBS support cut bool Plater::can_cut_to_clipboard() const { if (is_selection_empty()) @@ -12600,7 +12792,7 @@ bool Plater::can_copy_to_clipboard() const if (is_selection_empty()) return false; - const Selection& selection = p->view3D->get_canvas3d()->get_selection(); + const Selection &selection = p->view3D->get_canvas3d()->get_selection(); if ((wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) && !selection.is_sla_compliant()) return false; @@ -12610,7 +12802,7 @@ bool Plater::can_copy_to_clipboard() const bool Plater::can_undo() const { return IsShown() && p->is_view3D_shown() && p->undo_redo_stack().has_undo_snapshot(); } bool Plater::can_redo() const { return IsShown() && p->is_view3D_shown() && p->undo_redo_stack().has_redo_snapshot(); } bool Plater::can_reload_from_disk() const { return p->can_reload_from_disk(); } -//BBS +// BBS bool Plater::can_fillcolor() const { return p->can_fillcolor(); } bool Plater::has_assmeble_view() const { return p->has_assemble_view(); } bool Plater::can_replace_with_stl() const { return p->can_replace_with_stl(); } @@ -12620,59 +12812,39 @@ bool Plater::can_split(bool to_objects) const { return p->can_split(to_objects); bool Plater::can_scale_to_print_volume() const { return p->can_scale_to_print_volume(); } #endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT -const UndoRedo::Stack& Plater::undo_redo_stack_main() const { return p->undo_redo_stack_main(); } -void Plater::clear_undo_redo_stack_main() { p->undo_redo_stack_main().clear(); } -void Plater::enter_gizmos_stack() { p->enter_gizmos_stack(); } -bool Plater::leave_gizmos_stack() { return p->leave_gizmos_stack(); } // BBS: return false if not changed -bool Plater::inside_snapshot_capture() { return p->inside_snapshot_capture(); } +const UndoRedo::Stack &Plater::undo_redo_stack_main() const { return p->undo_redo_stack_main(); } +void Plater::clear_undo_redo_stack_main() { p->undo_redo_stack_main().clear(); } +void Plater::enter_gizmos_stack() { p->enter_gizmos_stack(); } +bool Plater::leave_gizmos_stack() { return p->leave_gizmos_stack(); } // BBS: return false if not changed +bool Plater::inside_snapshot_capture() { return p->inside_snapshot_capture(); } -void Plater::toggle_render_statistic_dialog() -{ - p->show_render_statistic_dialog = !p->show_render_statistic_dialog; -} +void Plater::toggle_render_statistic_dialog() { p->show_render_statistic_dialog = !p->show_render_statistic_dialog; } -bool Plater::is_render_statistic_dialog_visible() const -{ - return p->show_render_statistic_dialog; -} +bool Plater::is_render_statistic_dialog_visible() const { return p->show_render_statistic_dialog; } -void Plater::toggle_show_wireframe() -{ - p->show_wireframe = !p->show_wireframe; -} +void Plater::toggle_show_wireframe() { p->show_wireframe = !p->show_wireframe; } -bool Plater::is_show_wireframe() const -{ - return p->show_wireframe; -} +bool Plater::is_show_wireframe() const { return p->show_wireframe; } -void Plater::enable_wireframe(bool status) -{ - p->wireframe_enabled = status; -} - -bool Plater::is_wireframe_enabled() const -{ - return p->wireframe_enabled; -} +void Plater::enable_wireframe(bool status) { p->wireframe_enabled = status; } +bool Plater::is_wireframe_enabled() const { return p->wireframe_enabled; } /*Plater::TakeSnapshot::TakeSnapshot(Plater *plater, const std::string &snapshot_name) : TakeSnapshot(plater, from_u8(snapshot_name)) {} Plater::TakeSnapshot::TakeSnapshot(Plater* plater, const std::string& snapshot_name, UndoRedo::SnapshotType snapshot_type) : TakeSnapshot(plater, from_u8(snapshot_name), snapshot_type) {}*/ - // Wrapper around wxWindow::PopupMenu to suppress error messages popping out while tracking the popup menu. -bool Plater::PopupMenu(wxMenu *menu, const wxPoint& pos) +bool Plater::PopupMenu(wxMenu *menu, const wxPoint &pos) { // Don't want to wake up and trigger reslicing while tracking the pop-up menu. SuppressBackgroundProcessingUpdate sbpu; // When tracking a pop-up menu, postpone error messages from the slicing result. m_tracking_popup_menu = true; - bool out = this->wxPanel::PopupMenu(menu, pos); + bool out = wxGetApp().mainframe->PopupMenu(menu, pos); m_tracking_popup_menu = false; - if (! m_tracking_popup_menu_error_message.empty()) { + if (!m_tracking_popup_menu_error_message.empty()) { // Don't know whether the CallAfter is necessary, but it should not hurt. // The menus likely sends out some commands, so we may be safer if the dialog is shown after the menu command is processed. wxString message = std::move(m_tracking_popup_menu_error_message); @@ -12681,24 +12853,15 @@ bool Plater::PopupMenu(wxMenu *menu, const wxPoint& pos) } return out; } -void Plater::bring_instance_forward() -{ - p->bring_instance_forward(); -} +void Plater::bring_instance_forward() { p->bring_instance_forward(); } -bool Plater::need_update() const -{ - return p->need_update(); -} +bool Plater::need_update() const { return p->need_update(); } -void Plater::set_need_update(bool need_update) -{ - p->set_need_update(need_update); -} +void Plater::set_need_update(bool need_update) { p->set_need_update(need_update); } // BBS -//BBS: add popup logic for table object -bool Plater::PopupObjectTable(int object_id, int volume_id, const wxPoint& position) +// BBS: add popup logic for table object +bool Plater::PopupObjectTable(int object_id, int volume_id, const wxPoint &position) { return p->PopupObjectTable(object_id, volume_id, position); } @@ -12706,25 +12869,24 @@ bool Plater::PopupObjectTable(int object_id, int volume_id, const wxPoint& posit bool Plater::PopupObjectTableBySelection() { wxDataViewItem item; - int obj_idx, vol_idx; - const wxPoint pos = wxPoint(0, 0); //Fake position + int obj_idx, vol_idx; + const wxPoint pos = wxPoint(0, 0); // Fake position wxGetApp().obj_list()->get_selected_item_indexes(obj_idx, vol_idx, item); return p->PopupObjectTable(obj_idx, vol_idx, pos); } - -wxMenu* Plater::plate_menu() { return p->menus.plate_menu(); } -wxMenu* Plater::object_menu() { return p->menus.object_menu(); } -wxMenu* Plater::part_menu() { return p->menus.part_menu(); } -wxMenu* Plater::sla_object_menu() { return p->menus.sla_object_menu(); } -wxMenu* Plater::default_menu() { return p->menus.default_menu(); } -wxMenu* Plater::instance_menu() { return p->menus.instance_menu(); } -wxMenu* Plater::layer_menu() { return p->menus.layer_menu(); } -wxMenu* Plater::multi_selection_menu() { return p->menus.multi_selection_menu(); } +wxMenu *Plater::plate_menu() { return p->menus.plate_menu(); } +wxMenu *Plater::object_menu() { return p->menus.object_menu(); } +wxMenu *Plater::part_menu() { return p->menus.part_menu(); } +wxMenu *Plater::sla_object_menu() { return p->menus.sla_object_menu(); } +wxMenu *Plater::default_menu() { return p->menus.default_menu(); } +wxMenu *Plater::instance_menu() { return p->menus.instance_menu(); } +wxMenu *Plater::layer_menu() { return p->menus.layer_menu(); } +wxMenu *Plater::multi_selection_menu() { return p->menus.multi_selection_menu(); } int Plater::GetPlateIndexByRightMenuInLeftUI() { return p->m_is_RightClickInLeftUI; } void Plater::SetPlateIndexByRightMenuInLeftUI(int index) { p->m_is_RightClickInLeftUI = index; } -SuppressBackgroundProcessingUpdate::SuppressBackgroundProcessingUpdate() : - m_was_scheduled(wxGetApp().plater()->is_background_process_update_scheduled()) +SuppressBackgroundProcessingUpdate::SuppressBackgroundProcessingUpdate() + : m_was_scheduled(wxGetApp().plater()->is_background_process_update_scheduled()) { wxGetApp().plater()->suppress_background_process(m_was_scheduled); } @@ -12734,70 +12896,4 @@ SuppressBackgroundProcessingUpdate::~SuppressBackgroundProcessingUpdate() wxGetApp().plater()->schedule_background_process(m_was_scheduled); } -// Printago: Load Project -void Plater::printago_load_project(wxString const& filename2, - wxString const& originfile) -{ - auto filename = filename2; - if (filename.empty()) - return; - - //BBS: add only gcode mode - bool previous_gcode = m_only_gcode; - - // BBS - if (m_loading_project) { - //some error cases happens - //return directly - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": current loading other project, return directly"); - return; - } - else - m_loading_project = true; - - m_only_gcode = false; - m_exported_file = false; - - auto path = into_path(filename); - - auto strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig | LoadStrategy::Silence; - bool load_restore = false; - - std::vector input_paths; - input_paths.push_back(path); - - std::vector res = load_files(input_paths, strategy); - - reset_project_dirty_initial_presets(); - update_project_dirty_from_presets(); - wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); - - // if res is empty no data has been loaded - if (!res.empty() && (load_restore || !(strategy & LoadStrategy::Silence))) { - p->set_project_filename(load_restore ? originfile : filename); - if (load_restore && originfile.IsEmpty()) - p->set_project_name(_L("Untitled")); - } else { - if (using_exported_file()) - p->set_project_filename(filename); - } - - - // wxGetApp().app_config->update_last_backup_dir(model().get_backup_path()); - // if (load_restore && !originfile.empty()) { - // wxGetApp().app_config->update_skein_dir(into_path(originfile).parent_path().string()); - // wxGetApp().app_config->update_config_dir(into_path(originfile).parent_path().string()); - // } - - if (!load_restore) - up_to_date(true, false); - else - p->dirty_state.update_from_undo_redo_stack(true); - up_to_date(true, true); - - wxGetApp().params_panel()->switch_to_object_if_has_object_configs(); - - m_loading_project = false; -} - -}} // namespace Slic3r::GUI +}} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 82e6fe2041b..b56fdce5999 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -1,3 +1,22 @@ +///|/ Copyright (c) Prusa Research 2018 - 2023 Tomáš Mészáros @tamasmeszaros, Oleksandra Iushchenko @YuSanka, Enrico Turri @enricoturri1966, +///David Kocík @kocikdav, Lukáš Hejl @hejllukas, Vojtěch Bubník @bubnikv, Lukáš Matěna @lukasmatena, Pavel Mikuš @Godrak, Filip Sykala +///@Jony01, Vojtěch Král @vojtechkral +///|/ +///|/ ported from lib/Slic3r/GUI/Plater.pm: +///|/ Copyright (c) Prusa Research 2016 - 2019 Vojtěch Bubník @bubnikv, Vojtěch Král @vojtechkral, Enrico Turri @enricoturri1966, Oleksandra +///Iushchenko @YuSanka, Lukáš Matěna @lukasmatena, Tomáš Mészáros @tamasmeszaros +///|/ Copyright (c) 2018 Martin Loidl @LoidlM +///|/ Copyright (c) 2017 Matthias Gazzari @qtux +///|/ Copyright (c) Slic3r 2012 - 2016 Alessandro Ranellucci @alranel +///|/ Copyright (c) 2017 Joseph Lenox @lordofhyphens +///|/ Copyright (c) 2015 Daren Schwenke +///|/ Copyright (c) 2014 Mark Hindess +///|/ Copyright (c) 2012 Mike Sheldrake @mesheldrake +///|/ Copyright (c) 2012 Henrik Brix Andersen @henrikbrixandersen +///|/ Copyright (c) 2012 Sam Wong +///|/ +///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher +///|/ #ifndef slic3r_Plater_hpp_ #define slic3r_Plater_hpp_ @@ -25,8 +44,10 @@ #include "libslic3r/PrintBase.hpp" #include "libslic3r/calib.hpp" +#include "libslic3r/CutUtils.hpp" +#include "libslic3r/FlushVolCalc.hpp" -#define FILAMENT_SYSTEM_COLORS_NUM 16 +#define FILAMENT_SYSTEM_COLORS_NUM 16 class wxButton; class ScalableButton; @@ -41,25 +62,23 @@ class BuildVolume; enum class BuildVolume_Type : unsigned char; class Model; class ModelObject; -enum class ModelObjectCutAttribute : int; -using ModelObjectCutAttributes = enum_bitmask; class ModelInstance; class Print; class SLAPrint; -//BBS: add partplatelist and SlicingStatusEvent +// BBS: add partplatelist and SlicingStatusEvent class PartPlateList; class SlicingStatusEvent; enum SLAPrintObjectStep : unsigned int; enum class ConversionType : int; class Ams; -using ModelInstancePtrs = std::vector; +using ModelInstancePtrs = std::vector; namespace UndoRedo { - class Stack; - enum class SnapshotType : unsigned char; - struct Snapshot; -} +class Stack; +enum class SnapshotType : unsigned char; +struct Snapshot; +} // namespace UndoRedo namespace GUI { @@ -71,51 +90,56 @@ class ObjectList; class GLCanvas3D; class Mouse3DController; class NotificationManager; +class DailyTipsWindow; struct Camera; class GLToolbar; class PlaterPresetComboBox; class PartPlateList; -using t_optgroups = std::vector >; +using t_optgroups = std::vector>; class Plater; enum class ActionButtonType : int; -#define EVT_PUBLISHING_START 1 -#define EVT_PUBLISHING_STOP 2 +#define EVT_PUBLISHING_START 1 +#define EVT_PUBLISHING_STOP 2 -//BBS: add EVT_SLICING_UPDATE declare here +// BBS: add EVT_SLICING_UPDATE declare here wxDECLARE_EVENT(EVT_SLICING_UPDATE, Slic3r::SlicingStatusEvent); -wxDECLARE_EVENT(EVT_PUBLISH, wxCommandEvent); -wxDECLARE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent); -wxDECLARE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent); -wxDECLARE_EVENT(EVT_INSTALL_PLUGIN_NETWORKING, wxCommandEvent); -wxDECLARE_EVENT(EVT_INSTALL_PLUGIN_HINT, wxCommandEvent); -wxDECLARE_EVENT(EVT_UPDATE_PLUGINS_WHEN_LAUNCH, wxCommandEvent); -wxDECLARE_EVENT(EVT_PREVIEW_ONLY_MODE_HINT, wxCommandEvent); -wxDECLARE_EVENT(EVT_GLCANVAS_COLOR_MODE_CHANGED, SimpleEvent); -wxDECLARE_EVENT(EVT_PRINT_FROM_SDCARD_VIEW, SimpleEvent); - +wxDECLARE_EVENT(EVT_PUBLISH, wxCommandEvent); +wxDECLARE_EVENT(EVT_OPEN_PLATESETTINGSDIALOG, wxCommandEvent); +wxDECLARE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent); +wxDECLARE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent); +wxDECLARE_EVENT(EVT_INSTALL_PLUGIN_NETWORKING, wxCommandEvent); +wxDECLARE_EVENT(EVT_INSTALL_PLUGIN_HINT, wxCommandEvent); +wxDECLARE_EVENT(EVT_UPDATE_PLUGINS_WHEN_LAUNCH, wxCommandEvent); +wxDECLARE_EVENT(EVT_PREVIEW_ONLY_MODE_HINT, wxCommandEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_COLOR_MODE_CHANGED, SimpleEvent); +wxDECLARE_EVENT(EVT_PRINT_FROM_SDCARD_VIEW, SimpleEvent); +wxDECLARE_EVENT(EVT_CREATE_FILAMENT, SimpleEvent); +wxDECLARE_EVENT(EVT_MODIFY_FILAMENT, SimpleEvent); const wxString DEFAULT_PROJECT_NAME = "Untitled"; class Sidebar : public wxPanel { - ConfigOptionMode m_mode; + ConfigOptionMode m_mode; + public: Sidebar(Plater *parent); - Sidebar(Sidebar &&) = delete; - Sidebar(const Sidebar &) = delete; - Sidebar &operator=(Sidebar &&) = delete; + Sidebar(Sidebar &&) = delete; + Sidebar(const Sidebar &) = delete; + Sidebar &operator=(Sidebar &&) = delete; Sidebar &operator=(const Sidebar &) = delete; ~Sidebar(); + void create_printer_preset(); void init_filament_combo(PlaterPresetComboBox **combo, const int filament_idx); void remove_unused_filament_combos(const size_t current_extruder_count); void update_all_preset_comboboxes(); - //void update_partplate(PartPlateList& list); + // void update_partplate(PartPlateList& list); void update_presets(Slic3r::Preset::Type preset_type); - //BBS + // BBS void update_presets_from_to(Slic3r::Preset::Type preset_type, std::string from, std::string to); void change_top_border_for_mode_sizer(bool increase_border); @@ -123,72 +147,74 @@ class Sidebar : public wxPanel void sys_color_changed(); void search(); void jump_to_option(size_t selected); - void jump_to_option(const std::string& opt_key, Preset::Type type, const std::wstring& category); + void jump_to_option(const std::string &opt_key, Preset::Type type, const std::wstring &category); // BBS. Add on_filaments_change() method. void on_filaments_change(size_t num_filaments); // BBS - void on_bed_type_change(BedType bed_type); - void load_ams_list(std::string const & device, MachineObject* obj); - std::map build_filament_ams_list(MachineObject* obj); - void sync_ams_list(); + void on_bed_type_change(BedType bed_type); + void load_ams_list(std::string const &device, MachineObject *obj); + std::map build_filament_ams_list(MachineObject *obj); + void sync_ams_list(); - ObjectList* obj_list(); - ObjectSettings* obj_settings(); - ObjectLayers* obj_layers(); - wxPanel* scrolled_panel(); - wxPanel* print_panel(); - wxPanel* filament_panel(); + ObjectList *obj_list(); + ObjectSettings *obj_settings(); + ObjectLayers *obj_layers(); + wxPanel *scrolled_panel(); + wxPanel *print_panel(); + wxPanel *filament_panel(); - ConfigOptionsGroup* og_freq_chng_params(const bool is_fff); - wxButton* get_wiping_dialog_button(); + ConfigOptionsGroup *og_freq_chng_params(const bool is_fff); + wxButton *get_wiping_dialog_button(); // BBS - void enable_buttons(bool enable); - void set_btn_label(const ActionButtonType btn_type, const wxString& label) const; - bool show_reslice(bool show) const; - bool show_export(bool show) const; - bool show_send(bool show) const; - bool show_eject(bool show)const; - bool show_export_removable(bool show) const; - bool get_eject_shown() const; - bool is_multifilament(); - void update_mode(); - bool is_collapsed(); - void collapse(bool collapse); - void update_searcher(); - void update_ui_from_settings(); - bool show_object_list(bool show) const; - void finish_param_edit(); - + void enable_buttons(bool enable); + void set_btn_label(const ActionButtonType btn_type, const wxString &label) const; + bool show_reslice(bool show) const; + bool show_export(bool show) const; + bool show_send(bool show) const; + bool show_eject(bool show) const; + bool show_export_removable(bool show) const; + bool get_eject_shown() const; + bool is_multifilament(); + void update_mode(); + bool is_collapsed(); + void collapse(bool collapse); + void update_searcher(); + void update_ui_from_settings(); + bool show_object_list(bool show) const; + void finish_param_edit(); + void auto_calc_flushing_volumes(const int modify_id); + void jump_to_object(ObjectDataViewModelNode *item); + void can_search(); #ifdef _MSW_DARK_MODE - void show_mode_sizer(bool show); + void show_mode_sizer(bool show); #endif - std::vector& combos_filament(); - Search::OptionsSearcher& get_searcher(); - std::string& get_search_line(); + std::vector &combos_filament(); + Search::OptionsSearcher &get_searcher(); + std::string &get_search_line(); private: struct priv; std::unique_ptr p; - wxBoxSizer* m_scrolled_sizer = nullptr; - ComboBox* m_bed_type_list = nullptr; - ScalableButton* connection_btn = nullptr; - ScalableButton* ams_btn = nullptr; + wxBoxSizer *m_scrolled_sizer = nullptr; + ComboBox *m_bed_type_list = nullptr; + ScalableButton *connection_btn = nullptr; + ScalableButton *ams_btn = nullptr; }; -class Plater: public wxPanel +class Plater : public wxPanel { public: using fs_path = boost::filesystem::path; Plater(wxWindow *parent, MainFrame *main_frame); - Plater(Plater &&) = delete; - Plater(const Plater &) = delete; - Plater &operator=(Plater &&) = delete; + Plater(Plater &&) = delete; + Plater(const Plater &) = delete; + Plater &operator=(Plater &&) = delete; Plater &operator=(const Plater &) = delete; - ~Plater() = default; + ~Plater() = default; bool Show(bool show = true); @@ -196,28 +222,28 @@ class Plater: public wxPanel bool is_presets_dirty() const; void set_plater_dirty(bool is_dirty); void update_project_dirty_from_presets(); - int save_project_if_dirty(const wxString& reason); + int save_project_if_dirty(const wxString &reason); void reset_project_dirty_after_save(); void reset_project_dirty_initial_presets(); #if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW void render_project_state_debug_window() const; #endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW - Sidebar& sidebar(); - const Model& model() const; - Model& model(); - const Print& fff_print() const; - Print& fff_print(); - const SLAPrint& sla_print() const; - SLAPrint& sla_print(); + Sidebar &sidebar(); + const Model &model() const; + Model &model(); + const Print &fff_print() const; + Print &fff_print(); + const SLAPrint &sla_print() const; + SLAPrint &sla_print(); - int new_project(bool skip_confirm = false, bool silent = false, const wxString& project_name = wxString()); + int new_project(bool skip_confirm = false, bool silent = false, const wxString &project_name = wxString()); // BBS: save & backup - void load_project(wxString const & filename = "", wxString const & originfile = "-"); - int save_project(bool saveAs = false); - //BBS download project by project id + void load_project(wxString const &filename = "", wxString const &originfile = "-"); + int save_project(bool saveAs = false); + // BBS download project by project id void import_model_id(wxString download_info); - void download_project(const wxString& project_id); + void download_project(const wxString &project_id); void request_model_download(wxString url); void request_download_project(std::string project_id); // BBS: check snapshot @@ -230,56 +256,58 @@ class Plater: public wxPanel void import_sl1_archive(); void extract_config_from_project(); void load_gcode(); - void load_gcode(const wxString& filename); + void load_gcode(const wxString &filename); void reload_gcode_from_disk(); void refresh_print(); // SoftFever - void calib_pa(const Calib_Params& params); + void calib_pa(const Calib_Params ¶ms); void calib_flowrate(int pass); - void calib_temp(const Calib_Params& params); - void calib_max_vol_speed(const Calib_Params& params); - void calib_retraction(const Calib_Params& params); - void calib_VFA(const Calib_Params& params); + void calib_temp(const Calib_Params ¶ms); + void calib_max_vol_speed(const Calib_Params ¶ms); + void calib_retraction(const Calib_Params ¶ms); + void calib_VFA(const Calib_Params ¶ms); BuildVolume_Type get_build_volume_type() const; - //BBS: add only gcode mode + // BBS: add only gcode mode bool only_gcode_mode() { return m_only_gcode; } void set_only_gcode(bool only_gcode) { m_only_gcode = only_gcode; } - //BBS: add only gcode mode + // BBS: add only gcode mode bool using_exported_file() { return m_exported_file; } - void set_using_exported_file(bool exported_file) { - m_exported_file = exported_file; - } + void set_using_exported_file(bool exported_file) { m_exported_file = exported_file; } // BBS wxString get_project_name(); - void update_all_plate_thumbnails(bool force_update = false); - void invalid_all_plate_thumbnails(); - void force_update_all_plate_thumbnails(); + void update_all_plate_thumbnails(bool force_update = false); + void invalid_all_plate_thumbnails(); + void force_update_all_plate_thumbnails(); static wxColour get_next_color_for_filament(); - static wxString get_slice_warning_string(GCodeProcessorResult::SliceWarning& warning); + static wxString get_slice_warning_string(GCodeProcessorResult::SliceWarning &warning); // BBS: restore - std::vector load_files(const std::vector& input_files, LoadStrategy strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig, bool ask_multi = false); + std::vector load_files(const std::vector &input_files, + LoadStrategy strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig, + bool ask_multi = false); // To be called when providing a list of files to the GUI slic3r on command line. - std::vector load_files(const std::vector& input_files, LoadStrategy strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig, bool ask_multi = false); + std::vector load_files(const std::vector &input_files, + LoadStrategy strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig, + bool ask_multi = false); // to be called on drag and drop - bool load_files(const wxArrayString& filenames); + bool load_files(const wxArrayString &filenames); - const wxString& get_last_loaded_gcode() const { return m_last_loaded_gcode; } + const wxString &get_last_loaded_gcode() const { return m_last_loaded_gcode; } void update(bool conside_update_flag = false, bool force_background_processing_update = false); - //BBS + // BBS void object_list_changed(); void stop_jobs(); bool is_any_job_running() const; - void select_view(const std::string& direction); - //BBS: add no_slice logic - void select_view_3D(const std::string& name, bool no_slice = true); + void select_view(const std::string &direction); + // BBS: add no_slice logic + void select_view_3D(const std::string &name, bool no_slice = true); bool is_preview_shown() const; bool is_preview_loaded() const; @@ -298,7 +326,7 @@ class Plater: public wxPanel // Update the UI based on the current preferences. void update_ui_from_settings(); - //BBS + // BBS void select_curr_plate_all(); void remove_curr_plate_all(); @@ -307,12 +335,12 @@ class Plater: public wxPanel void remove(size_t obj_idx); void reset(bool apply_presets_change = false); void reset_with_confirm(); - //BBS: return int for various result + // BBS: return int for various result int close_with_confirm(std::function second_check = nullptr); // BBS close project - //BBS: trigger a restore project event + // BBS: trigger a restore project event void trigger_restore_project(int skip_confirm = 0); bool delete_object_from_model(size_t obj_idx, bool refresh_immediately = true); // BBS support refresh immediately - void delete_all_objects_from_model(); //BBS delete all objects from model + void delete_all_objects_from_model(); // BBS delete all objects from model void set_selected_visible(bool visible); void remove_selected(); void increase_instances(size_t num = 1); @@ -322,28 +350,31 @@ class Plater: public wxPanel bool is_selection_empty() const; void scale_selection_to_fit_print_volume(); void convert_unit(ConversionType conv_type); - // BBS: replace z with plane_points void cut(size_t obj_idx, size_t instance_idx, std::array plane_points, ModelObjectCutAttributes attributes); // BBS: segment model with CGAL - void segment(size_t obj_idx, size_t instance_idx, double smoothing_alpha=0.5, int segment_number=5); - void merge(size_t obj_idx, std::vector& vol_indeces); - - void send_to_printer(bool isall = false); - void export_gcode(bool prefer_removable); - void export_gcode_3mf(bool export_all = false); - void send_gcode_finish(wxString name); - void export_core_3mf(); - static TriangleMesh combine_mesh_fff(const ModelObject& mo, int instance_id, std::function notify_func = {}); - void export_stl(bool extended = false, bool selection_only = false); - //BBS: remove amf - //void export_amf(); - //BBS add extra param for exporting 3mf silence - // BBS: backup - int export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path(), SaveStrategy strategy = SaveStrategy::Default, int export_plate_idx = -1, Export3mfProgressFn proFn = nullptr); - - //BBS + void segment(size_t obj_idx, size_t instance_idx, double smoothing_alpha = 0.5, int segment_number = 5); + void apply_cut_object_to_model(size_t init_obj_idx, const ModelObjectPtrs &cut_objects); + void merge(size_t obj_idx, std::vector &vol_indeces); + + void send_to_printer(bool isall = false); + void export_gcode(bool prefer_removable); + void export_gcode_3mf(bool export_all = false); + void send_gcode_finish(wxString name); + void export_core_3mf(); + static TriangleMesh combine_mesh_fff(const ModelObject &mo, int instance_id, std::function notify_func = {}); + void export_stl(bool extended = false, bool selection_only = false, bool multi_stls = false); + // BBS: remove amf + // void export_amf(); + // BBS add extra param for exporting 3mf silence + // BBS: backup + int export_3mf(const boost::filesystem::path &output_path = boost::filesystem::path(), + SaveStrategy strategy = SaveStrategy::Default, + int export_plate_idx = -1, + Export3mfProgressFn proFn = nullptr); + + // BBS void publish_project(); void reload_from_disk(); @@ -361,39 +392,44 @@ class Plater: public wxPanel void changed_mesh(int obj_idx); void changed_object(int obj_idx); - void changed_objects(const std::vector& object_idxs); + void changed_objects(const std::vector &object_idxs); void schedule_background_process(bool schedule = true); bool is_background_process_update_scheduled() const; - void suppress_background_process(const bool stop_background_process) ; + void suppress_background_process(const bool stop_background_process); /* -1: send current gcode if not specified * -2: send all gcode to target machine */ - int send_gcode(int plate_idx = -1, Export3mfProgressFn proFn = nullptr); + int send_gcode(int plate_idx = -1, Export3mfProgressFn proFn = nullptr); void send_gcode_legacy(int plate_idx = -1, Export3mfProgressFn proFn = nullptr); - int export_config_3mf(int plate_idx = -1, Export3mfProgressFn proFn = nullptr); - //BBS jump to nonitor after print job finished + int export_config_3mf(int plate_idx = -1, Export3mfProgressFn proFn = nullptr); + // BBS jump to nonitor after print job finished void send_calibration_job_finished(wxCommandEvent &evt); void print_job_finished(wxCommandEvent &evt); - void send_job_finished(wxCommandEvent& evt); - void publish_job_finished(wxCommandEvent& evt); - void on_change_color_mode(SimpleEvent& evt); - void eject_drive(); + void send_job_finished(wxCommandEvent &evt); + void publish_job_finished(wxCommandEvent &evt); + void open_platesettings_dialog(wxCommandEvent &evt); + void on_change_color_mode(SimpleEvent &evt); + void eject_drive(); void take_snapshot(const std::string &snapshot_name); - //void take_snapshot(const wxString &snapshot_name); + // void take_snapshot(const wxString &snapshot_name); void take_snapshot(const std::string &snapshot_name, UndoRedo::SnapshotType snapshot_type); - //void take_snapshot(const wxString &snapshot_name, UndoRedo::SnapshotType snapshot_type); + // void take_snapshot(const wxString &snapshot_name, UndoRedo::SnapshotType snapshot_type); void undo(); void redo(); void undo_to(int selection); void redo_to(int selection); - bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text); - void undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text); - int update_print_required_data(Slic3r::DynamicPrintConfig config, Slic3r::Model model, Slic3r::PlateDataPtrs plate_data_list, std::string file_name, std::string file_path); - bool search_string_getter(int idx, const char** label, const char** tooltip); + bool undo_redo_string_getter(const bool is_undo, int idx, const char **out_text); + void undo_redo_topmost_string_getter(const bool is_undo, std::string &out_text); + int update_print_required_data(Slic3r::DynamicPrintConfig config, + Slic3r::Model model, + Slic3r::PlateDataPtrs plate_data_list, + std::string file_name, + std::string file_path); + bool search_string_getter(int idx, const char **label, const char **tooltip); // For the memory statistics. - const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const; - void clear_undo_redo_stack_main(); + const Slic3r::UndoRedo::Stack &undo_redo_stack_main() const; + void clear_undo_redo_stack_main(); // Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo. void enter_gizmos_stack(); // BBS: return false if not changed @@ -403,76 +439,76 @@ class Plater: public wxPanel // BBS void on_bed_type_change(BedType bed_type); bool update_filament_colors_in_full_config(); - void config_change_notification(const DynamicPrintConfig &config, const std::string& key); + void config_change_notification(const DynamicPrintConfig &config, const std::string &key); void on_config_change(const DynamicPrintConfig &config); void force_filament_colors_update(); void force_print_bed_update(); // On activating the parent window. - void on_activate(); - std::vector get_extruder_colors_from_plater_config(const GCodeProcessorResult* const result = nullptr) const; - std::vector get_colors_for_color_print(const GCodeProcessorResult* const result = nullptr) const; + void on_activate(); + std::vector get_extruder_colors_from_plater_config(const GCodeProcessorResult *const result = nullptr) const; + std::vector get_colors_for_color_print(const GCodeProcessorResult *const result = nullptr) const; void update_menus(); // BBS - //void show_action_buttons(const bool is_ready_to_slice) const; + // void show_action_buttons(const bool is_ready_to_slice) const; - wxString get_project_filename(const wxString& extension = wxEmptyString) const; - wxString get_export_gcode_filename(const wxString& extension = wxEmptyString, bool only_filename = false, bool export_all = false) const; - void set_project_filename(const wxString& filename); + wxString get_project_filename(const wxString &extension = wxEmptyString) const; + wxString get_export_gcode_filename(const wxString &extension = wxEmptyString, bool only_filename = false, bool export_all = false) const; + void set_project_filename(const wxString &filename); void update_print_error_info(int code, std::string msg, std::string extra); bool is_export_gcode_scheduled() const; - const Selection& get_selection() const; - int get_selected_object_idx(); - bool is_single_full_object_selection() const; - GLCanvas3D* canvas3D(); - const GLCanvas3D * canvas3D() const; - GLCanvas3D* get_current_canvas3D(bool exclude_preview = false); - GLCanvas3D* get_view3D_canvas3D(); - GLCanvas3D* get_preview_canvas3D(); - GLCanvas3D* get_assmeble_canvas3D(); - wxWindow* get_select_machine_dialog(); + const Selection &get_selection() const; + int get_selected_object_idx(); + bool is_single_full_object_selection() const; + GLCanvas3D *canvas3D(); + const GLCanvas3D *canvas3D() const; + GLCanvas3D *get_current_canvas3D(bool exclude_preview = false); + GLCanvas3D *get_view3D_canvas3D(); + GLCanvas3D *get_preview_canvas3D(); + GLCanvas3D *get_assmeble_canvas3D(); + wxWindow *get_select_machine_dialog(); void arrange(); void orient(); - void find_new_position(const ModelInstancePtrs &instances); - //BBS: add job state related functions + void find_new_position(const ModelInstancePtrs &instances); + // BBS: add job state related functions void set_prepare_state(int state); - int get_prepare_state(); - //BBS: add print job releated functions - void get_print_job_data(PrintPrepareData* data); - int get_send_calibration_finished_event(); - int get_print_finished_event(); - int get_send_finished_event(); - int get_publish_finished_event(); + int get_prepare_state(); + // BBS: add print job releated functions + void get_print_job_data(PrintPrepareData *data); + int get_send_calibration_finished_event(); + int get_print_finished_event(); + int get_send_finished_event(); + int get_publish_finished_event(); void set_current_canvas_as_dirty(); void unbind_canvas_event_handlers(); void reset_canvas_volumes(); - PrinterTechnology printer_technology() const; - const DynamicPrintConfig * config() const; - bool set_printer_technology(PrinterTechnology printer_technology); + PrinterTechnology printer_technology() const; + const DynamicPrintConfig *config() const; + bool set_printer_technology(PrinterTechnology printer_technology); - //BBS + // BBS void cut_selection_to_clipboard(); void copy_selection_to_clipboard(); void paste_from_clipboard(); - //BBS: add clone logic + // BBS: add clone logic void clone_selection(); void center_selection(); - void search(bool plater_is_active, Preset::Type type, wxWindow *tag, TextInput *etag, wxWindow *stag); + void search(bool plater_is_active, Preset::Type type, wxWindow *tag, TextInput *etag, wxWindow *stag); void mirror(Axis axis); void split_object(); void split_volume(); void optimize_rotation(); - //BBS: + // BBS: void fill_color(int extruder_id); - //BBS: + // BBS: void edit_text(); bool can_edit_text() const; @@ -489,7 +525,7 @@ class Plater: public wxPanel bool can_split_to_objects() const; bool can_split_to_volumes() const; bool can_arrange() const; - //BBS + // BBS bool can_cut_to_clipboard() const; bool can_layers_editing() const; bool can_paste_from_clipboard() const; @@ -504,7 +540,7 @@ class Plater: public wxPanel bool can_scale_to_print_volume() const; #endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT - //BBS: + // BBS: bool can_fillcolor() const; bool has_assmeble_view() const; @@ -520,48 +556,48 @@ class Plater: public wxPanel bool init_collapse_toolbar(); void enable_collapse_toolbar(bool enable); - const Camera& get_camera() const; - Camera& get_camera(); + const Camera &get_camera() const; + Camera &get_camera(); - //BBS: partplate list related functions - PartPlateList& get_partplate_list(); - void validate_current_plate(bool& model_fits, bool& validate_error); - //BBS: select the plate by index + // BBS: partplate list related functions + PartPlateList &get_partplate_list(); + void validate_current_plate(bool &model_fits, bool &validate_error); + // BBS: select the plate by index int select_plate(int plate_index, bool need_slice = false); - //BBS: update progress result + // BBS: update progress result void apply_background_progress(); - //BBS: select the plate by hover_id + // BBS: select the plate by hover_id int select_plate_by_hover_id(int hover_id, bool right_click = false, bool isModidyPlateName = false); - //BBS: delete the plate, index= -1 means the current plate + // BBS: delete the plate, index= -1 means the current plate int delete_plate(int plate_index = -1); - //BBS: select the sliced plate by index + // BBS: select the sliced plate by index int select_sliced_plate(int plate_index); - //BBS: set bed positions - void set_bed_position(Vec2d& pos); - //BBS: is the background process slicing currently + // BBS: set bed positions + void set_bed_position(Vec2d &pos); + // BBS: is the background process slicing currently bool is_background_process_slicing() const; - //BBS: update slicing context + // BBS: update slicing context void update_slicing_context_to_current_partplate(); - //BBS: show object info + // BBS: show object info void show_object_info(); - //BBS + // BBS bool show_publish_dialog(bool show = true); - //BBS: post process string object exception strings by warning types + // BBS: post process string object exception strings by warning types void post_process_string_object_exception(StringObjectException &err); #if ENABLE_ENVIRONMENT_MAP - void init_environment_texture(); + void init_environment_texture(); unsigned int get_environment_texture_id() const; #endif // ENABLE_ENVIRONMENT_MAP - const BuildVolume& build_volume() const; + const BuildVolume &build_volume() const; // BBS - //const GLToolbar& get_view_toolbar() const; - //GLToolbar& get_view_toolbar(); + // const GLToolbar& get_view_toolbar() const; + // GLToolbar& get_view_toolbar(); - const GLToolbar& get_collapse_toolbar() const; - GLToolbar& get_collapse_toolbar(); + const GLToolbar &get_collapse_toolbar() const; + GLToolbar &get_collapse_toolbar(); void update_preview_bottom_toolbar(); void update_preview_moves_slider(); @@ -574,16 +610,22 @@ class Plater: public wxPanel void reset_gcode_toolpaths(); void reset_last_loaded_gcode() { m_last_loaded_gcode = ""; } - const Mouse3DController& get_mouse3d_controller() const; - Mouse3DController& get_mouse3d_controller(); - - //BBS: add bed exclude area - void set_bed_shape() const; - void set_bed_shape(const Pointfs& shape, const Pointfs& exclude_area, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const; - - const NotificationManager* get_notification_manager() const; - NotificationManager* get_notification_manager(); - //BBS: show message in status bar + const Mouse3DController &get_mouse3d_controller() const; + Mouse3DController &get_mouse3d_controller(); + + // BBS: add bed exclude area + void set_bed_shape() const; + void set_bed_shape(const Pointfs &shape, + const Pointfs &exclude_area, + const double printable_height, + const std::string &custom_texture, + const std::string &custom_model, + bool force_as_custom = false) const; + + const NotificationManager *get_notification_manager() const; + NotificationManager *get_notification_manager(); + DailyTipsWindow *get_dailytips() const; + // BBS: show message in status bar void show_status_message(std::string s); void init_notification_manager(); @@ -594,36 +636,31 @@ class Plater: public wxPanel void set_need_update(bool need_update); // ROII wrapper for suppressing the Undo / Redo snapshot to be taken. - class SuppressSnapshots - { - public: - SuppressSnapshots(Plater *plater) : m_plater(plater) - { - m_plater->suppress_snapshots(); - } - ~SuppressSnapshots() - { - m_plater->allow_snapshots(); - } - private: - Plater *m_plater; - }; + class SuppressSnapshots + { + public: + SuppressSnapshots(Plater *plater) : m_plater(plater) { m_plater->suppress_snapshots(); } + ~SuppressSnapshots() { m_plater->allow_snapshots(); } + + private: + Plater *m_plater; + }; // RAII wrapper for taking an Undo / Redo snapshot while disabling the snapshot taking by the methods called from inside this snapshot. - class TakeSnapshot - { - public: + class TakeSnapshot + { + public: TakeSnapshot(Plater *plater, const std::string &snapshot_name) : m_plater(plater) { - m_plater->take_snapshot(snapshot_name); - m_plater->suppress_snapshots(); - } - /*TakeSnapshot(Plater *plater, const wxString &snapshot_name) : m_plater(plater) - { - m_plater->take_snapshot(snapshot_name); - m_plater->suppress_snapshots(); - }*/ - TakeSnapshot(Plater* plater, const std::string& snapshot_name, UndoRedo::SnapshotType snapshot_type) : m_plater(plater) + m_plater->take_snapshot(snapshot_name); + m_plater->suppress_snapshots(); + } + /*TakeSnapshot(Plater *plater, const wxString &snapshot_name) : m_plater(plater) + { + m_plater->take_snapshot(snapshot_name); + m_plater->suppress_snapshots(); + }*/ + TakeSnapshot(Plater *plater, const std::string &snapshot_name, UndoRedo::SnapshotType snapshot_type) : m_plater(plater) { m_plater->take_snapshot(snapshot_name, snapshot_type); m_plater->suppress_snapshots(); @@ -634,37 +671,33 @@ class Plater: public wxPanel m_plater->suppress_snapshots(); }*/ - ~TakeSnapshot() - { - m_plater->allow_snapshots(); - } - private: - Plater *m_plater; - }; + ~TakeSnapshot() { m_plater->allow_snapshots(); } + + private: + Plater *m_plater; + }; // BBS: limit to single snapshot taking by the methods called from inside // this snapshot. class SingleSnapshot { public: - SingleSnapshot(Plater *plater) : m_plater(plater) - { - m_plater->single_snapshots_enter(this); - } + SingleSnapshot(Plater *plater) : m_plater(plater) { m_plater->single_snapshots_enter(this); } ~SingleSnapshot() { m_plater->single_snapshots_leave(this); } bool check(bool modify) { - if (token && (this->modify || !modify)) return false; - token = true; + if (token && (this->modify || !modify)) + return false; + token = true; this->modify = modify; return true; } private: Plater *m_plater; - bool token = false; + bool token = false; bool modify = false; }; @@ -678,29 +711,29 @@ class Plater: public wxPanel void enable_wireframe(bool status); bool is_wireframe_enabled() const; - // Wrapper around wxWindow::PopupMenu to suppress error messages popping out while tracking the popup menu. - bool PopupMenu(wxMenu *menu, const wxPoint& pos = wxDefaultPosition); + // Wrapper around wxWindow::PopupMenu to suppress error messages popping out while tracking the popup menu. + bool PopupMenu(wxMenu *menu, const wxPoint &pos = wxDefaultPosition); bool PopupMenu(wxMenu *menu, int x, int y) { return this->PopupMenu(menu, wxPoint(x, y)); } - //BBS: add popup logic for table object - bool PopupObjectTable(int object_id, int volume_id, const wxPoint& position); - //BBS: popup selection at default position + // BBS: add popup logic for table object + bool PopupObjectTable(int object_id, int volume_id, const wxPoint &position); + // BBS: popup selection at default position bool PopupObjectTableBySelection(); // get same Plater/ObjectList menus - wxMenu* plate_menu(); - wxMenu* object_menu(); - wxMenu* part_menu(); - wxMenu* sla_object_menu(); - wxMenu* default_menu(); - wxMenu* instance_menu(); - wxMenu* layer_menu(); - wxMenu* multi_selection_menu(); - int GetPlateIndexByRightMenuInLeftUI(); - void SetPlateIndexByRightMenuInLeftUI(int); - static bool has_illegal_filename_characters(const wxString& name); - static bool has_illegal_filename_characters(const std::string& name); - static void show_illegal_characters_warning(wxWindow* parent); + wxMenu *plate_menu(); + wxMenu *object_menu(); + wxMenu *part_menu(); + wxMenu *sla_object_menu(); + wxMenu *default_menu(); + wxMenu *instance_menu(); + wxMenu *layer_menu(); + wxMenu *multi_selection_menu(); + int GetPlateIndexByRightMenuInLeftUI(); + void SetPlateIndexByRightMenuInLeftUI(int); + static bool has_illegal_filename_characters(const wxString &name); + static bool has_illegal_filename_characters(const std::string &name); + static void show_illegal_characters_warning(wxWindow *parent); std::string get_preview_only_filename() { return m_preview_only_filename; }; @@ -710,8 +743,6 @@ class Plater: public wxPanel return m_arrange_running.compare_exchange_strong(prevRunning, true); }; std::atomic m_arrange_running{false}; - - void printago_load_project(wxString const & filename = "", wxString const & originfile = "-"); private: struct priv; @@ -720,17 +751,17 @@ class Plater: public wxPanel // Set true during PopupMenu() tracking to suppress immediate error message boxes. // The error messages are collected to m_tracking_popup_menu_error_message instead and these error messages // are shown after the pop-up dialog closes. - bool m_tracking_popup_menu = false; + bool m_tracking_popup_menu = false; wxString m_tracking_popup_menu_error_message; wxString m_last_loaded_gcode; - //BBS: add only gcode mode - bool m_only_gcode { false }; - bool m_exported_file { false }; - bool skip_thumbnail_invalid { false }; - bool m_loading_project {false }; + // BBS: add only gcode mode + bool m_only_gcode{false}; + bool m_exported_file{false}; + bool skip_thumbnail_invalid{false}; + bool m_loading_project{false}; std::string m_preview_only_filename; - int m_valid_plates_count { 0 }; + int m_valid_plates_count{0}; void suppress_snapshots(); void allow_snapshots(); @@ -740,13 +771,13 @@ class Plater: public wxPanel // BBS: add project slice related functions int start_next_slice(); - void _calib_pa_pattern(const Calib_Params& params); - void _calib_pa_tower(const Calib_Params& params); + void _calib_pa_pattern(const Calib_Params ¶ms); + void _calib_pa_tower(const Calib_Params ¶ms); void _calib_pa_select_added_objects(); - friend class SuppressBackgroundProcessingUpdate; - + void cut_horizontal(size_t obj_idx, size_t instance_idx, double z, ModelObjectCutAttributes attributes); + friend class SuppressBackgroundProcessingUpdate; }; class SuppressBackgroundProcessingUpdate @@ -754,6 +785,7 @@ class SuppressBackgroundProcessingUpdate public: SuppressBackgroundProcessingUpdate(); ~SuppressBackgroundProcessingUpdate(); + private: bool m_was_scheduled; }; @@ -761,4 +793,4 @@ class SuppressBackgroundProcessingUpdate } // namespace GUI } // namespace Slic3r -#endif +#endif \ No newline at end of file diff --git a/version.inc b/version.inc index 324fdfecc98..e3597f513f8 100644 --- a/version.inc +++ b/version.inc @@ -1,8 +1,8 @@ # Included by CMakeLists, edited by the build script # (the version numbers are generated by the build script from the git current label) -set(SLIC3R_APP_NAME "OrcaSlicer - Printago Edition") -set(SLIC3R_APP_KEY "OrcaSlicer - Printago Edition") +set(SLIC3R_APP_NAME "OrcaSlicer") +set(SLIC3R_APP_KEY "OrcaSlicer") if(NOT DEFINED BBL_RELEASE_TO_PUBLIC) set(BBL_RELEASE_TO_PUBLIC "1")