--- jupyter: description: 'A column base as a 3D CAD exercise: a dimensioned drawing with a full section to model in planex2d or any CAD system, a solution from a centered rectangle padded into a plate, a boss padded onto its top and a blind bore, and the volume, mass and center of mass to check a model against.' --- # Column base A column base carries a post on a plate that is bolted down through two holes. The post sits in the blind bore of a boss on the plate. As a solid, it is a plate padded from a sketch, a boss padded from a sketch on the plate's top and fused with it, and a bore pocketed into the boss. Model the column base from the drawing in planex2d or in any CAD system, then check its volume, mass and center of mass against the values at the end of the page. A solution in planex2d follows. ![The column base exercise: a dimensioned drawing of a rectangular plate with two holes and a boss with a blind bore, in a full section, a top view and an isometric](../_static/gallery/column-base.png){.result} ```python import math import netgen.occ as occ import planex as px ``` ```python nbsphinx="hidden" from docs_figures import Row, Views ``` ## The plate The plate is a rectangle around the origin, 100 by 60, drawn with `RectangleC`. Its lines are `plate.Line.1` to `plate.Line.4`, the first one the bottom edge along $x$ and the second the right edge. Its center is the origin, and with `auto_constraint={"horizontal": True, "vertical": True}` its edges, drawn level and plumb, stay so. The two holes, 9 across, lie on the horizontal axis, mirrored about the vertical one and 76 apart (Figure 1): ```python base = px.Sketch(auto_constraint={"horizontal": True, "vertical": True}) base.RectangleC(100, 60, id="plate") base.Constrain("plate.center", "origin", px.Coincident) base.Constrain("plate.Line.1", px.Distance, 100, id="length") base.Constrain("plate.Line.2", px.Distance, 60, id="width") base.Circle(9 / 2, center=(-35, 0), id="left_hole") base.Circle(9 / 2, center=(35, 0), id="right_hole") base.Constrain("left_hole", px.Diameter, 9, id="hole_d") base.Constrain("right_hole", "left_hole", px.Equal) base.Constrain("left_hole.center", "right_hole.center", px.Distance, 76, id="spacing") base.Constrain("left_hole.center", "H", px.Coincident) base.Constrain("left_hole.center", "right_hole.center", "V", px.Symmetric) print("status", base.status, "| degrees of freedom", base.dof) ``` ```python nbsphinx="hide-input" Row((base, "The plate and its holes, every dimension and tie", {"constraints": True}), caption="The plate") ``` `px.Pad` extrudes the sketch 12 up, the plate's thickness (Figure 2): ```python block = px.Pad(base, 12) ``` ```python nbsphinx="hide-input" Views(("The plate, 12 thick", [(block, "shade"), (block, "ink")]), angles=(-60, 0, 30), caption="The padded plate") ``` ## The boss The boss is a circle of 40 around the origin, sketched on the plate's top, the face highest in $z$. It is padded 30 up from the face, and `+` fuses it with the plate (Figure 3): ```python boss = px.Sketch(block.faces.Max(occ.Z)) boss.Circle(40 / 2, id="boss") boss.Constrain("boss.center", "origin", px.Coincident) boss.Constrain("boss", px.Diameter, 40, id="boss_d") block = block + px.Pad(boss, 30) # + fuses two solids ``` ```python nbsphinx="hide-input" Views(("The boss on the plate", [(block, "shade"), (block, "ink")]), angles=(-60, 0, 30), caption="The boss") ``` ## The bore The bore for the post, 25 across, is sketched on the boss's top, now the face highest in $z$, and pocketed 35 deep. It ends 7 above the plate's bottom (Figure 4): ```python bore = px.Sketch(block.faces.Max(occ.Z)) bore.Circle(25 / 2, id="bore") bore.Constrain("bore.center", "origin", px.Coincident) bore.Constrain("bore", px.Diameter, 25, id="bore_d") block = px.Pocket(block, bore, 35) # 35 deep, against the face's normal: down ``` ```python nbsphinx="hide-input" Views(("The blind bore in the boss", [(block, "shade"), (block, "ink")]), angles=(-50, 0, 30), caption="The bore") ``` ## The checks These are the volume, the mass in steel S235 (7.85 g/cm³) and the center of mass, with the origin in the middle of the plate's bottom, to compare with your own model. The volume is the plate, $100 \cdot 60 \cdot 12$, less its two holes, plus the boss, $\pi \cdot 20^2 \cdot 30$, less the bore, $\pi \cdot 12.5^2 \cdot 35$. The column base is symmetric about two planes, so its center of mass lies on the vertical axis: ```python exact = 100 * 60 * 12 - 2 * math.pi * 4.5**2 * 12 + math.pi * 20**2 * 30 - math.pi * 12.5**2 * 35 c = block.center print("volume", round(block.mass, 1), "mm³, exact", round(exact, 1)) print("mass", round(block.mass * 7.85e-6, 3), "kg") print("center of mass", round(c.z, 2), "above the bottom, off the axis by", round(math.hypot(c.x, c.y), 6)) ``` The column base as STEP, for another CAD system: ```python block.WriteStep("column_base.step") ``` The column base as STEP: [column_base.step](column_base.step) ```python nbsphinx="hidden" import sys sys.path.insert(0, "..") import matplotlib.pyplot as plt from drawings import Pictorial, SheetFigure, View from gallery import save_figure # the full section through the plane y = 0 (the symmetry plane: no designation needed), the part behind it seen from # the front, its cut faces hatched; the top view from the sketches front = px.XZ # x to the right, z up half = block * occ.Box((-60, 0, -1), (60, 40, 50)) cut = [f for f in half.faces if abs(f.center.y) < 1e-6 and f.bounding_box[1].y - f.bounding_box[0].y < 1e-6] top_z = block.faces.Max(occ.Z).center.z section = View([], solid=half, plane=front, hidden_edges=False, hatch=cut, axes=[((0, -4), (0, top_z + 4))] + [((x, -3), (x, 15)) for x in (-38, 38)], measures=[((-50, 0), (-50, 12), -62, 12), ((20, 0), (20, top_z), 64, top_z), ((-6, top_z - 35), (-6, top_z), -6, 35), ((-20, top_z), (20, top_z), top_z + 10, "⌀40")]) top_view = View([(base, {"length": -42, "width": 62, "spacing": 40, "hole_d": (225, "leader", 2)}), (bore, {"bore_d": 45}, {})], solid=block, plane=px.XY, at=(0, -95)) pictorial = Pictorial(block, at=(115, -95), width=60) drawing = SheetFigure([section, top_view, pictorial], margin=25, notes=("planex2d.org", "3D exercise 08"), first_angle=True) print("scale", drawing.planex_scale, "| paper", [round(v * 25.4) for v in drawing.get_size_inches()], "mm") save_figure(drawing, "column-base", dpi=200) plt.close(drawing) ```