Jump to content

Output print settings to text file?


brianskyze

Recommended Posts

Posted (edited) · Output print settings to text file?

This is a good idea, worth looking into.

 

I am not a programmer, so I am thinking purely philosophically too here. If the print-routine would take the output to the screen as its input, and format that into a nice TXT or CSV file, wouldn't that work? Then you have a nice list of all relevant settings, and you can print, review, compare and manually enter them again if ever required.

 

Then this print-routine wouldn't have to be aware of the internal structure of Cura? Because the merging of profile defaults, custom settings, and whatever else, is already done at that point?

 

Of course the routine can't just use the pixel-stream to the screen. It has to intercept the communication somewhere earlier when the text-content is sent to the GUI-system, before it is converted into pixels.

 

Or am I missing something?

 

For me a simple TXT file would do. So that you can open it in Notepad, Notepad++, Wordpad, Word, Excel, or whatever editor you like. And you can then easily format it and write to PDF if required, or print on paper. This would be the most versatile and probably easiest to implement. With such TXT-files you could also input multiple TXT-files in Excel in different columns and then compare them next to each other, and print tables if you want.

 

Edited by geert_2
  • Like 2
Link to post
Share on other sites

Posted · Output print settings to text file?

Addition:

 

For easy importing in Excel, for example if you want lots of profiles in one big table, for a good overview and easy comparing, it is desirable to have only two columns (A and B) in the text-output. And the units being part of column A. Like this:

 

Column A  [TAB]  Column B

...

Profile name:  [TAB]  Normal PLA

User comment:  [TAB]  This is my usual PLA profile

Printing speed (mm/s):  [TAB]  50

Traveling speed (mm/s):  [TAB]  150

Nozzle temp (°C):  [TAB]  210

Number of skirt lines (#):  [TAB]  3

...

 

In which [TAB] is of course a tab-stop. A semicolon would also do (or better, user-selectable). But no comma's, since they might interfere with European decimal points.

 

In this way we can open such a file in Excel, and directly copy column B into a template with a big table. Or we can easily print it from Notepad, or from Word.

 

  • Link to post
    Share on other sites

    Posted · Output print settings to text file?
    On 3/17/2018 at 12:04 PM, yellowshark said:

    Hi @SandervG this is a really good idea from @brianskyze ; I have to write down notes for every print I do (and even then there are certain lesser settings do not get noted) - hitting a print key would be so much easier

     

    I agree! Little tip; when you tag a person you have to select the username from the dropdown list following @.. this is necessary to make a link to the database with user-accounts and you are not just writing something with an @. It would be the difference between @yellowshark and @yellowshark. 

     

    Perhaps it could be a nice plugin. I assume it is something one would select through file > export or something, and it doesn't generate a .csv automatically?

     

  • Link to post
    Share on other sites

    Posted · Output print settings to text file?

    I confess to only quickly skimming recent posts but I do wonder if we are trying to disappear up our own tail. Cura must already have all the code and data it needs because it displays the data we want on to the computer monitor. All (lol) it has to do is to route that "display" somewhere else, be that a document or a database record(s)

  • Link to post
    Share on other sites

    Posted · Output print settings to text file?
    1 hour ago, SandervG said:

    Ah I was not aware that the new forum had changed this. I thought that the selection box was there to help if necessary but one could still type the tag into the message directly.No wonder no one responds to my tags :'(

     

     

  • Link to post
    Share on other sites

    Posted · Output print settings to text file?
    13 hours ago, ahoeben said:

    Out of interest, what's the problem with more than 2 columns?

     

    In itself there is no problem with more columns. The problem would be if the data is divided over multiple columns, for example:

     

    Column A  [TAB]  Column B  [TAB]  Column C

    Nozzle temp:  [TAB]  °C  [TAB]  210

    Number of skirt lines:  [TAB]  3

     

    Here the temp is sitting in column C, while the number of skirt lines is in column B. Then you can not simply copy and paste the whole column with data into an Excel worksheet, into a prepared template. It would require manually re-arranging some data into different columns. For printing as a plain text file, it does not matter of course.

     

    The idea is similar to when copying data from a TXT-file into an Excel worksheet, to produce a graph. You want all the X-axis data in one column, and all Y-axis data in another column. If this would be a material test that is repeated 100 times, then we can simply copy the column with X-values into a prepared worksheet, and copy the Y-values, and immediately have a nice graph.

     

    It wouldn't matter if you would use two columns, like this:

       Description (units)  |  Numerical data

     

    Or three columns:

       Description  |  Units  |  Numerical data

     

    Or whatever else, as long as all items use the same layout, and all numerical data end up in the same column. That was the idea.

     

  • Link to post
    Share on other sites

    Posted · Output print settings to text file?

    Has anyone ever made a feature request about this here: 

    https://github.com/Ultimaker/Cura/issues ?

     

    I have imported some materials from marketplace which are lacking profiles (only Fast and Fine are existing). For technical stuff I love Engineering Intent Profiles. But I can't simply copy them as custom profiles because they are relying on other profiles that won't exist for the imported materials. 

     

    A good explanation about deriving settings from the different profile layers is here (thanks to nallath):

    https://github.com/Ultimaker/Cura/wiki/Profiles-&-Settings

     

    It would be great to have a way to export the settings to a text file. That way it would be much easier to build a similar profiles for different materials. It would be even better if there were an information given in the exported file from where the setting is originated (user/material/quality profile/intent profile/machine). Although that might be more difficult because there are also settings calculated by a formula. 

     

  • Link to post
    Share on other sites

    Posted (edited) · Output print settings to text file?

    You can find some plugins on github to export your profile under an HTML Document (in this case only values are exported. It's a full description without formula so every setting is easy to figure out)

     

    https://github.com/johnnygizmo/CuraSettingsWriter

     

    A curapackage for Cura 4.6 for this plugin can be found there : 

    https://github.com/5axes/CuraSettingsWriter/blob/master/Package/HTMLCuraSettings-v7.0.0-2020-06-12T16_31_19Z.curapackage

     

    You just have to drag and drop this file into Cura (4.6.1) for a direct installation.

     

    It creates an extra menu option under File -> "Save Project..." that allows you to save all of the settings to an HTML file for review/sharing.

     

    Edited by Cuq
  • Link to post
    Share on other sites

    Posted · Output print settings to text file?

    That's great.

    I can easily pull it from the HTML to do kind of automated comparision.

  • Link to post
    Share on other sites

    Posted · Output print settings to text file?
    On 6/8/2020 at 11:50 AM, Cuq said:

    You can find some plugins on github to export your profile under an HTML Document (in this case only values are exported. It's a full description without formula so every setting is easy to figure out)

     

    https://github.com/johnnygizmo/CuraSettingsWriter

     

    My joy was a bit premature. When looking at the values from the HTML output of the plugin some of the settings would differ from the values given in the Cura GUI.

     

    I have hesitate for some days to look into the code of the plugin as I have never coded Python nor have I found many informations about the internal objects structure of Cura.  Cause i'd really like to have a readable export of settings I have now tried.

     

    It seems that in the plugin all settings values are pulled from global stack

            machine_manager = application.getMachineManager()        
            global_stack = machine_manager.activeMachine

    But for a dual extruder machine where settings can be different for extruder 1 + 2 for some settings a single value can't be all.

     

    I found this information here:

    https://community.ultimaker.com/topic/22507-how-can-i-get-settings-in-postprocessing-plugin-script/

    "Cura has multiple "stacks" containing settings; a global stack that has all the settings that are properties of the printer (such as machine_start_gcode, build plate dimensions, but also those settings in the sidebar that have a "link" icon), and one or more extruder stacks for settings that can be different for each extruder. "

     

    So I tried to simply use the extruder stack instead of the global stack in the plugin code but I got less settings in the machine category (somehow understandable and the category isn't visible in the settings pane of the GUI anyways) but also none of the settings in the material category. So a really important part (temperatures) where missing.

     

    I have now tried to get the setting names from the global stack and request the corresponding values from the extruder stack.

     

    Can anybody confirm that this is a valid approach?

     

     

     

  • Link to post
    Share on other sites

    Posted (edited) · Output print settings to text file?

    For the machine category sounds logical as they are global settings, but the temperatures  should be linked to the extrudeur. Anyway that's clear  this code must be improved for a dual exturder. But it should be not so difficult on my point of view. 

    Edited by Cuq
  • Link to post
    Share on other sites

    Posted · Output print settings to text file?

    Based on the wiki explanation about profiles and settings here:

    https://github.com/Ultimaker/Cura/wiki/Profiles-&-Settings

     

    i have just made minor changes to the code (marked with ->). At the moment just enough to test on one extruder stack.

     

     Copyright (c) 2020 5axes
    # Initiale Source from Johnny Matthews 
    # The SnapShot plugin is released under the terms of the AGPLv3 or higher.
    
    from UM.Application import Application
    from cura.CuraVersion import CuraVersion  # type: ignore
    from UM.Preferences import Preferences
    from UM.Settings.ContainerRegistry import ContainerRegistry
    from UM.Workspace.WorkspaceWriter import WorkspaceWriter
    -> from cura.Settings.ExtruderManager import ExtruderManager
    
    import UM.Settings.SettingRelation
    
    class CuraSettingsWriter(WorkspaceWriter):
       
        def write(self, stream, nodes, mode):
            stream.write("<style>")
            stream.write(" .category { font-size:1.5em; } ")
            stream.write(" .off { background-color:grey; } ")
            stream.write(" .valueCol { width:200px;text-align:right }")
            stream.write("</style>")
            
            application = Application.getInstance()
            machine_manager = application.getMachineManager()        
            stack = application.getGlobalContainerStack()
    ->        extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
            global_stack = machine_manager.activeMachine
    
    
            #jquery = open("plugins/plugins/CuraSettingsWriter/jquery-3.3.1.min.js","r", encoding="utf-8")
            
            stream.write("<script src='https://code.jquery.com/jquery-3.3.1.slim.min.js'></script>\n")
            stream.write("""<script>
                                $(document).ready(function(){
                                        $("#enabled").on("click",toggleDisabled);
    
                                });
    
                                function toggleDisabled(){
                                        $("tr.disabled").toggle();
                                }
                            </script>
                            <h1>Cura Settings Export</h1>
                            <button id='enabled'>Toggle Disabled</button><P>""")
    
            stream.write("<table width=50% border=1 cellpadding=3>")
            
            # Version
            stream.write("<tr>")
            stream.write("<td class='ok' style='width:50%;padding-left:25'>Cura Version</td>")
            stream.write("<td class='ok' colspan=2>" + str(CuraVersion) + "</td>")
            stream.write("</tr>\n")  
            # Job
            J_Name = Application.getInstance().getPrintInformation().jobName
            stream.write("<tr>")
            stream.write("<td class='ok' style='width:50%;padding-left:25'>Job Name</td>")
            stream.write("<td class='ok' colspan=2>" + str(J_Name) + "</td>")
            stream.write("</tr>\n")         
            # Snapshot
            #stream.write("<tr>")
            #stream.write("<td class='ok' colspan=3>" + str(F_Name) + "</td>")
            #stream.write("</tr>\n")
            #   Profile
            P_Name = global_stack.qualityChanges.getMetaData().get("name", "")
            stream.write("<tr>")
            stream.write("<td class='ok' style='width:50%;padding-left:25'>Profile</td>")
            stream.write("<td class='ok' colspan=2>" + str(P_Name) + "</td>")
            stream.write("</tr>\n")
            #   Quality
            Q_Name = global_stack.quality.getMetaData().get("name", "")
            stream.write("<tr>")
            stream.write("<td class='ok' style='width:50%;padding-left:25'>Quality</td>")
            stream.write("<td class='ok' colspan=2>" + str(Q_Name) + "</td>")
            stream.write("</tr>\n")
            #   Material
            # M_Name = extruder.material.getMetaData().get("material", "")
            extruders = list(global_stack.extruders.values())
            M_Name = extruders[0].material.getMetaData().get("material", "")
            stream.write("<tr>")
            stream.write("<td class='ok' style='width:50%;padding-left:25'>Material</td>")
            stream.write("<td class='ok' colspan=2>" + str(M_Name) + "</td>")
            stream.write("</tr>\n")
            
            # Define every section to get the same order as in the Cura Interface
    ->        self._doTree(global_stack,extruder_stacks[0],"resolution",stream,0)
    ->        self._doTree(global_stack,extruder_stacks[0],"shell",stream,0)
    ->        self._doTree(global_stack,extruder_stacks[0],"infill",stream,0)
    ->         self._doTree(global_stack,extruder_stacks[0],"material",stream,0)
    ->         self._doTree(global_stack,extruder_stacks[0],"speed",stream,0)
    ->         self._doTree(global_stack,extruder_stacks[0],"travel",stream,0)
            # If single extruder doesn't export the data
            extruder_count=stack.getProperty("machine_extruder_count", "value")
            if extruder_count>1 :
    ->             self._doTree(global_stack,extruder_stacks[0],"dual",stream,0)
                
    ->         self._doTree(global_stack,extruder_stacks[0],"cooling",stream,0)
    ->         self._doTree(global_stack,extruder_stacks[0],"support",stream,0)
    ->         self._doTree(global_stack,extruder_stacks[0],"platform_adhesion",stream,0)
    ->         self._doTree(global_stack,extruder_stacks[0],"meshfix",stream,0)
    ->         self._doTree(global_stack,extruder_stacks[0],"blackmagic",stream,0)
    ->         self._doTree(global_stack,extruder_stacks[0],"experimental",stream,0)
    ->         self._doTree(global_stack,extruder_stacks[0],"machine_settings",stream,0)
    
            # This Method is smarter but unfortunatly settings are not in the same ordrer as the Cura interface
            # for key in global_stack.getAllKeys():
            #     if global_stack.getProperty(key,"enabled") == True:
            #         if global_stack.getProperty(key,"type") == "category":
            #             self._doTree(global_stack,key,stream,0)
    
            stream.write("</table>")
            return True
    
    ->     def _doTree(self,stack,extruder_stack,key,stream,depth):   
            #output node
            if stack.getProperty(key,"type") == "category":
                stream.write("<tr>")
                stream.write("<td class=category colspan=3>" + str(stack.getProperty(key,"label")) + "</td>")
                #stream.write("<td class=category>" + str(key) + "</td>")
                stream.write("</tr>\n")
            else:
                style = "ok"    
                if stack.getProperty(key,"enabled") == False:
                    style = "off"
                    stream.write("<tr class=disabled>")
                else:
                    stream.write("<tr>")
    ->             stream.write("<td class="+style+" style='width:50%;padding-left:"+str(depth*25)+"'>" + str(extruder_stack.getProperty(key,"label")) + "</td>")
    ->             GetType=extruder_stack.getProperty(key,"type")
    ->             GetVal=extruder_stack.getProperty(key,"value")
                if str(GetType)=='float':
                    GelValStr="{:.2f}".format(GetVal).replace(".00", "")  # Formatage
                else:
                    GelValStr=str(GetVal)
                    
                stream.write("<td class='"+style+" valueCol'>" + GelValStr + "</td>")
    ->             stream.write("<td class="+style+" >" + str(extruder_stack.getProperty(key,"unit")) + "</td>")
                
                stream.write("</tr>\n")
    
            #look for children
            if len(stack.getSettingDefinition(key).children) > 0:
                for i in stack.getSettingDefinition(key).children:       
                    self._doTree(stack,extruder_stack,i.key,stream,depth+1)
                        
                       

    The comment in the original code is correct, you can't use getAllKeys() on a stack if you wan't to have the same sequence that you see in the GUI. The original idea of getting the categories (Infill, Speed etc.) and pulling the children recursively seems to work. But I have made a lot of assumptions:

     

    1. The extruder stack (or all stacks) won't list settings as children if there is no direct value for them in the stack. That would explain why I don't get some settings if I simply replace the global stack by the extruder stack. So I kept the code to and get the complete settings from the global stack.

     

    2. According to the above mentioned doc about profiles and settings:

    "The extruder stack will then ask each of the profiles that it has (in sequence) if they have a value for the requested setting"

    I take every setting from the global stack and ask the extruder stack for the value and hope the result is the same as given in the GUI

     

    3. The next part of the wiki doc about formulas to calculate values for settings:

    "When we ask for the value of "foo", we expect to get 25 as a result. The following calls will be made in order: ..."

    Could be a bit more clear - who makes the calls in order?. I hope that the extruder stack will do it for me and will deliver the correct value so I don't have to do the calls in the plugin code.

     

    With all these assumptions I am not really sure about my results.

     

    • Like 1
    Link to post
    Share on other sites

    Posted (edited) · Output print settings to text file?

    In my case I will use the Settings of the extruders[0] for platform_adhesion, support, meshfix ,blackmagic ,experimental and Machine and the individual extruders for the other settings 

     

    Have a look to my modified solution :https://github.com/5axes/CuraSettingsWriter/blob/master/HtmlCuraSettings.py

     

     

    Edited by Cuq
    • Like 1
    Link to post
    Share on other sites

    Posted · Output print settings to text file?

    last curapackage https://github.com/5axes/CuraSettingsWriter/blob/master/Package/HTMLCuraSettings-v7.0.0-2020-06-12T16_31_19Z.curapackage

     

    Download it and drag& drop in the Cura windows for installation ( 4.6)

     

  • Link to post
    Share on other sites

    Posted · Output print settings to text file?
    22 hours ago, Cuq said:

     

    Thanks for completing the changes and building the package.

     

    If you like to maintain it, I think it is better to format numerical values like this:

     

                if str(GetType)=='float':
                    GelValStr="{:.5f}".format(GetVal).rstrip("0").rstrip(".")
                else:
                    GelValStr=str(GetVal)
                    

    it is better mimicking the GUI. The original code will give rounded values with 2 decimal places even when the GUI shows more decimals. 

     

    For myself I have changed the plugin to make  an CSV file because my main purpose is to compare different profiles and I can feed that directly into Excel to show the differences.

    • Like 2
    Link to post
    Share on other sites

    Posted (edited) · Output print settings to text file?

    Good suggestion  but i will use :

    GelValStr="{:.4f}".format(GetVal).rstrip("0").rstrip(".")

    5 is too much for me. And I don't really see the benefits of a CSV format if it's just to open in Excel . An HTML file is much more easy to open directly in Excel compare to an CSV file (Just my point of view) 

    Excel.JPG

    Edited by Cuq
  • Link to post
    Share on other sites

    Posted (edited) · Output print settings to text file?

    It's just easier to make an automated comparision from pure lists:

     

    image.thumb.png.417719b43d422665f2eccbd8301decb9.png

     

    I am quite happy with it.

     

    BTW: In my code I have kept the pulling of the settings from the extruder stack. It seems the stack is requesting the values from the right place. The benefit is that for the Machine settings it gives the correct Nozzle ID and Diameter for both extruders.

     

    image.thumb.png.5b2d1f1fe003e9c61a079838f8494870.png

     

    Maybe it's possible to get this values in the same way as the material from the global stack extruders values:

    #   Material
    # M_Name = extruder.material.getMetaData().get("material", "")
    extruders = list(global_stack.extruders.values())
    M_Name = extruders[extruder_stack.getProperty("extruder_nr","value")].material.getMetaData().get("material", "")
                

    But I don't know how to do that.

     

     

    Edited by r_moeller
    • Like 1
    Link to post
    Share on other sites

    Posted · Output print settings to text file?

    Dear colleagues,

    thank you for this great job. Has anyone tried to use the plugin in version 4.7.1? I'm afraid of crashing my installation by testing it.

     

  • Link to post
    Share on other sites

    Posted · Output print settings to text file?

    Did you instal it via the market place ?

  • Link to post
    Share on other sites

    Posted · Output print settings to text file?

    For anyone reading this, there is now a plugin available inside the Cura marketplace, that allows the export of profile settings to .csv (text).  Also one that exports to HTML if you fancy it!  

  • Link to post
    Share on other sites

    Posted (edited) · Output print settings to text file?

    Because only the parameters it's not enough , Postprocessing can also have a influence on the final Gcode.

    Output at the End of the HTML file.

    image.thumb.png.9a8432dec541e93b6ec1bf923fadfda7.png

    Edited by Cuq
  • Link to post
    Share on other sites

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now
    • Our picks

      • UltiMaker Cura 5.7 stable released
        Cura 5.7 is here and it brings a handy new workflow improvement when using Thingiverse and Cura together, as well as additional capabilities for Method series printers, and a powerful way of sharing print settings using new printer-agnostic project files! Read on to find out about all of these improvements and more. 
         
          • Like
        • 18 replies
      • S-Line Firmware 8.3.0 was released Nov. 20th on the "Latest" firmware branch.
        (Sorry, was out of office when this released)

        This update is for...
        All UltiMaker S series  
        New features
         
        Temperature status. During print preparation, the temperatures of the print cores and build plate will be shown on the display. This gives a better indication of the progress and remaining wait time. Save log files in paused state. It is now possible to save the printer's log files to USB if the currently active print job is paused. Previously, the Dump logs to USB option was only enabled if the printer was in idle state. Confirm print removal via Digital Factory. If the printer is connected to the Digital Factory, it is now possible to confirm the removal of a previous print job via the Digital Factory interface. This is useful in situations where the build plate is clear, but the operator forgot to select Confirm removal on the printer’s display. Visit this page for more information about this feature.
          • Like
        • 0 replies
    ×
    ×
    • Create New...