├── .gitattributes
├── .gitignore
├── MarkDown
├── Logo.png
├── Gif
│ ├── Create.gif
│ ├── AddInstance.gif
│ └── MarkProject.gif
└── Img
│ ├── Install.png
│ └── AddonFolder.png
├── src
└── main
│ ├── resources
│ ├── services
│ │ └── dic
│ │ │ └── blender.dic
│ ├── Python
│ │ ├── Templates
│ │ │ ├── new_operator.py
│ │ │ ├── new_panel.py
│ │ │ └── new_addon.py
│ │ ├── Python.iml
│ │ └── pycharm_connector.py
│ ├── inspectionDescriptions
│ │ ├── OperatorErrId.html
│ │ └── PanelWarnId.html
│ ├── locale
│ │ └── BlendCharm.properties
│ ├── icons
│ │ ├── blender_logo_gray.svg
│ │ ├── blender_logo_gray_big.svg
│ │ ├── blender_logo.svg
│ │ ├── addon_folder.svg
│ │ └── addon_src_folder.svg
│ └── META-INF
│ │ ├── plugin.xml
│ │ └── pluginIcon.svg
│ └── java
│ ├── plugin_settings
│ └── PluginSettings.java
│ ├── services
│ ├── BlenderDic.java
│ ├── BlendCharmPersistentData.java
│ ├── BlendCharmRepositoryIconManager.java
│ ├── inspections
│ │ ├── OperatorErrId.java
│ │ ├── base
│ │ │ └── OperatorIdInspection.java
│ │ └── PanelWarnId.java
│ └── BlenderConsoleFilter.java
│ ├── util
│ ├── MyInputStreamHelper.java
│ ├── MyVirtualFileHelper.java
│ ├── core
│ │ ├── MyFileUtils.java
│ │ └── socket
│ │ │ ├── server
│ │ │ └── MyServerSocket.java
│ │ │ └── MySocketConnection.java
│ ├── MySwingUtil.java
│ └── MyProjectHolder.java
│ ├── ui
│ ├── dialogs
│ │ ├── debug_popup
│ │ │ ├── DebugPopup.java
│ │ │ ├── DebugPopupWrapper.java
│ │ │ └── DebugPopup.form
│ │ ├── remove_blender_instance
│ │ │ ├── RemoveBlenderInstance.java
│ │ │ ├── RemoveBlenderInstanceWrapper.java
│ │ │ └── RemoveBlenderInstance.form
│ │ ├── new_blender_panel
│ │ │ ├── NewBlenderPanelWrapper.java
│ │ │ ├── NewBlenderPanel.java
│ │ │ └── NewBlenderPanel.form
│ │ ├── new_blender_addon
│ │ │ ├── NewBlenderAddonWrapper.java
│ │ │ ├── NewBlenderAddon.java
│ │ │ └── NewBlenderAddon.form
│ │ ├── new_blender_operator
│ │ │ ├── NewBlenderOperatorWrapper.java
│ │ │ ├── NewBlenderOperator.java
│ │ │ └── NewBlenderOperator.form
│ │ └── add_blender_instance
│ │ │ ├── AddBlenderInstanceWrapper.java
│ │ │ ├── AddBlenderInstance.java
│ │ │ └── AddBlenderInstance.form
│ └── tool_window
│ │ ├── BlenderToolWindowFactory.java
│ │ ├── BlenderToolWindow.form
│ │ └── BlenderToolWindow.java
│ ├── data
│ ├── BlenderToolWindowUtils.java
│ ├── BlenderInstance.java
│ ├── RunningBlenderProcessRenderer.java
│ ├── CommunicationData.java
│ ├── BlenderExeFileChooserDescriptor.java
│ ├── RunningBlenderProcess.java
│ └── VirtualBlenderFile.java
│ ├── settings
│ ├── BlenderSettingsData.java
│ ├── BlenderSettingsRaw.java
│ ├── Config.java
│ └── BlenderSettings.java
│ ├── icons
│ └── BlendCharmIcons.java
│ └── actions
│ ├── MarkAsAddonProjectAction.java
│ ├── UnmarkAsAddonProjectAction.java
│ ├── MarkAsAddonAction.java
│ ├── UnmarkAsAddonAction.java
│ ├── CreateNewBlenderOperatorAction.java
│ ├── CreateNewBlenderPanelAction.java
│ ├── DynamicActionGroup.java
│ └── CreateNewBlenderAddonAction.java
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── settings.gradle.kts
├── gradle.properties
├── changelog.md
├── LICENSE
├── update-urls
├── community-edition
│ └── updatePlugins.xml
└── professional-edition
│ └── updatePlugins.xml
├── gradlew.bat
├── README.md
└── gradlew
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | data/*
2 | build/*
3 | .idea/*
4 | .gradle/*
5 | MarkDown/.src/*
6 | .intellijPlatform
7 |
--------------------------------------------------------------------------------
/MarkDown/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlackStartx/PyCharm-Blender-Plugin/HEAD/MarkDown/Logo.png
--------------------------------------------------------------------------------
/src/main/resources/services/dic/blender.dic:
--------------------------------------------------------------------------------
1 | # Blender Common Keywords
2 | idname
3 |
4 | # Names
5 | BlackStartx
--------------------------------------------------------------------------------
/MarkDown/Gif/Create.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlackStartx/PyCharm-Blender-Plugin/HEAD/MarkDown/Gif/Create.gif
--------------------------------------------------------------------------------
/MarkDown/Img/Install.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlackStartx/PyCharm-Blender-Plugin/HEAD/MarkDown/Img/Install.png
--------------------------------------------------------------------------------
/MarkDown/Gif/AddInstance.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlackStartx/PyCharm-Blender-Plugin/HEAD/MarkDown/Gif/AddInstance.gif
--------------------------------------------------------------------------------
/MarkDown/Gif/MarkProject.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlackStartx/PyCharm-Blender-Plugin/HEAD/MarkDown/Gif/MarkProject.gif
--------------------------------------------------------------------------------
/MarkDown/Img/AddonFolder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlackStartx/PyCharm-Blender-Plugin/HEAD/MarkDown/Img/AddonFolder.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BlackStartx/PyCharm-Blender-Plugin/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | mavenCentral()
4 | gradlePluginPortal()
5 | }
6 | }
7 |
8 | rootProject.name = "Blend-Charm"
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/src/main/resources/Python/Templates/new_operator.py:
--------------------------------------------------------------------------------
1 | import bpy
2 |
3 |
4 | class OPERATOR_CLASS_NAME(bpy.types.Operator):
5 | bl_idname = "$ID_NAME$"
6 | bl_label = "$LABEL$"
7 |
8 | def execute(self, context):
9 | return {'FINISHED'}
10 |
--------------------------------------------------------------------------------
/src/main/java/plugin_settings/PluginSettings.java:
--------------------------------------------------------------------------------
1 | package plugin_settings;
2 |
3 | public class PluginSettings {
4 | public static final boolean isCommunity = false;
5 |
6 | public static String getStripeVersion() {
7 | return isCommunity ? "Community Edition" : "Professional Edition";
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/services/BlenderDic.java:
--------------------------------------------------------------------------------
1 | package services;
2 |
3 | import com.intellij.spellchecker.BundledDictionaryProvider;
4 |
5 | public class BlenderDic implements BundledDictionaryProvider {
6 | @Override
7 | public String[] getBundledDictionaries() {
8 | return new String[]{"dic/blender.dic"};
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/resources/Python/Templates/new_panel.py:
--------------------------------------------------------------------------------
1 | import bpy
2 |
3 |
4 | class PANEL_CLASS_NAME(bpy.types.Panel):
5 | bl_idname = "$ID_NAME$"
6 | bl_label = "$LABEL$"
7 | bl_category = "$CATEGORY$"
8 | bl_space_type = "$SPACE_TYPE$"
9 | bl_region_type = "$REGION_TYPE$"
10 |
11 | def draw(self, context):
12 | pass
13 |
--------------------------------------------------------------------------------
/src/main/java/util/MyInputStreamHelper.java:
--------------------------------------------------------------------------------
1 | package util;
2 |
3 | import java.io.InputStream;
4 | import java.util.Scanner;
5 |
6 | public class MyInputStreamHelper {
7 |
8 | public static String readString(InputStream stream) {
9 | Scanner s = new Scanner(stream).useDelimiter("\\A");
10 | return s.hasNext() ? s.next() : "";
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/ui/dialogs/debug_popup/DebugPopup.java:
--------------------------------------------------------------------------------
1 | package ui.dialogs.debug_popup;
2 |
3 | import javax.swing.*;
4 |
5 | public class DebugPopup extends JDialog {
6 |
7 | private JPanel contentPane;
8 |
9 | public DebugPopup() {
10 | setContentPane(contentPane);
11 | }
12 |
13 | JComponent getJComponent() {
14 | return contentPane;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib
2 | kotlin.stdlib.default.dependency=false
3 | # Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html
4 | org.gradle.configuration-cache=true
5 | # Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html
6 | org.gradle.caching=true
--------------------------------------------------------------------------------
/src/main/java/data/BlenderToolWindowUtils.java:
--------------------------------------------------------------------------------
1 | package data;
2 |
3 | import com.intellij.openapi.application.PathManager;
4 |
5 | import java.io.File;
6 |
7 | public class BlenderToolWindowUtils {
8 | public static File getEggFile() {
9 | String ide = PathManager.getHomePath();
10 | return new File(ide + File.separator + "debug-eggs" + File.separator + "pydevd-pycharm.egg");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/resources/Python/Templates/new_addon.py:
--------------------------------------------------------------------------------
1 | import bpy
2 |
3 | bl_info = {
4 | "name": "$ADDON_NAME$",
5 | "author": "$ADDON_AUTHOR$",
6 | "description": "$ADDON_DESCRIPTION$",
7 | "blender": (2, 80, 0),
8 | "location": "View3D",
9 | "warning": "",
10 | "category": "Generic"
11 | }
12 |
13 | classes = (
14 | )
15 |
16 | register, unregister = bpy.utils.register_classes_factory(classes)
17 |
--------------------------------------------------------------------------------
/src/main/java/ui/dialogs/remove_blender_instance/RemoveBlenderInstance.java:
--------------------------------------------------------------------------------
1 | package ui.dialogs.remove_blender_instance;
2 |
3 | import javax.swing.*;
4 |
5 | public class RemoveBlenderInstance extends JDialog {
6 |
7 | private JPanel contentPane;
8 |
9 | public RemoveBlenderInstance() {
10 | setContentPane(contentPane);
11 | }
12 |
13 | JComponent getJComponent() {
14 | return contentPane;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/resources/inspectionDescriptions/OperatorErrId.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Addons operator IDs must be lowercase.
5 | The following error rise otherwise:
6 |
7 | Error: Registering operator class: '{CLASS}', invalid bl_idname '{ID}'.
8 |
9 |
10 | Powered by: Blend-Charm plugin
11 |
12 |
--------------------------------------------------------------------------------
/src/main/java/settings/BlenderSettingsData.java:
--------------------------------------------------------------------------------
1 | package settings;
2 |
3 | import data.BlenderInstance;
4 |
5 | import javax.xml.bind.annotation.XmlElement;
6 | import java.util.ArrayList;
7 |
8 | public class BlenderSettingsData {
9 | @XmlElement(name = "showVerbose")
10 | public boolean showVerbose;
11 |
12 | @XmlElement(name = "blenderPath")
13 | public ArrayList blenderPaths;
14 |
15 | @XmlElement(name = "blenderAddonNames")
16 | public ArrayList blenderAddOnNames;
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/util/MyVirtualFileHelper.java:
--------------------------------------------------------------------------------
1 | package util;
2 |
3 | import com.intellij.openapi.vfs.VirtualFile;
4 |
5 | import java.util.Objects;
6 |
7 | public class MyVirtualFileHelper {
8 | public static VirtualFile getProjectFirstVirtualFile(MyProjectHolder project, VirtualFile virtualFile) {
9 | try {
10 | return project.projectVirtualFile.findChild(virtualFile.getPath().substring(Objects.requireNonNull(project.getBasePath()).length()).split("/", 1)[0].split("/", 3)[1]);
11 | } catch (Exception e) {
12 | return null;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/icons/BlendCharmIcons.java:
--------------------------------------------------------------------------------
1 | package icons;
2 |
3 | import com.intellij.openapi.util.IconLoader;
4 |
5 | import javax.swing.*;
6 |
7 | public interface BlendCharmIcons {
8 | Icon BLENDER_LOGO = IconLoader.findIcon("/icons/blender_logo_gray.svg", BlendCharmIcons.class);
9 | Icon BLENDER_LOGO_BIG = IconLoader.findIcon("/icons/blender_logo_gray_big.svg", BlendCharmIcons.class);
10 | Icon BLENDER_FOLDER_ICON = IconLoader.findIcon("/icons/addon_folder.svg", BlendCharmIcons.class);
11 | Icon BLENDER_SRC_FOLDER_ICON = IconLoader.findIcon("/icons/addon_src_folder.svg", BlendCharmIcons.class);
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/resources/Python/Python.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/main/java/ui/dialogs/remove_blender_instance/RemoveBlenderInstanceWrapper.java:
--------------------------------------------------------------------------------
1 | package ui.dialogs.remove_blender_instance;
2 |
3 | import com.intellij.openapi.ui.DialogWrapper;
4 | import org.jetbrains.annotations.Nullable;
5 |
6 | import javax.swing.*;
7 |
8 | public class RemoveBlenderInstanceWrapper extends DialogWrapper {
9 |
10 | public RemoveBlenderInstance form;
11 |
12 | public RemoveBlenderInstanceWrapper() {
13 | super(true);
14 | init();
15 | setTitle("Remove Blender Instance");
16 | }
17 |
18 | @Override
19 | protected @Nullable JComponent createCenterPanel() {
20 | form = new RemoveBlenderInstance();
21 | return form.getJComponent();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/ui/dialogs/debug_popup/DebugPopupWrapper.java:
--------------------------------------------------------------------------------
1 | package ui.dialogs.debug_popup;
2 |
3 | import com.intellij.openapi.ui.DialogWrapper;
4 | import org.jetbrains.annotations.NotNull;
5 | import org.jetbrains.annotations.Nullable;
6 |
7 | import javax.swing.*;
8 |
9 | public class DebugPopupWrapper extends DialogWrapper {
10 |
11 | public DebugPopup form;
12 |
13 | public DebugPopupWrapper() {
14 | super(true);
15 | setTitle("New Debug Information");
16 | init();
17 | }
18 |
19 | @Override
20 | protected Action @NotNull [] createActions() {
21 | return new Action[]{this.getOKAction()};
22 | }
23 |
24 | @Override
25 | protected @Nullable JComponent createCenterPanel() {
26 | form = new DebugPopup();
27 | return form.getJComponent();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | Changelog
2 | v2023.2
3 |
4 | - [Platform Update] PyCharm 2023.2 Compatibility.
5 | - [Run Configuration] Settings: You can now edit and change your Blender Run Configuration settings!
6 | - [Run Configuration] Environment: You can now set independent environment variables between your configurations!
7 |
8 | v2023.1
9 |
10 | - [Platform Update] PyCharm 2023.1 Compatibility.
11 | - [Enhancement] Icons are now SVG instead of PNG.
12 | - [Enhancement] Support for styled icons.
13 | - [FIX] Fixed debug breakpoint opening the external version of the file.
14 |
15 | v2022.3
16 |
17 | - [Platform Update] PyCharm 2022.3 Compatibility.
18 |
--------------------------------------------------------------------------------
/src/main/java/ui/dialogs/new_blender_panel/NewBlenderPanelWrapper.java:
--------------------------------------------------------------------------------
1 | package ui.dialogs.new_blender_panel;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.ui.DialogWrapper;
5 | import org.jetbrains.annotations.NotNull;
6 | import org.jetbrains.annotations.Nullable;
7 |
8 | import javax.swing.*;
9 |
10 | public class NewBlenderPanelWrapper extends DialogWrapper {
11 |
12 | private final Project project;
13 | public NewBlenderPanel form;
14 |
15 | public NewBlenderPanelWrapper(@NotNull Project project) {
16 | super(true);
17 | this.project = project;
18 | init();
19 | setTitle("Create New Blender Panel");
20 | }
21 |
22 | @Override
23 | protected @Nullable JComponent createCenterPanel() {
24 | form = new NewBlenderPanel(project);
25 | return form.getJComponent();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/ui/dialogs/new_blender_addon/NewBlenderAddonWrapper.java:
--------------------------------------------------------------------------------
1 | package ui.dialogs.new_blender_addon;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.ui.DialogWrapper;
5 | import org.jetbrains.annotations.NotNull;
6 | import org.jetbrains.annotations.Nullable;
7 |
8 | import javax.swing.*;
9 |
10 | public class NewBlenderAddonWrapper extends DialogWrapper {
11 |
12 | private final Project project;
13 | public NewBlenderAddon form;
14 |
15 | public NewBlenderAddonWrapper(@NotNull Project project) {
16 | super(true);
17 | this.project = project;
18 | init();
19 | setTitle("Create New Blender Addon");
20 | }
21 |
22 | @Override
23 | protected @Nullable JComponent createCenterPanel() {
24 | form = new NewBlenderAddon(project, myOKAction);
25 | return form.getJComponent();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/ui/dialogs/new_blender_operator/NewBlenderOperatorWrapper.java:
--------------------------------------------------------------------------------
1 | package ui.dialogs.new_blender_operator;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.intellij.openapi.ui.DialogWrapper;
5 | import org.jetbrains.annotations.NotNull;
6 | import org.jetbrains.annotations.Nullable;
7 |
8 | import javax.swing.*;
9 |
10 | public class NewBlenderOperatorWrapper extends DialogWrapper {
11 |
12 | private final Project project;
13 | public NewBlenderOperator form;
14 |
15 | public NewBlenderOperatorWrapper(@NotNull Project project) {
16 | super(true);
17 | this.project = project;
18 | init();
19 | setTitle("Create New Blender Operator");
20 | }
21 |
22 | @Override
23 | protected @Nullable JComponent createCenterPanel() {
24 | form = new NewBlenderOperator(project);
25 | return form.getJComponent();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/resources/locale/BlendCharm.properties:
--------------------------------------------------------------------------------
1 | addBlenderInstance.extraSettings=Extra Settings
2 | addBlenderInstance.environmentVariables=Environment Variables
3 | addBlenderInstance.name=Name
4 | addBlenderInstance.path=Path
5 | newBlenderAddon.description=Description:
6 | newBlenderAddon.author=Author:
7 | newBlenderAddon.name=Name:
8 | newBlenderOperator.label=Label:
9 | newBlenderOperator.idName=ID Name
10 | newBlenderPanel.label=Label:
11 | newBlenderPanel.category=Category:
12 | newBlenderPanel.region=&Region:
13 | newBlenderPanel.space=&Space:
14 | removeBlenderInstance.removeBlenderInstance=Remove Blender instance?
15 | blenderToolWindow.blenderInstances=&Blender Instances:
16 | blenderToolWindow.noBlenderInstanceRunning=No Blender Instance Running...
17 | debugPopup.title=The debug session has been terminated due to newer information.
18 | debugPopup.description=This is totally normal on first executions, please restart the debug mode.
--------------------------------------------------------------------------------
/src/main/java/data/BlenderInstance.java:
--------------------------------------------------------------------------------
1 | package data;
2 |
3 | import javax.xml.bind.annotation.XmlElement;
4 | import java.util.Map;
5 |
6 | public class BlenderInstance {
7 | @XmlElement(name = "path")
8 | public String path;
9 | @XmlElement(name = "name")
10 | public String name;
11 | @XmlElement(name = "addonPath")
12 | public String addonPath;
13 | @XmlElement(name = "environment")
14 | public Map environment;
15 |
16 | @SuppressWarnings("unused")
17 | public BlenderInstance() {
18 | }
19 |
20 | public BlenderInstance(String path, String name, Map environment) {
21 | this.path = path;
22 | this.name = name;
23 | this.environment = environment;
24 | }
25 |
26 | public String getAddonPath() {
27 | return addonPath == null ? null : addonPath.toLowerCase();
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return name;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/data/RunningBlenderProcessRenderer.java:
--------------------------------------------------------------------------------
1 | package data;
2 |
3 | import com.intellij.icons.AllIcons;
4 |
5 | import javax.swing.*;
6 | import java.awt.*;
7 |
8 | public class RunningBlenderProcessRenderer extends DefaultListCellRenderer implements ListCellRenderer