Blender Krita Link: plugin for texture editing in krita

It’s a plugin for linking krita image with blender image texture allowing for fast updates without file reloads(using python shared memory)

Features:

  • link one image from krita to image texture in blender
  • Allows for rapid updates of the image without the necessity of saving files.
  • Transfers UV maps from Blender objects to Krita as an overlay.
  • Imports images from Blender into Krita as a new layer.
  • shortcuts for all above
  • Supports making Krita selection areas based on Blender UV maps (requires an additional C++ plugin).

Download

get the newest release at releases page

Installation:

  • Download the .zip files from the release page and import them into Krita and Blender.
  • To enable Krita selection area functionality, extract the Plugin_native_addition to your Krita installation folder, or alternatively, compile Krita with the provided source files.

Usage:

Enabling the Plugin

  • In Krita: Activate the plugin via Settings > Configure Krita > Python Plugin Manager. Restart Krita and enable the dock under Settings > Docker > Blender Krita Link.
  • In Blender: Enable the plugin through Edit > Preferences > Add-ons > Blender Krita Link.

Plugin Operations

  • Use the Connect button to link to Blender, after that you can use Disconnect button to end your session. Also you can change Connection port both in Krita and Blender.
  • The plugin loads images from Blender into a list. Link an image by right-clicking it and selecting Link image, or import a texture by clicking From Blender to new layer. you open an image in new document(and link) too. Also you can use double click to make action based on context.
  • To enable linking, ensure the Krita document is the same size as the Blender image. Set the correct color spectrum under Image > Properties > Image Color Space (RGB/Alpha and Profile: sRGB options are recommended).
  • If “Send on draw” is activated, the image will update in Blender when you release the draw button on the canvas (and use ctrl+(Shift)+Z). You can also send data manually using the “Send Data” button.
  • Use Refresh to update image list from blender and query it by Search Blender images list textbox.
  • Use Refresh in uvs section to get the UV map from selected object(in blender) to krita.
    • you can also change color and the stroke weight of uv maps and their visibility
  • Use Select in uvs section for converting selected uvs in Blender to Krita selection
  • you can also enable the auto update of uvs and images list in blender using sync uvs and images checkbox, with the sync interval variable.

Note:

  • plugin is still pretty buggy and sometimes you may get a runtime error
  • handling large files(8K+) takes long time
  • The UV overlay feature does not adjust with the canvas in fullscreen mode when rulers are disabled.
  • macos is not supported right now
33 Likes

Hello @heisenshark and welcome to the forum :slight_smile:

People are becoming more and more interested in some kind of ‘bridging’ capability between Blender and Krita so your plugin will be very interesting for them.
Thank you for posting details of your work.

Have you seen this topic, which is a similar item by another user:
Plugin: Blender Layer - Live 3d View in Krita

3 Likes

So, now we have the third Blender connection, cool. :+1:

Michelist

2 Likes

My plugin focuses on improving texture editing workflow without focusing on 3D rendering(3Dview plugin) or viewing blender(blender layer) so there is no feature like projection painting for example.
It’s more like this plugin but doesn’t require saving any files and adds useful UV additions(getting UV overlay, UV faces to krita selection).

Additionally, there are two other plugins similar to mine, but they are paid or closed source.

6 Likes

Thank you for sharing your plugin with us, @heisenshark.

As far as these things are concerned, you coders are the ones with the more precise knowledge of the capabilities of your plugins!

I myself use Blender at most to occasionally view an object created by others, and only wanted to mention the third plugin I know that combines Krita and Blender in a way I do only understand halfway in principle not in detail, not to point out any functional similarities I don’t know about anyway, I don’t know Blender well enough for that.

I also firmly believe that it is a good thing that the plugins cover different areas of application, as this opens up more possibilities for the user community. Even if the existence of similar products often promotes their progress, as every provider wants to offer the best solution/the best product, it doesn’t matter what the products are, may they be cars, smartphones or TV-Sets, every manufacturer wants to be the best in its area.

So, every such plugin is a winner for the programs to be connected.
And I can only say thank you all for your efforts!

Michelist

4 Likes

This is the type of thing that will actually make Krita even more useful and awesome. Can’t wait to test this out in a real model. I know most people here have no clue or even care about these things beyond tracing over models but this is really BIG.

3 Likes

Can you evaluate it a bit more? I’m absolutely clueless.

Michelist

Being able to paint a model texture in Krita and get immediate feedback in Blender is really nice.

But as mentioned, it does seem to be a bit buggy.
It’s crashing Krita with SIGPIPE when doing “From Blender To new Layer” and then “Link Image”. (The last message printed to the terminal in this case is file exists, trying another way.) It also sometimes crashes when unlinking.

1 Like

Does this problems occur when using plugin on macos? I can’t really test it in that case because I don’t have a macbook.

Seems like I coded some stuff with shared memory that may not be necessary and causes issues.

Could you provide more steps to replicate the problem, like programs versions, image size, color space, maybe more verbose log from krita and blender.
Also thanks for testing the plugin

Yes, this is on macOS.
Versions: Krita 5.3.0-prealpha git 3ad80aaf, Blender 4.0.2
Image size: 1024x1024
Colorspace: the Krita file is the default sRGB. the texture is also RGB8.

Steps:

  • Load a textured model into Blender
  • Load an image into Krita
  • Use the plugin to connect to Blender. The image list loads.
  • Right-click an image in the list for “From Blender To new Layer”. The image is loaded.
  • Right-click the same image to “Link Image”
  • SIGPIPE
Krita's terminal output (click to show):
{"listenCanvas": true, "showUVs": true}
init state....
Docker init!!!
True
<PyQt5.QtWidgets.QWidget object at 0x12c825fc0> <PyQt5.QtWidgets.QPushButton object at 0x12c825d80>
/Users/name/Library/Application Support/krita/pykrita/KritaBlenderLink/BlenderKritaLinkUI.ui
something Happened
window Created
view Created
onviewcreated, attaching shortcuts listeners...
something Happened
something Happened
image Created
something Happened
None
connected krita to blender
client created
future before
recived message {'type': 'GET_IMAGES', 'data': [{'name': 'Render Result', 'path': '', 'size': [0, 0], 'isActive': False}, {'name': 'tile0.bmp', 'path': '/Users/name/game dat/tile0.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'tile1.bmp', 'path': '/Users/name/game dat/tile1.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'tile2.bmp', 'path': '/Users/name/game dat/tile2.bmp', 'size': [256, 256], 'isActive': False}, {'name': 'tile3.bmp', 'path': '/Users/name/game dat/tile3.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'Viewer Node', 'path': '', 'size': [256, 256], 'isActive': False}], 'requestId': 0, 'formattedMessage': True}
[<KritaBlenderLink.connection.MessageListener object at 0x12c8183a0>, <KritaBlenderLink.connection.MessageListener object at 0x12c818a60>, <KritaBlenderLink.connection.MessageListener object at 0x12c818af0>, <KritaBlenderLink.connection.MessageListener object at 0x12c818e80>, <KritaBlenderLink.connection.MessageListener object at 0x13dc1ea40>, <KritaBlenderLink.connection.MessageListener object at 0x13dc1eb90>] {'type': 'GET_IMAGES', 'data': [{'name': 'Render Result', 'path': '', 'size': [0, 0], 'isActive': False}, {'name': 'tile0.bmp', 'path': '/Users/name/game dat/tile0.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'tile1.bmp', 'path': '/Users/name/game dat/tile1.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'tile2.bmp', 'path': '/Users/name/game dat/tile2.bmp', 'size': [256, 256], 'isActive': False}, {'name': 'tile3.bmp', 'path': '/Users/name/game dat/tile3.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'Viewer Node', 'path': '', 'size': [256, 256], 'isActive': False}], 'requestId': 0, 'formattedMessage': True}
future success
update time
items to be removed 6
future done
update time
items to be removed 6
<PyQt5.QtWidgets.QAction object at 0x13dc4a0e0>
from blender to krita selected
future before
recived message {'type': 'GET_IMAGES', 'data': [{'name': 'Render Result', 'path': '', 'size': [0, 0], 'isActive': False}, {'name': 'tile0.bmp', 'path': '/Users/name/game dat/tile0.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'tile1.bmp', 'path': '/Users/name/game dat/tile1.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'tile2.bmp', 'path': '/Users/name/game dat/tile2.bmp', 'size': [256, 256], 'isActive': False}, {'name': 'tile3.bmp', 'path': '/Users/name/game dat/tile3.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'Viewer Node', 'path': '', 'size': [256, 256], 'isActive': False}], 'requestId': 1, 'formattedMessage': True}
[<KritaBlenderLink.connection.MessageListener object at 0x12c8183a0>, <KritaBlenderLink.connection.MessageListener object at 0x12c818a60>, <KritaBlenderLink.connection.MessageListener object at 0x12c818af0>, <KritaBlenderLink.connection.MessageListener object at 0x12c818e80>, <KritaBlenderLink.connection.MessageListener object at 0x13dc1f520>, <KritaBlenderLink.connection.MessageListener object at 0x13dc1f640>] {'type': 'GET_IMAGES', 'data': [{'name': 'Render Result', 'path': '', 'size': [0, 0], 'isActive': False}, {'name': 'tile0.bmp', 'path': '/Users/name/game dat/tile0.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'tile1.bmp', 'path': '/Users/name/game dat/tile1.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'tile2.bmp', 'path': '/Users/name/game dat/tile2.bmp', 'size': [256, 256], 'isActive': False}, {'name': 'tile3.bmp', 'path': '/Users/name/game dat/tile3.bmp', 'size': [1024, 1024], 'isActive': False}, {'name': 'Viewer Node', 'path': '', 'size': [256, 256], 'isActive': False}], 'requestId': 1, 'formattedMessage': True}
future success
future done
1024 1024 1 4194304
future before
[<KritaBlenderLink.connection.MessageListener object at 0x12c8183a0>, <KritaBlenderLink.connection.MessageListener object at 0x12c818a60>, <KritaBlenderLink.connection.MessageListener object at 0x12c818af0>, <KritaBlenderLink.connection.MessageListener object at 0x12c818e80>, <KritaBlenderLink.connection.MessageListener object at 0x13dc1f520>, <KritaBlenderLink.connection.MessageListener object at 0x13dc1f6a0>] {'type': 'IMAGE_TO_LAYER', 'data': '', 'imageData': '', 'requestId': 2, 'formattedMessage': True}
future success
future done
update time
items to be removed 6
krita: Unknown option 'c'.
<PyQt5.QtWidgets.QAction object at 0x13dc48d30>
link selected
[1024, 1024] memsize 4194304 4 8 {'name': 'tile0.bmp', 'path': '/Users/name/game dat/tile0.bmp', 'size': [1024, 1024], 'isActive': False} <PyKrita.krita.Document object at 0x13dc48af0>
resizing
unlink
file exists, trying another way
Blender's terminal output (click to show):
Read prefs: "/Users/name/Library/Application Support/Blender/4.0/config/userpref.blend"
Warning: '_PT_BlenderKritaLinkPanel' does not contain '_PT_' with prefix and suffix
UPDATING MESSAGE:  listening
UPDATING MESSAGE:  listening
UPDATING MESSAGE:  connected
connection accepted
UPDATING MESSAGE:  connected
{'type': 'GET_IMAGES', 'requestId': 0}
message is object UwU
{'type': 'GET_IMAGES', 'requestId': 0}
message sent
{'data': '', 'type': 'GET_IMAGES', 'requestId': 1}
message is object UwU
{'data': '', 'type': 'GET_IMAGES', 'requestId': 1}
message sent
{'data': {'image': {'name': 'tile0.bmp', 'path': '/Users/name/game dat/tile0.bmp', 'size': [1024, 1024], 'isActive': False}, 'depth': 'U8'}, 'type': 'IMAGE_TO_LAYER', 'requestId': 2}
message is object UwU
OMG krita requests blender image
{'depth': 'U8',
 'image': {'isActive': False,
           'name': 'tile0.bmp',
           'path': '/Users/name/game '
                   'dat/tile0.bmp',
           'size': [1024, 1024]}}
siema z powodzeniem pobrano rzeczy
depth:  1 len 4194304
4194304 1 4194304 1024 1048576
mem created
EOFError()
UPDATING MESSAGE:  listening

I hadn’t thought to check Blender’s output. Seems it hit some kind of EOF.

1 Like

new release, added some big qol changes

macos support is still in shambles but I am planning to use vm to investigate it.

8 Likes

I love this little plugin and have only gotten to take it for a whirl a little bit. But, This is what I have been wanting for years. Im so excited.

I was wondering if it is possible to have layers or groups of layers (in krita) represent maps? I saw we can open textures as a new layer and I fiddled around with trying to link a roughness map and an albedo in a single document on separate layers, it didn’t work out well. I didn’t know if this is possible and im just not doing it right or what. It’d be really nice to be able to keep all texture maps in 1 kra doc. But i understand if that isnt possible. Just in case here is what i mean.

1 Krita Doc

  • Layer group named (Albedo) - Linked to blender map called “Albedo”

    • layer
    • layer
  • Layer group named (Roughness) - Linked to blender texture called “Roughness”

    • layer
    • layer
  • Layer named (AO) - Linked to blender map called “AO”

Why is this easier? Say I draw a crack in an albedo map on a separate layer, and that crack is supposed to be shiny. I can duplicate that layer put it in my roughness group and then alter that layer. and I can be positive that the textures like up perfectly. Just a thought. Don’t know if it possible or already possible.

One other thing I was struggling with, I dont know if its a me thing, or if it is a limitation of the script.
If i link a texture to krita then draw on it, then alter the texture via texture paint in blender (because sometimes its easier to mark a spot on a model rather than struggle to find it in the UV). I feel like I had a difficult time getting that alteration back to krita.

I feel like there was one other thing, but my brain has brained and gone MIA. :rofl:

2 Likes

I now remember my missing thought. It’d be cool if we could save the UVs either as a layer or as specified sets? Since the UVs in krita only shows what faces are currently selected.

1 Like

Thank you for feedback, I am really glad that someone found this plugin useful.

So, no you can’t link groups or single layers, you can link only whole document and only one at a time. I will try to get workflow like that to work in next update as it might be useful.

yes this plugin is not the best when it comes to bidirectional editting workflow(blender can export only whole texture), it works as long as you are editting stuff on one layer and is harder when u have multiple. It might be better with features you are proposing

As for uvs you can always export them to an image in blender, but I will explore exporting them as new layer to krita, it might be really useful, uv sets are also pretty interesting idea.

Very useful plugin, thanks for your work. He will help me a lot in my work.
I would like to add a wish for future versions, or maybe when I get to know python and creating plugins for the mole a little better, I will implement it myself as an extension for your plugin.
The parameter that will be responsible for indents when choosing UV islands is missing. So-called Padding.
Texturing without this option will cause more trouble.
I think this can be implemented as an addition to your code by creating an additional slider next to your selection button. It will specify in pixels the extension of the selection that will be referenced Krita - Selected - Grow selection. And growing selection after your button selected

If you mean adding additional margin to create smaller or bigger selection, It can definitely be done with some modification to c++ code in plugin as I use it for creating selections.
It may be possible to be accomplished using python. Altough I am planning to just create a tool for selecting UVs kinda like in blender with all the faces selectable using rectangular selection in ui. and I might add some padding to the tool options. And as you said the selection is created so growing it is like pressing 3-4 buttons(krita>selected>grow).

As for contributing to the project you can always submit Pull Request to the main project on github.

Also the code for creating selections is not really good and the implementation is pretty naive, right now it just selects all faces individually. If someone could help me out to optimize selecting uvs in that c++ part I would be very grateful

details of c++ plugin face selection optimalization

the problem is I am sending all faces and selecting them in krita, I think it would be nice to preprocess the data and send only the border of the selection, but it would involve some kind of flood fill to process all faces and create a nice selection outline that preserves all holes in the island. Also the problem is that the uvs can overlap. But it would definitely helpful to speed up the selection of 6k+ of faces in an island.
some code reference if someone is interested to help

krita handle blender uvs

blender get uv island data

selecting uv faces

old branch with some optimizations, maybe not the best tho

I don’t know much about programming, but based on logic, I can suggest this. Blender has a function in the menu of the UV editor - UV - Export UV Layout. It allows you to export the selected polygons as an image and uses an alpha channel, choosing 100% fill from the image will work better, also here you can specify the size of the image according to the texture. This image can then be imported into Krita. After right clicking on the imported blender image I chose Select_Opaque (Replace) and this created a new selection mask. Perhaps this will push you to work more thoughtfully with masks.

Also, to optimize image rendering, you can add a canvas cropping feature based on the image before importing it into Krita. I think I’ve heard of a Python library that helps work with images

new release, now linking is possible on layer/layergroups and you can link to multiple images, also you can export selected uvs to new layer now

6 Likes

Thank you so much for creating this, its incredibly usefull!
Just jumping into Krita, touching up textures and sending them to Blender with one click is godsend!

Only feedback i have is “Send on draw” likes to crash blender or Krita (mostly krita i think) if both programs are on and I’m working in Blender (not necesarry editing texture).
I keep it off and no crashes! Live draw is cool but manual Send Linked doesn’t bother me at all :slight_smile:

Some of my work I used your plugin on:
Most of this model was painted in blender with basic brush but now I can jump to Krita and add some more textury brushes.


Adding and touching up photo textures is so fast now. No saving and loading files <3

Thank you again!

5 Likes