It is currently Tue Jul 02, 2024 4:09 am


All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: One Side Fold - Paper Folding Simulation Plug-in
PostPosted: Sun Apr 23, 2023 9:20 pm  (#1) 
Offline
Script Coder
User avatar

Joined: May 07, 2014
Posts: 4001
Location: Canada
I thought it would be fun to digitally simulate a pieces of paper being folded randomly by selecting a random rotation then apply a vertical fold.
And allow user to enter number of random folds they'd like to apply.
So here it is.
Image
Plug-in is located in /Python-Fu/One Side Fold...
Just have an image with 2 layers, top layer respresenting one side of paper and bottom layer representing the other side of paper and run it.
Here's the code
#!/usr/bin/env python
# 1-side-fold.py
# Created by TT
#
# License: GPLv3
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY# without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License
# visit: http://www.gnu.org/licenses/gpl.html
#
#
# ------------
#| Change Log |
# ------------
# Rel 1: Initial release

from gimpfu import *
import random
import math
def python_1_side_fold(image, layer, howmany):
   # pdb.gimp_image_undo_group_start(image)
   # pdb.gimp_context_push()
   #YOUR CODE BEGINS=======================
   howmany = int(howmany)
   pdb.gimp_selection_none(image)
   for layer in image.layers:
      if (pdb.gimp_drawable_has_alpha(layer) == FALSE):
         pdb.gimp_layer_add_alpha(layer)
   for i in range(0,howmany):
      pdb.gimp_progress_update(float(i)/howmany)

      #first rotate it randomly
      radians = random.randrange(0,360)/360.0 * 2.0 * math.pi
      for layer in image.layers:
         layer = pdb.gimp_item_transform_rotate(layer,radians,TRUE,0,0)
      pdb.gimp_image_resize_to_layers(image)

      #now do fold vertically randomly from min_crease to max_crease
      min_crease = 0.5; #at half point of width
      max_crease = 0.9; #at 90% of width
      crease_x = random.randrange(int(image.width*min_crease),int(image.width*max_crease))

      for layer in image.layers:
         pdb.gimp_image_select_rectangle(image,CHANNEL_OP_REPLACE,crease_x,0,image.width-crease_x,image.height)
         pdb.gimp_edit_cut(layer)
         float_sel = pdb.gimp_edit_paste(layer,FALSE)
         pdb.gimp_floating_sel_to_layer(float_sel)
         pdb.gimp_item_transform_flip_simple(float_sel,ORIENTATION_HORIZONTAL,FALSE,crease_x)
         pdb.gimp_image_raise_layer_to_top(image,float_sel)
         #layer = pdb.gimp_image_merge_down(image,float_sel,EXPAND_AS_NECESSARY)
         #pdb.plug_in_autocrop_layer(image,float_sel)

      #autocrop to clean up.
      pdb.gimp_image_resize_to_layers(image)
      visible = pdb.gimp_layer_new_from_visible(image,image,"visible")
      pdb.gimp_image_insert_layer(image,visible,None,0)
      pdb.plug_in_autocrop(image,visible) #after we autocrop to visible
      pdb.gimp_image_remove_layer(image,visible);
      #do resize layers to image size so that layers can rotate together the same again next time
      for layer in image.layers:
         pdb.gimp_layer_resize_to_image_size(layer)



   #YOUR CODE ENDS ========================
   # pdb.gimp_context_pop()
   # pdb.gimp_image_undo_group_end(image)
   pdb.gimp_image_resize_to_layers(image)
   pdb.gimp_displays_flush()

    #return

register(
   "python_fu_1_side_fold",
   "1 Side Folds a layer",
   "1 Side Folds a layer",
   "TT",
   "TT",
   "April 23, 2023",
   "<Image>/Python-Fu/One Side Fold...",
   "*",      # Create a new image, don't work on an existing one
   [
   #INPUT BEGINS
   (PF_INT, "howmany", "Random Fold How many times?:", 1),
   # (PF_INT, "ytiles", "ytiles:", 8),
   # (PF_INT, "spacing", "spacing:", 70),
   # (PF_TOGGLE, "shuffle", "Shuffle order:", 1),
   # (PF_SPINNER, "colors", "Number of Maximum Colors (randomly):", 16, (1, 32, 1)),
   # (PF_TOGGLE, "varysize",   "Vary up sizes:", 1), # initially True, checked.  Alias PF_BOOL
   # (PF_TOGGLE, "colorbackground",   "Color background randomly:", 0), # initially True, checked.  Alias PF_BOOL
   #(PF_SPINNER, "inc", "Increments (pixels):", 15, (1, 1000, 1)),
   #(PF_SPINNER, "outof", "Best out of:", 100, (1, 1000, 1)),
   #(PF_OPTION, "arrow_side", "Arrows Ends:", SIDE_END, SIDE_NAMES),
   #(PF_TOGGLE, "arrow_close", "Arrows Close:", 0),
   #(PF_SPINNER, "ignorelayers", "Ignore first (no of layers):", 2, (0, 200, 1)),
   #(PF_SPINNER, "shadow_offset_x", "Shadow Offset X:", 6, (-4096,4096,1)),
   #(PF_SPINNER, "shadow_offset_y", "Shadow Offset Y:", 6, (-4096,4096,1)),
   #(PF_SPINNER, "shadow_blur_radius", "Shadow Blur Radius:", 15, (0,1024,1)),
   #(PF_SPINNER, "shadow_opacity", "Shadow Opacity:", 100, (0,100,1)),
   #INPUT ENDS
   ],
   [],
   python_1_side_fold)

main()

#           (PF_INT, "p0", "_INT:", 0), # PF_INT8, PF_INT16, PF_INT32  similar but no difference in Python.
#           (PF_FLOAT, "p02", "_FLOAT:", 3.141),
#           (PF_STRING, "p03", "_STRING:", "foo"),  # alias PF_VALUE
#           (PF_TEXT, "p04", "TEXT:", "bar"),
#           # PF_VALUE
#           # Pick one from set of choices
#           (PF_OPTION,"p1",   "OPTION:", 0, ["0th","1st","2nd"]), # initially 0th is choice
#           (PF_RADIO, "p16", "RADIO:", 0, (("0th", 1),("1st",0))), # note bool indicates initial setting of buttons
#           # PF_RADIO is usually called a radio button group.
#           # SLIDER, ADJUSTMENT types require the extra parameter of the form (min, max, step).
#           (PF_TOGGLE, "p2",   "TOGGLE:", 1), # initially True, checked.  Alias PF_BOOL
#           # PF_TOGGLE is usually called a checkbox.
#           (PF_SLIDER, "p3", "SLIDER:", 0, (0, 100, 10)),
#           (PF_SPINNER, "p4", "SPINNER:", 21, (1, 1000, 50)),  # alias PF_ADJUSTMENT
#           # Pickers ie combo boxes ie choosers from lists of existing Gimp objects
#           (PF_COLOR, "p14", "_COLOR:", (100, 21, 40) ), # extra param is RGB triple
#           # PF_COLOUR is an alias by aussie PyGimp author lol
#           (PF_IMAGE, "p15", "IMAGE:", None), # should be type gimp.image, but None works
#           (PF_FONT, "p17", "FONT:", 0),
#           (PF_FILE, "p18", "FILE:", 0),
#           (PF_BRUSH, "p19", "BRUSH:", 0),
#           (PF_PATTERN, "p20", "PATTERN:", 0),
#           (PF_GRADIENT, "p21", "GRADIENT:", 0),
#           (PF_PALETTE, "p22", "PALETTE:", 0),
#           (PF_LAYER, "p23", "LAYER:", None),
#           (PF_CHANNEL, "p24", "CHANNEL:", None),  # ??? Usually empty, I don't know why.
#           (PF_DRAWABLE, "p25", "DRAWABLE:", None),
#           # Mostly undocumented, but work
#           (PF_VECTORS, "p26", "VECTORS:", None),
#           (PF_FILENAME, "p27", "FILENAME:", 0),
#           (PF_DIRNAME, "p28", "DIRNAME:", 0)
#           # PF_REGION might work but probably of little use.  See gimpfu.py.

_________________
TinT


Share on Facebook Share on Twitter Share on Orkut Share on Digg Share on MySpace Share on Delicious Share on Technorati
Top
 Post subject: Re: One Side Fold - Paper Folding Simulation Plug-in
PostPosted: Thu Apr 27, 2023 8:01 am  (#2) 
Offline
Script Coder
User avatar

Joined: May 07, 2014
Posts: 4001
Location: Canada
Here's the code to fold n times then unfold random(0-n) times.
#!/usr/bin/env python
# 1-side-fold2.py
# Created by TT
#
# License: GPLv3
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY# without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License
# visit: http://www.gnu.org/licenses/gpl.html
#
#
# ------------
#| Change Log |
# ------------
# Rel 1: Initial release

from gimpfu import *
import random
import math
def python_1_side_fold2(image, layer, howmany):
   # pdb.gimp_image_undo_group_start(image)
   # pdb.gimp_context_push()
   #YOUR CODE BEGINS=======================
   howmany = int(howmany)
   pdb.gimp_selection_none(image)
   for layer in image.layers:
      if (pdb.gimp_drawable_has_alpha(layer) == FALSE):
         pdb.gimp_layer_add_alpha(layer)
   rotatedradians = []
   creases = []      
   for i in range(0,howmany):
      pdb.gimp_progress_update(float(i)/howmany)

      #first rotate it randomly
      radians = random.randrange(0,360)/360.0 * 2.0 * math.pi
      rotatedradians.append(radians) #save the rotated radians for later use to unfold
      for layer in image.layers:
         layer = pdb.gimp_item_transform_rotate(layer,radians,TRUE,0,0)
      pdb.gimp_image_resize_to_layers(image)

      #now do fold vertically randomly from min_crease to max_crease
      min_crease = 0.5; #at half point of width
      max_crease = 0.9; #at 90% of width
      crease_x = random.randrange(int(image.width*min_crease),int(image.width*max_crease))
      creases.append(crease_x) #save the crease for later use to unfold
      for layer in image.layers:
         pdb.gimp_image_select_item(image,CHANNEL_OP_REPLACE,layer)
         pdb.gimp_image_select_rectangle(image,CHANNEL_OP_INTERSECT,crease_x-1,0,1,image.height)
         not_empty,x1,y1,x2,y2 = pdb.gimp_selection_bounds(image)
         if not_empty == TRUE:
            pdb.gimp_context_set_foreground((0,0,0))
            pdb.gimp_edit_fill(layer,FILL_FOREGROUND)
         
         pdb.gimp_image_select_rectangle(image,CHANNEL_OP_REPLACE,crease_x,0,image.width-crease_x,image.height)
         pdb.gimp_edit_cut(layer)
         float_sel = pdb.gimp_edit_paste(layer,FALSE)
         pdb.gimp_floating_sel_to_layer(float_sel)

         pdb.gimp_item_transform_flip_simple(float_sel,ORIENTATION_HORIZONTAL,FALSE,crease_x)
         pdb.gimp_image_raise_layer_to_top(image,float_sel)

         
         #layer = pdb.gimp_image_merge_down(image,float_sel,EXPAND_AS_NECESSARY)
         #pdb.plug_in_autocrop_layer(image,float_sel)

      #autocrop to clean up.
      pdb.gimp_image_resize_to_layers(image)
      visible = pdb.gimp_layer_new_from_visible(image,image,"visible")
      pdb.gimp_image_insert_layer(image,visible,None,0)
      pdb.plug_in_autocrop(image,visible) #after we autocrop to visible
      pdb.gimp_image_remove_layer(image,visible);
      #do resize layers to image size so that layers can rotate together the same again next time
      for layer in image.layers:
         pdb.gimp_layer_resize_to_image_size(layer)

   pdb.gimp_selection_none(image)
   unfolds = random.randrange(0,howmany+1)
   for i in range(0,unfolds):
      layercount = len(image.layers)
      for l in range(0,layercount/2):
         layer = image.layers[0]
         #pdb.gimp_item_transform_flip_simple(layer,ORIENTATION_HORIZONTAL,FALSE,creases[howmany-1-i])
         pdb.gimp_item_transform_flip_simple(layer,ORIENTATION_HORIZONTAL,FALSE,image.width)
         pdb.gimp_image_lower_item_to_bottom(image,layer)
         for j in range(0,l+1): #raise to right layer
            pdb.gimp_image_raise_item(image,layer)
         pdb.gimp_image_merge_down(image,layer,EXPAND_AS_NECESSARY)
      pdb.gimp_image_resize_to_layers(image)   
      #rotate in reverse   
      for layer in image.layers:
         layer = pdb.gimp_item_transform_rotate(layer,-rotatedradians[howmany-1-i],TRUE,0,0)
      pdb.gimp_image_resize_to_layers(image)
      pdb.gimp_image_resize_to_layers(image)
      visible = pdb.gimp_layer_new_from_visible(image,image,"visible")
      pdb.gimp_image_insert_layer(image,visible,None,0)
      pdb.plug_in_autocrop(image,visible) #after we autocrop to visible
      pdb.gimp_image_remove_layer(image,visible);
      #do resize layers to image size so that layers can rotate together the same again next time
      for layer in image.layers:
         pdb.gimp_layer_resize_to_image_size(layer)      


   #YOUR CODE ENDS ========================
   # pdb.gimp_context_pop()
   # pdb.gimp_image_undo_group_end(image)
   pdb.gimp_image_resize_to_layers(image)
   pdb.gimp_displays_flush()

    #return

register(
   "python_fu_1_side_fold2",
   "1 Side Folds a layer",
   "1 Side Folds a layer",
   "TT",
   "TT",
   "April 23, 2023",
   "<Image>/Python-Fu/One Side Fold2...",
   "*",      # Create a new image, don't work on an existing one
   [
   #INPUT BEGINS
   (PF_INT, "howmany", "Random Fold How many times?:", 1),
   # (PF_INT, "ytiles", "ytiles:", 8),
   # (PF_INT, "spacing", "spacing:", 70),
   # (PF_TOGGLE, "shuffle", "Shuffle order:", 1),
   # (PF_SPINNER, "colors", "Number of Maximum Colors (randomly):", 16, (1, 32, 1)),
   # (PF_TOGGLE, "varysize",   "Vary up sizes:", 1), # initially True, checked.  Alias PF_BOOL
   # (PF_TOGGLE, "colorbackground",   "Color background randomly:", 0), # initially True, checked.  Alias PF_BOOL
   #(PF_SPINNER, "inc", "Increments (pixels):", 15, (1, 1000, 1)),
   #(PF_SPINNER, "outof", "Best out of:", 100, (1, 1000, 1)),
   #(PF_OPTION, "arrow_side", "Arrows Ends:", SIDE_END, SIDE_NAMES),
   #(PF_TOGGLE, "arrow_close", "Arrows Close:", 0),
   #(PF_SPINNER, "ignorelayers", "Ignore first (no of layers):", 2, (0, 200, 1)),
   #(PF_SPINNER, "shadow_offset_x", "Shadow Offset X:", 6, (-4096,4096,1)),
   #(PF_SPINNER, "shadow_offset_y", "Shadow Offset Y:", 6, (-4096,4096,1)),
   #(PF_SPINNER, "shadow_blur_radius", "Shadow Blur Radius:", 15, (0,1024,1)),
   #(PF_SPINNER, "shadow_opacity", "Shadow Opacity:", 100, (0,100,1)),
   #INPUT ENDS
   ],
   [],
   python_1_side_fold2)

main()

#           (PF_INT, "p0", "_INT:", 0), # PF_INT8, PF_INT16, PF_INT32  similar but no difference in Python.
#           (PF_FLOAT, "p02", "_FLOAT:", 3.141),
#           (PF_STRING, "p03", "_STRING:", "foo"),  # alias PF_VALUE
#           (PF_TEXT, "p04", "TEXT:", "bar"),
#           # PF_VALUE
#           # Pick one from set of choices
#           (PF_OPTION,"p1",   "OPTION:", 0, ["0th","1st","2nd"]), # initially 0th is choice
#           (PF_RADIO, "p16", "RADIO:", 0, (("0th", 1),("1st",0))), # note bool indicates initial setting of buttons
#           # PF_RADIO is usually called a radio button group.
#           # SLIDER, ADJUSTMENT types require the extra parameter of the form (min, max, step).
#           (PF_TOGGLE, "p2",   "TOGGLE:", 1), # initially True, checked.  Alias PF_BOOL
#           # PF_TOGGLE is usually called a checkbox.
#           (PF_SLIDER, "p3", "SLIDER:", 0, (0, 100, 10)),
#           (PF_SPINNER, "p4", "SPINNER:", 21, (1, 1000, 50)),  # alias PF_ADJUSTMENT
#           # Pickers ie combo boxes ie choosers from lists of existing Gimp objects
#           (PF_COLOR, "p14", "_COLOR:", (100, 21, 40) ), # extra param is RGB triple
#           # PF_COLOUR is an alias by aussie PyGimp author lol
#           (PF_IMAGE, "p15", "IMAGE:", None), # should be type gimp.image, but None works
#           (PF_FONT, "p17", "FONT:", 0),
#           (PF_FILE, "p18", "FILE:", 0),
#           (PF_BRUSH, "p19", "BRUSH:", 0),
#           (PF_PATTERN, "p20", "PATTERN:", 0),
#           (PF_GRADIENT, "p21", "GRADIENT:", 0),
#           (PF_PALETTE, "p22", "PALETTE:", 0),
#           (PF_LAYER, "p23", "LAYER:", None),
#           (PF_CHANNEL, "p24", "CHANNEL:", None),  # ??? Usually empty, I don't know why.
#           (PF_DRAWABLE, "p25", "DRAWABLE:", None),
#           # Mostly undocumented, but work
#           (PF_VECTORS, "p26", "VECTORS:", None),
#           (PF_FILENAME, "p27", "FILENAME:", 0),
#           (PF_DIRNAME, "p28", "DIRNAME:", 0)
#           # PF_REGION might work but probably of little use.  See gimpfu.py.

Then here's the code that calls above code (n x m times) and make a n by m grid of it
#!/usr/bin/env python
# grid-of-folded.py
# Created by TT
#
# License: GPLv3
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY# without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License
# visit: http://www.gnu.org/licenses/gpl.html
#
#
# ------------
#| Change Log |
# ------------
# Rel 1: Initial release

from gimpfu import *
import random
import math
def python_grid_of_folded(image, layer, xtiles, ytiles):
   # pdb.gimp_image_undo_group_start(image)
   # pdb.gimp_context_push()
   #YOUR CODE BEGINS=======================
   xtiles = int(xtiles)
   ytiles = int(ytiles)
   diameter = (image.width**2 + image.height**2)**0.5;
   workingimage = pdb.gimp_image_new(diameter*xtiles,diameter*ytiles,RGB)
   pdb.gimp_display_new(workingimage)
   for y in range(0,ytiles):
      for x in range(0,xtiles):
         new_image = pdb.gimp_image_duplicate(image)
         dp = pdb.gimp_display_new(new_image)
         pdb.python_fu_1_side_fold2(new_image,None,random.randrange(2,6))
         visible = pdb.gimp_layer_new_from_visible(new_image,workingimage,"r" + str(y) + " " + " c" + str(x))
         pdb.gimp_image_insert_layer(workingimage,visible,None,0)
         pdb.gimp_layer_set_offsets(visible,x*diameter+diameter/2-visible.width/2,y*diameter+diameter/2-visible.height/2)
         pdb.gimp_display_delete(dp)
   #YOUR CODE ENDS ========================
   # pdb.gimp_context_pop()
   # pdb.gimp_image_undo_group_end(image)
   pdb.gimp_image_resize_to_layers(image)
   pdb.gimp_displays_flush()

    #return

register(
   "python_fu_grid_of_folded",
   "Grid of Folded",
   "Grid of Folded",
   "TT",
   "TT",
   "April 24, 2023",
   "<Image>/Python-Fu/One Side Folded Grid...",
   "*",      # Create a new image, don't work on an existing one
   [
   #INPUT BEGINS
   (PF_INT, "xtiles", "xtiles:", 3),
   (PF_INT, "ytiles", "ytiles:", 3),
   # (PF_INT, "ytiles", "ytiles:", 8),
   # (PF_INT, "spacing", "spacing:", 70),
   # (PF_TOGGLE, "shuffle", "Shuffle order:", 1),
   # (PF_SPINNER, "colors", "Number of Maximum Colors (randomly):", 16, (1, 32, 1)),
   # (PF_TOGGLE, "varysize",   "Vary up sizes:", 1), # initially True, checked.  Alias PF_BOOL
   # (PF_TOGGLE, "colorbackground",   "Color background randomly:", 0), # initially True, checked.  Alias PF_BOOL
   #(PF_SPINNER, "inc", "Increments (pixels):", 15, (1, 1000, 1)),
   #(PF_SPINNER, "outof", "Best out of:", 100, (1, 1000, 1)),
   #(PF_OPTION, "arrow_side", "Arrows Ends:", SIDE_END, SIDE_NAMES),
   #(PF_TOGGLE, "arrow_close", "Arrows Close:", 0),
   #(PF_SPINNER, "ignorelayers", "Ignore first (no of layers):", 2, (0, 200, 1)),
   #(PF_SPINNER, "shadow_offset_x", "Shadow Offset X:", 6, (-4096,4096,1)),
   #(PF_SPINNER, "shadow_offset_y", "Shadow Offset Y:", 6, (-4096,4096,1)),
   #(PF_SPINNER, "shadow_blur_radius", "Shadow Blur Radius:", 15, (0,1024,1)),
   #(PF_SPINNER, "shadow_opacity", "Shadow Opacity:", 100, (0,100,1)),
   #INPUT ENDS
   ],
   [],
   python_grid_of_folded)

main()

#           (PF_INT, "p0", "_INT:", 0), # PF_INT8, PF_INT16, PF_INT32  similar but no difference in Python.
#           (PF_FLOAT, "p02", "_FLOAT:", 3.141),
#           (PF_STRING, "p03", "_STRING:", "foo"),  # alias PF_VALUE
#           (PF_TEXT, "p04", "TEXT:", "bar"),
#           # PF_VALUE
#           # Pick one from set of choices
#           (PF_OPTION,"p1",   "OPTION:", 0, ["0th","1st","2nd"]), # initially 0th is choice
#           (PF_RADIO, "p16", "RADIO:", 0, (("0th", 1),("1st",0))), # note bool indicates initial setting of buttons
#           # PF_RADIO is usually called a radio button group.
#           # SLIDER, ADJUSTMENT types require the extra parameter of the form (min, max, step).
#           (PF_TOGGLE, "p2",   "TOGGLE:", 1), # initially True, checked.  Alias PF_BOOL
#           # PF_TOGGLE is usually called a checkbox.
#           (PF_SLIDER, "p3", "SLIDER:", 0, (0, 100, 10)),
#           (PF_SPINNER, "p4", "SPINNER:", 21, (1, 1000, 50)),  # alias PF_ADJUSTMENT
#           # Pickers ie combo boxes ie choosers from lists of existing Gimp objects
#           (PF_COLOR, "p14", "_COLOR:", (100, 21, 40) ), # extra param is RGB triple
#           # PF_COLOUR is an alias by aussie PyGimp author lol
#           (PF_IMAGE, "p15", "IMAGE:", None), # should be type gimp.image, but None works
#           (PF_FONT, "p17", "FONT:", 0),
#           (PF_FILE, "p18", "FILE:", 0),
#           (PF_BRUSH, "p19", "BRUSH:", 0),
#           (PF_PATTERN, "p20", "PATTERN:", 0),
#           (PF_GRADIENT, "p21", "GRADIENT:", 0),
#           (PF_PALETTE, "p22", "PALETTE:", 0),
#           (PF_LAYER, "p23", "LAYER:", None),
#           (PF_CHANNEL, "p24", "CHANNEL:", None),  # ??? Usually empty, I don't know why.
#           (PF_DRAWABLE, "p25", "DRAWABLE:", None),
#           # Mostly undocumented, but work
#           (PF_VECTORS, "p26", "VECTORS:", None),
#           (PF_FILENAME, "p27", "FILENAME:", 0),
#           (PF_DIRNAME, "p28", "DIRNAME:", 0)
#           # PF_REGION might work but probably of little use.  See gimpfu.py.

And here's an example output of using it (plus some manual drop shadow and setting background layer to nicely display result).
Image

_________________
TinT


Top
 Post subject: Re: One Side Fold - Paper Folding Simulation Plug-in
PostPosted: Sat Apr 29, 2023 11:33 am  (#3) 
Offline
GimpChat Member
User avatar

Joined: Apr 27, 2010
Posts: 1453
Location: Sweden
This is a really neat functionality. One could do a lot of fun things with this :)

_________________


Top
 Post subject: Re: One Side Fold - Paper Folding Simulation Plug-in
PostPosted: Sat Apr 29, 2023 12:11 pm  (#4) 
Offline
Script Coder
User avatar

Joined: May 07, 2014
Posts: 4001
Location: Canada
I don't what else it can be used for other than making some grid of random folds and sharing it on reddit.com/r/generative hehe.
Can you mention some ideas this can be used for?

_________________
TinT


Top
 Post subject: Re: One Side Fold - Paper Folding Simulation Plug-in
PostPosted: Sun Apr 30, 2023 6:51 am  (#5) 
Offline
GimpChat Member
User avatar

Joined: Jul 04, 2019
Posts: 136
Location: Lake Havasu City, Arizona, USA
I think its a brilliant plug-in, though I am not sure what I could use it for except as a prop. Have you considered adding a shadow to the fold to give the result an extra dimension?

_________________
Charles


Top
 Post subject: Re: One Side Fold - Paper Folding Simulation Plug-in
PostPosted: Sun Apr 30, 2023 8:28 am  (#6) 
Offline
Script Coder
User avatar

Joined: May 07, 2014
Posts: 4001
Location: Canada
Thank you for your suggestion. I think it's a great idea.
Here's the first plug-in (which folds only, no creases) with shadows (I'll work on the creased version now).
#!/usr/bin/env python
# 1-side-fold.py
# Created by TT
#
# License: GPLv3
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY# without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License
# visit: http://www.gnu.org/licenses/gpl.html
#
#
# ------------
#| Change Log |
# ------------
# Rel 1: Initial release

from gimpfu import *
import random
import math
def python_1_side_fold(image, layer, howmany):
   # pdb.gimp_image_undo_group_start(image)
   # pdb.gimp_context_push()
   #YOUR CODE BEGINS=======================
   howmany = int(howmany)
   pdb.gimp_selection_none(image)
   for layer in image.layers:
      if (pdb.gimp_drawable_has_alpha(layer) == FALSE):
         pdb.gimp_layer_add_alpha(layer)
   for i in range(0,howmany):
      pdb.gimp_progress_update(float(i)/howmany)

      #first rotate it randomly
      radians = random.randrange(0,360)/360.0 * 2.0 * math.pi
      for layer in image.layers:
         layer = pdb.gimp_item_transform_rotate(layer,radians,TRUE,0,0)
      pdb.gimp_image_resize_to_layers(image)

      #now do fold vertically randomly from min_crease to max_crease
      min_crease = 0.5; #at half point of width
      max_crease = 0.9; #at 90% of width
      crease_x = random.randrange(int(image.width*min_crease),int(image.width*max_crease))

      showlayers = [];
      shadowinsert = 0;
      for layer in image.layers:
         layerName = pdb.gimp_item_get_name(layer)
         if layerName.startswith("Drop Shadow"):
            #if it's shadow layer simply cut it
            pdb.gimp_image_select_rectangle(image,CHANNEL_OP_REPLACE,crease_x,0,image.width-crease_x,image.height)
            pdb.gimp_edit_cut(layer)
         else:
            pdb.gimp_image_select_rectangle(image,CHANNEL_OP_REPLACE,crease_x,0,image.width-crease_x,image.height)
            pdb.gimp_edit_cut(layer)
            float_sel = pdb.gimp_edit_paste(layer,FALSE)
            pdb.gimp_floating_sel_to_layer(float_sel)
            pdb.gimp_item_transform_flip_simple(float_sel,ORIENTATION_HORIZONTAL,FALSE,crease_x)
            pdb.gimp_image_raise_layer_to_top(image,float_sel)
            showlayers.append(float_sel)
            shadowinsert += 1;

      #hide all layers first
      for layer in image.layers:
         pdb.gimp_item_set_visible(layer,FALSE)

      for layer in showlayers:
         pdb.gimp_item_set_visible(layer,TRUE)

      pdb.gimp_selection_none(image)
      #new from visible to see shadow off   
      visible = pdb.gimp_layer_new_from_visible(image,image,"visible")
      pdb.gimp_image_insert_layer(image,visible,None,shadowinsert)

      #drop shawdow
      pdb.script_fu_drop_shadow(image,visible,0,0,15,(0,0,0),60,TRUE)
      pdb.gimp_image_select_rectangle(image,CHANNEL_OP_REPLACE,crease_x,0,image.width-crease_x,image.height)
      pdb.gimp_edit_cut(image.layers[shadowinsert+1])

      #remove the visible as we don't need it anymore
      pdb.gimp_image_remove_layer(image,visible);

      for layer in image.layers:
         pdb.gimp_item_set_visible(layer,TRUE)

      #autocrop to clean up.
      pdb.gimp_image_resize_to_layers(image)
      visible = pdb.gimp_layer_new_from_visible(image,image,"visible")
      pdb.gimp_image_insert_layer(image,visible,None,0)

      

      pdb.plug_in_autocrop(image,visible) #after we autocrop to visible
      pdb.gimp_image_remove_layer(image,visible);
      #do resize layers to image size so that layers can rotate together the same again next time
      for layer in image.layers:
         pdb.gimp_layer_resize_to_image_size(layer)



   #YOUR CODE ENDS ========================
   # pdb.gimp_context_pop()
   # pdb.gimp_image_undo_group_end(image)
   pdb.gimp_image_resize_to_layers(image)
   pdb.gimp_displays_flush()

    #return

register(
   "python_fu_1_side_fold",
   "1 Side Folds a layer",
   "1 Side Folds a layer",
   "TT",
   "TT",
   "April 23, 2023",
   "<Image>/Python-Fu/One Side Fold...",
   "*",      # Create a new image, don't work on an existing one
   [
   #INPUT BEGINS
   (PF_INT, "howmany", "Random Fold How many times?:", 1),
   # (PF_INT, "ytiles", "ytiles:", 8),
   # (PF_INT, "spacing", "spacing:", 70),
   # (PF_TOGGLE, "shuffle", "Shuffle order:", 1),
   # (PF_SPINNER, "colors", "Number of Maximum Colors (randomly):", 16, (1, 32, 1)),
   # (PF_TOGGLE, "varysize",   "Vary up sizes:", 1), # initially True, checked.  Alias PF_BOOL
   # (PF_TOGGLE, "colorbackground",   "Color background randomly:", 0), # initially True, checked.  Alias PF_BOOL
   #(PF_SPINNER, "inc", "Increments (pixels):", 15, (1, 1000, 1)),
   #(PF_SPINNER, "outof", "Best out of:", 100, (1, 1000, 1)),
   #(PF_OPTION, "arrow_side", "Arrows Ends:", SIDE_END, SIDE_NAMES),
   #(PF_TOGGLE, "arrow_close", "Arrows Close:", 0),
   #(PF_SPINNER, "ignorelayers", "Ignore first (no of layers):", 2, (0, 200, 1)),
   #(PF_SPINNER, "shadow_offset_x", "Shadow Offset X:", 6, (-4096,4096,1)),
   #(PF_SPINNER, "shadow_offset_y", "Shadow Offset Y:", 6, (-4096,4096,1)),
   #(PF_SPINNER, "shadow_blur_radius", "Shadow Blur Radius:", 15, (0,1024,1)),
   #(PF_SPINNER, "shadow_opacity", "Shadow Opacity:", 100, (0,100,1)),
   #INPUT ENDS
   ],
   [],
   python_1_side_fold)

main()

#           (PF_INT, "p0", "_INT:", 0), # PF_INT8, PF_INT16, PF_INT32  similar but no difference in Python.
#           (PF_FLOAT, "p02", "_FLOAT:", 3.141),
#           (PF_STRING, "p03", "_STRING:", "foo"),  # alias PF_VALUE
#           (PF_TEXT, "p04", "TEXT:", "bar"),
#           # PF_VALUE
#           # Pick one from set of choices
#           (PF_OPTION,"p1",   "OPTION:", 0, ["0th","1st","2nd"]), # initially 0th is choice
#           (PF_RADIO, "p16", "RADIO:", 0, (("0th", 1),("1st",0))), # note bool indicates initial setting of buttons
#           # PF_RADIO is usually called a radio button group.
#           # SLIDER, ADJUSTMENT types require the extra parameter of the form (min, max, step).
#           (PF_TOGGLE, "p2",   "TOGGLE:", 1), # initially True, checked.  Alias PF_BOOL
#           # PF_TOGGLE is usually called a checkbox.
#           (PF_SLIDER, "p3", "SLIDER:", 0, (0, 100, 10)),
#           (PF_SPINNER, "p4", "SPINNER:", 21, (1, 1000, 50)),  # alias PF_ADJUSTMENT
#           # Pickers ie combo boxes ie choosers from lists of existing Gimp objects
#           (PF_COLOR, "p14", "_COLOR:", (100, 21, 40) ), # extra param is RGB triple
#           # PF_COLOUR is an alias by aussie PyGimp author lol
#           (PF_IMAGE, "p15", "IMAGE:", None), # should be type gimp.image, but None works
#           (PF_FONT, "p17", "FONT:", 0),
#           (PF_FILE, "p18", "FILE:", 0),
#           (PF_BRUSH, "p19", "BRUSH:", 0),
#           (PF_PATTERN, "p20", "PATTERN:", 0),
#           (PF_GRADIENT, "p21", "GRADIENT:", 0),
#           (PF_PALETTE, "p22", "PALETTE:", 0),
#           (PF_LAYER, "p23", "LAYER:", None),
#           (PF_CHANNEL, "p24", "CHANNEL:", None),  # ??? Usually empty, I don't know why.
#           (PF_DRAWABLE, "p25", "DRAWABLE:", None),
#           # Mostly undocumented, but work
#           (PF_VECTORS, "p26", "VECTORS:", None),
#           (PF_FILENAME, "p27", "FILENAME:", 0),
#           (PF_DIRNAME, "p28", "DIRNAME:", 0)
#           # PF_REGION might work but probably of little use.  See gimpfu.py.

example outputs
ImageImageImage

_________________
TinT


Top
 Post subject: Re: One Side Fold - Paper Folding Simulation Plug-in
PostPosted: Sun Apr 30, 2023 9:08 am  (#7) 
Offline
Script Coder
User avatar

Joined: May 07, 2014
Posts: 4001
Location: Canada
Well I tried but unsuccessfully to make the fold with creases look good with shadows because of so many operations it's all off by the time I am done unfolding so refolding with creases looked funky (not good).
I guess we'll just have to live with shadows for the folds only version.

_________________
TinT


Top
 Post subject: Re: One Side Fold - Paper Folding Simulation Plug-in
PostPosted: Tue May 02, 2023 9:48 am  (#8) 
Offline
GimpChat Member
User avatar

Joined: Sep 27, 2016
Posts: 345
Location: Germany, BW
Gave it a try, too. Here's my outcome.
Attachment:
4x4.png


Nice to play with. Thank you Tim.

_________________
Regards
nelo

(Gimp 2.10 on Linux Mint MATE 20.1)


Top
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


   Similar Topics   Replies 
No new posts Attachment(s) Tri-fold or Four-fold Brochure effect plugin (Thank you Tim)

11

No new posts Attachment(s) uncrop-side.py - one of my old scripts revisited

0

No new posts Attachment(s) PERSPECTIVE TOOL BENDING OTHER SIDE BACK

13

No new posts Attachment(s) Don't work procedures plug-in-bump-map, plug-in-displace

2

No new posts Paper Cut Out Effect

0



* Login  



Powered by phpBB3 © phpBB Group