├── .github
├── FUNDING.yml
└── workflows
│ ├── gmic-blender-addon-test.yml
│ └── makecrossplatformrelease.yml
├── .gitignore
├── CI_simple_local_test.sh
├── COPYING
├── README.md
├── __init__.py
├── assets
├── .gitignore
├── bak
│ ├── fixjson.bash
│ ├── gmic_filters.json
│ └── gmic_filters_fixed.json
└── gmic_filters.json
├── blender_addon_tester_requirements.txt
├── examples
├── A4-flipbook-from-rendered-files
│ └── flipbookpostgmic.py
├── gmic-example-effects-operators-simple-menu
│ └── ExampleGmicEffectsMenu.py
└── gmic-filters-default-parameters-to-operators
│ ├── README.md
│ ├── bpy_operators_scripts.py
│ ├── default_parameters_gmic_py.py
│ ├── filters290.json
│ └── make_operators.py
├── get_latest_gmicpy_version.py
├── make_addon_requirements.txt
├── make_addon_zip.py
├── test_gmic_blender_addon.py
└── tests
└── test_version_and_gmicpy_import.py
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: https://libreart.info/en/projects/gmic
2 |
--------------------------------------------------------------------------------
/.github/workflows/gmic-blender-addon-test.yml:
--------------------------------------------------------------------------------
1 | name: gmic-blender-testing
2 |
3 | on:
4 | push:
5 | schedule:
6 | - cron: '0 0 * * *'
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: ${{ matrix.os }}
12 | strategy:
13 | max-parallel: 4
14 | matrix:
15 | blender-version: ["2.80", "2.81a", "2.82a", "2.83.0", "2.90.0"]
16 | os: [ubuntu-latest, macos-latest] #, windows-latest]
17 | env:
18 | BLENDER_CACHE: ${{ github.workspace }}/.blender_releases_cache # The place where blender releases are downloaded
19 | BLENDER_VERSION: ${{ matrix.blender-version }}
20 | GMICPY_DOWNLOADS_CACHE: ${{ github.workspace }}/.gmicpy_wheels_cache # The place where blender releases are downloaded
21 |
22 | steps:
23 | - uses: actions/checkout@v1
24 | - name: Set up Python
25 | uses: actions/setup-python@v1
26 | with:
27 | python-version: 3.7
28 | - name: Install python requirements and set latest gmic-py version into env
29 | run: |
30 | pip install -r make_addon_requirements.txt
31 | echo ::set-env name=GMICPYVERSION::$(python get_latest_gmicpy_version.py)
32 | - name: Cache Gmic Python ${{ env.GMICPYVERSION }} all-platforms wheels download
33 | uses: actions/cache@v1
34 | with:
35 | path: ${{ env.GMICPY_DOWNLOADS_CACHE }}
36 | key: gmic-py-${{ env.GMICPYVERSION }}
37 | - name: Cache ${{ matrix.os }} Blender ${{ matrix.blender-version }} release download
38 | uses: actions/cache@v1
39 | with:
40 | path: ${{ env.BLENDER_CACHE }}
41 | key: ${{ matrix.os }}-blender-${{ matrix.blender-version }}
42 | - name: Install MacOSX fftw and libomp with Homebrew
43 | if: matrix.os == 'macos-latest'
44 | run: |
45 | brew install fftw libomp
46 | - name: Grab Blender ${{ matrix.blender-version }}, build gmic-blender ${{ env.GMICPYVERSION }} and test them with pytest
47 | run: |
48 | python make_addon_zip.py
49 | pip install -r blender_addon_tester_requirements.txt
50 | python test_gmic_blender_addon.py # Uses the BLENDER_VERSION environment variable
51 | - name: Expose coverage as a CI download
52 | uses: actions/upload-artifact@v1
53 | with:
54 | name: ${{ matrix.os }}-blender-${{ matrix.blender-version }}-coverage.xml
55 | path: coverage.xml
56 |
--------------------------------------------------------------------------------
/.github/workflows/makecrossplatformrelease.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | # Sequence of patterns matched against refs/tags
4 | tags:
5 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
6 |
7 | name: Upload Release Asset
8 |
9 | jobs:
10 | build:
11 | name: Upload Release Asset
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: Checkout code
15 | uses: actions/checkout@v2
16 | - name: Set env
17 | run: echo ::set-env name=RELEASE_VERSION::${GITHUB_REF:10}
18 | - name: Set up Python
19 | uses: actions/setup-python@v1
20 | with:
21 | python-version: 3.7
22 | - name: Install Python requirements
23 | run: pip install -r make_addon_requirements.txt
24 | - name: Set latest gmic-py version into env
25 | run: echo ::set-env name=GMICPYVERSION::$(python get_latest_gmicpy_version.py)
26 | - name: Build Add-On ${{ github.ref }} x gmic-py ${{ env.GMICPYVERSION }} # This would actually build your project, using zip for an example artifact
27 | run: python make_addon_zip.py
28 | - name: Create Release
29 | id: create_release
30 | uses: actions/create-release@v1
31 | env:
32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33 | with:
34 | tag_name: ${{ github.ref }}
35 | release_name: Release ${{ github.ref }}
36 | draft: false
37 | prerelease: true
38 | - name: Upload Release Asset
39 | id: upload-release-asset
40 | uses: actions/upload-release-asset@v1
41 | env:
42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 | with:
44 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
45 | asset_path: ./downloads/gmic_blender.zip
46 | asset_name: gmic_blender-${{ env.RELEASE_VERSION }}-gmicpy-${{ env.GMICPYVERSION }}.zip
47 | asset_content_type: application/zip
48 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | coverage.xml
2 | .coverage
3 | downloads
4 | gmic-py
5 | tests/__pycache__
6 |
--------------------------------------------------------------------------------
/CI_simple_local_test.sh:
--------------------------------------------------------------------------------
1 | pip install -r make_addon_requirements.txt
2 | python make_addon_zip.py
3 | pip install -r blender_addon_tester_requirements.txt
4 | python test_gmic_blender_addon.py # Uses the BLENDER_VERSION environment variable
5 |
6 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 |
2 | CeCILL FREE SOFTWARE LICENSE AGREEMENT
3 |
4 | Version 2.1 dated 2013-06-21
5 |
6 |
7 | Notice
8 |
9 | This Agreement is a Free Software license agreement that is the result
10 | of discussions between its authors in order to ensure compliance with
11 | the two main principles guiding its drafting:
12 |
13 | * firstly, compliance with the principles governing the distribution
14 | of Free Software: access to source code, broad rights granted to users,
15 | * secondly, the election of a governing law, French law, with which it
16 | is conformant, both as regards the law of torts and intellectual
17 | property law, and the protection that it offers to both authors and
18 | holders of the economic rights over software.
19 |
20 | The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre])
21 | license are:
22 |
23 | Commissariat à l'énergie atomique et aux énergies alternatives - CEA, a
24 | public scientific, technical and industrial research establishment,
25 | having its principal place of business at 25 rue Leblanc, immeuble Le
26 | Ponant D, 75015 Paris, France.
27 |
28 | Centre National de la Recherche Scientifique - CNRS, a public scientific
29 | and technological establishment, having its principal place of business
30 | at 3 rue Michel-Ange, 75794 Paris cedex 16, France.
31 |
32 | Institut National de Recherche en Informatique et en Automatique -
33 | Inria, a public scientific and technological establishment, having its
34 | principal place of business at Domaine de Voluceau, Rocquencourt, BP
35 | 105, 78153 Le Chesnay cedex, France.
36 |
37 |
38 | Preamble
39 |
40 | The purpose of this Free Software license agreement is to grant users
41 | the right to modify and redistribute the software governed by this
42 | license within the framework of an open source distribution model.
43 |
44 | The exercising of this right is conditional upon certain obligations for
45 | users so as to preserve this status for all subsequent redistributions.
46 |
47 | In consideration of access to the source code and the rights to copy,
48 | modify and redistribute granted by the license, users are provided only
49 | with a limited warranty and the software's author, the holder of the
50 | economic rights, and the successive licensors only have limited liability.
51 |
52 | In this respect, the risks associated with loading, using, modifying
53 | and/or developing or reproducing the software by the user are brought to
54 | the user's attention, given its Free Software status, which may make it
55 | complicated to use, with the result that its use is reserved for
56 | developers and experienced professionals having in-depth computer
57 | knowledge. Users are therefore encouraged to load and test the
58 | suitability of the software as regards their requirements in conditions
59 | enabling the security of their systems and/or data to be ensured and,
60 | more generally, to use and operate it in the same conditions of
61 | security. This Agreement may be freely reproduced and published,
62 | provided it is not altered, and that no provisions are either added or
63 | removed herefrom.
64 |
65 | This Agreement may apply to any or all software for which the holder of
66 | the economic rights decides to submit the use thereof to its provisions.
67 |
68 | Frequently asked questions can be found on the official website of the
69 | CeCILL licenses family (http://www.cecill.info/index.en.html) for any
70 | necessary clarification.
71 |
72 |
73 | Article 1 - DEFINITIONS
74 |
75 | For the purpose of this Agreement, when the following expressions
76 | commence with a capital letter, they shall have the following meaning:
77 |
78 | Agreement: means this license agreement, and its possible subsequent
79 | versions and annexes.
80 |
81 | Software: means the software in its Object Code and/or Source Code form
82 | and, where applicable, its documentation, "as is" when the Licensee
83 | accepts the Agreement.
84 |
85 | Initial Software: means the Software in its Source Code and possibly its
86 | Object Code form and, where applicable, its documentation, "as is" when
87 | it is first distributed under the terms and conditions of the Agreement.
88 |
89 | Modified Software: means the Software modified by at least one
90 | Contribution.
91 |
92 | Source Code: means all the Software's instructions and program lines to
93 | which access is required so as to modify the Software.
94 |
95 | Object Code: means the binary files originating from the compilation of
96 | the Source Code.
97 |
98 | Holder: means the holder(s) of the economic rights over the Initial
99 | Software.
100 |
101 | Licensee: means the Software user(s) having accepted the Agreement.
102 |
103 | Contributor: means a Licensee having made at least one Contribution.
104 |
105 | Licensor: means the Holder, or any other individual or legal entity, who
106 | distributes the Software under the Agreement.
107 |
108 | Contribution: means any or all modifications, corrections, translations,
109 | adaptations and/or new functions integrated into the Software by any or
110 | all Contributors, as well as any or all Internal Modules.
111 |
112 | Module: means a set of sources files including their documentation that
113 | enables supplementary functions or services in addition to those offered
114 | by the Software.
115 |
116 | External Module: means any or all Modules, not derived from the
117 | Software, so that this Module and the Software run in separate address
118 | spaces, with one calling the other when they are run.
119 |
120 | Internal Module: means any or all Module, connected to the Software so
121 | that they both execute in the same address space.
122 |
123 | GNU GPL: means the GNU General Public License version 2 or any
124 | subsequent version, as published by the Free Software Foundation Inc.
125 |
126 | GNU Affero GPL: means the GNU Affero General Public License version 3 or
127 | any subsequent version, as published by the Free Software Foundation Inc.
128 |
129 | EUPL: means the European Union Public License version 1.1 or any
130 | subsequent version, as published by the European Commission.
131 |
132 | Parties: mean both the Licensee and the Licensor.
133 |
134 | These expressions may be used both in singular and plural form.
135 |
136 |
137 | Article 2 - PURPOSE
138 |
139 | The purpose of the Agreement is the grant by the Licensor to the
140 | Licensee of a non-exclusive, transferable and worldwide license for the
141 | Software as set forth in Article 5 <#scope> hereinafter for the whole
142 | term of the protection granted by the rights over said Software.
143 |
144 |
145 | Article 3 - ACCEPTANCE
146 |
147 | 3.1 The Licensee shall be deemed as having accepted the terms and
148 | conditions of this Agreement upon the occurrence of the first of the
149 | following events:
150 |
151 | * (i) loading the Software by any or all means, notably, by
152 | downloading from a remote server, or by loading from a physical medium;
153 | * (ii) the first time the Licensee exercises any of the rights granted
154 | hereunder.
155 |
156 | 3.2 One copy of the Agreement, containing a notice relating to the
157 | characteristics of the Software, to the limited warranty, and to the
158 | fact that its use is restricted to experienced users has been provided
159 | to the Licensee prior to its acceptance as set forth in Article 3.1
160 | <#accepting> hereinabove, and the Licensee hereby acknowledges that it
161 | has read and understood it.
162 |
163 |
164 | Article 4 - EFFECTIVE DATE AND TERM
165 |
166 |
167 | 4.1 EFFECTIVE DATE
168 |
169 | The Agreement shall become effective on the date when it is accepted by
170 | the Licensee as set forth in Article 3.1 <#accepting>.
171 |
172 |
173 | 4.2 TERM
174 |
175 | The Agreement shall remain in force for the entire legal term of
176 | protection of the economic rights over the Software.
177 |
178 |
179 | Article 5 - SCOPE OF RIGHTS GRANTED
180 |
181 | The Licensor hereby grants to the Licensee, who accepts, the following
182 | rights over the Software for any or all use, and for the term of the
183 | Agreement, on the basis of the terms and conditions set forth hereinafter.
184 |
185 | Besides, if the Licensor owns or comes to own one or more patents
186 | protecting all or part of the functions of the Software or of its
187 | components, the Licensor undertakes not to enforce the rights granted by
188 | these patents against successive Licensees using, exploiting or
189 | modifying the Software. If these patents are transferred, the Licensor
190 | undertakes to have the transferees subscribe to the obligations set
191 | forth in this paragraph.
192 |
193 |
194 | 5.1 RIGHT OF USE
195 |
196 | The Licensee is authorized to use the Software, without any limitation
197 | as to its fields of application, with it being hereinafter specified
198 | that this comprises:
199 |
200 | 1. permanent or temporary reproduction of all or part of the Software
201 | by any or all means and in any or all form.
202 |
203 | 2. loading, displaying, running, or storing the Software on any or all
204 | medium.
205 |
206 | 3. entitlement to observe, study or test its operation so as to
207 | determine the ideas and principles behind any or all constituent
208 | elements of said Software. This shall apply when the Licensee
209 | carries out any or all loading, displaying, running, transmission or
210 | storage operation as regards the Software, that it is entitled to
211 | carry out hereunder.
212 |
213 |
214 | 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS
215 |
216 | The right to make Contributions includes the right to translate, adapt,
217 | arrange, or make any or all modifications to the Software, and the right
218 | to reproduce the resulting software.
219 |
220 | The Licensee is authorized to make any or all Contributions to the
221 | Software provided that it includes an explicit notice that it is the
222 | author of said Contribution and indicates the date of the creation thereof.
223 |
224 |
225 | 5.3 RIGHT OF DISTRIBUTION
226 |
227 | In particular, the right of distribution includes the right to publish,
228 | transmit and communicate the Software to the general public on any or
229 | all medium, and by any or all means, and the right to market, either in
230 | consideration of a fee, or free of charge, one or more copies of the
231 | Software by any means.
232 |
233 | The Licensee is further authorized to distribute copies of the modified
234 | or unmodified Software to third parties according to the terms and
235 | conditions set forth hereinafter.
236 |
237 |
238 | 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION
239 |
240 | The Licensee is authorized to distribute true copies of the Software in
241 | Source Code or Object Code form, provided that said distribution
242 | complies with all the provisions of the Agreement and is accompanied by:
243 |
244 | 1. a copy of the Agreement,
245 |
246 | 2. a notice relating to the limitation of both the Licensor's warranty
247 | and liability as set forth in Articles 8 and 9,
248 |
249 | and that, in the event that only the Object Code of the Software is
250 | redistributed, the Licensee allows effective access to the full Source
251 | Code of the Software for a period of at least three years from the
252 | distribution of the Software, it being understood that the additional
253 | acquisition cost of the Source Code shall not exceed the cost of the
254 | data transfer.
255 |
256 |
257 | 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE
258 |
259 | When the Licensee makes a Contribution to the Software, the terms and
260 | conditions for the distribution of the resulting Modified Software
261 | become subject to all the provisions of this Agreement.
262 |
263 | The Licensee is authorized to distribute the Modified Software, in
264 | source code or object code form, provided that said distribution
265 | complies with all the provisions of the Agreement and is accompanied by:
266 |
267 | 1. a copy of the Agreement,
268 |
269 | 2. a notice relating to the limitation of both the Licensor's warranty
270 | and liability as set forth in Articles 8 and 9,
271 |
272 | and, in the event that only the object code of the Modified Software is
273 | redistributed,
274 |
275 | 3. a note stating the conditions of effective access to the full source
276 | code of the Modified Software for a period of at least three years
277 | from the distribution of the Modified Software, it being understood
278 | that the additional acquisition cost of the source code shall not
279 | exceed the cost of the data transfer.
280 |
281 |
282 | 5.3.3 DISTRIBUTION OF EXTERNAL MODULES
283 |
284 | When the Licensee has developed an External Module, the terms and
285 | conditions of this Agreement do not apply to said External Module, that
286 | may be distributed under a separate license agreement.
287 |
288 |
289 | 5.3.4 COMPATIBILITY WITH OTHER LICENSES
290 |
291 | The Licensee can include a code that is subject to the provisions of one
292 | of the versions of the GNU GPL, GNU Affero GPL and/or EUPL in the
293 | Modified or unmodified Software, and distribute that entire code under
294 | the terms of the same version of the GNU GPL, GNU Affero GPL and/or EUPL.
295 |
296 | The Licensee can include the Modified or unmodified Software in a code
297 | that is subject to the provisions of one of the versions of the GNU GPL,
298 | GNU Affero GPL and/or EUPL and distribute that entire code under the
299 | terms of the same version of the GNU GPL, GNU Affero GPL and/or EUPL.
300 |
301 |
302 | Article 6 - INTELLECTUAL PROPERTY
303 |
304 |
305 | 6.1 OVER THE INITIAL SOFTWARE
306 |
307 | The Holder owns the economic rights over the Initial Software. Any or
308 | all use of the Initial Software is subject to compliance with the terms
309 | and conditions under which the Holder has elected to distribute its work
310 | and no one shall be entitled to modify the terms and conditions for the
311 | distribution of said Initial Software.
312 |
313 | The Holder undertakes that the Initial Software will remain ruled at
314 | least by this Agreement, for the duration set forth in Article 4.2 <#term>.
315 |
316 |
317 | 6.2 OVER THE CONTRIBUTIONS
318 |
319 | The Licensee who develops a Contribution is the owner of the
320 | intellectual property rights over this Contribution as defined by
321 | applicable law.
322 |
323 |
324 | 6.3 OVER THE EXTERNAL MODULES
325 |
326 | The Licensee who develops an External Module is the owner of the
327 | intellectual property rights over this External Module as defined by
328 | applicable law and is free to choose the type of agreement that shall
329 | govern its distribution.
330 |
331 |
332 | 6.4 JOINT PROVISIONS
333 |
334 | The Licensee expressly undertakes:
335 |
336 | 1. not to remove, or modify, in any manner, the intellectual property
337 | notices attached to the Software;
338 |
339 | 2. to reproduce said notices, in an identical manner, in the copies of
340 | the Software modified or not.
341 |
342 | The Licensee undertakes not to directly or indirectly infringe the
343 | intellectual property rights on the Software of the Holder and/or
344 | Contributors, and to take, where applicable, vis-à-vis its staff, any
345 | and all measures required to ensure respect of said intellectual
346 | property rights of the Holder and/or Contributors.
347 |
348 |
349 | Article 7 - RELATED SERVICES
350 |
351 | 7.1 Under no circumstances shall the Agreement oblige the Licensor to
352 | provide technical assistance or maintenance services for the Software.
353 |
354 | However, the Licensor is entitled to offer this type of services. The
355 | terms and conditions of such technical assistance, and/or such
356 | maintenance, shall be set forth in a separate instrument. Only the
357 | Licensor offering said maintenance and/or technical assistance services
358 | shall incur liability therefor.
359 |
360 | 7.2 Similarly, any Licensor is entitled to offer to its licensees, under
361 | its sole responsibility, a warranty, that shall only be binding upon
362 | itself, for the redistribution of the Software and/or the Modified
363 | Software, under terms and conditions that it is free to decide. Said
364 | warranty, and the financial terms and conditions of its application,
365 | shall be subject of a separate instrument executed between the Licensor
366 | and the Licensee.
367 |
368 |
369 | Article 8 - LIABILITY
370 |
371 | 8.1 Subject to the provisions of Article 8.2, the Licensee shall be
372 | entitled to claim compensation for any direct loss it may have suffered
373 | from the Software as a result of a fault on the part of the relevant
374 | Licensor, subject to providing evidence thereof.
375 |
376 | 8.2 The Licensor's liability is limited to the commitments made under
377 | this Agreement and shall not be incurred as a result of in particular:
378 | (i) loss due the Licensee's total or partial failure to fulfill its
379 | obligations, (ii) direct or consequential loss that is suffered by the
380 | Licensee due to the use or performance of the Software, and (iii) more
381 | generally, any consequential loss. In particular the Parties expressly
382 | agree that any or all pecuniary or business loss (i.e. loss of data,
383 | loss of profits, operating loss, loss of customers or orders,
384 | opportunity cost, any disturbance to business activities) or any or all
385 | legal proceedings instituted against the Licensee by a third party,
386 | shall constitute consequential loss and shall not provide entitlement to
387 | any or all compensation from the Licensor.
388 |
389 |
390 | Article 9 - WARRANTY
391 |
392 | 9.1 The Licensee acknowledges that the scientific and technical
393 | state-of-the-art when the Software was distributed did not enable all
394 | possible uses to be tested and verified, nor for the presence of
395 | possible defects to be detected. In this respect, the Licensee's
396 | attention has been drawn to the risks associated with loading, using,
397 | modifying and/or developing and reproducing the Software which are
398 | reserved for experienced users.
399 |
400 | The Licensee shall be responsible for verifying, by any or all means,
401 | the suitability of the product for its requirements, its good working
402 | order, and for ensuring that it shall not cause damage to either persons
403 | or properties.
404 |
405 | 9.2 The Licensor hereby represents, in good faith, that it is entitled
406 | to grant all the rights over the Software (including in particular the
407 | rights set forth in Article 5 <#scope>).
408 |
409 | 9.3 The Licensee acknowledges that the Software is supplied "as is" by
410 | the Licensor without any other express or tacit warranty, other than
411 | that provided for in Article 9.2 <#good-faith> and, in particular,
412 | without any warranty as to its commercial value, its secured, safe,
413 | innovative or relevant nature.
414 |
415 | Specifically, the Licensor does not warrant that the Software is free
416 | from any error, that it will operate without interruption, that it will
417 | be compatible with the Licensee's own equipment and software
418 | configuration, nor that it will meet the Licensee's requirements.
419 |
420 | 9.4 The Licensor does not either expressly or tacitly warrant that the
421 | Software does not infringe any third party intellectual property right
422 | relating to a patent, software or any other property right. Therefore,
423 | the Licensor disclaims any and all liability towards the Licensee
424 | arising out of any or all proceedings for infringement that may be
425 | instituted in respect of the use, modification and redistribution of the
426 | Software. Nevertheless, should such proceedings be instituted against
427 | the Licensee, the Licensor shall provide it with technical and legal
428 | expertise for its defense. Such technical and legal expertise shall be
429 | decided on a case-by-case basis between the relevant Licensor and the
430 | Licensee pursuant to a memorandum of understanding. The Licensor
431 | disclaims any and all liability as regards the Licensee's use of the
432 | name of the Software. No warranty is given as regards the existence of
433 | prior rights over the name of the Software or as regards the existence
434 | of a trademark.
435 |
436 |
437 | Article 10 - TERMINATION
438 |
439 | 10.1 In the event of a breach by the Licensee of its obligations
440 | hereunder, the Licensor may automatically terminate this Agreement
441 | thirty (30) days after notice has been sent to the Licensee and has
442 | remained ineffective.
443 |
444 | 10.2 A Licensee whose Agreement is terminated shall no longer be
445 | authorized to use, modify or distribute the Software. However, any
446 | licenses that it may have granted prior to termination of the Agreement
447 | shall remain valid subject to their having been granted in compliance
448 | with the terms and conditions hereof.
449 |
450 |
451 | Article 11 - MISCELLANEOUS
452 |
453 |
454 | 11.1 EXCUSABLE EVENTS
455 |
456 | Neither Party shall be liable for any or all delay, or failure to
457 | perform the Agreement, that may be attributable to an event of force
458 | majeure, an act of God or an outside cause, such as defective
459 | functioning or interruptions of the electricity or telecommunications
460 | networks, network paralysis following a virus attack, intervention by
461 | government authorities, natural disasters, water damage, earthquakes,
462 | fire, explosions, strikes and labor unrest, war, etc.
463 |
464 | 11.2 Any failure by either Party, on one or more occasions, to invoke
465 | one or more of the provisions hereof, shall under no circumstances be
466 | interpreted as being a waiver by the interested Party of its right to
467 | invoke said provision(s) subsequently.
468 |
469 | 11.3 The Agreement cancels and replaces any or all previous agreements,
470 | whether written or oral, between the Parties and having the same
471 | purpose, and constitutes the entirety of the agreement between said
472 | Parties concerning said purpose. No supplement or modification to the
473 | terms and conditions hereof shall be effective as between the Parties
474 | unless it is made in writing and signed by their duly authorized
475 | representatives.
476 |
477 | 11.4 In the event that one or more of the provisions hereof were to
478 | conflict with a current or future applicable act or legislative text,
479 | said act or legislative text shall prevail, and the Parties shall make
480 | the necessary amendments so as to comply with said act or legislative
481 | text. All other provisions shall remain effective. Similarly, invalidity
482 | of a provision of the Agreement, for any reason whatsoever, shall not
483 | cause the Agreement as a whole to be invalid.
484 |
485 |
486 | 11.5 LANGUAGE
487 |
488 | The Agreement is drafted in both French and English and both versions
489 | are deemed authentic.
490 |
491 |
492 | Article 12 - NEW VERSIONS OF THE AGREEMENT
493 |
494 | 12.1 Any person is authorized to duplicate and distribute copies of this
495 | Agreement.
496 |
497 | 12.2 So as to ensure coherence, the wording of this Agreement is
498 | protected and may only be modified by the authors of the License, who
499 | reserve the right to periodically publish updates or new versions of the
500 | Agreement, each with a separate number. These subsequent versions may
501 | address new issues encountered by Free Software.
502 |
503 | 12.3 Any Software distributed under a given version of the Agreement may
504 | only be subsequently distributed under the same version of the Agreement
505 | or a subsequent version, subject to the provisions of Article 5.3.4
506 | <#compatibility>.
507 |
508 |
509 | Article 13 - GOVERNING LAW AND JURISDICTION
510 |
511 | 13.1 The Agreement is governed by French law. The Parties agree to
512 | endeavor to seek an amicable solution to any disagreements or disputes
513 | that may arise during the performance of the Agreement.
514 |
515 | 13.2 Failing an amicable solution within two (2) months as from their
516 | occurrence, and unless emergency proceedings are necessary, the
517 | disagreements or disputes shall be referred to the Paris Courts having
518 | jurisdiction, by the more diligent Party.
519 |
520 |
521 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |
4 | ####
5 | #### Blender 3d Add-on for G'MIC - A Full-Featured Open-Source Framework for Image Processing
6 | ##### https://gmic.eu
7 | # gmic-blender
8 |
9 |
10 | This WIP official G'MIC plugin for [Blender3D 2.8x](https://www.blender.org/) uses the [G'MIC Python binding](https://github.com/dtschump/gmic-py) and will add new Nodes to Blender3d without forking Blender's code. This project is under the CeCILL-A free software license.
11 |
12 | Estimated time of arrival of 1 first generic Node: September 2020.
13 |
14 | This is being worked on at the [GREYC](https://www.greyc.fr/) Image public research laboratory in Caen, France, with temporary funding by the [INS2I CNRS Information & Interaction Sciences Institute](https://ins2i.cnrs.fr/fr/institut).
15 |
16 | ## Installing
17 | [The latest version is v0.0.8 embedding gmic-py 2.9.0.](https://github.com/myselfhimself/gmic-blender/issues/15)
18 |
19 | For now, gmic can be imported from Blender's Python :) The addon should work on Linux and MacOS.
20 | On MacOS you may need to install libomp and fftw first yourself using Homebrew: `brew install libomp fftw`.
21 | 1. [Head over to the Releases section and download an early zip addon archive.](https://github.com/myselfhimself/gmic-blender/releases)
22 | 1. [Add the gmic-blender addon .zip to Blender as a 3rd-party addon.](https://docs.blender.org/manual/en/latest/editors/preferences/addons.html#rd-party-add-ons)
23 | 1. [Open up a text editor view into Blender](https://docs.blender.org/manual/en/latest/editors/text_editor.html), type "import gmic" and execute it with `Alt+P`.
24 |
25 | ## Test Driven Development
26 | We are using a Blender Python Pytest framework named [blender-addon-tester](https://github.com/douglaskastle/blender-addon-tester).
27 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
1 | bl_info = {
2 | "name": "Blender G'MIC Add-on",
3 | "author": "Jonathan-David Schröder",
4 | "blender": (2, 80, 0),
5 | "version": (0, 0, 2),
6 | "category": "Object",
7 | }
8 |
9 | import os
10 | import sys
11 | import platform
12 |
13 | # TODO ensure that globals are tolerated in Blender3d python scripting guidelines..
14 | __GMIC_ADDON_ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
15 | __GMIC_FILTERS_JSON_PATH = os.path.join(__GMIC_ADDON_ROOT_PATH, "assets", "gmic_filters.json")
16 | __GMIC_LOADED__ = False
17 | __GMIC_PY_RELATIVE_LIBS_DIR = "-".join([platform.system().lower(), platform.architecture()[0]])
18 |
19 | def register():
20 | print("Registering " + bl_info["name"])
21 | if not load_gmic_binary_library():
22 | print("Failed loading G'MIC binary library :-(")
23 | else:
24 | import gmic
25 | print(dir(gmic))
26 | generate_nodes_from_gmic_filters(load_gmic_filters())
27 |
28 | def unregister():
29 | print("Unregistring " + bl_info["name"])
30 |
31 | def load_gmic_binary_library():
32 | global __GMIC_LOADED__
33 |
34 | if __GMIC_LOADED__:
35 | return True
36 |
37 | __GMIC_LOADED__ = False
38 |
39 | import os
40 | import sys
41 | libdir = os.path.join(__GMIC_ADDON_ROOT_PATH, __GMIC_PY_RELATIVE_LIBS_DIR)
42 | if libdir not in sys.path:
43 | sys.path.insert(0, libdir)
44 | print("Added libdir to sys.path:", libdir)
45 |
46 | try:
47 | print("trying gmic import")
48 | import gmic
49 | print("gmic import worked")
50 | __GMIC_LOADED__ = True
51 | except ImportError as err:
52 | raise ImportError("Cannot load G'MIC binary python module at {}. Details: {}".format(libdir, sys.exc_info()[0]))
53 |
54 | try:
55 | type(gmic.Gmic) == type
56 | except AttributeError as err:
57 | raise ImportError("G'MIC binary Python module was loaded improperly from {} and is without symbols. Details: {}".format(libdir, sys.exc_info()[0]))
58 |
59 | return __GMIC_LOADED__
60 |
61 | def load_gmic_filters():
62 | import json
63 | # TODO add cache? // mtime check?
64 | filters_json = None
65 | # TODO catch exception and make a nice error pop-in if open this file fails
66 | with open(__GMIC_FILTERS_JSON_PATH) as f:
67 | filters_json = f.read()
68 | return json.loads(filters_json)
69 |
70 | def generate_nodes_from_gmic_filters(gmic_filters_dict):
71 | print("Loaded gmic_filters JSON overview:", gmic_filters_dict["format_version"], gmic_filters_dict["gmic_version"], "categories:", len(gmic_filters_dict["categories"]))
72 | print("")
73 | # TODO foreach loop on dict, create 1 node by filter
74 |
--------------------------------------------------------------------------------
/assets/.gitignore:
--------------------------------------------------------------------------------
1 | bak
2 |
--------------------------------------------------------------------------------
/assets/bak/fixjson.bash:
--------------------------------------------------------------------------------
1 | iconv -f ISO-8859-1 -t UTF-8//TRANSLIT gmic_filters.json -o gmic_filters.json2
2 | cat gmic_filters.json2 | python3 -c 'import html, sys; [print(html.unescape(l), end="") for l in sys.stdin]' > gmic_filters.json3
3 | rm gmic_filters.json2
4 | jsonlint-php gmic_filters.json3 && mv gmic_filters.json3 gmic_filters_fixed.json
5 |
--------------------------------------------------------------------------------
/assets/bak/gmic_filters.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/myselfhimself/gmic-blender/990324e645c56f4e2ef851d5b6ff99e8c28cc30b/assets/bak/gmic_filters.json
--------------------------------------------------------------------------------
/blender_addon_tester_requirements.txt:
--------------------------------------------------------------------------------
1 | blender-addon-tester
2 |
--------------------------------------------------------------------------------
/examples/A4-flipbook-from-rendered-files/flipbookpostgmic.py:
--------------------------------------------------------------------------------
1 | import bpy
2 | import os
3 | import os.path
4 | import gmic
5 |
6 | rendering_dir = os.path.dirname(bpy.context.scene.render.filepath)
7 |
8 | g = gmic.Gmic()
9 |
10 | good_filenames = []
11 | for filename in os.listdir(rendering_dir):
12 | if filename.startswith("engraved"):
13 | print(filename)
14 | good_filenames.append(os.path.join(rendering_dir, filename))
15 |
16 | print(good_filenames)
17 | g.run(" ".join(good_filenames) + " append_tiles , display")
18 |
--------------------------------------------------------------------------------
/examples/gmic-example-effects-operators-simple-menu/ExampleGmicEffectsMenu.py:
--------------------------------------------------------------------------------
1 | import bpy
2 | import gmic
3 |
4 | """
5 | This is a first example of using the gmic-blender 0.7+ addon for Blender 2.8x
6 | It was showcased at the Libre Graphics Meeting 2020
7 |
8 | Open or paste this script Blender 2.8x within the Text editor window
9 | and run it with Alt+P to let a little menu pop-up under your mouse.
10 | It will alter your last Render result (or may raise an error if no
11 | render has been done yet.
12 | """
13 |
14 | class GmicEngraveOperator(bpy.types.Operator):
15 | bl_idname = "object.gmic_engrave_render"
16 | bl_label = "Gmic Engrave Render"
17 |
18 | def execute(self, context):
19 | #bpy.ops.render.render()
20 | bpy.data.images['Render Result'].save_render("somefile.tga")
21 |
22 | gmic.run("somefile.tga fx_engrave 0.5,50,0,8,40,0,0,0,10,1,0,0,0,1,0 display")
23 |
24 | return {'FINISHED'}
25 |
26 | class GmicDericheOperator(bpy.types.Operator):
27 | bl_idname = "object.gmic_deriche_render"
28 | bl_label = "Gmic Deriche Render"
29 |
30 | def execute(self, context):
31 | #bpy.ops.render.render()
32 | bpy.data.images['Render Result'].save_render("somefile.tga")
33 |
34 | gmic.run("somefile.tga deriche 3,1,x display")
35 |
36 | return {'FINISHED'}
37 |
38 | class GmicBlurOperator(bpy.types.Operator):
39 | bl_idname = "object.gmic_blur_render"
40 | bl_label = "Gmic Blur Render"
41 |
42 | def execute(self, context):
43 | #bpy.ops.render.render()
44 | bpy.data.images['Render Result'].save_render("somefile.tga")
45 |
46 | gmic.run("somefile.tga blur 3 display")
47 |
48 | return {'FINISHED'}
49 |
50 | class GmicDefaultRenderOperator(bpy.types.Operator):
51 | bl_idname = "object.gmic_default_render"
52 | bl_label = "Gmic Show Default Render"
53 |
54 | def execute(self, context):
55 | #bpy.ops.render.render()
56 | bpy.data.images['Render Result'].save_render("somefile.tga")
57 |
58 | gmic.run("somefile.tga display")
59 |
60 | return {'FINISHED'}
61 |
62 |
63 | class SimpleCustomMenu(bpy.types.Menu):
64 | bl_label = "G'MIC Quick Filters"
65 | bl_idname = "OBJECT_simple_custom_menu"
66 |
67 | def draw(self, context):
68 | layout = self.layout
69 |
70 | op = layout.operator(GmicDefaultRenderOperator.bl_idname, text = 'Default Render', icon='HAND' )
71 | op = layout.operator(GmicBlurOperator.bl_idname, text = 'Blur', icon='META_ELLIPSOID' )
72 | op = layout.operator(GmicDericheOperator.bl_idname, text = 'Deriche', icon='MESH_CUBE' )
73 | op = layout.operator(GmicEngraveOperator.bl_idname, text = 'Engrave', icon='LIGHT_POINT' )
74 |
75 | def register():
76 | bpy.utils.register_class(GmicDefaultRenderOperator)
77 | bpy.utils.register_class(GmicBlurOperator)
78 | bpy.utils.register_class(GmicDericheOperator)
79 | bpy.utils.register_class(GmicEngraveOperator)
80 | bpy.utils.register_class(SimpleCustomMenu)
81 |
82 | def unregister():
83 | bpy.utils.unregister_class(GmicDefaultRenderOperator)
84 | bpy.utils.unregister_class(GmicBlurOperator)
85 | bpy.utils.register_class(GmicDericheOperator)
86 | bpy.utils.register_class(GmicEngraveOperator)
87 | bpy.utils.unregister_class(SimpleCustomMenu)
88 |
89 | if __name__ == "__main__":
90 | register()
91 |
92 | # The menu can also be called from scripts
93 | bpy.ops.wm.call_menu(name=SimpleCustomMenu.bl_idname)
94 |
--------------------------------------------------------------------------------
/examples/gmic-filters-default-parameters-to-operators/README.md:
--------------------------------------------------------------------------------
1 | Those scripts are not production quality, but I wanted them to be stored in
2 | some safe place in order to reuse their good parts some day when needed.
3 | The latest script in the list below (`bpy_operators_scripts.py`) was showcased at the LGM 2020 within the G'MIC+Blender presentation in the last Blender demo chapter.
4 |
5 | `default_parameters_gmic_py.py` was created from https://gmic.eu/filters290.json
6 | in some obscure way, maybe using this bash command: `cat /tmp/fff | cut -d' ' -f5,6 | sed "s/[^ ][^ ]*/'&'/g" | sed 's/ /: /g' | paste -s --delimiters="," > default_parameters_gmic_py.py`
7 |
8 | `make_operators.py` is a blender python script generator create 1 Operator class per G'MIC filters calling the latter's default parameters (tentatively..)
9 |
10 | `bpy_operators_scripts.py` is the resulting file, a generated python script for Blender 2.8x that can be run within Blender's Text editor with `Alt+P`
11 |
--------------------------------------------------------------------------------
/examples/gmic-filters-default-parameters-to-operators/default_parameters_gmic_py.py:
--------------------------------------------------------------------------------
1 | default_parameters = {'afre_edge': '1,1,1,1','fx_gmicky': '0','afre_contrastfft': '75,50,1','fx_hnorm': '1,50,0','-srand': '781123','afre_gleam': '3,50','afre_vigrect': '50,75,10,50,50','afre_softlight': '100,0','afre_vigcirc': '90,75,50,50','mc_rooster': '50,0,255,255,255,255,1','mc_kookaburra': '50,0,255,255,255,255,1','mc_paw': '50,0,255,255,255,255,1','fx_array_mirror': '1,0,0,2,0,0,0','fx_array_fade': '2,2,0,0,80,90,0,0','Annular_Steiner_Chain_Round_Tile': '800,1,0,0,100,0,100,12,0,1,0,0,0,255,0,255,255,0,127,0,0,255,127,0','Cercles_Concentriques_A': '800,1,6,0,0,90,1,1,50,1,1,0,0,0,255,0,0,0,0,5,0,0,0,255,255,255,255,0,255,255,0,0,255,0,255,255,255,255,0,255,255,0,1,0,5,0,0','fx_imagegrid': '10,10','fx_array': '2,2,0,0,0,0','array_random': '5,5,7,7','fx_ministeck': '8,64,8,2,100,0.3,0','samj_Carres_Noirs': '128,40,7,0,0,0,0,255,2,96,96,96,255,2,255,255,255,255,0,2,0','Cercles_Concentriques_A_en': '800,1,6,0,0,90,1,1,50,1,1,0,0,0,255,0,0,0,0,5,0,0,0,255,255,255,255,0,255,255,0,0,255,0,255,255,255,255,0,255,255,0,1,0,5,0,0','fx_dices': '2,24,1','samj_Moirage_Spline': '0,0,0,255,8,0,-50,50,-50,50,0,0,0,0,0,255,8,0,-50,50,-50,50,0,0','samj_en_Coeurs_Hearts_002': '16,100,0,0,1,0,255,255,255,255,0,0,0,1,1','fx_imagegrid_triangular': '10,18,0,255,255,255,128','fx_taquin': '7,7,0,50,5,0,0,0,0,255,0','samj_Bulles_Colorees': '64,64,64,255,8,0,0,3,0,0,0,0,0,0,0,0,255','fx_puzzle': '5,5,0.5,0,0,0.3,100,0.2,255,100,0,0,0,0,0,0','fx_rotate_tiles': '5,5,15,3,3,1.8','samj_Ellipses_Colorees': '64,64,64,255,8,8,0,0,0,0,0,255','samj_Losanges_Colores': '64,64,64,255,8,0,0,0,1.5,0,1,0,0,0,0,0,255,0','fx_brushify': '7,0.25,4,64,25,12,0,2,4,0.2,0.5,30,1,1,1,5,0,0.2,1','samj_Contour_Drawings_en': '5,0,2,0,0,5,10,0.8,0,1.1,10,0,1','samj_Pixelisation_Contours': '0.5,0,20,8,0,0,1,0,10,0.8','samj_Pointes_De_Diamants_Colorees': '64,64,64,255,8,0,0,1.5,0,0,0,0,0,0,0,255,0','gtutor_fpaint': '0.5,0.5,0.0,0,45.0,0.5,0.5,0.5,0','fx_parameterize_tiles': '10,10,0','fx_shift_tiles': '10,10,10,1','fx_graphic_boost4': '1.25,2,0,0.15,14,0,1,0.5,0.45,2,0,1,0,1,1,1,0.5,0.45,1','gcd_aurora': '6,1,0','fx_crayongraffiti2': '300,50,1,0.4,12,1,2,2,0','fx_cpencil': '1.3,50,20,2,2,1,0','Engrave_colore_en': '0,0.5,4,0,8,40,0,25,1,2,0,0,0,255,255,255','fx_neon_alpha': '0,0.45,40,60,0,2,1.15,20,0.4,0.1,2.25,5,0.2,0.1,2.25,2,1','afre_sharpenfft': '15,1','fx_tk_photoillustration': '0,0.25,0,0.30,0.50,0.50,1.00,0,5.00,0,1,0,0,1,0,0,1.2,98.5,5,0.5,0,0,0,0,0,1,0','fx_dreamy_watercolour': '0,0.3,40,60,0,1,50,0,10,2,1,1,0.5,10,0,0,7,1,3,1,1,1,1,1,11,1,25,5,1,10,1,0,0,1,0.5,0,8,1,0,128,128,128,0.5,1,8,0.2,1,1,0,27,0.75,0,1,20,40,40,1,2,1.25,0,2,1,27,1','samj_Edges_And_LIC': '0,200,0,0,0,15,8,127,255,0,0,1,20,0.2,0,14,1','samj_Angoisse': '1,5,0,5,100,2,4,1,250','mc_dragonfly': '50,0,255,255,255,255,1','fractalize': '0.8','samj_Couleurs_Rayees': '0,30,0,100,4,4,0,2,0.7,0','samj_en_Texture_Granuleuse': '0,20,80.0,0,0,0','Annular_Steiner_Chain_Round_Tile_en': '800,1,0,0,100,0,100,12,0,1,0,0,0,255,0,255,255,0,127,0,0,255,127,0','samj_Fond_Brosse': '3,1','fx_illustration_look': '100,0,0,0,0','fx_MorphoPaint': '1,18,2,25,100,230,8,3,4,0.5,2,0.5,200,1,1,1,1,1,1,1,1,0','fx_array_color': '5,5,0.5','samj_Isophotes_Vers_Aquarelle': '16,0.5,4,0,1,10,1,0,0,0,0,1,10,10,4,3,251,237,206,1','fx_pastell': '0.6,1,0,20,30,300,1,30,1,1,0.5,0,0,10,3,0,9,3,0,12,0','samj_Barbouillage_Paint_Daub_en': '2,2,100,0.2,1,4,1,0,8','fx_SimpleNoiseCanvas': '0,3,2,5,5,0,255,0,2,0,0,0,1,0,255,255,255,255,0','samj_Scintillements_Colores_en': '64,64,64,255,8,8,0.5,384,12,0,0,0,0,0,0,0,255,0','warhol': '3,3,2,40','samj_Plasmic_V2': '2,4,10,2,0.02,8,0,0,0,0,0,0,255','fx_pdithered': '1,1,0,0,20,1,0,1,0','fx_imagegrid_hexagonal': '32,0.1,1','fx_autofill_lineart': '90,1,8,0,0','Engrave_colore': '0,0.5,4,0,8,40,0,25,1,2,0,0,0,255,255,255','samj_Contour_Epais': '1,0,5,1,5,5,10,0.8,2,1','samj_Color_EdgesO_Engrave': '0,50,9,1,2,50,0,8,40,0,0,1,0,0,0','fx_montage': '0,"V(H(0",1,0.5,0,0,0,0,0,255,0,0,0,0,0','fx_gcd_layeretch': '11,4,12,0.12,100,8.5,5,0,0,3,1,1,0','samj_fond_broderie': '8,2,0,1,1','samj_Diff_Tensors_Blend': '10,5,1,0.15,1,0,3,1,0,3,1','samj_Coeurs_Hearts_002': '16,100,0,0,1,0,255,255,255,255,0,0,0,1,1','fx_channels2layers': '0','samj_Impressions': '10,5,5,1,1,0,2,0,1,5,0,5,100,2,4,1,250,1.2','samj_Gris_Raye': '0,30,0,100,4,4,255,1','samj_Moirage_Spline_XY': '0,0,0,255,8,0,-50,50,-50,50,0,0,0,0,255,8,0,-50,50,-50,50,0,0','fx_tk_colortemp': '0,0,0','samj_texture_coloree': '"A",0.7,200,125,50,5,5,45,200,4,0.2','samj_TensorTest': '0.3,0.9,0.6,1.1,0,0,20,32,20,2,1,0,2','fx_normalize_tiles': '25,25,0,255,11','fx_hsv_equalizer': '0,180,40,0,0,0,180,40,0,0,0,180,40,0,0,0','-srand': '781123','samj_texture_coloree_en': '"A",0.7,200,125,50,5,5,45,200,4,0.2,1,10,1,1','iain_hue_light_dark_p': '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,100,255,0,0,0','samj_Angoisse_en': '1,5,0,5,100,2,4,1,250','fx_whirling_lines': '30,6,0,0,0.45,40,60,0,0,30,0,3,3','fx_recolorize': '2,0.2,0','samj_Variations_RVB': '50,50,0,6,0,0,180,90,45,0,1,0','fx_ColorAbstractionPaint': '5,10,1,0,1,0,1,0,0,0,0,0,0,0','fx_colorize_lineart_smart': '0,95,0,0,1,24,200,0,75,2,60,20,90,1,10,1,0','fx_gcd_norm_eq': '0.5,0.5,2,0','fx_tk_vintage': '2,0.85,0.7,80,200,5,147,26,161,0.3,235,220,176,0.4,190,181,108,0.2,0,0,100,0,0.3,25,0,0','fx_dreamsmooth': '3,1,1,0.8,0,0.8,1,24,0','XY_hardsketchbw_samj_en': '0.2,300,50,1,0.1,20,0,0,0,0,180,40,160,255,0','fx_ink_wash': '0.14,23,0,0.5,0.54,2.25,0,2,6,5,20','samj_Coloriage': '612,255,2,6,2,0,0,0,255,0','samj_Flamboyance_Test': '65,28,9.25,0.3,0,1,1.1,10,12,2,0,0,1,0,150,0.42,0.85,0.6,7.83,0.68,19,2.65,0,1,1,3,200,20,0.1,1.5,8,1,3,1,0,20,0,0,0,0','fx_remove_scratches': '72,2,4,3,0','samj_scintillements': '0,5,0,1,20,2,6,20,5,45,2,6,5,20,1,7,0,0','fx_graphic_novelfxl': '0,2,6,5,20,0,0.62,14,0,1,0.5,0.78,1.92,0,0,0,1,1,1,0.5,0.8,1.28','samj_Quelques_Isophotes_B': '16,100,0,0,4','samj_Color_Palettes': '50,50,0,6,24,0,0,180,90,45,1,3,2,1','jl_colorgrading': '0.,0,1,1,0,0,0,0,0,0,1,0,0,0,70,0,0,0,0,0,70,180,0,1,0,0,0','fx_otsu_hessian_blend': '4,0,1,27,1,0','fx_corvo_painting_5': '35,10,10,0.5,50,0.3,50,2,5,1','fx_darken_sky': '.75,5,0,1,0,0','fx_decompose_channels': '7,0,0,1','samj_Plasmic': '0,1.1,2,40,0,0,0,0','fx_conformal_maps': '8,1,0,1,0,0,0,0,0,3,0,0,1024,1024','gcd_hsv_select': '0,0.5,1,180,0.5,0.5,2,2,18,0,0,0','gcd_hsl': '1,0,0,180,0.2,0,1,1,0','samj_Barbouillage_Paint_Daub': '2,2,100,0.2,1,4,1,0,8','fx_equirectangular2nadirzenith': '0','iain_rgb_tone': '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0','samj_At06A_2017_VarCouleurs': '1,0,100,0,0','samj_Couleurs_Rayees_2': '0,30,0,100,4,4,255,1','samj_Random_Small_Deformations': '10,5,3','iain_tone_presets_p': '0,100,0,0','fx_gcd_transfer_colors_patch': '6,3,5,5,0,0','samj_fx_sketchbw_modifie': '3,45,180,30,1.75,0.02,0.5,0.75,0.1,0.7,3,6,0,1,4,0,1234,0,2,100,0.2,1,4,1,0','fx_reflect': '50,1,110,160,190,64,0,1.5,0,-3.30,7,1.5','samj_Colored_Outlines': '0,2,8,0,0,0,0,0,255','samj_Carte_De_Repoussage': '30,1,0,0','samj_Pointillisme_B': '1,0,90,3,1,1,0,0,0,255','ripple': '10,20,2,0,0','samj_Quelques_Isophotes': '10,10,1,0.02,8','samj_Contours_Colores': '1.1,2,40,0,0','samj_Test_Skeletik': '10,1,0,0,0,3,1,0,0,0,255','samj_Cercle_Polaire': '1,0,0,1,0,0,2,0,0,0,50,50','samj_Skeletation': '2,100,100,0,0,1','samj_Test_Mauvais_Contours': '0,0,0,2,1,0,255,0,255,0,0,3,1','fx_watercolor': '1.8,0.1,1,80,0,0.5,0,0,0,2,0,2,4,2,0,3,3,2,0,4,2,0,0,0,0,0','fx_seamcarve': '85,100,15,0,1','fx_apply_YCbCrcurve': '0,-1,128,-1,128,-1,128,-1,128,-1,128,255,1,0,0','fx_auto_gnarl': '3,0.45,40,60,0,1,1,2,4,6,5,20,1,2.5,0.5,2,2,3','fx_colorize_lineart': '0,1,0,0.05','fx_map_sphere': '512,512,90,0.5,0,0,20,0,0,0,0.5','fx_crease': '30,10,3','fx_drop_water': '0,20,2,80,0,3,35,10,1,0.5,0.25,0.5,0.75,0.05,0.15,1','engrave_modifie': '0,0.5,4,0,8,40,0,25,1','fx_jr_spiral_transform': '0,0,0,0,0','raindrops': '80,0.1,1,0','deform': '10','samj_NB_EdgesO_Engrave': '0,50,9,1,2,50,0,8,40,0,0,1','fx_square_circle': '0,1,0,0,0,0,0','sawtoother_yuv8': '1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,2,0','fx_yag_soften': '0,0,0','iain_cmyk_tone_p': '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0','water': '30,1.5,45','fx_frame_blur': '30,30,0,5,0,0,128,128,128,0,5,255,255,255,2,2,1,0,0.5,0.5,0','fx_jr_smooth_eq': '8,2,0,3,2,1.5,0,4,2,2,0,5,2,2,0,6,2,2,0,7,2,2,0,3,2,0,0,0,1,1,0','fx_customize_clut': '100,0,10,0,0,0,0,0,0,0,8,0.5,1,0,0,0,0,0,0,1,255,255,255,255,196,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0','fx_simulate_grain': '0,1,0.2,100,0,0,0,0,0,0,0,0','frame_cube': '3,0,0,0,0,0,0','fx_streak': '255,0,0,255,0,0,3','fx_frequency_representation': '3,256,0,40,0','fx_blur_bloom_glare': '1,2,5,0,0,0,0,0,3,0.5,7,0','fx_superstreak': '10,10,3,0.50,0.50,10,30','fx_tk_metallic': '1,0,0,0','fx_frame_fuzzy': '5,5,10,1,255,255,255,255','fx_butterworth_bp': '3,2,0,4,2,0,0,0,1,1,0','fx_watermark_visible': '"\251','Saturation_EQ_p': '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0','fx_frame_mirror': '10,10,50,50,0,0,0,0,0.75','fx_gcd_crt': '1.8,1.8,0,0','fx_morpho': '0,5,0,0,0,0,0','fx_frame_painting': '10,0.4,6,225,200,120,2,400,50,10,1,0.5,123456,0','fx_zonesystem': '1,10,1,1,0,255,0','samj_Zones_Grises_en': '3,0,3,4,1','fx_bitplane8': '0,1,0,0','fx_frame_pattern': '10,1,1,1','samj_Contours_Arrondis': '1,3,5,10,0,0','fx_jfif_xt': '50,8,8','iain_constrained_sharpen': '.75,2,1,5,0,11,1','fx_frame': '0,100,0,100,10,10,0,0,0,255,1,255,255,255,255','samj_Scintillements_Colores_Contours': '0,8,0,8,8,1,768,12,0,0,0,0,0,0,0,255','samj_Degradations_Path_Solidify': '0,0,0,0,0,2,10,1,0,0,1,75,0,20','jeje_dehaze': '5,1,.2,1,0,0,0,0,0','fx_frame_round': '6,20,0.1,0,255,255,255,255,0,0.1,3','fx_apply_Labcurve': '0,-1,128,-1,128,-1,128,-1,128,-1,128,255,1,0,0','fx_pixelsort': '1,0,0,1,0,100,0,0,0','fx_tk_dri': '0,0,0,1,0.5,1,1,0','souphead_droste10': '40,100,1,1,1,0,0,0,0,0,1,10,1,0,90,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0','fx_frame_smooth': '10,10,0.25','samj_Random_Plasma': '0,80','fx_highpass': '5,2,0,0,0','fx_symmetrizoscope': '4,0,3,0','fx_old_photo': '200,50,85','fx_row_shift': '0,0,0.5,0,0.5,3,0','fx_LCE': '80,0.5,1,1,0,0','gcd_jpeg_smooth': '1,1,0,0','fx_polaroid': '10,20,0,0,3,0,20,50,70,95','samj_Ellipses_Inpaint': '0,0,0,8,8,2,0,10','jeje_normalize_local_variance': '50,5,5,1,0,0','gcd_layers': '100,0,1,0,0,0,0,0,1,0,0,1','samj_At06A_2017_frame_painting': '10,0.4,6,127,127,127,2,400,50,10,1,0.5,123456,35,1,1,1,0,100','samj_Zones_Grises': '3,0,3,4,1','make_up': '15,4,0,0,0','gcd_balance_lms': '1,1,1,0,0,0','fx_vignette': '70,70,95,0,0,0,255','sawtoother_cmy_k': '1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,1,0,0,2,0','fx_tk_mask': '0,0,0,255,0,1,0,0,1,0','gcd_fx_local_fmean': '15,0,0,5,0','fx_fourier': '1,1','sawtoother_hsx': '1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,0,1,1,0,0,2,0','fx_tk_portrait': '0,100,1,5,20,3,20,10,0,0,1,2,25,2,250,180,150,255,0,0,1,1.5,10,1,0,0,1,1,0,0','fx_watermark_fourier': '"(c)','tran_multi_threshold': '50,100,150,200,9,0,1,175,42,27,101,101,101,174,165,131,247,228,160','sawtoother_lab8': '1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,2,0','iain_pyramid_processing': '4,50,.5,0,0','gcd_normalize_brightness': '0,10,0,3,0,0','gcd_anti_alias': '60,0.3,50,0','sawtoother_lch8': '1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,2,0','samj_Antialias_Wavelet': '40,0,127,255,1,60,1,1,1','fx_gcd_quicktone': '1,4,20,0,3,1','gcd_auto_balance': '30,0,0,1,0','sawtoother_rgb': '1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,2,0','jeje_hessian_sharpen': '3,1,1,0,0','gcd_recol': '-14,14','gcd_blend_feather': '100,0.5,2,0,0','sawtoother_srgb': '1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,2,0','samj_Wavelet_Sharpen_Test_en': '0,0','gcd_sharpen_gradient': '0.5,2,0,0','gcd_comp_blur': '2,3,1,100,1,0,0','sawtoother_xyz8': '1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,2,0','jeje_whiten_frequency': '50,0,0','gcd_sharpen_tones': '1,128,0,0','fx_gcd_cumul_math': '0,1,1,0,0','sawtoother_ycbcr': '0,1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,2,0','fx_split_details_alpha': '6,10,1,5,0','gcd_srotate': '0,50,50,1,1,6,0.6,0','gcd_depth_blur': '0,15,0.25,2,4,0,1','sawtoother_yiq8': '1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,0,0,2,0','fx_split_details_gaussian': '6,10,1,0','gcd_emboss': '128,0','gcd_temp_balance': '0,0,1,0','iain_easy_skin_retouch': '7,2,.7,1,1,.7,.6,.5,.5,.5,0','fx_split_details_wavelets': '6,0,0','gcd_geometric_balance': '0','gcd_unquantize': '6,1,1,5,15','exfuse': '1,0.6,0,0.5,1,5','jeje_spotify': '1,1,1,1,11,0','gcd_upscale_box': '0,0,0','gcd_infomap': '0','exfusion5': '0,.2,0.2,1,0,0','iain_texture_enhance_p': '2,2,30,0,11,0,0','gcd_ebwarp': '0.5,1','gcd_upscale_noise': '16,2','fft_tile': '500,128,0','gcd_tone_enhance': '0,1,0,1,128,0,1,0.5,0,0,4,0,0','gcd_warpmap': '5,0,0,0,0','MS_Patch_NR3': '1.3,0,0,0,3,5,1,0,0,0,0,0','fill_holes': '11,21,5,0,0,1','samj_Wavelet_Sharpen_Test': '1','fx_gb_cfx': '10,0,0,0,0,0','ms_patch_smooth': '10,5,3,5,0,1,1,7,5,4,3,2,1,1,1.3,0','iain_descreen2': '3,-10000,10','jpr_phasecongruence': '45,1,50,1','fx_gb_lb': '10,7,0','ms_smooth': '0,0,0,0,0,0,2,0,2,0','iain_halftone_shapes': '100,0,0,0,0,0,0','hedcut': '0.5,0.5,0.5,0.0,0.5,0,1,0','jpr_remove_blocks1': '4,3,70','nr5': '1.6,5,1,1,.75,3,0,.75,.5,0,1,1,100,0,-100,0,1.3,0','iain_hearttone': '100,0','jpr_shapes_gradient': '2,0.25,0.001,100','iain_png_processing': '4,0,0,0,3,3,0,.75,2,1,5,0,0,1,1','iain_2d_scopes': '1,2,2,6,512,2048,1,0,0,0,0','iain_demosiac': '0','jpr_specularbumps': '270,1,13,0,80,0.1,0.1,0','iain_smooth_tutorial': '1000,0.5,1,0.6,1.1,0,0','simplelocalcontrast_p': '16,2,0,1,1,1,1,1,1,1,1,0','iain_denoise_2019_beta3': '1,0,0,0,0.5,1,0,5,3,0,3,0,.5,4,0','jpr_warpfromthreshold': '170,2,10,2','automixer': '0,0','iain_fx_skin_mask': '55,200,0,0,0,1','iain_remove_pattern': '3,3,3,0,4,128,1,0','fx_mesh_blend': '0,3,0,0,0,0','iain_brown_spot_clean': '1,2','iain_smartdemos': '0,1.5,2','iain_star_burst': '254,50,5,45,2,0,0','iain_CA_correction': '0,0,2,0,3','fx_align_layers': '0,0.7,0,0','star_tone': '100','iain_detect_moire': '50,5,9,30','iain_unindex': '30,20,1,50,50','fx_blend_average_all': '0','iain_sub_cast': '5,20,250','fx_tones2layers': '3,85,170,0.5,0','iain_weightmap': '1,40','fx_blend_edges': '1,0.8,0','iain_turbulent_halftone': '15,20,0,1,512,0.75,0,0,0','fx_contrast_swm': '2,0,1','iain_iains_nr': '3,3,1,0,0,0,1,0,0,0,1.35,0,0','fx_blend_fade': '1,0,0,5,0,0,0,0,0,0,"cos(4*pi*x/w)','mc_flip': '50,0,255,255,255,255,1','fx_dodgeburn': '15,1.5,25,10,40,1.5,25,10,0,0,10,0','iain_iid_demosaic': '1,1,1,0,0','fx_blend_median': '0','mc_information': '50,0,255,255,255,255,1','fx_drop_shadow': '3,3,1.8,0,0,0','fx_blend_seamless': '0,0,25,0,0','luminance_nr_two': '10,1,1,.8,.7,.6,.5,.4,.3,1200,64,0,0,0,0,0,0,0,0,0,0,0','mc_mail': '50,0,255,255,255,255,1','fx_drop_shadow3d': '0,0,0,0,1,1,2,0.5,0,0,0,200,0','mc_phone': '50,0,255,255,255,255,1','iain_minimum_chroma_demosaic': '0,2,0','fx_blend': '6,0,100,1,"1/2','fx_light_patch': '5,0.7,2.5,0','mc_shopping_cart': '50,0,255,255,255,255,1','iain_moire_removal': '5,5,0','fx_split_colors': '50,16,1,0','samj_Ombre_Portee': '0,0,0,128,0,0,0,0,255,127,127,127,255,2,2,255,255,255,255,0.1','iain_moire_removal_NP': '5,5,0','jeje_zernike_preview': '50,50,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0','fx_fade_layers': '10','samj_Ombre_Portee_B': '16,128,0,1,16,1,0,0,127,127,127,255,2,2,2,2,255,255,255,255','ms_nlmeans_c_noise2_p': '3,1,0,0,0,0,0,10,2,4,2,7,0,0,0,0','append_tiles': '0,0','jpr_colourillusion': '2,25','samj_Ombre_Portee_C': '32,8,16,192,0,1,16,1,0,0,96,96,96,255,2,2,2,2,255,255,255,255','fx_morph_layers': '10,0.2,0.1,0','jpr_coltexindex': '5,55,55,45,45,1,1,0,0.05,0.5,0.95,0.5,1,2,0.7','ms_patch_c': '5,1,1,5,4,3,2,1,1,1.3,0.375,.5,0.125,0','samj_Ombre_Portee_D': '16,64,64,2,1,16,5,1,-32,4,1,2,2,2,255,255,255,255','fx_apply_multiscale': '4,25,100,0,3,0.5,0.5,0,0,0.5,0.5,0,"",0,0','MS_Patch_NR': '1.3,0,0,0,3,5','jpr_decimate': '0.375,2','fx_shadow_patch': '0.7,0','Lylejk_Wicker_2': '50,50,1,50,50,1,1,12,10,5,1,1,0,0,0,255,150,0.54,0.85,0.6,7.83,0.68,19,2.64,0,1,3,0,0.29,28.7,100,0,0,1,10,20,0.1,1,10,12,2,40,0.7,0.3,0.6,1.1,0.8,30,2,0,1,3,1,0,16,1,0','fx_stroke': '3,50,0,2,1,100,0,0,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,1,0','jpr_gradient_smooth': '0,1.5','fx_slice_luminosity': '1,1,2,1,0,64,0,0,1,64,128,0,0,0,128,192,0,0,0,192,255,0,0','Lylejk_Woven': '19.6,32.4,1,0,0,19.6,32.4,1,0,0,12,10,5,1,1,0,0,0,255,19.6,32.4,1,0,0,19.6,32.4,1,0,0,150,0.61,0.85,0.6,7.83,0.68,19,2.64,0,1,1,0,0.29,37.2,100,0,0,2,0,16,0','split_tiles': '3,3,0','jpr_orientedthinning': '5,15,1,0,0','fx_blend_shapeaverage': '1,0,0','fx_split_luminance': '1,1,1,0,0','garagecoder_lylejk_samj_points_outlines': '0,0.05,10,0.12,0,0,2,0','fx_crystal_background': '10,25,0,100,1','fx_lylejk_stencil': '5,10,3,0','fx_hue_overlay_masks': '0,5','fx_MappedSmooth': '0,0,0,300,1,0','samj_Degrades_HSL_TSL': '4,800,240,240,40,255,120,40,240,255,0,0,0,360,100,100,0,0,0,718,75,100,0,100,0,0,0,0','Lylejk_Luma_Invert': '1,0','fx_fix_HDR_black': '20,25,50,200,0,0','mc_barbed_wire': '50,0,255,255,255,255,1','jeje_fibers': '10,50,10,0','Lylejk_Quantize_Wicker': '16,50,50,0,16,10,5,1,1,0,0,0,255,1,10,10,153,0,2,10,20,0.1,1,0','fx_noisepainting': '0,0,0,5,2.5,1.5,50,1,0','mc_crosshair': '50,0,255,255,255,255,1','samj_Formes_Couleurs_Variees_Dans_Image': '0,0,0,0,0,192,128,64,255,1,1,1,0,0,127,255,0,0,0,0,1','Lylejk_Ribbon': '150,0.42,0.85,0.6,7.83,0.68,19,2.64,0,1,2,16,3.44,0,3,0.79,0.72,4.97,1.70,150,0.42,0.85,0.6,7.83,0.68,19,2.64,0,1,2,0,0.32,43.1,100,0,2,1.15,5,1,0','fx_SmoothSketch': '1,6,0.8,0.3,0.3,0,1000,0,50,10,2,0.6,0.55,1,0','fx_cupid': '75,0,255,255,255,255,1','fx_marble': '.5,1,0,0,.4,.6,.6,1.1,0,100','lylejk_test_TRW': '50,50,1,16,10,5,1,1,0,0,0,255,50,50,1,1,1.8,10,153,150,0.42,0.85,0.6,7.83,0.68,19,2.64,0,1,1,0,0.5,10.5,100,0,0,0.5,10.5,100,0,1.15,5,1,0.68,0.5,10.5,100,0,0,1,10,1,0,0','fx_gear': '75,12,15,0,40,0,255,255,255,255,1','fx_DemoVecRot': '0','samj_Marbre_en': '1,1,8,5,0.2,0,0,0,140,120,220,0,3,1','Lylejk_Wicker': '10,10,153,150,0.42,0.85,0.6,7.83,0.68,19,2.64,0,1,1,0,0.5,10.5,100,0,0,0.5,10.5,100,0,1.15,5,1,0.68,0.5,10.5,100,0,0,1,10,1,0,0','fx_WarpTest': '0,0,0,1,0','fx_heart': '75,0,255,255,255,255,1','fx_maze': '24,1,0,1,0','jeje_rays': '50,50,10,0,0.5,255,0,0,255,255,0,0','mc_paint_splat': '50,0,255,255,255,255,1','mc_australia': '50,0,255,255,255,255,1','fx_mineral_mosaic': '1,2,1,100,0','samj_Rays_Of_Colors': '300,12,40,16,38,1,0,0,0','fx_barnsley_fern': '0,100,30,40,10,178,0,255,1','fx_sierpinski': '6,50,0,0,100,100,100,255,255,255,1','samj_Motifs_Aleatoires_Symetriques_Degrades': '0,400,4,1,1,1','samj_Contours_Gros_Pixels': '1,8,0,20,20,16,1.1,0,0,15,0,0,0,1','fx_AbstractFlood': '1,10,7,2,0,10,5,3,255,255,255,255,0,300,10,90,0.7,0,0,0','samj_Degrades_XYZ_CIE': '6,800,240,240,40,255,120,40,240,255,0,0,0,100,64,64,0,0,1,0,100,-128,128,-128,128,0,11,0,0','samj_EPPE_Transform': '50,50,0,10,10,32,0.1,10,18,0,255,255,255,255,3,0,0.1','fx_bwfilmsimulate': '0,0.299,0,0.587,0,0.114,0,1,1,0,0,0,0,0,0,2,0,0,0,16,4,0','samj_Lignes_H_ou_V_Colorees': '159,190,195,55,67,140,54,40,39,140,81,88,207,175,190,220,202,196,170,186,192,130,149,139,112,96,96,237,168,138,220,199,205,234,217,219,255,256,256,1,0,0','mc_gum_leaf': '50,0,255,255,255,255,1','fx_blockism': '3,1.6,0.5,50,0.5,64,0,1,0','samj_Marbre': '1,1,8,5,0.2,0,0,0,140,120,220,0,3,1','fx_CompositionAnalysis': '0','samj_Motif_Plasma': '2,20,20,30,1,75,0','fx_shapes': '1,16,10,2,5,90,0,0,1,1,0','fx_dodgesketch': '3,10,7,2,0,0','mc_maple_leaf': '50,0,255,255,255,255,1','samj_Motifs_7200': '2,0,20,20,30,1,75,0,0,255,0,221,255,0,0,0','fx_ExposureWeightMap': '0.3,0.3,0.2,0.3,1,0','samj_Motifs_7200_VarianteA': '2,0,20,20,30,1,75,0,0,255,0,221,255,0,0,0','samj_Steps_V2': '10,10,4,1,10,2,60,0,1.1,10','samj_Tissu_Fond_Flou': '0,0,100,100,0,1,0,1,0,0,0,0,0','fx_snowflake': '5,1,255,255,255','samj_Variation_Stained_Glass': '0,2,8,0,3,40,100,0,1.1,20','jeje_periodic_dots': '6,4,0,1,0','fx_satin': '20,1,0,0,0,0,255,255,255,255,255,0,0,0,-50,0,0','fx_mad_rorscharchp': '3,0,50,1,300,0,0,0,0','fx_jobs_colors': '0,0,0','fx_StructureTensors': '0.1,0','fx_plaid_texture': '50,2,0,90,1,300','fx_stars': '10,0,32,5,0.38,0,255,255,100,200','samj_en_Contours_Gros_Pixels': '1,8,2,20,20,16,1.1,0,1,15,1,0,0,1','fx_dragoncurve': '20,0,1,255,255,255','jeje_strip': '45,50,0,1,0','samj_Points_Aleatoires_001': '10,255,255,0,255,3,0,1','fx_tetris': '10','rgb2bayer': '0,1','fx_truchet': '32,5,1,1,0','fx_camouflage': '9,12,100,30,46,33,75,90,65,179,189,117,255,246,158','jeje_turing_pattern': '1,2000,.1,.899,-.91,2,.1,.25','fx_polka_dots': '80,20,50,50,0,0.5,0.1,1,255,0,0,255','weave': '6,65,0,0.5,0,0,0,0,0','texturize_canvas': '20,3,0.6','fx_color_ellipses': '400,8,0.1','fx_elevation3d': '100,1,1024,1024,0.8,25,0,21,45,0,0,-100,0.5,0.7,2,1','fx_steampen': '0.95,14,2,2,0.9,0,1,0,0.5,0.75,0.48,0','fx_extrude3d': '10,512,0.6,1024,1024,0.5,57,41,21,45,0,0,-100,0.5,0.7,4,1','fx_graphic_boost': '1.25,2,0,0.15,14,0,1,0.5,0.45,2,0,1,0,1,1,0.5,0.45,1,0','fx_compose_boostscreen': '0.7,0,0.7','fx_imageobject3d': '1,1024,1024,0.5,57,41,21,45,0,0,-100,0.5,0.7,4,1','fx_compose_colordoping': '1,0','fx_lathing3d': '76,2,361,1024,1024,0.5,0,0,0,45,0,0,-100,0.5,0.7,4,1','fx_colorstamp': '1,50,1,20,2,0','fx_random3d': '0,50,3,100,45,0,0,-100,0.5,0.7,3,1','fx_compose_graphicolor': '0.6,0,0.8','fx_compose_comix_color': '1,0,1','samj_Adjacent_Annular_Steiner_Chains_en': '50,50,0,0,6,56,20,50,0,255,0,221,127,72,0,255,127,0,145,255,127,0,255,144,127,72,255,0,127,255,217,0,127,255,0,0,127,5,0,0,2,0,0,0,255,0,0,0','fx_compose_darkedges': '1,0.5,0,0.7','samj_Adjacent_Annular_Steiner_Chains': '50,50,0,0,6,56,20,50,0,255,0,221,127,72,0,255,127,0,145,255,127,0,255,144,127,72,255,0,127,255,217,0,127,255,0,0,127,5,0,0,2,0,0,0,255,0,0,0','fx_novelfx': '0,2,6,5,20,0,0.62,14,0,1,0.5,0.78,1.92,0,0,0,1,1,0.5,0.8,1.28,0','samj_Rectangles_Adjacents': '10,10,80,80,0,50,6,0,0,0,0,0,255,1,255,255,0,127,0,0,255,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_en_Rectangles_Adjacents': '10,10,80,80,0,50,6,0,0,0,0,0,255,1,255,255,0,127,0,0,255,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_en_Annular_Steiner_Chains': '50,50,50,6,0,0,0,0,255,1,255,255,0,127,64,192,128,127,0,255,0,127,0,0,255,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_Annular_Steiner_Chains': '50,50,50,6,0,0,0,0,255,1,255,255,0,127,64,192,128,127,0,255,0,127,0,0,255,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','fx_compose_heavyscreen': '0.6,0,0.7','fx_phoenix': '0.95,14,2,2,0.9,0,0,0,1,1,0','fx_smooth_anisotropic': '60,0.16,0.63,0.6,2.35,0.8,30,2,0,1,1,0,1','fx_psyglass': '0,20,0.1,1,1,0,1,1,0,1,1,0,0,2,0,0,0','fx_viral': '3,0,0,0,0,0','fx_compose_vivid_color': '1,0,1','fx_compose_vividedges': '1,0.5,0,0.7','fx_seamless_turbulence': '15,20,0,1,3,0','samj_Noel_2016': '50,50,100,150,7,0,240,45,15,255,-15,2.5,2,0.8,1,1.5,0,0,0,0.25,10,0.8','fx_compose_vividscreen': '0.6,0,0.7','samj_Chryzodes': '100,0,0,0,255,0,50,50,45,79,3,1,240,128,64,255,0,0,0,0,0,0,0,0,0,0,0','fx_m_l_unsharp2': '12,2.18,0.3,1.5,1,0.5,0,0.5,0.8,1.28,0','samj_en_Chryzodes': '100,0,0,0,255,0,50,50,45,79,3,1,240,128,64,255,0,0,0,0,0,0,0,0,0,0,0','samj_Contour_Line_Laser_LED': '0,1,0','samj_dessiner_un_polygone': '5,50,50,0,40,50,1,255,255,0,0,0,0,0,1,0,0,255,0,0,255,0,0,0,127,127,127,0,0,0,0,0,255,255,255,0,0,0,0,1,255,0,0,0,1','samj_Egg_Oeuf_Granville': '50,50,0,20,30,10,0,0,0,0,255,1,255,255,0,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_Egg_Oeuf_Hugelschaffer': '50,50,50,6,48,0,0,0,0,0,255,1,255,255,0,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_Egg_Oeuf_Rosillo': '50,50,40,200,300,0,0,0,0,255,1,255,255,0,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_Engrenages_Laser_LED': '80,20,12,14,17,1,1,2,19,250,0,0,0,0','fx_equation_parametric': '"sin(t)*(exp(cos(t))-2*cos(4*t)-sin(t/12)^5)","cos(t)*(exp(cos(t))-2*cos(4*t)-sin(t/12)^5)",0,100,4096,1,0,64,0,0,128,0,0,1,1,1','fx_compose_darkscreen': '0.7,0,0.7','samj_Etoile_De_Pompei_Triangles_Sierpinski': '50,50,30,100,0,0,0,255,0,5,255,0,0,127,255,0,255,127,0,0,255,127,0,255,255,127,255,255,0,127,0,63,255,64,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_Etoiles_Laser_LED': '1400,5,2,0,0,0,0','samj_Etoiles_Remplies_Triangles_Sierpinski': '6,50,50,50,40,30,0,0,0,0,0,255,1,4,255,0,0,127,255,192,64,127,0,0,255,127,0,255,255,127,255,255,0,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_Flocon_De_Neige': '50,50,6,50,40,0,3,192,192,192,1,0,3,255,255,255,0.7,0,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_Flocon_Laser_LED': '1400,6,5,0','samj_Fractal_Tree': '50,100,-90,11,10,20,255,0,0,255,20,0,4,1,0,0.25,10,0.8,0','fx_corner_gradient': '255,255,255,128,255,0,0,255,0,255,0,255,0,0,255,255,1','fx_custom_gradient': '0,0,0,1,4,1,0,128,100,100,2,0,1,0,"",1,0,0,0,0,255,255,0,0,255,255,255,0,255,255,255,255,255,0,255,255,255,0,255,0,255,0,0,255,255,128,128,128,255,255,0,255,255,0,0,0,0','fx_linear_gradient': '0,0,0,255,255,255,255,255,0,45,0,100,0','fx_random_gradient': '32,0,0,128,128,128,1','fx_ball': '128,0.8,1,1.5,255,0,255','samj_Linear_Gradient_CIE_Lab': '0,0,240,40,160,255,240,240,40,255','samj_en_Shape_Linear_Gradient_CIE_Lab': '10,10,90,90,2,0,240,40,160,255,240,240,40,255,0,0,0,0,255,0','samj_Shape_Linear_Gradient_CIE_Lab': '10,10,90,90,2,0,240,40,160,255,240,240,40,255,0,0,0,0,255,0','gtutor_hairlock': '0.5,0.5,0.5,255,255,0,255,0.5,45,0.5,0.5,0','Harmonograph_samj_en': '50,50,192,128,64,255,0,0,1000,0,400,150,200,200,100,4,6,2,2,15,270,75,60,0.04,0.04,0.05,0.06,0,0,0,1,1','Harmonograph_samj': '50,50,192,128,64,255,0,0,1000,0,400,150,200,200,100,4,6,2,2,15,270,75,60,0.04,0.04,0.05,0.06,0,0,0,1,1','samj_Hawaiian_Earring': '50,50,40,6,0,0,0,0,0,255,1,255,255,0,127,0,0,255,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_en_Hawaiian_Earring': '50,50,40,6,0,0,0,0,0,255,1,255,255,0,127,0,0,255,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','Traits_Strokes_samj_en': '50,50,35,0,100,0,30,0,360,240,60,120,255,0,0,0,20,0,0,0,1,1','fx_coloredobject3d': '1,128,128,128,255,0.5,0.5,0.5,57,41,21,45,0,0,-100,0.5,0.7,4,1','samj_en_Lignes_Epaisseur_Variable': '0,32,3,0,0,0,255,255,255,255,255,0,0,1,0,0,0,0,0,0,0.5,0.5,1.8,0,0','fx_lissajous': '4096,0.9,0.9,3,8,7,0,0,0,0,0,0,0,0,255,255,255,255','samj_Orbites': '100,0,0,0,255,50,50,20,79,45,2,240,128,64,255,0,0,0,0,0,0,0,0','samj_Cercles_Tangents_Dans_Cercle': '50,50,50,40,0,0,0,0,255,1,127,127,127,127,255,0,0,127,0,255,0,127,0,0,255,127,255,0,255,127,255,255,0,127,0,255,255,127,192,128,64,127,64,192,128,127,128,64,192,127,192,64,128,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_en_Cercles_Tangents_Dans_Cercle': '50,50,50,40,0,0,0,0,255,1,127,127,127,127,255,0,0,127,0,255,0,127,0,0,255,127,255,0,255,127,255,255,0,127,0,255,255,127,192,128,64,127,64,192,128,127,128,64,192,127,192,64,128,127,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','Pintograph_samj': '50,50,192,128,64,255,0,0,1000,0,400,150,200,200,100,4.00,4.05,4.16,4.32,75,150,75,60,0,0,0,1,1','Pintograph_samj_en': '50,50,192,128,64,255,0,0,1000,0,400,150,200,200,100,4.00,4.05,4.16,4.32,75,150,75,60,0,0,0,1,1','fx_plasma': '0.5,0,8,0,0,128,128,128','fx_equation_plot': '"X*c+10*cos(X+c+u)",-10,10,100,3,2,0','samj_Arbre_Pythagore': '50,95,11,12,255,0,0,255,20,"A",1,0,0,0.25,10,0.8,0','fx_rainbow': '80,80,175,175,3,80','samj_Rosace_Triangles_Sierpinski': '6,6,50,50,50,-15,25,5,30,0,0,0,255,0,0,0,0,3,0,0,255,127,255,255,0,127,128,64,192,127,64,128,192,127,0,255,255,127,0,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_en_Linear_Gradient_CIE_Lab': '0,0,240,40,160,255,240,240,40,255','fx_shadebobs': '50,5,200,1,-1,2,1,0.8,0,8','samj_en_Cercles_Qui_Tournent': '800,255,255,255,255,0,1,0.5,0.33,7,17,1,0.5,0.33,7,17,1,10,0,0,0,255,0,0,0,0,0,0,0,0.5,0.5,1.8,0','samj_Formes_Geometriques_Simples': '50,50,127,127,127,127,255,255,0,255,0,0,255,255,5,40,40,4,0,0,1','samj_Lignes_Epaisseur_Variable': '0,32,3,0,0,0,255,255,255,255,255,0,0,1,0,0,0,0,0,0,0.5,0.5,1.8,0,0','fx_superformula': '4096,0.9,0.9,8,1,5,8,0,0,0,3,128,255,128,255','samj_Cercles_Qui_Tournent': '800,255,255,255,255,0,1,0.5,0.33,7,17,1,0.5,0.33,7,17,1,10,0,0,0,255,0,0,0,0,0,0,0,0.5,0.5,1.8,0','samj_en_Formes_Geometriques_Simples': '50,50,127,127,127,127,255,255,0,255,0,0,255,255,5,40,40,4,0,0,1','samj_Poisson_D_Avril': '50,50,40,2,0,0,0,0,255,1,250,60,10,255,255,255,255,255,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','banding_denoise': '5,5,5,10,0','samj_Superposition_Triangles_Sierpinski': '6,6,50,50,50,1,20,30,0,0,0,255,1,4,0,0,255,127,255,255,0,127,128,64,192,127,64,128,192,127,0,255,255,127,0,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_en_Flocon_De_Neige': '50,50,6,50,40,0,3,192,192,192,1,0,3,255,255,255,0.7,0,0,0,0,0,0,0,0,0.5,0.5,1.8,0,0,0,0','samj_Chains_Solidify': '50,50,0,6,56,20,50,0,255,0,221,255,72,0,255,255,0,145,255,255,0,255,144,255,72,255,0,255,255,217,0,255,255,0,0,255,5,255,127,0,255,0,0,0,255,100','bayer2rgb': '6,6,4','Traits_Strokes_samj': '50,50,35,0,100,0,30,0,360,240,60,120,255,0,0,0,20,0,0,0,1,1','samj_Palette_De_Degrades': '159,190,195,55,67,140,54,40,39,140,81,88,207,175,190,220,202,196,170,186,192,130,149,139,112,96,96,237,168,138,220,199,205,234,217,219,0,0,256,2','Spirographe_samj_en': '50,50,200,50,150,192,128,64,255,0,0,3,0,1,0,0,0,255,0,0,255,0,255,255,0,255,0,0,0,1,1','fx_tree': '11,10000,0,0,15,150,0,2.15,0.8,-40,40,10,75,0,70,20,40,25,0,255,100,70,140,60,255,100,0.4,0.4','afre_cleantext': '8,1,80,95','gcd_deinterlace2x': '40,0,0,2,0,1','Spirographe_samj': '50,50,200,50,150,192,128,64,255,0,0,3,0,1,0,0,0,255,0,0,255,0,255,255,0,255,0,0,0,1,1','samj_Splines_Test': '50,50,30,30,90,30,1,10,2,2,2,2,2,2,2,2,255,255,0,255,0,255,255,255,1,0,0','Triangles_Shades_Adjacents': '0,50,50,60,-1,0,255,255,255,255,0,221,72,0,255,0,145,255,0,255,144,72,255,0,255,217,0,255,0,0,5,0,0,128,128,128,1,0,3,1,0','fx_pahlsson_descreen': '0','samj_Des_Lignes_002': '100,0,0,192,128,64,255,0,0,1,50,50,0,0,0,0,1','samj_Test_Visu_3D': '1,"C:\\GimpEval-2.9.5-Win\\images_test\\GMIC\\cube.off",0.5,1,1,0,0,0,1,0,0,0,1024,1024,0.5,0,0,0,45,0,0,-100,0.5,0.7,2,1,400,1,225,255,255,255','fx_turbulence': '128,6,4,0,0','gcd_despeckle': '20,10','samj_en_Des_Lignes_002': '100,0,0,192,128,64,255,0,0,1,50,50,0,0,0,0,1','iain_fast_denoise_p': '0,0,1,0,0,0,1','Twisted_Rays_en': '800,1,0.2,2,5,21,0,0,0,0,255,255,0,255,255,255,0,255,0,255,255,255,0,255,255,0,0,255,255,0,255,255,255,255,255,255,0,0,0,0,255,0,2,2,0,0,5,0,0','iain_recursive_median_p': '3,1,0,0,1','fx_inpaint_holes': '4,20,1','iain_nr_2019': '1,0,0,0,0.5,1,0,5,3,0,3,0,.5,4,0','Twisted_Rays': '800,1,0.2,2,5,21,0,0,0,0,255,255,0,255,255,255,0,255,0,255,255,255,0,255,255,0,0,255,255,0,255,255,255,255,255,255,0,0,0,0,255,0,2,2,0,0,5,0,0','fx_inpaint_morpho': '255,0,0,255,0','jeje_scandoc': '3,1,90,5,0','rep_binary_quaddro_mc_gui': '0,0,0,0,1,2,0,1,2,3,0,1,2,3,4,0,8,8,128,2,0,0,0,1,0,8,8,128,2,0,0,0,1,0,8,8,128,2,0,0,0,1,0,8,8,128,2,0,0,0,1,0,8,8,128,2,0,0,0,1','jeje_local_wiener': '2,11,0,0','fx_inpaint_matchpatch': '0,9,10,5,1,255,0,0,255,0,0','samj_CorLine': '0,10,0.5,0,0,50,1,0','gui_rep_shape_brick': '150,150,5,5,0,0,0,0,0,0,170,0,0,255,85,0,0,255,121,77,2,255,0,41,100,0','jeje_unstrip': '1,20,4,1,0,0','rep_color_existence_distribution_rgb8': '1','samj_CorLine_B': '0,1,10,0,0,0,0.5,0,0,50,1,0','fx_inpaint_patch': '7,16,0.1,1.2,0,0.05,10,1,255,0,0,255,0,"100%"','jeje_denoise_patch_dict': '1,8,1.1,1.1,0,0','fx_inpaint_pde': '75,1,20,255,0,0,255,0','goof_res': '8,0,0,0','fx_scale_dcci2x': '1.15,5,0','-srand': '781123','jeje_denoise_iuwt': '3,4,2,0','fx_upscale_smart': '"200%","200%",2,0.4,50','fx_rep_nebulous': '0,4,10,10,0,0,0,1,0,0,1,0,0,0,0,2,0,1,3','iain_pixel_denoise_p': '2,1,11,0,1','sp': 'cliff','fx_scalenx': '0,0','rep_mj_newf': '16,0,0,128,9,0,75,5,10,50,50,45,0,0,0','plasma_transition': '0.5,5,1,42','fx_modulo': '1,0','fx_faded_mirror': '0,10,10','randomwaves': '84,80.,1.2,42','gui_rep_prime_surface': '0,0','fx_rep_rand_sqrrecfill': '0,0,15,2,1,1,0,1,1,1,0,0,0','gaap_test': '0,0,0,0','fx_adjust_orientation': '5','rep_binary_quaddro_basic_gui': '0,0,8,8,128,2,0,0,0,256,255,1,361,361','fx_gca': '255,255,255,1,0,0,0','fx_grain': '40,5,0,2,0.8,0.5,0.5,1,0,0.5,0.6,0.2,0.5,0','fx_apply_curve': '0,-1,128,-1,128,-1,128,-1,128,-1,128,255,1,0,0,0,0','fx_perspective_scale': '2,75,0,0,0','fx_lavalampbw': '3,30,1,20,2,0.01,0','gui_rep_tfrac': '0,0,10000,255,3,0,0,1,1,1,1,0,0,0,"atan2(a^2","b/sin(a)","sin(a)/cos(b)","b/cos(a)","a/sin(b)","b/cos(a+b)","a","b","a","b",0,3,0','KittyRings': '30,8,0,1,113,0,113,0,255,0','dt_segment_shaded': '1,0.7,1','fx_moire': '1,0,2,1,1,2,1,5','gui_layer_info': '1','fx_tk_make3D': '0,20,0,20,0,0,0,0,0,0,0,0,0,1.2,25,1,0,1,0,0,0,2,200','moon2panorama': '0,0,0,360,0,0,1,0,0','fx_text_pointcloud3d': '64,"G\'MIC","Rocks!",1,200,220,255,255,255,255,255,2,2,1,19','fx_tk_animateobject': '0,0,0,0.5,0.5,400,2,0,0,0,0,0,1,0,0,1','fx_tk_deana': '20,2','fx_souphead_filter': '0','fx_tk_depthmap': '0,20,0,0,0,0,0,0,0,0','fx_transition3d': '10,8,8,1,1,0,800,1','fx_tk_lenticular': '30,0,5,0,1,0','disco': '10,15,20,250','gcd_unstereo': '5,0.1,1,1,1,1,0','spiral_RGB': '1,3,5,0','fx_tk_retouch': '30,3,1,20,1.5,1,2.5,0,0,0','fx_tk_depth_obtain': '0,0.1,100,0','samj_CeKoaSa_001': '0,15,3,1,3,0','gcd_stereo_img': '0,0.5,1.2,1,0.25,2,4,1,0','mc_flou': '30,6,1,1,1,0,255,1,1,1,0','fx_tk_dof': '50,50,30,60,5,15,2,0,0,200,40,2,0,0,0,0,0.01,0,1,0,0','samj_CeKoaSa_002': '0,15,3,1,3,1,0','samj_CeKoaSa_003': '0,5,1,1,3,0','fx_tk_stereoimage': '0,0,1,0,1,0','mc_pendraw': '8,0.8,450,21,0.5,1,0,0,255,0,0','fx_tk_infrared': '0.75,0.5,-100,0.75,0,1,0,0,1,1,0,50,0','samj_CeKoaSa_005': '16,16,0,0,0.2,1,1,0,1,0','samj_BoxFiter_Map': '2,3,3,0,0,0,2,127,16,0,0,0.2','samj_BoxFiter_Test': '2,3,3,1,2','samj_CeKoaSa_004': '30,0,0,0.8,0,0','samj_CeKoaSa_007': '8,8,10,8,8','Polygonize_GUI': '300,10,10,10,10,0,0','samj_CeKoaSa_008': '64,64,4,1,2,16,1,20,0.1,0,1,64,1,2,10,0.8,255,255,255,255,0','samj_CeKoaSa_010': '30,10,0.1,2,10','samj_Relief_A': '3,1,0,1,16,1,50,1,1.0,1.2,1,1,1,1,1,1,0,0,0,0,0,0,100','samj_CeKoaSa_011': '0.2,0,0,5,0,0,0,0,240,40,160,255,240,240,40,255,0,50,205','samj_test_B': '100','samj_test_C': '100','samj_test_E': '0,0.7,0.3,0.6,1.1,0,200,125,50,0,1','samj_test_D': '40,255,10,30,5,0,8,0,4,0,25','samj_test_F': '40,50,1','samj_test_G': '0,0,0,30','fx_image_sample': '0,0,0','samj_Test_Solidify': '10,10,1,0.02,8,1,75,0,20','samj_test_x_color_curves': '1,0','samj_gimp_texture_zero_zero_deux': '0,10,4,10,0.5,1,1,1,0.3','samj_Texture_Aquarelle_1': '10,10,4,3,251,237,206,1','demo_xy': '1,1','samj_Toile_D_Araignee': '0,10,4','demo_ra': '1,1','mathmap_flag': '0.05,5,1,5','mathmap_spiral': '5,0'}
2 |
--------------------------------------------------------------------------------
/examples/gmic-filters-default-parameters-to-operators/make_operators.py:
--------------------------------------------------------------------------------
1 | import json
2 | from default_parameters_gmic_py import default_parameters
3 |
4 | print("""import gmic
5 | import bpy
6 | gmic.default_parameters = {DEFAULT_PARAMETERS}
7 | """.format(DEFAULT_PARAMETERS=default_parameters))
8 |
9 | operator_template = \
10 | """
11 | def gmic_enum_items_cb{OperatorSuffix}(self, context):
12 | l = {MenuItems} #(('ONE','One','First'), ('TWO','Two','Second'), ('THREE', 'Three', 'Third'))
13 | gmic_enum_items_cb{OperatorSuffix}.lookup = {{id: name for id, name, desc in l}}
14 | return l
15 |
16 | class GmicOperator{OperatorSuffix}(bpy.types.Operator):
17 | bl_idname = "object.gmic_operator{OperatorSuffix}"
18 | bl_label = "{Label}"
19 |
20 | myprop = bpy.props.EnumProperty(items=gmic_enum_items_cb{OperatorSuffix})
21 |
22 | def execute(self, context):
23 | bpy.ops.render.render()
24 | bpy.data.images['Render Result'].save_render("somefile.tga")
25 | gmic.run("somefile.tga " + gmic.default_parameters[self.myprop] + " display")
26 |
27 | self.report({{'INFO'}}, gmic_enum_items_cb{OperatorSuffix}.lookup[self.myprop])
28 | return {{'FINISHED'}}
29 | """
30 |
31 | opLines = []
32 | opline_template = "op = layout.operator_menu_enum(GmicOperator{OperatorSuffix}.bl_idname, 'myprop', text=GmicOperator{OperatorSuffix}.bl_label)"
33 | registerLines = []
34 | register_template = "bpy.utils.register_class(GmicOperator{OperatorSuffix})"
35 | unregisterLines = []
36 | unregister_template = "bpy.utils.unregister_class(GmicOperator{OperatorSuffix})"
37 | with open("/home/jd/Productions/GMIC/filters290.json", "r") as f:
38 | f_json = f.read()
39 | all_filters = json.loads(f_json)
40 | if all_filters:
41 | for pos, category in enumerate(all_filters["categories"]):
42 | print(operator_template.format(Label=category['name'], OperatorSuffix=pos, MenuItems=tuple((filter['command'], filter['command'], filter['command']) for filter in category['filters'])))
43 | opLines.append(" "*8 + opline_template.format(OperatorSuffix=pos))
44 | registerLines.append(" "*4 + register_template.format(OperatorSuffix=pos))
45 | unregisterLines.append(" "*4 + unregister_template.format(OperatorSuffix=pos))
46 |
47 | custom_menu_template = \
48 | """
49 | class SimpleCustomMenu(bpy.types.Menu):
50 | bl_label = "G'MIC Quick Filters"
51 | bl_idname = "OBJECT_MT_simple_custom_menu"
52 |
53 | def draw(self, context):
54 | layout = self.layout
55 | {operatorLines}
56 | """
57 |
58 | print(custom_menu_template.format(operatorLines="\n".join(opLines)))
59 |
60 | footer_template = \
61 | """
62 | def register():
63 | {registerLines}
64 | bpy.utils.register_class(SimpleCustomMenu)
65 |
66 | def unregister():
67 | {unregisterLines}
68 | bpy.utils.unregister_class(SimpleCustomMenu)
69 |
70 | if __name__ == "__main__":
71 | register()
72 |
73 | # The menu can also be called from scripts
74 | bpy.ops.wm.call_menu(name=SimpleCustomMenu.bl_idname)
75 | """
76 |
77 | print(footer_template.format(registerLines="\n".join(registerLines), unregisterLines="\n".join(unregisterLines)))
78 |
--------------------------------------------------------------------------------
/get_latest_gmicpy_version.py:
--------------------------------------------------------------------------------
1 | """
2 | Prints the latest available gmic-py version from PyPI.org on standard output
3 | This comes in handy for Github CI scripts steps labels.
4 | """
5 |
6 | import yolk.pypi
7 | PYPI_GMIC_PACKAGE_NAME="gmic"
8 |
9 | if __name__ == "__main__":
10 | releases = yolk.pypi.CheeseShop().package_releases(PYPI_GMIC_PACKAGE_NAME)
11 | releases.sort()
12 | print(releases[-1], end='')
13 |
--------------------------------------------------------------------------------
/make_addon_requirements.txt:
--------------------------------------------------------------------------------
1 | yolk3k
2 |
--------------------------------------------------------------------------------
/make_addon_zip.py:
--------------------------------------------------------------------------------
1 | """
2 | Run this after installing the make_addon_requirements.txt with python 3.7 or more eg. in a virtual environment.
3 | It will create a freshest release of gmic-blender embedding gmic-py inside the downloads directory.
4 | """
5 |
6 | import shutil
7 | import urllib.request, json
8 | import tempfile
9 | import os
10 | from distutils.dir_util import copy_tree
11 | import zipfile
12 | import re
13 |
14 | import yolk.pypi
15 |
16 | # CONSTANTS
17 | RELEASE_NAME = "gmic_blender"
18 | RELEASE_ADDONZIP_DIRECTORY_NAME = "downloads"
19 | ADDON_PATH = f"downloads/{RELEASE_NAME}.zip"
20 | PYPI_GMIC_PACKAGE_NAME = "gmic"
21 | GMICPY_DIRECTORY_NAME = "gmic-py"
22 | GMICPY_DOWNLOADS_CACHE_ENV_VARIABLE = "GMICPY_DOWNLOADS_CACHE"
23 | ASSETS_DIRECTORY_NAME = "assets"
24 | ASSETS_GMIC_FILTERS_JSON_PATH = os.path.join(ASSETS_DIRECTORY_NAME, "gmic_filters.json")
25 | BLENDER_ADDON_MODULE_FILE = "__init__.py"
26 | BLENDER_ADDON_README_FILE = "README.md"
27 |
28 | def is_skippable_wheel(filename):
29 | """Skip cpython and non-manylinux linux releases"""
30 | return re.match(r".*cpython.*|.*-linux-.*|.*manylinux2010.*", filename) is not None
31 |
32 | def is_targettable_python_version(filename):
33 | return re.match(r".*cp37.*", filename) is not None
34 |
35 | def get_simplified_directory_name_from_wheel(whl_filename):
36 | """ Return a full target directory path where a wheel should be extracted, that the Blender addon can generate
37 | The target expression on the Blender addon side will be: platform.system().lower() + "-" + platform.architecture()[0]"""
38 | parent_directory_name = os.path.dirname(whl_filename)
39 | target_subdirectory_name = os.path.basename(whl_filename).replace(".whl", "")
40 | if re.match(r".*macosx.*x86_64.*", whl_filename):
41 | target_subdirectory_name = "darwin-64bit"
42 | elif re.match(r".*linux.*x86_64.*", whl_filename):
43 | target_subdirectory_name = "linux-64bit"
44 | elif re.match(r".*linux.*686.*", whl_filename):
45 | target_subdirectory_name = "linux-32bit"
46 | # Add support for macosx 32bit (or not..) and for Windows
47 | return os.path.join(parent_directory_name, target_subdirectory_name)
48 |
49 | def _download_and_unzip_wheel_files(dirpath, latest_release_data):
50 | for release in latest_release_data:
51 | if is_targettable_python_version(release["filename"]):
52 | if is_skippable_wheel(release["filename"]):
53 | continue
54 | release_filename = os.path.basename(release["url"])
55 |
56 | if is_skippable_wheel(release_filename):
57 | continue
58 |
59 | if os.path.exists(os.path.join(dirpath, release_filename)):
60 | print(f"Found cached {release_filename}")
61 | else:
62 | print(f"Will download {release_filename} into {dirpath}")
63 | print(release["url"])
64 | datatowrite = urllib.request.urlopen(release["url"]).read()
65 | with open(os.path.join(dirpath, release_filename), "wb") as f:
66 | f.write(datatowrite)
67 | copy_tree(dirpath, GMICPY_DIRECTORY_NAME)
68 | import glob
69 | whl_files = glob.glob(f"./{GMICPY_DIRECTORY_NAME}/*.whl")
70 | for whl_file in whl_files:
71 | extract_target_path = get_simplified_directory_name_from_wheel(whl_file)
72 | print(f"Extracting wheel {whl_file} into {extract_target_path}")
73 | with zipfile.ZipFile(whl_file, 'r') as zipObj:
74 | zipObj.extractall(extract_target_path)
75 | os.unlink(whl_file)
76 |
77 | def download_gmicpy_wheel_files():
78 | releases = yolk.pypi.CheeseShop().package_releases(PYPI_GMIC_PACKAGE_NAME)
79 | releases.sort()
80 | latest_release_data = yolk.pypi.CheeseShop().release_urls(PYPI_GMIC_PACKAGE_NAME, releases[-1])
81 |
82 | tempdir = os.environ.get(GMICPY_DOWNLOADS_CACHE_ENV_VARIABLE, False)
83 | if tempdir:
84 | print(f"Detected cache path for Gmic Python wheel downloads: {tempdir}")
85 | tempdir = os.path.expanduser(tempdir)
86 | if not os.path.exists(tempdir):
87 | print(f"Creating non-existing configured cache path: {tempdir}")
88 | os.makedirs(tempdir)
89 | _download_and_unzip_wheel_files(tempdir, latest_release_data)
90 | else:
91 | with tempfile.TemporaryDirectory() as dirpath:
92 | _download_and_unzip_wheel_files(dirpath, latest_release_data)
93 |
94 | def clean_old_directories():
95 | shutil.rmtree(RELEASE_ADDONZIP_DIRECTORY_NAME, ignore_errors=True)
96 | shutil.rmtree(GMICPY_DIRECTORY_NAME, ignore_errors=True)
97 | shutil.rmtree(RELEASE_NAME, ignore_errors=True)
98 |
99 | def setup_addon_files():
100 | # Copy addon files into the RELEASE_NAME directory
101 | # The RELEASE_ADDONZIP_DIRECTORY_NAME directory is for final archives
102 | os.mkdir(RELEASE_ADDONZIP_DIRECTORY_NAME)
103 | os.mkdir(RELEASE_NAME)
104 |
105 | shutil.copy(BLENDER_ADDON_MODULE_FILE, RELEASE_NAME)
106 | shutil.copy(BLENDER_ADDON_README_FILE, RELEASE_NAME)
107 | copy_tree(GMICPY_DIRECTORY_NAME, RELEASE_NAME)
108 |
109 | # TODO This json file will be useless from gmic 2.9.0
110 | assets_dir = os.path.join(RELEASE_NAME, ASSETS_DIRECTORY_NAME)
111 | os.makedirs(assets_dir)
112 | shutil.copy(ASSETS_GMIC_FILTERS_JSON_PATH, assets_dir)
113 |
114 | def zip_addon_files():
115 | # Per https://www.tutorialspoint.com/How-to-zip-a-folder-recursively-using-Python
116 | def zipdir(path, ziph):
117 | # ziph is zipfile handle
118 | for root, dirs, files in os.walk(path):
119 | for file in files:
120 | ziph.write(os.path.join(root, file))
121 | zipf = zipfile.ZipFile(ADDON_PATH, 'w', zipfile.ZIP_DEFLATED)
122 | zipdir(RELEASE_NAME, zipf)
123 | zipf.close()
124 |
125 | def make_addon_zip():
126 | clean_old_directories()
127 | # Grab gmic-py .whl(s) from Pypi.org and extract them
128 | download_gmicpy_wheel_files()
129 | setup_addon_files()
130 | zip_addon_files()
131 | shutil.rmtree(RELEASE_NAME)
132 | shutil.rmtree(GMICPY_DIRECTORY_NAME)
133 | print(f"here you are :) static add-on to test in Blender: {ADDON_PATH}")
134 |
135 | if __name__ == "__main__":
136 | make_addon_zip()
137 |
--------------------------------------------------------------------------------
/test_gmic_blender_addon.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os
3 | import blender_addon_tester as BAT
4 |
5 | addon_path = "downloads/gmic_blender.zip"
6 |
7 | def usage():
8 | print("{}: [blender_version]".format(sys.argv[0]))
9 | print("Tests the {} addon archive on blender_version for your OS only (MacOS or Linux)".format(sys.argv[0]))
10 | print("A pytest coverage report is saved to coverage.xml in the current directory at the end of the test.")
11 | print("If the blender_version argument is not provided. The BLENDER_VERSION environment variable is checked. Else 2.80 is assumed.")
12 | print("This script requires the blender-addon-tester Python module installed first, see requirements.txt or install yourself with pip.")
13 |
14 | if __name__ == "__main__":
15 | blender_revision = None
16 | if len(sys.argv) > 1:
17 | blender_revision = sys.argv[1]
18 | else:
19 | blender_revision = os.environ.get("BLENDER_VERSION", False)
20 | if not blender_revision:
21 | print("No blender_revision CLI argument or BLENDER_VERSION environment variable found, defaulting to Blender 2.80 for testing!")
22 | config = {"coverage": True}
23 |
24 | BAT.test_blender_addon(addon_path=addon_path, blender_revision=blender_revision, config=config)
25 |
--------------------------------------------------------------------------------
/tests/test_version_and_gmicpy_import.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from addon_helper import get_version
3 |
4 |
5 | @pytest.fixture
6 | def bpy_module(cache):
7 | return cache.get("bpy_module", None)
8 |
9 |
10 | def test_versionID_pass(bpy_module):
11 | expect_version = (0, 0, 1)
12 | return_version = get_version(bpy_module)
13 | assert expect_version == return_version
14 |
15 |
16 | def test_versionID_fail(bpy_module):
17 | expect_version = (0, 1, 1)
18 | return_version = get_version(bpy_module)
19 | assert not expect_version == return_version
20 |
21 | def test_gmic_loaded():
22 | import gmic
23 | assert type(gmic.Gmic.run).__name__ == 'method_descriptor'
24 |
--------------------------------------------------------------------------------