McBin

cat_pees_on_efnet.scad

/*
 * 3D Printed Cat Urinating on a Crappy Configured EFNET Server
 * by MatCat - Because some networks deserve what they get.
 *
 * Render with F6, then export as STL for printing.
 * WARNING: May cause uncontrollable laughter at your local makerspace.
 */

$fn = 32;

// Colors
cat_color = [0.4, 0.25, 0.15];       // Brown tabby
server_color = [0.15, 0.15, 0.2];    // Dark metal
urine_color = [0.9, 0.85, 0.2];      // That golden EFNET quality
led_color = [1, 0, 0];               // Error red
glow_color = [1, 0.5, 0];            // Warning orange

// ===== ANGRY CAT BODY =====
module cat() {
    // Body
    translate([-80, 0, 12]) rotate([0, -5, 0]) {
        difference() {
            union() {
                // Main body - arched back of an angry cat
                scale([1.6, 0.9, 0.9]) sphere(r=30);
                // Rump
                translate([-20, 0, -5]) scale([1.3, 0.8, 0.85]) sphere(r=25);
            }
            // Flatten bottom
            translate([0, 0, -30]) cube([120, 80, 20], center=true);
        }
    }

    // Head - turned back looking at the server with contempt
    translate([-110, -12, 30]) rotate([0, 15, -10]) {
        union() {
            sphere(r=18);
            // Snout
            translate([-5, -10, 5]) scale([0.7, 0.6, 0.5]) sphere(r=12);
            // Nose triangle
            translate([-8, -18, 6]) rotate([0, 0, 30]) cylinder(r=3, h=2, $fn=3);
        }
    }

    // Ears - flattened back (aggressive posture)
    translate([-118, -25, 45]) rotate([20, -15, 0]) {
        cylinder(r1=1, r2=10, h=12);
        translate([0, -3, 8]) sphere(r=6);
    }
    translate([-115, 5, 42]) rotate([-15, -20, 0]) {
        cylinder(r1=1, r2=10, h=12);
        translate([0, 3, 8]) sphere(r=6);
    }

    // Tail - straight up, angry
    translate([-50, 5, 18]) rotate([-30, 15, 0]) {
        for(i=[0:5]) {
            translate([0, 0, i*8])
                rotate([i*8, i*3, 0])
                cylinder(r1=5-i*0.6, r2=4-i*0.5, h=8);
        }
        // Tail tip
        translate([0, 0, 52]) sphere(r=3);
    }

    // Legs
    // Front legs
    translate([-92, -20, -5]) cylinder(r=6, h=15);
    translate([-92, 20, -5]) cylinder(r=6, h=15);
    // Hind legs - slightly bent (peeing stance)
    translate([-58, -22, -5]) rotate([5, 0, 0]) cylinder(r=7, h=14);
    translate([-58, 22, -5]) rotate([-5, 0, 0]) cylinder(r=7, h=14);

    // Paws
    translate([-92, -20, 10]) sphere(r=6.5);
    translate([-92, 20, 10]) sphere(r=6.5);
    translate([-58, -22, 9]) sphere(r=7.5);
    translate([-58, 22, 9]) sphere(r=7.5);

    // Evil eyes - glowing
    translate([-120, -18, 33]) sphere(r=4.5);
    translate([-120, -5, 33]) sphere(r=4.5);
    // Pupils - slits of pure hatred
    translate([-122, -18, 33]) scale([0.2, 1, 1]) sphere(r=3);
    translate([-122, -5, 33]) scale([0.2, 1, 1]) sphere(r=3);
}

// ===== THE PISS STREAM =====
module urine_stream() {
    // Main arc from cat to server
    difference() {
        hull() {
            translate([-72, -8, 8]) sphere(r=2.5);
            translate([-50, -5, 15]) sphere(r=2.8);
            translate([-30, -2, 20]) sphere(r=3);
            translate([-10, 0, 18]) sphere(r=3.2);
            translate([10, 2, 12]) sphere(r=3.5);
            translate([30, 3, 5]) sphere(r=3.8);
            translate([50, 3, -2]) sphere(r=4);
            translate([70, 2, -8]) sphere(r=4.2);
        }
        // Hollow center for realistic fluid look
        hull() {
            translate([-72, -8, 8]) sphere(r=1);
            translate([-50, -5, 15]) sphere(r=1.2);
            translate([-30, -2, 20]) sphere(r=1.5);
            translate([-10, 0, 18]) sphere(r=1.5);
            translate([10, 2, 12]) sphere(r=1.8);
            translate([30, 3, 5]) sphere(r=2);
            translate([50, 3, -2]) sphere(r=2.2);
            translate([70, 2, -8]) sphere(r=2.5);
        }
    }

    // Splatter on the server
    translate([68, -2, -12]) {
        // Drip trails
        for(i=[0:5]) {
            translate([i*4, sin(i*30)*6, -i*3])
                sphere(r=2.5 - i*0.3);
        }
        // Main splat
        scale([2, 1.5, 0.3]) sphere(r=6);
    }

    // Drops in the arc
    for(i=[0:15]) {
        t = i / 15;
        x = -72 + t * 142;
        y = -8 + t * 11 + sin(t*20)*2;
        z = 8 + t * -20 + sin(t*15)*3;
        translate([x, y, z]) sphere(r=1.2 + t*0.8);
    }
}

// ===== CRAPPY CONFIGURED EFNET SERVER =====
module efnet_server() {
    // Main chassis - a rackmount server
    difference() {
        union() {
            // Server body
            translate([75, -20, -30]) cube([60, 40, 20]);

            // Drive bays (because it's probably a Dell)
            translate([110, -17, -28]) cube([20, 14, 4]);
            translate([110, -17, -22]) cube([20, 14, 4]);
            translate([110, -17, -16]) cube([20, 14, 4]);

            // Power supply bulge
            translate([75, -24, -30]) cube([15, 8, 20]);

            // Back panel with "network" ports
            translate([72, -12, -20]) cube([5, 20, 12]);

            // Antenna bent at wrong angle (bad wifi config)
            translate([100, -2, -10]) rotate([45, 30, 0]) cylinder(r=1.5, h=15);
            sphere(r=2);
        }

        // Ventilation slots (overheating from bad config)
        for(i=[-2:2]) {
            translate([90, i*4+2, -26]) cube([25, 2, 1]);
        }

        // Status screen cutout
        translate([120, -3, -22]) cube([12, 6, 4]);
    }

    // ===== BADGE: "EFNET" =====
    // Because branding matters, even for a garbage fire
    translate([118, -8, -20]) {
        color("silver") cube([16, 18, 2]);
        // Text representation: E F N E T
        // E
        translate([1, 0, 1]) cube([2, 14, 1]);
        translate([1, 12, 1]) cube([4, 2, 1]);
        translate([1, 6, 1]) cube([4, 2, 1]);
        translate([1, 0, 1]) cube([4, 2, 1]);
        // F
        translate([6, 0, 1]) cube([2, 14, 1]);
        translate([6, 12, 1]) cube([4, 2, 1]);
        translate([6, 6, 1]) cube([4, 2, 1]);
        // N
        translate([11, 0, 1]) cube([2, 14, 1]);
        translate([11, 12, 1]) cube([2, 2, 1]);
        translate([15, 0, 1]) cube([2, 14, 1]);
        translate([11, 0, 1]) cube([2, 2, 1]);
        // E
        translate([18, 0, 1]) cube([2, 14, 1]);
        translate([18, 12, 1]) cube([4, 2, 1]);
        translate([18, 6, 1]) cube([4, 2, 1]);
        translate([18, 0, 1]) cube([4, 2, 1]);
        // T
        translate([24, 0, 1]) cube([2, 14, 1]);
        translate([23, 12, 1]) cube([6, 2, 1]);
    }

    // Blinking ERROR LEDs
    for(i=[0:3]) {
        translate([80 + i*10, -8, -14]) color("red") sphere(r=1.5);
    }

    // Smoke/overheat indicator
    translate([95, -2, -10]) color("orange") scale([1.5, 0.8, 0.5]) sphere(r=4);
    translate([100, 0, -12]) color("orange") scale([1, 0.6, 0.4]) sphere(r=3);

    // Warning tape stripes (yellow/black)
    for(i=[0:8]) {
        translate([77 + i*7, -22, -14])
            color(i%2==0 ? "yellow" : "black")
            cube([3, 3, 15]);
    }
}

// ===== GROUND/PLATFORM =====
module ground() {
    color([0.3, 0.3, 0.35]) {
        difference() {
            translate([-100, -35, -35]) cube([190, 70, 5]);
            // Puddle of... golden EFNET quality
            translate([60, -5, -33])
                scale([1.5, 1, 0.3])
                sphere(r=20);
        }
    }
    // The puddle
    translate([60, -5, -33]) {
        color(urine_color)
        scale([1.5, 1, 0.2])
        sphere(r=20);
        // Puddle highlights
        translate([-5, 3, 1]) color([1,1,0.8,0.3])
            scale([0.6, 0.4, 0.1])
            sphere(r=10);
    }
}

// ===== ASSEMBLY =====
module angry_cat_pees_on_efnet() {
    ground();
    cat();
    efnet_server();
    color(urine_color) urine_stream();
}

// ROTATE SO IT PRINTS FLAT
// Uncomment for 3D printing:
// translate([0, 0, 35]) rotate([0, 0, 0]) angry_cat_pees_on_efnet();

// PREVIEW ANGLE FOR MAXIMUM INSULT VISIBILITY
rotate([0, -5, 15]) angry_cat_pees_on_efnet();

/*
 * PRINTING NOTES:
 * - Print at 150-200% scale for best detail
 * - Supports needed under the urine stream
 * - Pause at layer ~5 to swap filament colors
 *   (Brown > Yellow > Silver/Grey)
 * - For true authenticity, print on a printer
 *   with the shittiest config you can manage
 * - EFNET text as per: RFC 2196 (the "IETF
 *   standard of garbage configs")
 *
 * 73 and piss off, EFNET!
 */
Copied to clipboard!