-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path__init__.py
More file actions
127 lines (82 loc) · 2.95 KB
/
__init__.py
File metadata and controls
127 lines (82 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""
KiRender - KiCad 3D PCB Renderer Plugin
A KiCad Action Plugin for creating 3D animations, static images,
and SVG exports from PCB designs.
Author: PCBTools
Website: https://pcbtools.xyz
Version: 1.3.0
License: MIT
"""
import os
import sys
import atexit
import pcbnew
import wx # Required for window management
# --- DEPENDENCY LINKING START ---
# Add the current plugin directory to sys.path.
PLUGIN_DIR = os.path.dirname(os.path.abspath(__file__))
if PLUGIN_DIR not in sys.path:
sys.path.append(PLUGIN_DIR)
# Attempt to link pcbschema (optional dependency)
try:
import pcbschema
HAS_PCBSCHEMA = True
except ImportError:
HAS_PCBSCHEMA = False
pcbschema = None
# --- DEPENDENCY LINKING END ---
__version__ = "1.3.0"
__all__ = ['KiRenderPlugin']
# Singleton reference for dialog
_dialog_instance = None
def _cleanup_on_exit():
"""Cleanup function called when Python interpreter exits (KiCad closing)."""
global _dialog_instance
if _dialog_instance is not None:
try:
_dialog_instance.Destroy()
except:
pass
_dialog_instance = None
# Register cleanup to run when KiCad/Python exits
atexit.register(_cleanup_on_exit)
class KiRenderPlugin(pcbnew.ActionPlugin):
"""KiRender Action Plugin for KiCad."""
def defaults(self):
self.name = "KiRender"
self.category = "Render"
self.description = "Generate 3D animations, static renders, and SVG exports"
self.show_toolbar_button = True
icon_path = os.path.join(PLUGIN_DIR, "icon.png")
if os.path.exists(icon_path):
self.icon_file_name = icon_path
def Run(self):
global _dialog_instance
board = pcbnew.GetBoard()
if not board or not board.GetFileName():
wx.MessageBox(
"No PCB loaded. Please open a PCB file first.",
"KiRender - Error",
wx.OK | wx.ICON_ERROR
)
return
# If dialog exists and is still valid, bring it to front
if _dialog_instance is not None:
try:
if _dialog_instance.IsIconized():
_dialog_instance.Iconize(False)
_dialog_instance.Raise()
_dialog_instance.SetFocus()
return
except RuntimeError:
# Dialog was destroyed but reference remained
_dialog_instance = None
# Import dialog module (lazy import for faster plugin list load)
from .dialog import RenderDialog
# Get the main KiCad window as parent
parent = wx.GetTopLevelWindows()[0] if wx.GetTopLevelWindows() else None
# Create new dialog instance, passing pcbschema if available
_dialog_instance = RenderDialog(parent, schema_lib=pcbschema if HAS_PCBSCHEMA else None)
_dialog_instance.Show()
# Register the plugin
KiRenderPlugin().register()