2021-03-12 04:17:19 +00:00
|
|
|
# Authors: see git history
|
|
|
|
#
|
|
|
|
# Copyright (c) 2010 Authors
|
|
|
|
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
2023-12-17 22:03:39 +00:00
|
|
|
|
2018-10-24 00:08:46 +00:00
|
|
|
import os
|
2018-04-29 01:26:53 +00:00
|
|
|
import sys
|
2024-01-05 16:05:22 +00:00
|
|
|
from pathlib import Path # to work with paths as objects
|
|
|
|
import configparser # to read DEBUG.ini
|
2024-01-13 14:42:49 +00:00
|
|
|
from argparse import ArgumentParser # to parse arguments and remove --extension
|
2024-01-05 16:05:22 +00:00
|
|
|
|
2024-01-13 14:42:49 +00:00
|
|
|
import lib.debug_utils as debug_utils
|
2023-12-17 22:03:39 +00:00
|
|
|
|
|
|
|
SCRIPTDIR = Path(__file__).parent.absolute()
|
|
|
|
|
2024-01-05 16:05:22 +00:00
|
|
|
running_as_frozen = getattr(sys, 'frozen', None) is not None # check if running from pyinstaller bundle
|
|
|
|
|
2023-12-17 22:03:39 +00:00
|
|
|
if len(sys.argv) < 2:
|
2023-12-29 15:25:17 +00:00
|
|
|
# no arguments - prevent accidentally running this script
|
2024-01-13 14:42:49 +00:00
|
|
|
msg = "No arguments given, exiting!" # without gettext localization see _()
|
|
|
|
if running_as_frozen: # we show dialog only when running from pyinstaller bundle - using wx
|
2024-01-05 16:05:22 +00:00
|
|
|
try:
|
|
|
|
import wx
|
|
|
|
app = wx.App()
|
|
|
|
dlg = wx.MessageDialog(None, msg, "Inkstitch", wx.OK | wx.ICON_ERROR)
|
|
|
|
dlg.ShowModal()
|
|
|
|
dlg.Destroy()
|
|
|
|
except ImportError:
|
|
|
|
print(msg)
|
|
|
|
else:
|
|
|
|
print(msg)
|
|
|
|
exit(1)
|
2023-12-25 18:54:52 +00:00
|
|
|
|
2023-12-29 15:25:17 +00:00
|
|
|
ini = configparser.ConfigParser()
|
2024-01-05 16:05:22 +00:00
|
|
|
ini.read(SCRIPTDIR / "DEBUG.ini") # read DEBUG.ini file if exists
|
2023-12-29 15:25:17 +00:00
|
|
|
|
|
|
|
# check if running from inkscape, given by environment variable
|
|
|
|
if os.environ.get('INKSTITCH_OFFLINE_SCRIPT', '').lower() in ['true', '1', 'yes', 'y']:
|
|
|
|
running_from_inkscape = False
|
|
|
|
else:
|
|
|
|
running_from_inkscape = True
|
2023-12-17 22:03:39 +00:00
|
|
|
|
|
|
|
debug_active = bool((gettrace := getattr(sys, 'gettrace')) and gettrace()) # check if debugger is active on startup
|
|
|
|
debug_type = 'none'
|
2024-01-11 13:19:16 +00:00
|
|
|
profiler_type = 'none'
|
2023-12-17 22:03:39 +00:00
|
|
|
|
2024-01-13 14:42:49 +00:00
|
|
|
if not running_as_frozen: # debugging/profiling only in development mode
|
2023-12-29 15:25:17 +00:00
|
|
|
# specify debugger type
|
2024-01-13 14:42:49 +00:00
|
|
|
# but if script was already started from debugger then don't read debug type from ini file or cmd line
|
2023-12-29 15:25:17 +00:00
|
|
|
if not debug_active:
|
2024-01-13 14:42:49 +00:00
|
|
|
debug_type = debug_utils.resole_debug_type(ini) # read debug type from ini file or cmd line
|
2023-12-25 18:54:52 +00:00
|
|
|
|
2024-01-13 14:42:49 +00:00
|
|
|
profile_type = debug_utils.resole_profile_type(ini) # read profile type from ini file or cmd line
|
2023-12-25 18:54:52 +00:00
|
|
|
|
|
|
|
if running_from_inkscape:
|
2024-01-05 16:05:22 +00:00
|
|
|
# process creation of the Bash script - should be done before sys.path is modified, see below in prefere_pip_inkex
|
2024-01-13 14:42:49 +00:00
|
|
|
if ini.getboolean("DEBUG", "create_bash_script", fallback=False): # create script only if enabled in DEBUG.ini
|
2024-01-05 16:05:22 +00:00
|
|
|
debug_utils.write_offline_debug_script(SCRIPTDIR, ini)
|
2024-01-13 14:42:49 +00:00
|
|
|
|
2023-12-29 15:25:17 +00:00
|
|
|
# disable debugger when running from inkscape
|
2024-01-13 14:42:49 +00:00
|
|
|
disable_from_inkscape = ini.getboolean("DEBUG", "disable_from_inkscape", fallback=False)
|
2023-12-29 15:25:17 +00:00
|
|
|
if disable_from_inkscape:
|
2023-12-25 18:54:52 +00:00
|
|
|
debug_type = 'none' # do not start debugger when running from inkscape
|
|
|
|
|
2024-01-05 16:05:22 +00:00
|
|
|
# prefer pip installed inkex over inkscape bundled inkex, pip version is bundled with Inkstitch
|
|
|
|
# - must be be done before importing inkex
|
2024-01-13 14:42:49 +00:00
|
|
|
prefere_pip_inkex = ini.getboolean("LIBRARY", "prefer_pip_inkex", fallback=True)
|
2023-12-25 18:54:52 +00:00
|
|
|
if prefere_pip_inkex and 'PYTHONPATH' in os.environ:
|
2024-01-05 16:05:22 +00:00
|
|
|
debug_utils.reorder_sys_path()
|
|
|
|
|
|
|
|
# enabling of debug depends on value of debug_type in DEBUG.ini file
|
2023-12-17 22:03:39 +00:00
|
|
|
if debug_type != 'none':
|
2024-01-13 14:42:49 +00:00
|
|
|
from lib.debug import debug # import global variable debug - don't import whole module
|
2024-01-05 16:05:22 +00:00
|
|
|
debug.enable(debug_type, SCRIPTDIR, ini)
|
2023-12-17 22:03:39 +00:00
|
|
|
# check if debugger is really activated
|
|
|
|
debug_active = bool((gettrace := getattr(sys, 'gettrace')) and gettrace())
|
|
|
|
|
2024-01-05 16:05:22 +00:00
|
|
|
# warnings are used by some modules, we want to ignore them all in release
|
|
|
|
# - see warnings.warn()
|
2023-12-17 22:03:39 +00:00
|
|
|
if running_as_frozen or not debug_active:
|
2022-01-11 22:11:57 +00:00
|
|
|
import warnings
|
|
|
|
warnings.filterwarnings('ignore')
|
|
|
|
|
2024-01-11 16:48:11 +00:00
|
|
|
# TODO - check if this is still needed for shapely, apparently shapely now uses only exceptions instead of io.
|
|
|
|
# all logs were removed from version 2.0.0 and above
|
2024-01-05 16:05:22 +00:00
|
|
|
# ---- plan to remove this in future ----
|
2024-01-13 14:42:49 +00:00
|
|
|
# import logging # to set logger for shapely
|
|
|
|
# from io import StringIO # to store shapely errors
|
2024-01-05 16:05:22 +00:00
|
|
|
# set logger for shapely - for old versions of shapely
|
|
|
|
# logger = logging.getLogger('shapely.geos') # attach logger of shapely
|
|
|
|
# logger.setLevel(logging.DEBUG)
|
|
|
|
# shapely_errors = StringIO() # in memory file to store shapely errors
|
|
|
|
# ch = logging.StreamHandler(shapely_errors)
|
|
|
|
# ch.setLevel(logging.DEBUG)
|
|
|
|
# formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
|
|
|
|
# ch.setFormatter(formatter)
|
|
|
|
# logger.addHandler(ch)
|
|
|
|
# ---- plan to remove this in future ----
|
2018-11-15 01:23:06 +00:00
|
|
|
|
2023-12-17 22:03:39 +00:00
|
|
|
# pop '--extension' from arguments and generate extension class name from extension name
|
2024-01-05 16:05:22 +00:00
|
|
|
# example: --extension=params will instantiate Params() class from lib.extensions.
|
2024-01-13 14:42:49 +00:00
|
|
|
|
|
|
|
# we need to import only after possible modification of sys.path, we disable here flake8 E402
|
|
|
|
from lib import extensions # noqa: E402 # import all supported extensions of institch
|
|
|
|
|
2018-04-29 02:14:23 +00:00
|
|
|
parser = ArgumentParser()
|
|
|
|
parser.add_argument("--extension")
|
|
|
|
my_args, remaining_args = parser.parse_known_args()
|
2018-04-29 01:26:53 +00:00
|
|
|
|
2018-04-29 02:14:23 +00:00
|
|
|
extension_name = my_args.extension
|
2018-07-29 00:40:14 +00:00
|
|
|
|
|
|
|
# example: foo_bar_baz -> FooBarBaz
|
|
|
|
extension_class_name = extension_name.title().replace("_", "")
|
|
|
|
|
|
|
|
extension_class = getattr(extensions, extension_class_name)
|
2023-12-17 22:03:39 +00:00
|
|
|
extension = extension_class() # create instance of extension class - call __init__ method
|
|
|
|
|
2024-01-05 16:05:22 +00:00
|
|
|
# extension run(), we differentiate between debug and normal mode
|
|
|
|
# - in debug or profile mode we debug or profile extension.run() method
|
|
|
|
# - in normal mode we run extension.run() in try/except block to catch all exceptions and hide GTK spam
|
2024-01-11 13:19:16 +00:00
|
|
|
if debug_active or profiler_type != "none": # if debug or profile mode
|
|
|
|
if profiler_type == 'none': # only debugging
|
2023-12-17 22:03:39 +00:00
|
|
|
extension.run(args=remaining_args)
|
2024-01-05 16:05:22 +00:00
|
|
|
else: # do profiling
|
2024-01-11 13:19:16 +00:00
|
|
|
debug_utils.profile(profiler_type, SCRIPTDIR, ini, extension, remaining_args)
|
2022-06-30 17:22:33 +00:00
|
|
|
|
2023-12-17 22:03:39 +00:00
|
|
|
else: # if not debug nor profile mode
|
2024-01-13 14:42:49 +00:00
|
|
|
from lib.exceptions import InkstitchException, format_uncaught_exception
|
|
|
|
from inkex import errormsg # to show error message in inkscape
|
|
|
|
from lxml.etree import XMLSyntaxError # to catch XMLSyntaxError from inkex
|
|
|
|
from lib.i18n import _ # see gettext translation function _()
|
|
|
|
from lib.utils import restore_stderr, save_stderr # to hide GTK spam
|
|
|
|
|
|
|
|
save_stderr() # hide GTK spam
|
new extension: Auto-Route Satin Columns (#330)
**video demo:** https://www.youtube.com/watch?v=tbghtqziB1g
This branch adds a new extension, Auto-Route Satin Columns, implementing #214! This is a huge new feature that opens the door wide for exciting stuff like lettering (#142).
To use it, select some satin columns and run the extension. After a few seconds, it will replace your satins with a new set with a logical stitching order. Under-pathing and jump-stitches will be added as necessary, and satins will be broken to facilitate jumps. The resulting satins will retain all of the parameters you had set on the original satins, including underlay, zig-zag spacing, etc.
By default, it will choose the left-most extreme as the starting point and the right-most extreme as the ending point (even if these occur partway through a satin such as the left edge of a letter "o"). You can override this by attaching the new "Auto-route satin stitch starting/ending position" commands.
There's also an option to add trims instead of jump stitches. Any jump stitch over 1mm is trimmed. I might make this configurable in the future but in my tests it seems to do a good job. Trim commands are added to the SVG, so it's easy enough to modify/delete as you see fit.
2018-10-30 23:43:21 +00:00
|
|
|
exception = None
|
|
|
|
try:
|
2021-03-04 17:40:53 +00:00
|
|
|
extension.run(args=remaining_args)
|
new extension: Auto-Route Satin Columns (#330)
**video demo:** https://www.youtube.com/watch?v=tbghtqziB1g
This branch adds a new extension, Auto-Route Satin Columns, implementing #214! This is a huge new feature that opens the door wide for exciting stuff like lettering (#142).
To use it, select some satin columns and run the extension. After a few seconds, it will replace your satins with a new set with a logical stitching order. Under-pathing and jump-stitches will be added as necessary, and satins will be broken to facilitate jumps. The resulting satins will retain all of the parameters you had set on the original satins, including underlay, zig-zag spacing, etc.
By default, it will choose the left-most extreme as the starting point and the right-most extreme as the ending point (even if these occur partway through a satin such as the left edge of a letter "o"). You can override this by attaching the new "Auto-route satin stitch starting/ending position" commands.
There's also an option to add trims instead of jump stitches. Any jump stitch over 1mm is trimmed. I might make this configurable in the future but in my tests it seems to do a good job. Trim commands are added to the SVG, so it's easy enough to modify/delete as you see fit.
2018-10-30 23:43:21 +00:00
|
|
|
except (SystemExit, KeyboardInterrupt):
|
|
|
|
raise
|
2021-03-04 17:40:53 +00:00
|
|
|
except XMLSyntaxError:
|
|
|
|
msg = _("Ink/Stitch cannot read your SVG file. "
|
|
|
|
"This is often the case when you use a file which has been created with Adobe Illustrator.")
|
|
|
|
msg += "\n\n"
|
|
|
|
msg += _("Try to import the file into Inkscape through 'File > Import...' (Ctrl+I)")
|
|
|
|
errormsg(msg)
|
2023-09-07 17:25:47 +00:00
|
|
|
except InkstitchException as exc:
|
|
|
|
errormsg(str(exc))
|
new extension: Auto-Route Satin Columns (#330)
**video demo:** https://www.youtube.com/watch?v=tbghtqziB1g
This branch adds a new extension, Auto-Route Satin Columns, implementing #214! This is a huge new feature that opens the door wide for exciting stuff like lettering (#142).
To use it, select some satin columns and run the extension. After a few seconds, it will replace your satins with a new set with a logical stitching order. Under-pathing and jump-stitches will be added as necessary, and satins will be broken to facilitate jumps. The resulting satins will retain all of the parameters you had set on the original satins, including underlay, zig-zag spacing, etc.
By default, it will choose the left-most extreme as the starting point and the right-most extreme as the ending point (even if these occur partway through a satin such as the left edge of a letter "o"). You can override this by attaching the new "Auto-route satin stitch starting/ending position" commands.
There's also an option to add trims instead of jump stitches. Any jump stitch over 1mm is trimmed. I might make this configurable in the future but in my tests it seems to do a good job. Trim commands are added to the SVG, so it's easy enough to modify/delete as you see fit.
2018-10-30 23:43:21 +00:00
|
|
|
except Exception:
|
2023-09-07 17:25:47 +00:00
|
|
|
errormsg(format_uncaught_exception())
|
|
|
|
sys.exit(1)
|
new extension: Auto-Route Satin Columns (#330)
**video demo:** https://www.youtube.com/watch?v=tbghtqziB1g
This branch adds a new extension, Auto-Route Satin Columns, implementing #214! This is a huge new feature that opens the door wide for exciting stuff like lettering (#142).
To use it, select some satin columns and run the extension. After a few seconds, it will replace your satins with a new set with a logical stitching order. Under-pathing and jump-stitches will be added as necessary, and satins will be broken to facilitate jumps. The resulting satins will retain all of the parameters you had set on the original satins, including underlay, zig-zag spacing, etc.
By default, it will choose the left-most extreme as the starting point and the right-most extreme as the ending point (even if these occur partway through a satin such as the left edge of a letter "o"). You can override this by attaching the new "Auto-route satin stitch starting/ending position" commands.
There's also an option to add trims instead of jump stitches. Any jump stitch over 1mm is trimmed. I might make this configurable in the future but in my tests it seems to do a good job. Trim commands are added to the SVG, so it's easy enough to modify/delete as you see fit.
2018-10-30 23:43:21 +00:00
|
|
|
finally:
|
|
|
|
restore_stderr()
|
|
|
|
|
2024-01-11 16:48:11 +00:00
|
|
|
# if shapely_errors.tell(): # see above plan to remove this in future for shapely
|
2024-01-11 13:19:16 +00:00
|
|
|
# errormsg(shapely_errors.getvalue())
|
new extension: Auto-Route Satin Columns (#330)
**video demo:** https://www.youtube.com/watch?v=tbghtqziB1g
This branch adds a new extension, Auto-Route Satin Columns, implementing #214! This is a huge new feature that opens the door wide for exciting stuff like lettering (#142).
To use it, select some satin columns and run the extension. After a few seconds, it will replace your satins with a new set with a logical stitching order. Under-pathing and jump-stitches will be added as necessary, and satins will be broken to facilitate jumps. The resulting satins will retain all of the parameters you had set on the original satins, including underlay, zig-zag spacing, etc.
By default, it will choose the left-most extreme as the starting point and the right-most extreme as the ending point (even if these occur partway through a satin such as the left edge of a letter "o"). You can override this by attaching the new "Auto-route satin stitch starting/ending position" commands.
There's also an option to add trims instead of jump stitches. Any jump stitch over 1mm is trimmed. I might make this configurable in the future but in my tests it seems to do a good job. Trim commands are added to the SVG, so it's easy enough to modify/delete as you see fit.
2018-10-30 23:43:21 +00:00
|
|
|
|
2023-09-07 17:25:47 +00:00
|
|
|
sys.exit(0)
|