spakin / SimpInkScr

Simple Inkscape Scripting
https://inkscape.org/~pakin/%E2%98%85simple-inkscape-scripting
GNU General Public License v3.0
320 stars 31 forks source link

can´t do path union / intersection / exclusion #67

Closed pak-man closed 1 year ago

pak-man commented 1 year ago

Hello, maybe I miss something obvious but i parsed all example and found this example: https://github.com/spakin/SimpInkScr/blob/master/examples/holes.py makes what Inkscape calls path difference,

but i cannot find a way to do the other boolean path operations. I wonder if just an example is missing, or if i missed something obvious ?

pak-man commented 1 year ago

Actually the example above demonstrates path exclusion, not difference as I wrote.

It seems SimpInkScr lacks path boolean operations altogether.

pak-man commented 1 year ago

Browsing SimpInkScr closed issues, I found this: https://github.com/spakin/SimpInkScr/issues/60 which boils down to "inkex lib does not support it" Since that other issue has been closed, I guess I can close mine too...

spakin commented 1 year ago

I, too, wish inkex supported Boolean path operations.

I asked on chat.inkscape.org if there exist plans to add such support. The answer was no, but I was directed to lib2geom, which Inkscape uses internally for its Boolean path operations.

If you feel up for a challenge, you might try building lib2geom and seeing if you can get its Python interface, py2geom, to work within a Simple Inkscape Scripting script.

pak-man commented 1 year ago

Thank you for the tip. I gave a try and managed to compile lib2geom on Debian 11 in a VM with the following:

sudo apt install build-essential cmake git libboost-all-dev libgtest-dev libdouble-conversion-dev libgsl-dev libcairo2-dev

git clone git://git.launchpad.net/lib2geom

mkdir lib2geom/build

cd lib2geom/build

cmake ..

But this does not build the Python bindings. I have to dig a bit deeper. I don´t know if adding comments to this closed issue here would be the best solution to keep a trace of my attempts, or reopen the issue, or ?

s1291 commented 1 year ago

I want to note that lib2geom repository is located here: https://gitlab.com/inkscape/lib2geom

spakin commented 1 year ago

But this does not build the Python bindings. I have to dig a bit deeper. I don´t know if adding comments to this closed issue here would be the best solution to keep a trace of my attempts, or reopen the issue, or ?

I just fought with this myself and made some progress: I managed to build py2geom but haven't yet unearthed the magic incantation needed to get it to install. In case it helps, I first cloned the lib2geom repository that @s1291 referenced. I then enabled various Boost and Cython options (after having installed both Boost.Python and Cython:

$ cmake -D2GEOM_BOOST_PYTHON=ON -D2GEOM_BUILD_SHARED=ON -D2GEOM_CYTHON_BINDINGS=ON 2GEOM_CYTHON_BUILD_SHARED=ON -DCYTHON_EXECUTABLE=cython3 ..

I then built both lib2geom and (explicitly) py2geom:

$ make
$ make py2geom

This is where I got stuck. make install installs lib2geom but not py2geom.

Perhaps it would be worth asking the Inkscape developers for help?

s1291 commented 1 year ago

I have managed to build py2geom after modifying some hardcoded paths et al. in the CMakeLists.txt files:

image

s1291 commented 1 year ago

On Ubuntu 20.04 I had to manually modify the CMakeLists.txt files to update some hard-coded paths, change the version of boost, and many other options.

Then, I had to build using cmake as follows:

cmake -D2GEOM_BOOST_PYTHON=ON -D2GEOM_BUILD_SHARED=ON -D2GEOM_CYTHON_BINDINGS=ON -D2GEOM_CYTHON_BUILD_SHARED=ON -DCYTHON_EXECUTABLE=cython3 -DPython3_INCLUDE_DIRS=/usr/include/python3.8 ..
spakin commented 1 year ago

Nice detective work! Running make install from build/src/py2geom with DESTDIR set worked for me, too. N.B. I didn't need to edit CMakeLists.txt on my Ubuntu 22.10 system.

Now you finally can begin the real work of learning what it takes to apply Boolean path operations from a Simple Inkscape Scripting script…

s1291 commented 1 year ago

@spakin

Maybe one should use a workaround by calling inkscape from the command line. For an example of such implementation, see this extension: https://gitlab.com/moini_ink/inx-pathops/-/blob/master/pathops.py

spakin commented 1 year ago

@s1291: In the past, I had tried something like that, unsuccessfully. I'll take a look at pathops.py and see if I can figure out what the trick is.

s1291 commented 1 year ago

I have suggested adding the pyclipper library to inkscape, then realized later that supporting Bezier curves is not obvious.

spakin commented 1 year ago

I see the thread on Inkscape GitLab you referenced. It certainly will be nice to have a proper way to invoke Boolean path operations directly from an extension.

spakin commented 1 year ago

@s1291: In the past, I had tried something like that, unsuccessfully. I'll take a look at pathops.py and see if I can figure out what the trick is.

pathops.py is a total kludge! Sadly, without inkex support for path operations, there's no good alternative.

pathops.py runs Inkscape once to query the Inkscape version number, then based on the version (1.0, 1.1, or 1.2) it constructs an inkscape command line. It then copies the current image to a temporary file and launches Inkscape a second time, which modifies the temporary file in place. Finally, it replaces the current image with the contents of the temporary file.

I believe I can make pathops.py's approach work in the context of Simple Inkscape Scripting. I plan, however, to sacrifice cross-version Inkscape portability in favor of automatically exposing new path operators to scripts. A consequence is that scripts running on Inkscape 1.0 or 1.1 will have to specify a verb like SelectionIntersect while scripts running on Inkscape 1.2+ will instead specify an action like path-intersection.

Stay tuned…