Retro stuff

Discussions regarding modelling with SOFTIMAGE©
User avatar
mc_axe
Posts: 420
Joined: 12 Mar 2013, 17:44

Retro stuff

Post by mc_axe » 25 May 2024, 00:19

Hi there old friends!

So i want to create something printable, in the form of pixel art,
Smething that kids can get in their hands, paint it, give it back to their parents, then parents are hit with an overdose of nostalgia, typical stuff..

Iv seen some image to stl online tools, requiring only high res pixel art, many pixels per pixel, else they produce only horrors,
But i wanted something different, since i need to control each individual pixel ceiling (create bevels or something)

And i came back to SI (to feel like absolute begginer),
Iv tried driving a push deformer with a tiny black and white image 11x8px I want to avoid any type of interpolation,
Image
but im getting this type of result,

Image

Of course, since the grid needs to stay together,
Maybe i should try to drive an extrude op is that even possible :-? maybe i should disconnect before trying, if any ideas im all ears,

(its for a retro event),

User avatar
rray
Moderator
Posts: 1810
Joined: 26 Sep 2009, 13:51
Location: Bonn, Germany

Re: Retro stuff

Post by rray » 25 May 2024, 14:10

Hey mc_axe - I did the same thing handing out little printed figures at an event around 10 years ago, but stopped doing that really quickly after I got a warning from some parents that were concerned little children might try to swallow them!

So make sure they're large enough.. that alien looks quite untasty anyway :)

For creating a 3D version I think I would probably try to get in some zen like mode and select the squares manually then extrude. Maybe before that cut some additional edges where 2 squares touch each other diagonally so it is thicker there.
softimage resources section updated Sep 26th 2026

User avatar
mc_axe
Posts: 420
Joined: 12 Mar 2013, 17:44

Re: Retro stuff

Post by mc_axe » 26 May 2024, 12:54

Thanks Rray!

I will forward the feeback, items have to be imposible to swallow (so we will scale them propperly), and pixels should be icredibly hard to be broken by hand, so tiny extrusions in the real world object,

In our case i might get handed few simmilar foes or heroes to print, should be really easy to select their pixels,
But we might also print entire screenshots from retro machines (for example in game action)!

This is why i wanted to avoid going through all the manual selection.

So i researched a litle:
First i looked for readable image formats, i found PPM (Gimp can export that to ascii), basically headers and then rgb values each chanel on a new line,

So now the plan is to parse the PPM, and somehow.. find (lets say) the 'black pixel indices',
Then feed those values into ICE and make an extrusion based on a string array,

Image

Also i might have to convert the indexing from raw based to column based,

At least this is the plan, @-)

User avatar
mc_axe
Posts: 420
Joined: 12 Mar 2013, 17:44

Re: Retro stuff

Post by mc_axe » 26 May 2024, 14:30

nom nom

Image

Ok so here is how i did the conversion from image (ppm) to string array, with some assistance from GPT:

Code: Select all

<!DOCTYPE html>
<html>
<head>
    <title>Find Black Pixels</title>
</head>
<body>
    <script>
        function findBlackPixelIndices(ppmData) {
            // Split the input by lines
            const lines = ppmData.trim().split('\n');

            // Remove comments &  empty lines
            const filteredLines = lines.filter(line => line.trim() !== '' && line.trim()[0] !== '#');

            // Read the header
            const width = parseInt(filteredLines[1].split(' ')[0], 10);
            const height = parseInt(filteredLines[1].split(' ')[1], 10);

            // Read the pixel data
            const pixelData = filteredLines.slice(3).map(Number); // Assuming header is 3 lines: P3, width height, max color value

            // Initialize an array to store indices of black pixels
            const blackPixelIndices = [];

            // Iterate through pixel data
            for (let i = 0; i < pixelData.length; i += 3) {
                const r = pixelData[i];
                const g = pixelData[i + 1];
                const b = pixelData[i + 2];

                if (r === 0 && g === 0 && b === 0) {
                    // Calculate the pixel index
                    const pixelIndex = i / 3;

                    // Store the index
                    blackPixelIndices.push(pixelIndex);
                }
            }

            return blackPixelIndices.join(' ');
        }

        function convertToColumnOrder(indicesString, width, height) {
            // Convert the string of indices into an array of numbers
            const indices = indicesString.split(' ').map(Number);
            const columnOrderedIndices = [];

            // Calculate the column-based order index for each pixel
            indices.forEach(index => {
                const x = index % width;
                const y = Math.floor(index / width);
                const columnIndex = x * height + y;
                columnOrderedIndices.push(columnIndex);
            });

            return columnOrderedIndices.join(' ');
        }

        // Example PPM data (first 3 lines are headers 11 & 8 is the width and height (in pixels) 255 is the max color range)
        const ppmData = `
P3
11 8
255
252
252
252
252
252
252
0
0
0
252
252
252
252
252
252
252
252
252
252
252
252
252
252
252
0
0
0
252
252
252
252
252
252
0
0
0
252
252
252
252
252
252
0
0
0
252
252
252
252
252
252
252
252
252
0
0
0
252
252
252
252
252
252
0
0
0
0
0
0
252
252
252
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
252
252
252
0
0
0
0
0
0
0
0
0
0
0
0
252
252
252
0
0
0
0
0
0
0
0
0
252
252
252
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
252
252
252
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
252
252
252
252
252
252
252
252
252
0
0
0
252
252
252
252
252
252
252
252
252
252
252
252
252
252
252
0
0
0
252
252
252
252
252
252
252
252
252
0
0
0
252
252
252
252
252
252
252
252
252
252
252
252
252
252
252
252
252
252
252
252
252
0
0
0
252
252
252
`;

        const blackPixels = findBlackPixelIndices(ppmData);
        console.log('Row-based indices:', blackPixels);  //Logs raw based black pixel indices

        const width = 11;
        const height = 8;
        const columnOrderedPixels = convertToColumnOrder(blackPixels, width, height);
        console.log('Column-based indices:', columnOrderedPixels);  //Logs black pixel indices traversed in to column based order

    </script>
</body>
</html>
I simply pasted the result from the last log (column based order) as input in the string array.

User avatar
Kolya
Posts: 45
Joined: 03 Oct 2017, 17:17

Re: Retro stuff

Post by Kolya » 26 May 2024, 14:35

Yo, try this

User avatar
mc_axe
Posts: 420
Joined: 12 Mar 2013, 17:44

Re: Retro stuff

Post by mc_axe » 26 May 2024, 15:11

Hey Kolya!

Maybe i overcomplicated things, thanks a ton, will definately try this :-bd
The first part seems exactly what i need!
Kolya wrote: 26 May 2024, 14:35 Yo, try this
p.s SI community rocks

User avatar
rray
Moderator
Posts: 1810
Joined: 26 Sep 2009, 13:51
Location: Bonn, Germany

Re: Retro stuff

Post by rray » 26 May 2024, 20:19

Ah nice good solution.
I missed pooby's videos, I'll go and watch a bunch of them now.
softimage resources section updated Sep 26th 2026