Jump to content

Plugin development


awit

Recommended Posts

Posted · Plugin development

Hi everyone!

 

I was wondering if anybody could direct me / give me some advice on how to start the development of a custom plugin for Cura 4.13.1.

I have read a lot of forum posts and the general instructions on the official github concerning plugins, packages, Uranium, etc.

 

However, I am not sure where to start. For instance - how to set up a framework, what do I need to write/build and test a plugin?

I would greatly appreciate any information that could push me forwards in this endeavour.

 

AW

 

 

  • Link to post
    Share on other sites

    Posted · Plugin development

    If you are developing on Windows, the easiest way to get started is to just use the normal Cura and create your plugins in your configuration folder (see Help -> Show configuration folder). Start with a plugin that is somewhat in the general direction of what you want to do and learn from its code. There's documentation here, and some example plugins here.

    • Like 1
    • Thanks 1
    Link to post
    Share on other sites

    Posted · Plugin development

    Thanks for the quick reply!

     

    As I understand it, I should just create the plugin folder with __init__.py, main .py file and a json file and paste it to the Cura 'plugins' folder? Shouldn't I somehow 'build' it (I read about curapackage / curaplugin files)? 

     

    My main goal is to update a plugin made by someone else in the past, ScalableExtraPrime, for the current Cura version.

     

     

  • Link to post
    Share on other sites

    Posted · Plugin development
    1 hour ago, awit said:

    Shouldn't I somehow 'build' it (I read about curapackage / curaplugin files)? 

    A curapackage is only needed if you want to easily have others install the plugin, by dropping the curapackge into the Cura viewport.

  • Link to post
    Share on other sites

    • 1 month later...
    Posted (edited) · Plugin development

    Hi @ahoeben,

    I have made some progress in the plugin development process, however, I am temporarily stuck on the following issue.

     

    For one of the functions, I have to access the value of a setting (in this case - the value of retraction that has been set by the user) directly from Cura, so that I can use it as a variable inside of the function.

     

    I have used the following lines of code:

    global_container_stack = self._application.getGlobalContainerStack()
    
    if not global_container_stack:
    	return
    
    # get the retraction value
        retraction = global_container_stack.getProperty("retraction_amount", "value")

     

    However, this returns the value of 6.5, which I assume is the default; and not the correct value set by me in Cura.

    I have read about the stack and how Cura retrieves values. I think that somehow it skips the user settings and goes right into the definitions.

     

    Taking a look at the .cfg files, I noticed two files being updated together whenever I make changes. One is named custom_myProfileName and the other custom_extruder1_myProfileName. The first one contains comparatively less settings, whereas the second one contains all the custom ones. Is it possible that my code returns the value for the case of the first .cfg file, where the retraction_amount has not been saved? If so, what would be the solution for this issue.

     

    Best regards,

    AW

    Edited by awit
  • Link to post
    Share on other sites

    Posted · Plugin development

    The retraction amount can be different for each extruder. Even if you have only one extruder, you need to get the value from the extruder stack, not the global stack.

     

    For example, to get the value from the first extruder, use:

    extruder_stack = CuraApplication.getInstance().getExtruderManager().getActiveExtruderStacks()[0]
    
    if not extruder_stack:
    	return
    
    retraction = extruder_stack.getProperty("retraction_amount", "value")

     

  • Link to post
    Share on other sites

    Posted · Plugin development

    With a slight change it started working:

     

    extruder_stack = self._application.getInstance().getExtruderManager().getActiveExtruderStacks()[0]

     

    Thanks!

  • Link to post
    Share on other sites

    Posted · Plugin development

    Depends on what you have imported and how you have defined self._application

     

  • Link to post
    Share on other sites

    Posted · Plugin development
    8 minutes ago, ahoeben said:

    Depends on what you have imported and how you have defined self._application

     

     

    This is the approach I found in the Z-Offset plugin:

    self._application = Application.getInstance()

     

  • Link to post
    Share on other sites

    Posted (edited) · Plugin development

    Then you actually miss-copy-pasted your current solution; it should be as follows:

     

    extruder_stack = self._application.getExtruderManager().getActiveExtruderStacks()[0]

     

    My original version works, if you import Cura.CuraApplication. You probably have imported UM.Application in your code.

     

    I know how Z-Offset plugin works; I wrote it.

    Edited by ahoeben
  • Link to post
    Share on other sites

    Posted · Plugin development
    1 hour ago, ahoeben said:

    I know how Z-Offset plugin works; I wrote it.

     

    I am aware and very thankful, I looked through the plugins you wrote at least several times. I just wanted to provide the source of the code I used.

     

    I greatly appreciate the opportunity to ask questions.

     

    1 hour ago, ahoeben said:

    My original version works, if you import Cura.CuraApplication. You probably have imported UM.Application in your code.

     

    I was wondering if Cura.CuraApplication and UM.Application can be used interchangeably or is one a newer version of the other? As I based on the Z-Offset plugin, I used the UM imports.

     

    For now my understanding of the various imports, and the code structure of Cura in general, is very limited (before asking the recent question I tried to find the answer here). From my initial question I have settled to create a folder with the __init__.py, .json and python scripts; and paste it to the plugin directory of Cura. So every change is followed by the restart of Cura and the various imports are unresolved.

  • Link to post
    Share on other sites

    Posted · Plugin development

    Effectively, UM.Application.getInstance() and Cura.CuraApplication.getInstance() point to the same object, so in use they are equivalent.

     

    Technically, Cura.CuraApplication inherits from UM.Application. Cura.CuraApplication has additional properties that UM.Application does not have. For example, UM.Application has no method getExtruderManager(). However, because the object is actually instantiated as a Cura.CuraApplication, Python does not complain at runtime. It is more "correct" to use Cura.CuraApplication if you want to access getExtruderManager(). and a decent IDE will tell you so.

    • Like 1
    Link to post
    Share on other sites

    Posted · Plugin development
    47 minutes ago, awit said:

    I have settled to create a folder with the __init__.py, .json and python scripts; and paste it to the plugin directory of Cura. So every change is followed by the restart of Cura and the various imports are unresolved.

    Hard to tell what is going wrong without seeing the code, and the cura logs.

  • 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...