07.10.24

A visit from an old friend, the boreGauge

A few years back we made a gauge for measuring large bores in hydraulic cylinders. Seems the company that bought it from us needed the software for it again. I had to dig through my old source code and see if I had a recent version, turns out I did. On this project I did the electronics, software and commissioned it.

An image of the BoreGauge

What the device does is, you place it in the bore, set your zeros and then measure the bore all the way down. This way you can see if there are any high spots, low spots or waviness. The software keeps track of the position as well and provides a csv file of the data and plots it on the screen.

This was a pretty fun project, I might redesign it and make a more substantial attempt at monetizing it later.

| Posted in Design, Electronics, Programming | Comments Off on A visit from an old friend, the boreGauge
05.28.24

StableDiffusion Permutation Script Update

So, like a week ago I wrote a script to make permutations for SD prompts. I’ve updated the script to allow for random terms as well. This allows one to add variance in the prompt but to not add to the number of permutations. Everything is explained in the code block comment. just change the filenames near the end of the script and run.

"""
Script: prompt_permutator.py

Description:
This script generates permutations of a given prompt with various modifiers.
The script reads an input file that contains a base prompt and lists of modifiers.
It creates all possible combinations of the modifiers and generates new prompts
based on these combinations. Additionally, it handles placeholders that are randomly
replaced with specified values and ensures these placeholders are not included in the final output.

Input File Format:
- The first line contains the base prompt.
- Subsequent lines contain comma-separated lists of modifiers.
- Lines starting with a placeholder (e.g., %1) are treated as random modifiers and are replaced
  with random values from the list provided.

Example Input File (test2.txt):

A %1 flower on a hill, photorealistic
on a hill, in a vase, on a bed
photorealistic, manga
%1, Red, Green, Blue

In this example:
- The base prompt is: "A %1 flower on a hill, photorealistic"
- The modifiers are: ["on a hill", "in a vase", "on a bed"] and ["photorealistic", "manga"]
- The placeholder %1 will be replaced with a random choice from ["Red", "Green", "Blue"]

Output:
The script generates all permutations of the prompt with the modifiers and replaces
the placeholder with a random value. The results are saved to an output file.

Usage:
1. Prepare an input file (e.g., 'test2.txt') following the described format.
2. Specify the input and output file paths in the script or pass them as arguments.
3. Run the script to generate the permutations and save them to the output file.

Example Execution:
$ python prompt_permutator.py

Dependencies:
- itertools
- random

Author:
Steven M

Date:
May 28, 2024

"""

import itertools
import random

def load_file(file_path):
    with open(file_path, 'r') as file:
        lines = file.readlines()
    return [line.strip() for line in lines]

def generate_permutations(prompt, modifiers, random_modifiers):
    # Create all combinations of modifiers
    all_combinations = list(itertools.product(*modifiers))
    
    permutations = []
    for combination in all_combinations:
        new_prompt = prompt
        for original, replacement in zip(modifiers, combination):
            new_prompt = replace_first(new_prompt, original[0], replacement)
        
        # Handle random modifiers
        for placeholder, values in random_modifiers.items():
            if placeholder in new_prompt:
                replacement = random.choice(values)
                new_prompt = new_prompt.replace(placeholder, replacement, 1)
        
        # Remove placeholders from the final prompt
        new_prompt = remove_placeholders(new_prompt, random_modifiers.keys())
        
        permutations.append(new_prompt)
    
    return permutations

def replace_first(text, search, replacement):
    # Helper function to replace only the first occurrence of a term
    if search not in text:
        raise ValueError(f"Term '{search}' not found in the prompt.")
    return text.replace(search, replacement, 1)

def remove_placeholders(text, placeholders):
    for placeholder in placeholders:
        text = text.replace(placeholder, "")
    return text

def save_to_file(output_path, permutations):
    with open(output_path, 'w') as file:
        for permutation in permutations:
            file.write(permutation + '\n')

def main(input_file_path, output_file_path):
    lines = load_file(input_file_path)
    if not lines:
        print("The input file is empty.")
        return

    prompt = lines[0]
    modifiers = [line.split(', ') for line in lines[1:] if not line.startswith('%')]
    random_modifiers = {}
    
    for line in lines[1:]:
        if line.startswith('%'):
            parts = line.split(', ')
            key = parts[0]
            values = parts[1:]
            random_modifiers[key] = values

    try:
        all_permutations = generate_permutations(prompt, modifiers, random_modifiers)
        save_to_file(output_file_path, all_permutations)
        print(f"Generated prompts have been saved to {output_file_path}")
        print(f"Total number of permutations: {len(all_permutations)}")
    except ValueError as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    input_file_path = 'test2.txt'  # Change this to the path of your input file
    output_file_path = 'output.txt'  # Change this to the desired path for the output file
    main(input_file_path, output_file_path)

So, in essence, anything with a % at the beginning of the line will be processed differently and the term will be matched up. As always, I guarantee nothing.

Tags: , , ,
| Posted in Programming | Comments Off on StableDiffusion Permutation Script Update
05.28.24

Pong-2024

I was bored and made a quick Pong game. It’s not great, not terribly well finished but I wanted to see how good the tools are these days. It’s been a while since I wrote a game. It was fun to make. Give it a shot.

https://smackaay.com/webgames/pong2024/index.html

It’s output in HTML5 so no installation is required.

Tags: , , ,
| Posted in Programming | Comments Off on Pong-2024
05.25.24

Calgary Zoo and Torrington Gopher Museum

Last weekend we decided to go with my parents for a quick trip to our neighbors to the south and visit the Calgary Zoo, It was a big place. Lots of cool animals, nice facilities. everything was pretty good.

Here’s a few images as well from the zoo. It was overcast for the most part so it wasn’t great for photography but it was ok.

So, we went to Crossiron Mills and New Horizons Mall. I quite liked New Horizons. If I want to go to one of the 3 quintillion trash stores, I can find them at CrossIron Mills. If I want to see some smaller businesses where they sell things the owners know and give a crap about, I’ll go to New Horizons. Unfortunately it doesn’t seem to be terribly successful even a few years later from opening. Oddly enough, I think the location is wrong for that kind of business style. But whatever.

We took a detour to Torrington where the have the WORLD FAMOUS GOPHER HOLE MUSEUM!!! It’s a charming little museum with dioramas of taxidermy gophers in various settings. Cute in it’s own way. It was surprisingly busy and they seem to really care about their museum and town proper. very cool.

Anyways, http://worldfamousgopherholemuseum.ca/ is a fun little place. go check it out!

Tags: , , , , ,
| Posted in Personal stuff | Comments Off on Calgary Zoo and Torrington Gopher Museum
05.23.24

Resolutions for SD image generation

When making images for StableDiffusion it’s best to take the aspect ratio in mind and make it fit into the total number of pixels that the model was trained on. This results in the best images for that given model. So, for SDXL it’s 1024×1024, others it may be 768×768 or even 512×512. Here is a list of effective X and Y values to total up to the most common aspect ratios for various training sizes. Obviously you would reverse the values if you go y/x.

1024x1024

Aspect Ratio 4:3 - Resolution: 1182x886
Aspect Ratio 16:9 - Resolution: 1365x768
Aspect Ratio 21:9 - Resolution: 1564x670
Aspect Ratio 1:1 - Resolution: 1024x1024
Aspect Ratio 3:2 - Resolution: 1254x836
Aspect Ratio 5:4 - Resolution: 1144x915
Aspect Ratio 16:10 - Resolution: 1295x809
Aspect Ratio 2:1 - Resolution: 1448x724
Aspect Ratio 18:9 - Resolution: 1448x724
Aspect Ratio 32:9 - Resolution: 1930x543
Aspect Ratio 3:1 - Resolution: 1773x591
Aspect Ratio 4:1 - Resolution: 2048x512
Aspect Ratio 5:3 - Resolution: 1321x793

768x768

Aspect Ratio 4:3 - Resolution: 886x665
Aspect Ratio 16:9 - Resolution: 1024x576
Aspect Ratio 21:9 - Resolution: 1173x502
Aspect Ratio 1:1 - Resolution: 768x768
Aspect Ratio 3:2 - Resolution: 940x627
Aspect Ratio 5:4 - Resolution: 858x686
Aspect Ratio 16:10 - Resolution: 971x607
Aspect Ratio 2:1 - Resolution: 1086x543
Aspect Ratio 18:9 - Resolution: 1086x543
Aspect Ratio 32:9 - Resolution: 1448x407
Aspect Ratio 3:1 - Resolution: 1330x443
Aspect Ratio 4:1 - Resolution: 1536x384
Aspect Ratio 5:3 - Resolution: 991x594

512x512

Aspect Ratio 4:3 - Resolution: 591x443
Aspect Ratio 16:9 - Resolution: 682x384
Aspect Ratio 21:9 - Resolution: 782x335
Aspect Ratio 1:1 - Resolution: 512x512
Aspect Ratio 3:2 - Resolution: 627x418
Aspect Ratio 5:4 - Resolution: 572x457
Aspect Ratio 16:10 - Resolution: 647x404
Aspect Ratio 2:1 - Resolution: 724x362
Aspect Ratio 18:9 - Resolution: 724x362
Aspect Ratio 32:9 - Resolution: 965x271
Aspect Ratio 3:1 - Resolution: 886x295
Aspect Ratio 4:1 - Resolution: 1024x256
Aspect Ratio 5:3 - Resolution: 660x396

So, if for some reason you need to calculate this on your own for some future or past resolution, here is the Python.

from sympy import symbols, Eq, solve

# Define symbols
x, y = symbols('x y')

# Equation 1: Total pixel count remains constant
total_pixels = 512*512

# List of common aspect ratios as tuples (width, height)
aspect_ratios = [
    (4, 3), (16, 9), (21, 9), (1, 1), (3, 2),
    (5, 4), (16, 10), (2, 1), (18, 9), (32, 9),
    (3, 1), (4, 1), (5, 3)
]

# Iterate over the aspect ratios and solve the equations
resolutions = []
for width_ratio, height_ratio in aspect_ratios:
    # Equation 2: Aspect ratio
    eq1 = Eq(x * y, total_pixels)
    eq2 = Eq(x / y, width_ratio / height_ratio)
    
    # Solve the equations
    solution = solve((eq1, eq2), (x, y))
    
    # Extract the resolution and convert to positive integers
    resolution = (abs(int(solution[0][0])), abs(int(solution[0][1])))
    resolutions.append((width_ratio, height_ratio, resolution))

# Print the results
for width_ratio, height_ratio, resolution in resolutions:
    print(f"Aspect Ratio {width_ratio}:{height_ratio} - Resolution: {resolution[0]}x{resolution[1]}")

As always, I guarantee nothing. enjoy.

Tags: , , ,
| Posted in Miscellaneous stuff, Programming | Comments Off on Resolutions for SD image generation
05.20.24

A quick script for creating prompt permutations for StableDiffusion

So, I enjoy making stuff in StableDiffusion and in the WebUI interface is an option for a prompt list. I like using the Prompt S/R in the scripts but it tends to top out after about 1500 permutations. Here is a script for generating those in as many dimensions as you want.

import itertools

def load_file(file_path):
    with open(file_path, 'r') as file:
        lines = file.readlines()
    return [line.strip() for line in lines]

def generate_permutations(prompt, modifiers):
    # Create all combinations of modifiers
    all_combinations = list(itertools.product(*modifiers))
    
    permutations = []
    for combination in all_combinations:
        new_prompt = prompt
        for original, replacement in zip(modifiers, combination):
            new_prompt = replace_first(new_prompt, original[0], replacement)
        permutations.append(new_prompt)
    
    return permutations

def replace_first(text, search, replacement):
    # Helper function to replace only the first occurrence of a term
    if search not in text:
        raise ValueError(f"Term '{search}' not found in the prompt.")
    return text.replace(search, replacement, 1)

def save_to_file(output_path, permutations):
    with open(output_path, 'w') as file:
        for permutation in permutations:
            file.write(permutation + '\n')

def main(input_file_path, output_file_path):
    lines = load_file(input_file_path)
    if not lines:
        print("The input file is empty.")
        return

    prompt = lines[0]
    modifiers = [line.split(', ') for line in lines[1:]]

    try:
        all_permutations = generate_permutations(prompt, modifiers)
        save_to_file(output_file_path, all_permutations)
        print(f"Generated prompts have been saved to {output_file_path}")
        print(f"Total number of permutations: {len(all_permutations)}")
    except ValueError as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    input_file_path = 'testprompt.txt'  # Change this to the path of your input file
    output_file_path = 'output.txt'  # Change this to the desired path for the output file
    main(input_file_path, output_file_path)

This Python script will allow you to generate a permutation of a prompt based on the original words that are in the prompt. So, for example, here is the prompt file with the first line being the raw prompt and the following lines being the search and replace terms:

A beautiful flower sitting on a wooden table. in a kitchen
beautiful flower, tall woman, eager beaver, soup can
sitting, jumping, glowering

This will generate the following in output.txt

A beautiful flower sitting on a wooden table. in a kitchen
A beautiful flower jumping on a wooden table. in a kitchen
A beautiful flower glowering on a wooden table. in a kitchen
A tall woman sitting on a wooden table. in a kitchen
A tall woman jumping on a wooden table. in a kitchen
A tall woman glowering on a wooden table. in a kitchen
A eager beaver sitting on a wooden table. in a kitchen
A eager beaver jumping on a wooden table. in a kitchen
A eager beaver glowering on a wooden table. in a kitchen
A soup can sitting on a wooden table. in a kitchen
A soup can jumping on a wooden table. in a kitchen
A soup can glowering on a wooden table. in a kitchen

So, the strings “Beautiful flower” and “sitting” and the following terms are replaced in the original prompt. So, in this case you have 4 terms in the first term line (line 2) and 3 terms in the second term line so, 4 time 3 is 12. All 12 permutations of that prompt are outputted to a file. It will tell you the total number of permutations and throw an error when a term isn’t found.

I make no guarantees about this script, enjoy anyways.

| Posted in Programming | Comments Off on A quick script for creating prompt permutations for StableDiffusion
05.9.24

Some of my AI ‘art’

I’m not stupid enough to consider plugging in some prompts to a diffusion AI to be art but I enjoy it nonetheless. Also, I’m aware of the copyright, moral and overall societal implications of it. That’s not for me to solve. Here are a few of my favorites from December 2023 to February 2024.

| Posted in Uncategorized | Comments Off on Some of my AI ‘art’
05.8.24

An RTJ chart

Here is a chart for RTJ ring groove facings. It’s very specific to my own use case but maybe somebody else will find it useful. I guarantee nothing, if you use it, it’s at your own risk. Bottom width is the size at the bottom of the groove, Largest Ball is the largest ball that will sit tangent at the top of the groove, and well, Smallest is the one that will sit on the bottom and touch the two sides. Obviously you want to be somewhere between, not at, theses sizes. Also, the lists on the bottom denote the Depth, Width sets and the numbers that follow are the R sizes that match that set.

| Posted in Machining, Miscellaneous stuff | Comments Off on An RTJ chart
04.27.24

CMM, a test video

So, I was measuring a plate on our Mitutoyo CMM yesterday and I figured it’d be a good test to see how videos embed on WordPress these days. When I started this site the first time, you could not embed videos very easily and you had to embed with either YouTube or whatever other video service was available. Still, the limit is only 512MB but, hey, good enough. That’s almost enough for a movie.

This was a plate we needed to grind flat withing a few thou. Worked out well.

Tags: , ,
| Posted in Machining | Comments Off on CMM, a test video
04.25.24

A new die/punch housing

Just finished a new die/punch housing for use on an old press. Works well and allows you to index at different distances. The initial drawing was kind of wrong when I drew it but I just shifted it a bit to work given the machine.

| Posted in Design, Machining | Comments Off on A new die/punch housing