Main Restorations Software Audio/Jukebox/MP3 Everything Else Buy/Sell/Trade
Project Announcements Monitor/Video GroovyMAME Merit/JVL Touchscreen Meet Up Retail Vendors
Driving & Racing Woodworking Software Support Forums Consoles Project Arcade Reviews
Automated Projects Artwork Frontend Support Forums Pinball Forum Discussion Old Boards
Raspberry Pi & Dev Board controls.dat Linux Miscellaneous Arcade Wiki Discussion Old Archives
Lightguns Arcade1Up Try the site in https mode Site News

Unread posts | New Replies | Recent posts | Rules | Chatroom | Wiki | File Repository | RSS | Submit news

  

Author Topic: Request: arcade-related fan grill/ guard (will print on resin printer!)  (Read 2795 times)

0 Members and 1 Guest are viewing this topic.

ChurchOfSolipsism

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 231
  • Last login:May 09, 2023, 01:43:39 pm
So here's the deal: I'm working on a mini Donkey Kong bartop, and I think it would be a nice touch to add a custom DK related fan grill cover. Maybe somebody here is into 3D-sculpting/ CAD and would be willing to throw something together? I have a resin printer (not a filament printer, but the one that gives you industry-quality prints with no visible resolution), and of course I'd print one and send it to the sculptor for free... also, if other people were interested, I could sure print out some more.

Here are some ideas:
- just incorporate the Nintendo logo into a fan grill, by combining these two for example:
https://www.thingiverse.com/thing:2437634
https://www.thingiverse.com/thing:2203044

- using other logos would certainly look cool as well:
https://www.thingiverse.com/thing:2754051
https://www.thingiverse.com/thing:3426823
https://www.thingiverse.com/thing:3047031

- use a DK Or Mario silhouette and add rings that would allow you to screw it onto wood:
https://www.thingiverse.com/thing:2409434

- or you could go crazy and do something completely different?
https://www.thingiverse.com/thing:923076

Anyway, thanks for reading, mates!

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
It's not that hard to make something like this using OpenSCAD and Inkscape.

1. Start with a parametric fan grill like this one or add some logo-supports to this instrument holder model or code one from scratch.

If you want something that looks like the grill from your first link the code would have these elements:

- Difference (subtract 2nd and later objects from the first object)
  -- Hull (first object) for the body of the grill, defined by four cylinders, one at each corner
  -- Cylinder x4 (2nd - 5th objects) for the screw holes, use tapered cylinders for countersunk screws
  -- Hull x7 (6th - 12th objects) for the slots, defined by two cylinders, one at each end of the slot

If you plan to use the Nintendo oval logo, you might want the slots to be horizontal instead of vertical.

2. Choose a 2d monochrome logo like this one.
- It's a good size and resolution, just need to crop the bottom using MSPaint.
- Depending on the print size, you may also want to remove the "®".

Use Inkscape to vectorize and export it to .DXF using the workflow process in this post.
------------------
LMK if this approach sounds like what you're looking for.


Scott

ChurchOfSolipsism

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 231
  • Last login:May 09, 2023, 01:43:39 pm
Many thanks mate, I actually had Blender installed one time, but since I have so many other projects lined up and not much time due to job etc., I wasn't really going to bother learning that. I'll try out your guide, can't promise it'll be any time soon though.

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
I was just putting forward a few ideas to see which grill and logo combination you preferred and explain the process I use to build models like this in 3d.

No sense writing code for a combination that isn't quite what you're looking for.

I can cut and paste a good chunk of the needed code from previous projects.

Once I convert the logo and write the basic parametric code, anyone can tweak the variables to customize the model.   ;D


Scott

ChurchOfSolipsism

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 231
  • Last login:May 09, 2023, 01:43:39 pm
Oooooh I see, that's mighty generous of you! Well, I was going to leave it up to whoever would go to the trouble of actually making this thing, but if you ask me, something iconic would be coolest. Like, combine a

appropriately old school looking fan guard (like this one:

https://www.thingiverse.com/thing:2203044

- and yeah I agree, the bars should be horizontal) with this pixel DK head:

https://www.thingiverse.com/thing:2409434

would be tight (the head would need more holes though so it doesn't stop the air flow from the fan too much). Then again, having the authentic Donkey Kong logo in the middle of the fan guard like this:

DONKEY
  KONG

would look good as well? Not sure, I'm not a designer and I'm bad at imagining what sth will look like when finished. What do you think?

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
Should have asked earlier, but what size fans are you using?
- 40mm fans are so tiny that we shouldn't do anything to restrict the airflow.
-- Maybe do something like angled girders for the fan grills and on the top, outside the airflow area, a silhouette of DK rolling a barrel on one and Pauline on top of the other.
- 80mm fans allow enough wiggle room to add some detail.
- 120mm fans we can get away with a lot more.

appropriately old school looking fan guard (like this one:

https://www.thingiverse.com/thing:2203044

- and yeah I agree, the bars should be horizontal)
Easy stuff.   ;D

The reason I originally suggested turning the slots horizontal was to keep the ovals parallel and better support the text in the Nintendo oval logo.

The other option to consider is whether you want the slots to look like the ones on the front of a Nintendo cab.

with this pixel DK head:

https://www.thingiverse.com/thing:2409434

would be tight (the head would need more holes though so it doesn't stop the air flow from the fan too much).
I agree that there won't be nearly enough airflow through that model unless the head is the same size or smaller than the center hub of the fan.

Re-doing that pixel DK head as a bunch of square straws of varying heights might work, but that is a whole lot of extremely detailed code for an uncertain outcome.

Then again, having the authentic Donkey Kong logo in the middle of the fan guard like this:

DONKEY
  KONG

would look good as well?
Depends on what size fans you're using.

On larger fans, you might want to use the red outlines of this DK logo (better airflow) and split it into two lines of text.



On smaller fans, you might want to use the yellow outline of this DK logo.




Scott

ChurchOfSolipsism

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 231
  • Last login:May 09, 2023, 01:43:39 pm
Should have asked earlier, but what size fans are you using?


I'm using an 8cm fan, but I routed the edges of the hole to make it look a bit more elegant, which means that the effective diametre for the whole thing is 8,5cm. Just to give you an idea of the overall dimensions, the cab is about 35cm wide.

-- Maybe do something like angled girders for the fan grills and on the top, outside the airflow area, a silhouette of DK rolling a barrel on one and Pauline on top of the other.

 :dizzy: that would be bonkers... if you really think you can make this work go right ahead. Thing is, resin, while a sturdy material, tends to break rather easily if you make objects too small or thin. I'd hate for you to go to all the trouble and then it's all for naught. I'd say no details should be thinner/ smaller than 2-3mm unless it's very short and attached to a larger body (so for example individual long strands of hair wouldn't work).

If it's bars instead of steel girders, let's make them horizontal if we're going with the Nintendo logo - not sure vertical bars similar to the speaker openings would work with it. I've made a couple of sketches, and I'M still having a hard tiem deciding what I want; one consideration is that making a fan guard with just the Nintendo logo would make it useable on more than one machine. The DK logo looks swell, too (let's drop the DK's head-idea though since it doesn't seem to make much sense). So let's say if you can make the first idea with the steel girders and characters work, definitely go for that. Having anything more than just the two letters DK would probably make it too cluttered... I think? If it's just bars, let's go with DONKEY and KONG as two lines of text. If you'd rather do the Nintendo logo, go ahead, I'm grateful for any help you'd be willing to give!

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
Here's a first-pass mashup turning the oval slot grill into abstract DK girders.

It's parametric so you can easily change the variables (lines 13 - 37) and preview in OpenSCAD.

Code: [Select]
// Fan Grill - Nintendo

// Logo exported from Inkscape to .dxf file using https://github.com/brad/Inkscape-OpenSCAD-DXF-Export

/////////////////////////////
//  Adjustable variables
/////////////////////////////

// Logo
LogoDepth = 7.0; // Overall logo depth

// Body
Body = 85; // X- and Y-axis size of the grill

BodyThick = 4; // Z-axis thickness of the grill

BodyRoundDia = 6; // Body corner rounding diameter

// Screw holes
ScrewDist = 71.5; // Center-center distance for the screw holes

ScrewLowDia = 5; // Lower diameter for the screw holes

ScrewUpperDia = 8; // Upper diameter for the screw holes - for non-countersunk holes use the same value as ScrewLowDia

// Slots
NumberOfSlots = 6; // The number of slots

SlotSpacing = ScrewDist/NumberOfSlots; // The distance between slots

SlotInset = 4; // The distance between the end of the slot and the edge/screw hole

SlotSmDia = 4; // Slot small diameter

SlotMedDia = 7; // Slot medium diameter (used for first and last slots)

SlotLgDia = 13; // Slot large diameter

// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360
    // 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.
    // Lower the number for faster rendering, raise the number for smoother rendering.


/////////////////////////////
//  Make the part
/////////////////////////////

// Make the Logo (Optional)
// Comment out the next three lines to skip the logo
//translate([0, 0, 0])
//linear_extrude(height = LogoDepth, convexity = 10)
//import(file = "SNK_Logo.dxf", layer="Logo");
// The "SNK_Logo.dxf" file needs to be in the same directory as this SCAD file.
//

// Make the grill
difference(){ // Body minus screw holes and slots

    // Body
    hull() {
    translate([Body/2-BodyRoundDia, Body/2-BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper right corner

    translate([Body/2-BodyRoundDia, -Body/2+BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower right corner

    translate([-Body/2+BodyRoundDia, -Body/2+BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower left corner

    translate([-Body/2+BodyRoundDia, Body/2-BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper left corner
    }
    // End body

    // Screw holes
    translate([ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper right screw hole

    translate([ScrewDist/2, -ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower right screw hole

    translate([-ScrewDist/2, -ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower left screw hole

    translate([-ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper left screw hole
    // End screw holes

    // Slot0
    hull() {
    translate([-ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, ScrewDist/2 - SlotMedDia/2 + SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot0

    // Slot1
    hull() {
    translate([-Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot1

    // Slot2
    hull() {
    translate([-Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot2

    // Slot3
    hull() {
    translate([-Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot3

    // Slot4
    hull() {
    translate([-Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot4

    // Slot5
    hull() {
    translate([-Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot5

    // Slot last
    hull() {
    translate([-ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, - ScrewDist/2 + SlotMedDia/2 - SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot last
}  // End body minus screw holes and slots
//

The code for importing a logo is commented out. (lines 51-53)
- It just needs the file name, layer name, and positioning info for the .dxf file of whichever logo we choose.

We can also add "ladders" to the inclined "girders" if desired.


Scott
EDIT: 80mm fan screw holes are 71.5mm center-to-center.
« Last Edit: May 16, 2020, 08:39:52 pm by PL1 »

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
. . . and here it is with the oval logo added and rotated.

Save "nin_no_R.dxf" from the .zip file in the same folder as your OpenSCAD file.

Code: [Select]
// Fan Grill - Nintendo

// Logo exported from Inkscape to .dxf file using https://github.com/brad/Inkscape-OpenSCAD-DXF-Export

/////////////////////////////
//  Adjustable variables
/////////////////////////////

// Logo
LogoDepth = 7.0; // Overall logo depth

LogoWidth = 213.254; // From inkscape file

LogoHeight = 52.652; // From inkscape file

LogoScale = 0.44; // Desired scale relative to original size i.e. 0.5 will render the logo at half-size

LogoRotation = 4; // Degrees of rotatation for the logo

LogoXOffset = -45.8; // Move the logo on the X-axis

LogoYOffset = -9; // Move the logo on the Y-axis

// Body
Body = 85; // X- and Y-axis size of the grill

BodyThick = 4; // Z-axis thickness of the grill

BodyRoundDia = 6; // Body corner rounding diameter

// Screw holes
ScrewDist = 71.5; // Center-center distance for the screw holes

ScrewLowDia = 5; // Lower diameter for the screw holes

ScrewUpperDia = 8; // Upper diameter for the screw holes - for non-countersunk holes use the same value as ScrewLowDia

// Slots
NumberOfSlots = 6; // The number of slots

SlotSpacing = ScrewDist/NumberOfSlots; // The distance between slots

SlotInset = 4; // The distance between the end of the slot and the edge/screw hole

SlotSmDia = 4; // Slot small diameter

SlotMedDia = 7; // Slot medium diameter (used for first and last slots)

SlotLgDia = 13; // Slot large diameter

// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360
    // 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.
    // Lower the number for faster rendering, raise the number for smoother rendering.


/////////////////////////////
//  Make the part
/////////////////////////////

// Make the Logo (Optional)
// Comment out the next five lines to skip the logo
translate([LogoXOffset, LogoYOffset, 0])
rotate([0, 0, LogoRotation])
scale([LogoScale, LogoScale, 1])
linear_extrude(height = LogoDepth, convexity = 10)
import(file = "nin_no_R.dxf", layer="Logo");
// The "nin_no_R.dxf" file needs to be in the same directory as this SCAD file.
//

// Make the grill
difference(){ // Body minus screw holes and slots

    // Body
    hull() {
    translate([Body/2 - BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper right corner

    translate([Body/2 - BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower right corner

    translate([- Body/2 + BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower left corner

    translate([- Body/2 + BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper left corner
    }
    // End body

    // Screw holes
    translate([ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper right screw hole

    translate([ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower right screw hole

    translate([- ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower left screw hole

    translate([- ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper left screw hole
    // End screw holes

    // Slot0
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, ScrewDist/2 - SlotMedDia/2 + SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot0

    // Slot1
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot1

    // Slot2
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot2

    // Slot3
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot3

    // Slot4
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot4

    // Slot5
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot5

    // Slot last
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, - ScrewDist/2 + SlotMedDia/2 - SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot last
}  // End body minus screw holes and slots
//

Do you want ladders?


Scott
P.S. Here's the code with the variables adjusted for un-tapered ovals and an un-tilted logo.
Code: [Select]
// Fan Grill - Nintendo

// Logo exported from Inkscape to .dxf file using https://github.com/brad/Inkscape-OpenSCAD-DXF-Export

/////////////////////////////
//  Adjustable variables
/////////////////////////////

// Logo
LogoDepth = 7.0; // Overall logo depth

LogoWidth = 213.254; // From inkscape file

LogoHeight = 52.652; // From inkscape file

LogoScale = 0.386; // Desired scale relative to original size i.e. 0.5 will render the logo at half-size

LogoRotation = 0; // Degrees of rotatation for the logo

LogoXOffset = -41.08; // Move the logo on the X-axis

LogoYOffset = -10.6; // Move the logo on the Y-axis

// Body
Body = 85; // X- and Y-axis size of the grill

BodyThick = 4; // Z-axis thickness of the grill

BodyRoundDia = 6; // Body corner rounding diameter

// Screw holes
ScrewDist = 71.5; // Center-center distance for the screw holes

ScrewLowDia = 5; // Lower diameter for the screw holes

ScrewUpperDia = 8; // Upper diameter for the screw holes - for non-countersunk holes use the same value as ScrewLowDia

// Slots
NumberOfSlots = 6; // The number of slots

SlotSpacing = ScrewDist/NumberOfSlots; // The distance between slots

SlotInset = 4; // The distance between the end of the slot and the edge/screw hole

SlotSmDia = 8; // Slot small diameter

SlotMedDia = 8; // Slot medium diameter (used for first and last slots)

SlotLgDia = 8; // Slot large diameter

// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360
    // 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.
    // Lower the number for faster rendering, raise the number for smoother rendering.


/////////////////////////////
//  Make the part
/////////////////////////////

// Make the Logo (Optional)
// Comment out the next five lines to skip the logo
translate([LogoXOffset, LogoYOffset, 0])
rotate([0, 0, LogoRotation])
scale([LogoScale, LogoScale, 1])
linear_extrude(height = LogoDepth, convexity = 10)
import(file = "nin_no_R.dxf", layer="Logo");
// The "nin_no_R.dxf" file needs to be in the same directory as this SCAD file.
//

// Make the grill
difference(){ // Body minus screw holes and slots

    // Body
    hull() {
    translate([Body/2 - BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper right corner

    translate([Body/2 - BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower right corner

    translate([- Body/2 + BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower left corner

    translate([- Body/2 + BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper left corner
    }
    // End body

    // Screw holes
    translate([ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper right screw hole

    translate([ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower right screw hole

    translate([- ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower left screw hole

    translate([- ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper left screw hole
    // End screw holes

    // Slot0
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, ScrewDist/2 - SlotMedDia/2 + SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot0

    // Slot1
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot1

    // Slot2
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot2

    // Slot3
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot3

    // Slot4
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot4

    // Slot5
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot5

    // Slot last
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, - ScrewDist/2 + SlotMedDia/2 - SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot last
}  // End body minus screw holes and slots
//
EDIT: 80mm fan screw holes are 71.5mm center-to-center.
« Last Edit: May 16, 2020, 08:41:06 pm by PL1 »

ChurchOfSolipsism

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 231
  • Last login:May 09, 2023, 01:43:39 pm
Wicked, absolutely wicked! Re: ladders, you think it's possible to do them so it's clear they're ladders? But yeah, ladders would probably be great. And would you be interested, as you suggested, in adding DK and Pauline? Not that it doesn't already look very cool. I'll absolutely take it as it is...

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
you think it's possible to do them so it's clear they're ladders?
Pretty sure that adding some narrow "siderails" and "rungs" that are maybe 1/2 the depth of the  grill should look decent.
- The shallower depth will add to the 3d look.

And would you be interested, as you suggested, in adding DK and Pauline?
It should be easy to import and scale either that pixel-art DK head model that you linked earlier or a full-body model like this one or this one.

The hard part is coming up with a similar Pauline figure.   :dunno
- It might be possible to start from a screencap or pixelart, but unless you can find some better source material this path looks like a really painful time-suck.   :banghead:

 

Another possibility is to use Mario/Jumpman.
- Pixel-art models like this, this, or this should be easy to import/mirror/scale/crop.

Since Mario is about the same height as DK's head that might be a good combination -- DK's head peering over the top of the left grill and Mario facing left on top of the right grill.


Scott

ChurchOfSolipsism

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 231
  • Last login:May 09, 2023, 01:43:39 pm
DK's and Mario's head in the top corners sounds good! Another thing that would probably look nice is having the aforementioned grinning DK head

https://www.thingiverse.com/thing:2409434

on top of the fan guard, similar to the DK Junior sideart:

https://www.vintagearcade.net/wp-content/uploads/2015/02/DK_jr_Flyer_1.jpg

Probably a lot less work, too. Ladders would be great...

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
Another thing that would probably look nice is having the aforementioned grinning DK head

https://www.thingiverse.com/thing:2409434

on top of the fan guard, similar to the DK Junior sideart:

https://www.vintagearcade.net/wp-content/uploads/2015/02/DK_jr_Flyer_1.jpg
Yep.  That's the model and layout I was picturing for one gril.   :cheers:

The other grill would have a full-body Mario standing in place of DK's head.
-------------
Ladders first, then the models.   ;D


Scott

ChurchOfSolipsism

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 231
  • Last login:May 09, 2023, 01:43:39 pm

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
Good news:  Ladders added.  You can resize/reposition them using the variables on lines 52 - 71.

Code: [Select]
// Fan Grill - Nintendo

// Logo exported from Inkscape to .dxf file using https://github.com/brad/Inkscape-OpenSCAD-DXF-Export

/////////////////////////////
//  Adjustable variables
/////////////////////////////

// Logo
LogoDepth = 7.0; // Overall logo depth

LogoWidth = 213.254; // From inkscape file

LogoHeight = 52.652; // From inkscape file

LogoScale = 0.44; // Desired scale relative to original size i.e. 0.5 will render the logo at half-size

LogoRotation = 4; // Degrees of rotatation for the logo

LogoXOffset = -45.8; // Move the logo on the X-axis

LogoYOffset = -9; // Move the logo on the Y-axis

// Body
Body = 85; // X- and Y-axis size of the grill

BodyThick = 4; // Z-axis thickness of the grill

BodyRoundDia = 6; // Body corner rounding diameter

// Screw holes
ScrewDist = 71.5; // Center-center distance for the screw holes

ScrewLowDia = 5; // Lower diameter for the screw holes

ScrewUpperDia = 8; // Upper diameter for the screw holes - for non-countersunk holes use the same value as ScrewLowDia

// Slots
NumberOfSlots = 6; // The number of slots

SlotSpacing = ScrewDist/NumberOfSlots; // The distance between slots

SlotInset = 4; // The distance between the end of the slot and the edge/screw hole

SlotSmDia = 4; // Slot small diameter

SlotMedDia = 7; // Slot medium diameter (used for first and last slots)

SlotLgDia = 13; // Slot large diameter

// Ladders
LadderDepth = 2;

RungWidth = 4;

RungHeight = 1.2;

RungSpace = 2.6;

RailWidth = 1.2;

RailHeight = 10;

Ladder1X = 19;
Ladder1Y = -24;

Ladder2X = -19;
Ladder2Y = -12;

Ladder3X = 19;
Ladder3Y = 24;

// Topper
TopperXOffset = 0;

TopperYOffset = 63.5;


// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360
    // 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.
    // Lower the number for faster rendering, raise the number for smoother rendering.


/////////////////////////////
//  Make the part
/////////////////////////////

// Make the Logo (Optional)
// Comment out the next five lines to skip the logo
translate([LogoXOffset, LogoYOffset, 0])
rotate([0, 0, LogoRotation])
scale([LogoScale, LogoScale, 1])
linear_extrude(height = LogoDepth, convexity = 10)
import(file = "nin_no_R.dxf", layer="Logo");
// The "nin_no_R.dxf" file needs to be in the same directory as this SCAD file.
//

// Make the grill
difference(){ // Body minus screw holes and slots

    // Body
    hull() {
    translate([Body/2 - BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper right corner

    translate([Body/2 - BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower right corner

    translate([- Body/2 + BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower left corner

    translate([- Body/2 + BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper left corner
    }
    // End body

    // Screw holes
    translate([ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper right screw hole

    translate([ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower right screw hole

    translate([- ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower left screw hole

    translate([- ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper left screw hole
    // End screw holes

    // Slot0
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, ScrewDist/2 - SlotMedDia/2 + SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot0

    // Slot1
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot1

    // Slot2
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot2

    // Slot3
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot3

    // Slot4
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot4

    // Slot5
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot5

    // Slot last
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, - ScrewDist/2 + SlotMedDia/2 - SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot last
}  // End body minus screw holes and slots
//

// Ladder 1
translate([Ladder1X - RungWidth/2 - RailWidth/2, Ladder1Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Left rail

translate([Ladder1X +  RungWidth/2 + RailWidth/2, Ladder1Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Right rail

translate([Ladder1X, Ladder1Y + RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Top rung

translate([Ladder1X, Ladder1Y - RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Bottom rung

// Ladder 2
translate([Ladder2X - RungWidth/2 - RailWidth/2, Ladder2Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Left rail

translate([Ladder2X +  RungWidth/2 + RailWidth/2, Ladder2Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Right rail

translate([Ladder2X, Ladder2Y + RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Top rung

translate([Ladder2X, Ladder2Y - RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Bottom rung

// Ladder 3
translate([Ladder3X - RungWidth/2 - RailWidth/2, Ladder3Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Left rail

translate([Ladder3X +  RungWidth/2 + RailWidth/2, Ladder3Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Right rail

translate([Ladder3X, Ladder3Y + RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Top rung

translate([Ladder3X, Ladder3Y - RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Bottom rung

Not-so-good news:  The DK and Mario models both preview fine after importing, but cause an error during rendering.  So far, haven't figured out how to repair what appear to be mesh errors.   :angry:

Likely-good-news:  It is possible to make a pixel-art model from a .png file using the "surface" command.
- The color of each pixel determines how tall that cube is -- the darker the color, the taller the cube.
- The DK arcade sprite sheet is probably a good starting point to grab the right outlines and patterns.
- Then I just need to color-match each pixel to the desired height.   :banghead:


Scott

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
Turns out that the surface command sucks for importing pixel-art :puke, but then I remembered this model that uses nested for loops to convert a matrix of ones and zeros into cubes that form the selected type of Pac Ghost.

After a few tweaks to Garrett Melenka's great code, it can now convert a 20x16 matrix of numbers between zero and five into 1-5mm thick cubes that form either DK's head or Mario, depending on the "TopSelect" setting on line 76.
- DK came out really good IMHO.
- Mario . . . might need some help or it might just be less-than flattering lighting on the render.   :lol

Code: [Select]
// Fan Grill - Nintendo (v2)

// Logo exported from Inkscape to .dxf file using https://github.com/brad/Inkscape-OpenSCAD-DXF-Export

// Pixel-art topper code adapted from https://www.thingiverse.com/thing:1833458 by Garrett Melenka

/////////////////////////////
//  Adjustable variables
/////////////////////////////

// Logo
LogoDepth = 7.0; // Overall logo depth

LogoWidth = 213.254; // From inkscape file

LogoHeight = 52.652; // From inkscape file

LogoScale = 0.44; // Desired scale relative to original size i.e. 0.5 will render the logo at half-size

LogoRotation = 4; // Degrees of rotatation for the logo

LogoXOffset = -45.8; // Move the logo on the X-axis

LogoYOffset = -9; // Move the logo on the Y-axis

// Body
Body = 85; // X- and Y-axis size of the grill

BodyThick = 4; // Z-axis thickness of the grill

BodyRoundDia = 6; // Body corner rounding diameter

// Screw holes
ScrewDist = 71.5; // Center-center distance for the screw holes

ScrewLowDia = 5; // Lower diameter for the screw holes

ScrewUpperDia = 8; // Upper diameter for the screw holes - for non-countersunk holes use the same value as ScrewLowDia

// Slots
NumberOfSlots = 6; // The number of slots

SlotSpacing = ScrewDist/NumberOfSlots; // The distance between slots

SlotInset = 4; // The distance between the end of the slot and the edge/screw hole

SlotSmDia = 4; // Slot small diameter

SlotMedDia = 7; // Slot medium diameter (used for first and last slots)

SlotLgDia = 13; // Slot large diameter

// Ladders
LadderDepth = 2; // Z-axis depth of all ladder parts

RungWidth = 4; // X-axis width of the rungs

RungHeight = 1.2; // Y-axis height of the rungs

RungSpace = 2.6; // Y-axis space between rungs

RailWidth = 1.2; // X-axis width of the side rails

RailHeight = 10; // Y-axis height of the side rails

Ladder1X = 19; // X-axis center of ladder 1
Ladder1Y = -24; // y-axis center of ladder 1

Ladder2X = -19; // X-axis center of ladder 2
Ladder2Y = -12; // Y-axis center of ladder 2

Ladder3X = 19; // X-axis center of ladder 3
Ladder3Y = 24; // Y-axis center of ladder 3

// Pixel-art topper
TopSelect = 1; // Topper selection, 0 = None, 1 = Donkey Kong, 2 = Mario

pixelSize = 3; // Size of each square in the pixel-art

TopperXOffset = -28; // Adjust the X-axis position of the topper
TopperYOffset = 43.8; // Adjust the Y-axis position of the topper


// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360
    // 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.
    // Lower the number for faster rendering, raise the number for smoother rendering.


/////////////////////////////
//  Make the part
/////////////////////////////

// Make the Logo (Optional)
// Comment out the next five lines to skip the logo
translate([LogoXOffset, LogoYOffset, 0])
rotate([0, 0, LogoRotation])
scale([LogoScale, LogoScale, 1])
linear_extrude(height = LogoDepth, convexity = 10)
import(file = "nin_no_R.dxf", layer="Logo");
// The "nin_no_R.dxf" file needs to be in the same directory as this SCAD file.
//

// Make the grill
difference(){ // Body minus screw holes and slots

    // Body
    hull() {
    translate([Body/2 - BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper right corner

    translate([Body/2 - BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower right corner

    translate([- Body/2 + BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower left corner

    translate([- Body/2 + BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper left corner
    }
    // End body

    // Screw holes
    translate([ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper right screw hole

    translate([ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower right screw hole

    translate([- ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower left screw hole

    translate([- ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper left screw hole
    // End screw holes

    // Slot0
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, ScrewDist/2 - SlotMedDia/2 + SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot0

    // Slot1
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot1

    // Slot2
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot2

    // Slot3
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot3

    // Slot4
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot4

    // Slot5
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot5

    // Slot last
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, - ScrewDist/2 + SlotMedDia/2 - SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot last
}  // End body minus screw holes and slots
//

// Ladder 1
translate([Ladder1X - RungWidth/2 - RailWidth/2, Ladder1Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Left rail

translate([Ladder1X +  RungWidth/2 + RailWidth/2, Ladder1Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Right rail

translate([Ladder1X, Ladder1Y + RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Top rung

translate([Ladder1X, Ladder1Y - RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Bottom rung

// Ladder 2
translate([Ladder2X - RungWidth/2 - RailWidth/2, Ladder2Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Left rail

translate([Ladder2X +  RungWidth/2 + RailWidth/2, Ladder2Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Right rail

translate([Ladder2X, Ladder2Y + RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Top rung

translate([Ladder2X, Ladder2Y - RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Bottom rung

// Ladder 3
translate([Ladder3X - RungWidth/2 - RailWidth/2, Ladder3Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Left rail

translate([Ladder3X +  RungWidth/2 + RailWidth/2, Ladder3Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Right rail

translate([Ladder3X, Ladder3Y + RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Top rung

translate([Ladder3X, Ladder3Y - RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Bottom rung

// Pixel-art matrices for the different toppers

        // Matrix top01 for Donkey Kong
        // Bottom pixel   ==>   top pixel
top01 = [[0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0], // Left 1
         [0,0,0,3,3,3,0,3,3,3,0,0,0,0,0,0], // Col. 2
         [0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0], // Col. 3
         [0,3,3,2,1,3,3,4,4,4,0,0,0,0,0,0], // Col. 4
         [0,3,1,1,1,1,3,4,4,4,4,0,0,0,0,0], // Col. 5
         [0,3,1,2,1,1,3,4,4,3,4,4,0,0,0,0], // Col. 6
         [3,3,2,2,2,3,3,3,3,3,3,4,4,0,0,0], // Col. 7
         [3,1,1,2,1,3,3,3,3,3,3,3,4,4,0,0], // Col. 8
         [3,1,1,1,1,3,3,3,2,2,3,3,4,4,0,0], // Col. 9
         [3,1,1,2,1,3,5,3,0,2,3,4,4,4,0,0], // Col. 10
         [3,3,2,2,2,3,5,3,3,3,4,4,4,4,0,0], // Col. 11
         [3,1,1,2,1,3,5,3,0,2,3,4,4,4,0,0], // Col. 12
         [3,1,1,1,1,3,3,3,2,2,3,3,4,4,0,0], // Col. 13
         [3,1,1,2,1,3,3,3,2,3,3,3,4,4,0,0], // Col. 14
         [3,3,2,2,2,3,3,3,3,3,3,4,4,0,0,0], // Col. 15
         [0,3,1,2,1,1,3,4,4,3,4,4,0,0,0,0], // Col. 16
         [0,3,1,1,1,1,3,4,4,4,4,0,0,0,0,0], // Col. 17
         [0,0,3,2,1,3,3,3,3,3,0,0,0,0,0,0], // Col. 18
         [0,0,0,3,3,3,0,3,3,3,0,0,0,0,0,0], // Col. 19
         [0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0]];// Right 20

        // Matrix top02 for Mario
        // Bottom pixel   ==>   top pixel
top02 = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], // Left
         [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,2,0,0,0,0], // Col. 1
         [0,0,0,0,0,0,0,0,0,0,3,2,2,0,0,0], // Col. 2
         [5,0,0,4,4,4,0,0,0,2,3,2,2,0,4,0], // Col. 3
         [5,5,4,4,4,4,4,3,0,2,3,3,2,0,4,0], // Col. 4
         [5,5,4,4,4,4,4,3,3,2,3,2,0,2,4,0], // Col. 5
         [5,5,4,4,4,4,2,4,3,2,2,2,2,2,4,4], // Col. 6
         [0,0,0,4,2,4,4,4,3,2,2,3,2,3,4,4], // Col. 7
         [5,0,4,2,2,3,4,3,3,2,2,3,3,3,4,4], // Col. 8
         [5,5,4,2,2,3,3,3,3,2,2,2,2,3,4,4], // Col. 9
         [5,5,4,4,3,3,3,3,3,0,3,2,2,3,4,0], // Col. 10
         [5,5,4,4,4,3,3,3,0,0,3,3,3,0,0,0], // Col. 11
         [0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0], // Col. 12
         [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]];// Right

// Define the modules used to generate the topper

module pixel1() // Makes a 1mm tall cube
{
    translate([0,0,0.5])
    cube(size = [pixelSize, pixelSize, 1], center = true);
}
//

module pixel2() // Makes a 2mm tall cube
{
    translate([0,0,1])
    cube(size = [pixelSize, pixelSize, 2], center = true);
}
//

module pixel3() // Makes a 3mm tall cube
{
    translate([0,0,1.5])
    cube(size = [pixelSize, pixelSize, 3], center = true);
}
//

module pixel4() // Makes a 4mm tall cube
{
    translate([0,0,2])
    cube(size = [pixelSize, pixelSize, 4], center = true);
}
//

module pixel5() // Makes a 5mm tall cube
{
    translate([0,0,2.5])
    cube(size = [pixelSize, pixelSize, 5], center = true);
}
//

module topper()
{
    for(i = [0:19]) // X-axis loop
    {
        for(j = [0:15]) // Y-axis loop
        {
            // Topper 01 Donkey Kong loop
            if (TopSelect ==1)
            {

            // Was this pixel a "1" in matrix 1?
            if (top01[i][j] == 1)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel1();
            }
            } // End check for a "1" pixel in matrix 1
              //

            // Was this pixel a "2" in matrix 1?
            if (top01[i][j] == 2)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel2();
            }
            } // End check for a "2" pixel in matrix 1
              //

            // Was this pixel a "3" in matrix 1?
            if (top01[i][j] == 3)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel3();
            }
            } // End check for a "3" pixel in matrix 1
              //

            // Was this pixel a "4" in matrix 1?
            if (top01[i][j] == 4)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel4();
            }
            } // End check for a "4" pixel in matrix 1
              //

            // Was this pixel a "5" in matrix 1?
            if (top01[i][j] == 5)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel5();
            }
            } // End check for a "5" pixel in matrix 1
              //

            } // End Topper 01 Donkey Kong loop
              //
           
            // Topper 02 Mario loop
            if (TopSelect ==2)
            {

            // Was this pixel a "1" in matrix 2?
            if (top02[i][j] == 1)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel1();
            }
            } // End check for a "1" pixel in matrix 2
              //

            // Was this pixel a "2" in matrix 2?
            if (top02[i][j] == 2)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel2();
            }
            } // End check for a "2" pixel in matrix 2
              //

            // Was this pixel a "3" in matrix 2?
            if (top02[i][j] == 3)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel3();
            }
            } // End check for a "3" pixel in matrix 2
              //

            // Was this pixel a "4" in matrix 2?
            if (top02[i][j] == 4)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel4();
            }
            } // End check for a "4" pixel in matrix 2
              //
           
            // Was this pixel a "5" in matrix 2?
            if (top02[i][j] == 5)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel5();
            }
            } // End check for a "5" pixel in matrix 2
              //

            } // End Topper 02 Mario loop
              //

        } // End Y-axis loop
          //

    } // End X-axis loop
      //

} // End topper module
  //

// Make the topper by running the topper module
topper();
//

If you want something a little different, play around with the variable settings on lines 12 - 81.

If you like the grills "as-is", you can use the .STLs in the attached .ZIP file.
- OpenSCAD  gave this warning during rendering for both models, but the .STLs load and slice in Cura.   :dunno
Quote
WARNING: Object may not be a valid 2-manifold and may need repair!

If you print one, let everyone know how it turns out.   :cheers:


Scott

ChurchOfSolipsism

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 231
  • Last login:May 09, 2023, 01:43:39 pm
So sorry for not replying earlier, was suffering from my yearly sinusitis.  :banghead:

The grill came out awesome, can't wait to print it! I'll go with the DK grill btw, Mario does indeed look a bit dopey haha. Thank you so much, you must have put quite a lot of your time into this. Amazing work!

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
The grill came out awesome, can't wait to print it!
Before you do, double check that these variable values are right for your hardware/needs. (values are in mm)

- Body = 85; // X- and Y-axis size of the grill

- ScrewLowDia = 5; // Lower diameter for the screw holes

- ScrewUpperDia = 8; // Upper diameter for the screw holes - for non-countersunk holes use the same value as ScrewLowDia

The diameter values may need to be *very slightly* larger to account for the 180-sided polygon used to render circles -- see "undersized holes" at https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids#cylinder

If you use the exact size of the screw diameter (green) as the variable, you'll get a hole (blue) that's slightly too small.
- A slightly larger value will give a slightly larger hole. (pink)



I'll go with the DK grill btw, Mario does indeed look a bit dopey haha.
Yeah, the height difference between Mario's face and mustache were pretty extreme.   :embarassed:
- Added variables on lines 85-95 so you can independently adjust the height of the pixel-art cubes for each topper instead of having them at fixed 1mm intervals.
- Mario looks decent with the new settings on lines 91-95, but there's probably some room for improvement.   :dunno

Code: [Select]
// Fan Grill - Nintendo (v3)

// Logo exported from Inkscape to .dxf file using https://github.com/brad/Inkscape-OpenSCAD-DXF-Export

// Pixel-art topper code adapted from https://www.thingiverse.com/thing:1833458 by Garrett Melenka

// The diameter values may need to be *very slightly* larger to account for the 180-sided polygon used to render circles -- see "undersized holes" at https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids#cylinder

/////////////////////////////
//  Adjustable variables
/////////////////////////////

// Logo
LogoDepth = 7.0; // Overall logo depth

LogoWidth = 213.254; // From inkscape file

LogoHeight = 52.652; // From inkscape file

LogoScale = 0.44; // Desired scale relative to original size i.e. 0.5 will render the logo at half-size

LogoRotation = 4; // Degrees of rotatation for the logo

LogoXOffset = -45.8; // Move the logo on the X-axis

LogoYOffset = -9; // Move the logo on the Y-axis

// Body
Body = 85; // X- and Y-axis size of the grill

BodyThick = 4; // Z-axis thickness of the grill

BodyRoundDia = 6; // Body corner rounding diameter

// Screw holes
ScrewDist = 71.5; // Center-center distance for the screw holes

ScrewLowDia = 5; // Lower diameter for the screw holes

ScrewUpperDia = 8; // Upper diameter for the screw holes - for non-countersunk holes use the same value as ScrewLowDia

// Slots
NumberOfSlots = 6; // The number of slots

SlotSpacing = ScrewDist/NumberOfSlots; // The distance between slots

SlotInset = 4; // The distance between the end of the slot and the edge/screw hole

SlotSmDia = 4; // Slot small diameter

SlotMedDia = 7; // Slot medium diameter (used for first and last slots)

SlotLgDia = 13; // Slot large diameter

// Ladders
LadderDepth = 2; // Z-axis depth of all ladder parts

RungWidth = 4; // X-axis width of the rungs

RungHeight = 1.2; // Y-axis height of the rungs

RungSpace = 2.6; // Y-axis space between rungs

RailWidth = 1.2; // X-axis width of the side rails

RailHeight = 10; // Y-axis height of the side rails

Ladder1X = 19; // X-axis center of ladder 1
Ladder1Y = -24; // y-axis center of ladder 1

Ladder2X = -19; // X-axis center of ladder 2
Ladder2Y = -12; // Y-axis center of ladder 2

Ladder3X = 19; // X-axis center of ladder 3
Ladder3Y = 24; // Y-axis center of ladder 3

// Pixel-art topper
TopperXOffset = -28; // Adjust the X-axis position of the topper
TopperYOffset = 43.8; // Adjust the Y-axis position of the topper

TopSelect = 2; // Topper selection, 0 = None, 1 = Donkey Kong, 2 = Mario

pixelSize = 3; // X-Y Size of each square in the pixel-art

pixel1heightDK = 1; // Height for DK "1" pixel
pixel2heightDK = 2; // Height for DK "2" pixel
pixel3heightDK = 3; // Height for DK "3" pixel
pixel4heightDK = 4; // Height for DK "4" pixel
pixel5heightDK = 5; // Height for DK "5" pixel

pixel1heightMario = 2; // Height for Mario "1" pixel
pixel2heightMario = 2.4; // Height for Mario "2" pixel
pixel3heightMario = 3; // Height for Mario "3" pixel
pixel4heightMario = 4; // Height for Mario "4" pixel
pixel5heightMario = 4.5; // Height for Mario "5" pixel


// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360
    // 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.
    // Lower the number for faster rendering, raise the number for smoother rendering.


/////////////////////////////
//  Make the part
/////////////////////////////

// Make the Logo (Optional)
// Comment out the next five lines to skip the logo
translate([LogoXOffset, LogoYOffset, 0])
rotate([0, 0, LogoRotation])
scale([LogoScale, LogoScale, 1])
linear_extrude(height = LogoDepth, convexity = 10)
import(file = "nin_no_R.dxf", layer="Logo");
// The "nin_no_R.dxf" file needs to be in the same directory as this SCAD file.
//

// Make the grill
difference(){ // Body minus screw holes and slots

    // Body
    hull() {
    translate([Body/2 - BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper right corner

    translate([Body/2 - BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower right corner

    translate([- Body/2 + BodyRoundDia, - Body/2 + BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Lower left corner

    translate([- Body/2 + BodyRoundDia, Body/2 - BodyRoundDia, BodyThick/2])
    cylinder (BodyThick, r = BodyRoundDia, center=true); // Upper left corner
    }
    // End body

    // Screw holes
    translate([ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper right screw hole

    translate([ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower right screw hole

    translate([- ScrewDist/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Lower left screw hole

    translate([- ScrewDist/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d1 = ScrewLowDia, d2 = ScrewUpperDia, center=true); // Upper left screw hole
    // End screw holes

    // Slot0
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, ScrewDist/2 - SlotMedDia/2 + SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot0

    // Slot1
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 1, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot1

    // Slot2
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot2

    // Slot3
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 3, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot3

    // Slot4
    hull() {
    translate([- Body/2 + SlotInset + SlotSmDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotLgDia/2, ScrewDist/2 - SlotSpacing * 4, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Right cylinder
    }
    // End slot4

    // Slot5
    hull() {
    translate([- Body/2 + SlotInset + SlotLgDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotLgDia, center=true); // Left cylinder

    translate([Body/2 - SlotInset - SlotSmDia/2, ScrewDist/2 - SlotSpacing * 5, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Right cylinder
    }
    // End slot5

    // Slot last
    hull() {
    translate([- ScrewDist/2 + SlotInset + ScrewUpperDia/2 + SlotSmDia/2, - ScrewDist/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotSmDia, center=true); // Left cylinder

    translate([ScrewDist/2 - SlotInset - ScrewUpperDia/2 - SlotMedDia/2, - ScrewDist/2 + SlotMedDia/2 - SlotSmDia/2, BodyThick/2])
    cylinder (BodyThick + 0.01, d = SlotMedDia, center=true); // Right cylinder
    }
    // End slot last
}  // End body minus screw holes and slots
//

// Ladder 1
translate([Ladder1X - RungWidth/2 - RailWidth/2, Ladder1Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Left rail

translate([Ladder1X +  RungWidth/2 + RailWidth/2, Ladder1Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Right rail

translate([Ladder1X, Ladder1Y + RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Top rung

translate([Ladder1X, Ladder1Y - RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Bottom rung

// Ladder 2
translate([Ladder2X - RungWidth/2 - RailWidth/2, Ladder2Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Left rail

translate([Ladder2X +  RungWidth/2 + RailWidth/2, Ladder2Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Right rail

translate([Ladder2X, Ladder2Y + RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Top rung

translate([Ladder2X, Ladder2Y - RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Bottom rung

// Ladder 3
translate([Ladder3X - RungWidth/2 - RailWidth/2, Ladder3Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Left rail

translate([Ladder3X +  RungWidth/2 + RailWidth/2, Ladder3Y, LadderDepth/2])
cube ([RailWidth, RailHeight, LadderDepth], center=true); // Right rail

translate([Ladder3X, Ladder3Y + RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Top rung

translate([Ladder3X, Ladder3Y - RungSpace/2, LadderDepth/2])
cube ([RungWidth, RungHeight, LadderDepth], center=true); // Bottom rung

// Pixel-art matrices for the different toppers

        // Matrix top01 for Donkey Kong
        // Bottom pixel   ==>   top pixel
top01 = [[0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0], // Left 1
         [0,0,0,3,3,3,0,3,3,3,0,0,0,0,0,0], // Col. 2
         [0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0], // Col. 3
         [0,3,3,2,1,3,3,4,4,4,0,0,0,0,0,0], // Col. 4
         [0,3,1,1,1,1,3,4,4,4,4,0,0,0,0,0], // Col. 5
         [0,3,1,2,1,1,3,4,4,3,4,4,0,0,0,0], // Col. 6
         [3,3,2,2,2,3,3,3,3,3,3,4,4,0,0,0], // Col. 7
         [3,1,1,2,1,3,3,3,3,3,3,3,4,4,0,0], // Col. 8
         [3,1,1,1,1,3,3,3,2,2,3,3,4,4,0,0], // Col. 9
         [3,1,1,2,1,3,5,3,0,2,3,4,4,4,0,0], // Col. 10
         [3,3,2,2,2,3,5,3,3,3,4,4,4,4,0,0], // Col. 11
         [3,1,1,2,1,3,5,3,0,2,3,4,4,4,0,0], // Col. 12
         [3,1,1,1,1,3,3,3,2,2,3,3,4,4,0,0], // Col. 13
         [3,1,1,2,1,3,3,3,2,3,3,3,4,4,0,0], // Col. 14
         [3,3,2,2,2,3,3,3,3,3,3,4,4,0,0,0], // Col. 15
         [0,3,1,2,1,1,3,4,4,3,4,4,0,0,0,0], // Col. 16
         [0,3,1,1,1,1,3,4,4,4,4,0,0,0,0,0], // Col. 17
         [0,0,3,2,1,3,3,3,3,3,0,0,0,0,0,0], // Col. 18
         [0,0,0,3,3,3,0,3,3,3,0,0,0,0,0,0], // Col. 19
         [0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0]];// Right 20

        // Matrix top02 for Mario
        // Bottom pixel   ==>   top pixel
top02 = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], // Left
         [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,2,0,0,0,0], // Col. 1
         [0,0,0,0,0,0,0,0,0,0,3,2,2,0,0,0], // Col. 2
         [5,0,0,4,4,4,0,0,0,2,3,2,2,0,4,0], // Col. 3
         [5,5,4,4,4,4,4,3,0,2,3,3,2,0,4,0], // Col. 4
         [5,5,4,4,4,4,4,3,3,2,3,2,0,2,4,0], // Col. 5
         [5,5,4,4,4,4,2,4,3,2,2,2,2,2,4,4], // Col. 6
         [0,0,0,4,2,4,4,4,3,2,2,3,2,3,4,4], // Col. 7
         [5,0,4,2,2,3,4,3,3,2,2,3,3,3,4,4], // Col. 8
         [5,5,4,2,2,3,3,3,3,2,2,2,2,3,4,4], // Col. 9
         [5,5,4,4,3,3,3,3,3,0,3,2,2,3,4,0], // Col. 10
         [5,5,4,4,4,3,3,3,0,0,3,3,3,0,0,0], // Col. 11
         [0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0], // Col. 12
         [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]];// Right

// Define the modules used to generate the topper

module pixel1DK() // Makes a pixel1heightDK tall cube
{
    translate([0,0,pixel1heightDK/2])
    cube(size = [pixelSize, pixelSize, pixel1heightDK], center = true);
}
//

module pixel2DK() // Makes a pixel2heightDK tall cube
{
    translate([0,0,pixel2heightDK/2])
    cube(size = [pixelSize, pixelSize, pixel2heightDK], center = true);
}
//

module pixel3DK() // Makes a pixel3heightDK tall cube
{
    translate([0,0,pixel3heightDK/2])
    cube(size = [pixelSize, pixelSize, pixel3heightDK], center = true);
}
//

module pixel4DK() // Makes a pixel4heightDK tall cube
{
    translate([0,0,pixel4heightDK/2])
    cube(size = [pixelSize, pixelSize, pixel4heightDK], center = true);
}
//

module pixel5DK() // Makes a pixel5heightDK tall cube
{
    translate([0,0,pixel5heightDK/2])
    cube(size = [pixelSize, pixelSize, pixel5heightDK], center = true);
}
//

module pixel1Mario() // Makes a pixel1heightMario tall cube
{
    translate([0,0,pixel1heightMario/2])
    cube(size = [pixelSize, pixelSize, pixel1heightMario], center = true);
}
//

module pixel2Mario() // Makes a pixel2heightMario tall cube
{
    translate([0,0,pixel2heightMario/2])
    cube(size = [pixelSize, pixelSize, pixel2heightMario], center = true);
}
//

module pixel3Mario() // Makes a pixel3heightMario tall cube
{
    translate([0,0,pixel3heightMario/2])
    cube(size = [pixelSize, pixelSize, pixel3heightMario], center = true);
}
//

module pixel4Mario() // Makes a pixel4heightMario tall cube
{
    translate([0,0,pixel4heightMario/2])
    cube(size = [pixelSize, pixelSize, pixel4heightMario], center = true);
}
//

module pixel5Mario() // Makes a pixel5heightMario tall cube
{
    translate([0,0,pixel5heightMario/2])
    cube(size = [pixelSize, pixelSize, pixel5heightMario], center = true);
}
//

module topper()
{
    for(i = [0:19]) // X-axis loop
    {
        for(j = [0:15]) // Y-axis loop
        {
            // Topper 01 Donkey Kong loop
            if (TopSelect ==1)
            {

            // Was this pixel a "1" in matrix 1?
            if (top01[i][j] == 1)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel1DK();
            }
            } // End check for a "1" pixel in matrix 1
              //

            // Was this pixel a "2" in matrix 1?
            if (top01[i][j] == 2)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel2DK();
            }
            } // End check for a "2" pixel in matrix 1
              //

            // Was this pixel a "3" in matrix 1?
            if (top01[i][j] == 3)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel3DK();
            }
            } // End check for a "3" pixel in matrix 1
              //

            // Was this pixel a "4" in matrix 1?
            if (top01[i][j] == 4)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel4DK();
            }
            } // End check for a "4" pixel in matrix 1
              //

            // Was this pixel a "5" in matrix 1?
            if (top01[i][j] == 5)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel5DK();
            }
            } // End check for a "5" pixel in matrix 1
              //

            } // End Topper 01 Donkey Kong loop
              //
           
            // Topper 02 Mario loop
            if (TopSelect ==2)
            {

            // Was this pixel a "1" in matrix 2?
            if (top02[i][j] == 1)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel1Mario();
            }
            } // End check for a "1" pixel in matrix 2
              //

            // Was this pixel a "2" in matrix 2?
            if (top02[i][j] == 2)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel2Mario();
            }
            } // End check for a "2" pixel in matrix 2
              //

            // Was this pixel a "3" in matrix 2?
            if (top02[i][j] == 3)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel3Mario();
            }
            } // End check for a "3" pixel in matrix 2
              //

            // Was this pixel a "4" in matrix 2?
            if (top02[i][j] == 4)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel4Mario();
            }
            } // End check for a "4" pixel in matrix 2
              //
           
            // Was this pixel a "5" in matrix 2?
            if (top02[i][j] == 5)
            {
            translate([pixelSize*i + TopperXOffset, pixelSize*j + TopperYOffset,0])
            {
                pixel5Mario();
            }
            } // End check for a "5" pixel in matrix 2
              //

            } // End Topper 02 Mario loop
              //

        } // End Y-axis loop
          //

    } // End X-axis loop
      //

} // End topper module
  //

// Make the topper by running the topper module
topper();
//

Thank you so much, you must have put quite a lot of your time into this. Amazing work!
You're welcome.   ;D


Scott

ChurchOfSolipsism

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 231
  • Last login:May 09, 2023, 01:43:39 pm
Alright, finally got around to printing it out and painting it. As you can see, the print is far from perfect; I need to recalibrate the printer, but it's enough to see that it works. Once again, thank you so much, Scott!  :cheers:

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 10:37:59 am
  • Designated spam hunter
Glad to assist.   ;D


Scott