// Last edited on 2019-06-24 00:52:47 by jstolfi // Last edited on 2019-06-23 13:45:17 by jstolfi #include "fume_hood_bar_M.inc" #include "fume_hood_bar_T.inc" #include "fume_hood_bar_L.inc" #include "fume_hood_bar_B.inc" #macro fume_hood_iron(dx,dy, shape, wd,ht,th, orr,irr ang0, ang1, what, tx) // Metalon iron rod of various cross-sections, depending on {shape}: // "L" - L-shaped // "T" - T-shaped. // "B" - rectangular cross-section with rounded edges. // "M" - round tubing or square tubing with rounded edges ("metalon") // The cross-section will be inscribed in a rectangle with X-side // {wd} and Z-side {ht}, with nominal wall thickness {th}. // The outer surface of the bar will be painted with texture {tx}. // The axis of the rod will extend diagonally from {<0,0,0>} to {}. // The end at the origin will be cut by a vertical plane whose normal makes an angle {ang0} with the {x} axis. // The parameter {ang1} is similar for the cut at the other end. // All parameters must be positive, including {dx} and {dy}. // Outer and inner corner edges will be rounded with radii {orr} and {irr}, // respectively. {orr} is irrelevant for "T" bars; {irr} and {th} are irrelevant // for "B" bars. // If {what} is zero, returns the dimensions of the rod as if its axis // was parallel to the {x} axis, including the overshoots due to // the oblique cuts. Otherwise returns the rod itself, rotated // as above. // Compute the length of the axis of the rod: #local elen = sqrt(dx*dx + dy*dy); // Rotation angle: #local rsin = dy/elen; #local rang = degrees(asin(rsin)); #debug concat("!! rotation = ", str(rang,0,4), "\n") // Extra length needed to support the cut: #local extra0 = 0.5*wd/abs(cos(radians(ang0 - rang))); #local extra1 = 0.5*wd/abs(cos(radians(ang1 - rang))); #local tlen = extra0 + elen + extra1; // Total length of tube before the cut. #if (what = 0) #local res = < tlen, wd, ht >; #else // Uncut bar, with axis from {<0,0,0>} to {} plus extras at both ends: #local trod = object{ #if (shape = "M") // Rectangular cross-section tube ("metalon"): fume_hood_bar_M(tlen, wd,ht,th, orr,irr, tx) #elseif (shape = "B") // Rectangular cross-section solid bar: fume_hood_bar_B(tlen, wd,ht, orr, tx) #elseif (shape = "L") // "L"-bar; the corner is at the {-y,-z} edge: fume_hood_bar_L(tlen, wd,ht,th, orr,irr, tx) #elseif (shape = "T") // "T"-bar; the roof strip is the {+z} side: fume_hood_bar_T(tlen, wd,ht,th, irr, tx) #else #debug concat("!! shape = ", shape, "\n") #error "** invalid iron shape code\n" #end translate -extra0*x rotate rang*z } #local res = difference{ object{ trod } union{ plane{ x, 0 rotate ang0*z } plane{ -x, 0 rotate ang1*z translate dx*x + dy*y } texture{ tx_cut } } } #end res #end