Fix (UI): Corrected console outputs for UBOM.
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
env_scad/
|
||||
env_scad/*
|
||||
32
config.py
Normal file
32
config.py
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
from models.dimensions_3d import Dimensions_3D
|
||||
|
||||
from pydantic import BaseModel
|
||||
from typing import ClassVar
|
||||
|
||||
class Config(BaseModel):
|
||||
D_AXLE_FRONT: ClassVar[float] = 42
|
||||
D_AXLE_REAR: ClassVar[float] = 27
|
||||
D_WASHER_AXLE_REAR_WHEEL_POSITIONING: ClassVar[float] = 50
|
||||
D_WASHER_BOLT_REAR_WHEEL_POSITIONING: ClassVar[float] = 30
|
||||
D_WHEEL: ClassVar[float] = 400
|
||||
D_WHEEL_BONE: ClassVar[float] = 25
|
||||
L_BOLT_EXTENSION: ClassVar[float] = 10
|
||||
# M_TOTAL: ClassVar[float] = 160
|
||||
R_BED: ClassVar[Dimensions_3D] = Dimensions_3D(x=400, y=1200, z=18)
|
||||
SIZE_BOLT: ClassVar[float] = 25
|
||||
SIZE_BOLT_REAR_WHEEL_POSITIONING: ClassVar[float] = 10
|
||||
SPACING_WASHER_AXLE_REAR_WHEEL_POSITIONING: ClassVar[float] = 1
|
||||
SPACING_XY_BED_BORDER: ClassVar[float] = 10
|
||||
T_CLAMP: ClassVar[float] = 20
|
||||
T_PLATE: ClassVar[float] = 8
|
||||
T_WASHER_AXLE_REAR_WHEEL_POSITIONING: ClassVar[float] = 4
|
||||
T_WASHER_BOLT_REAR_WHEEL_POSITIONING: ClassVar[float] = 1.5
|
||||
T_WHEEL: ClassVar[float] = 100
|
||||
Z_OVERLAP_TEE_CLAMP_ROUND: ClassVar[float] = 80
|
||||
Z_OFFSET_WHEEL_TO_BED_BASE: ClassVar[float] = 5
|
||||
|
||||
X_POSITION_WHEEL_CENTRE: float
|
||||
Y_POSITION_AXLE_FRONT: float
|
||||
Y_POSITION_AXLE_REAR: float
|
||||
Z_OFFSET_BED_TO_AXLE: float
|
||||
@@ -45,7 +45,7 @@ X_POS_AXLE_LEG_REAR = min(X_POS_WHEEL_CENTRE - T_WHEEL / 2 - SPACING_WASHER_AXLE
|
||||
// THICKNESS_SHELL_BRAKE_BEAM = 5;
|
||||
// L_BEAM_BRAKE_BELT_TENSION_FIXING = 150;
|
||||
D_BEAM_BRAKE = 40;
|
||||
T_BEAM_BRAKE = 5;
|
||||
T_BEAM_BRAKE = 3;
|
||||
D_BRAKE_BALLSCREW_AXLE = 16; // M16 pitch 1.5
|
||||
L_BRAKE_BALLSCREW_AXLE = 450;
|
||||
D_BRAKE_BALLSCREW_POWER_WHEEL = 120;
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
,teddy,lord-T-1024,20.02.2025 13:01,file:///home/teddy/.config/libreoffice/4;
|
||||
BIN
docs/UBOM.ods
BIN
docs/UBOM.ods
Binary file not shown.
0
models/__init__.py
Normal file
0
models/__init__.py
Normal file
69
models/base_3d_object.py
Normal file
69
models/base_3d_object.py
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
from coordinates_3d import Coordinates_3D
|
||||
from dimensions_3d import Dimensions_3D
|
||||
from material import Material
|
||||
|
||||
from abc import ABC
|
||||
from pydantic import BaseModel
|
||||
import openpyscad as ops
|
||||
# from solid import OpenSCADObject
|
||||
from typing import Optional
|
||||
|
||||
class Base_3D_Object(BaseModel, ABC):
|
||||
colour: str = ''
|
||||
dimensions_enclosing_cube: Dimensions_3D
|
||||
__mass: float
|
||||
material: Material
|
||||
object: ops.base.BaseObject
|
||||
parent: 'Base_3D_Object' = None
|
||||
position_centre_local_assembly: Coordinates_3D = Coordinates_3D(x = 0, y = 0, z = 0)
|
||||
rotation: Coordinates_3D = Coordinates_3D(x = 0, y = 0, z = 0)
|
||||
__volume_solid: float
|
||||
|
||||
"""
|
||||
@classmethod
|
||||
def make_local_object(cls, colour: str, dimensions_enclosing_cube: Dimensions_3D, material: Material, position_centre_local_assembly: Coordinates_3D, rotation: Coordinates_3D) -> 'Base_3D_Object':
|
||||
return cls(
|
||||
colour=colour,
|
||||
dimensions_enclosing_cube=dimensions_enclosing_cube,
|
||||
mass=material.density * dimensions_enclosing_cube.x * dimensions_enclosing_cube.y * dimensions_enclosing_cube.z,
|
||||
material=material,
|
||||
position_centre_local_assembly=position_centre_local_assembly,
|
||||
position_centre_major_assembly=position_centre_local_assembly,
|
||||
rotation=rotation,
|
||||
volume_solid=dimensions_enclosing_cube.x * dimensions_enclosing_cube.y * dimensions_enclosing_cube.z
|
||||
)
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_dimensions_and_material_and_parent(cls, dimensions_enclosing_cube: Dimensions_3D, material: Material, parent: Optional['Base_3D_Object']) -> 'Base_3D_Object':
|
||||
return cls(
|
||||
dimensions_enclosing_cube = dimensions_enclosing_cube,
|
||||
material = material,
|
||||
colour = material.colour,
|
||||
parent = parent,
|
||||
)
|
||||
|
||||
def get_position_centre_major_assembly(self) -> Coordinates_3D:
|
||||
if self.parent is None:
|
||||
return self.position_centre_local_assembly
|
||||
else:
|
||||
position_centre_parent_major_assembly = self.parent.get_position_centre_major_assembly()
|
||||
return Coordinates_3D(
|
||||
x=self.position_centre_local_assembly.x + position_centre_parent_major_assembly.x,
|
||||
y=self.position_centre_local_assembly.y + position_centre_parent_major_assembly.y,
|
||||
z=self.position_centre_local_assembly.z + position_centre_parent_major_assembly.z
|
||||
)
|
||||
|
||||
def get_mass(self) -> float:
|
||||
if self.__mass is None:
|
||||
self.__mass = self.material.density * self.volume_solid
|
||||
return self.__mass
|
||||
|
||||
def get_volume_solid(self) -> float:
|
||||
if self.__volume_solid is None:
|
||||
self.__volume_solid = self.dimensions_enclosing_cube.x * self.dimensions_enclosing_cube.y * self.dimensions_enclosing_cube.z
|
||||
return self.__volume_solid
|
||||
|
||||
|
||||
|
||||
0
models/bed/__init__.py
Normal file
0
models/bed/__init__.py
Normal file
10
models/bed/bed_assembly.py
Normal file
10
models/bed/bed_assembly.py
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
from models.base_3d_object import Base_3D_Object
|
||||
import models.fixings.tube_clamp_round_base_plate_132
|
||||
|
||||
"""
|
||||
import solid
|
||||
import solid.utils
|
||||
"""
|
||||
|
||||
class Bed_Assembly(Base_3D_Object):
|
||||
43
models/common/metric_bolt.py
Normal file
43
models/common/metric_bolt.py
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
from models.base_3d_object import Base_3D_Object
|
||||
from models.dimensions_3d import Dimensions_3D
|
||||
from models.material import Material
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
|
||||
class Metric_Bolt(Base_3D_Object):
|
||||
head_diameter: float = Field(gt = 0)
|
||||
head_length: float = Field(gt = 0)
|
||||
length: float = Field(gt = 0)
|
||||
shaft_length: float = Field(gt = 0)
|
||||
size: float = Field(gt = 0)
|
||||
|
||||
@classmethod
|
||||
def from_size_and_length_and_material(cls, size: float, length: float, material: Material) -> 'Metric_Bolt':
|
||||
head_diameter = cls.get_head_diameter(size = size)
|
||||
bolt = Metric_Bolt.from_dimensions_and_material(
|
||||
dimensions_enclosing_cube = Dimensions_3D(
|
||||
x = head_diameter,
|
||||
y = head_diameter,
|
||||
z = length
|
||||
),
|
||||
material = material
|
||||
)
|
||||
bolt.size = size
|
||||
bolt.length = length
|
||||
bolt.head_diameter = head_diameter
|
||||
bolt.head_length = cls.get_head_length(size = size)
|
||||
bolt.shaft_length = bolt.length - bolt.head_length
|
||||
|
||||
@classmethod
|
||||
def get_head_diameter(cls, size: float) -> float:
|
||||
return size * 2
|
||||
|
||||
@classmethod
|
||||
def get_head_length(cls, size: float) -> float:
|
||||
return size
|
||||
|
||||
@classmethod
|
||||
def get_washer_diameter_safe_working_clearance(cls, size: float) -> float:
|
||||
return size * 4 if size < 20 else size * 3
|
||||
7
models/coordinates_3d.py
Normal file
7
models/coordinates_3d.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
class Coordinates_3D(BaseModel):
|
||||
x: float
|
||||
y: float
|
||||
z: float
|
||||
7
models/dimensions_3d.py
Normal file
7
models/dimensions_3d.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
class Dimensions_3D(BaseModel):
|
||||
x: float = Field(ge = 0)
|
||||
y: float = Field(ge = 0)
|
||||
z: float = Field(ge = 0)
|
||||
17
models/fixings/base_tube_clamp.py
Normal file
17
models/fixings/base_tube_clamp.py
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
from models.base_3d_object import Base_3D_Object
|
||||
from models.material import Material
|
||||
|
||||
from abc import abstractmethod
|
||||
from typing import ClassVar
|
||||
|
||||
class Base_Tube_Clamp(Base_3D_Object):
|
||||
MATERIAL_DEFAULT: ClassVar[Material] = Material(
|
||||
name = 'Steel',
|
||||
density = 7.85,
|
||||
colour = 'LightGrey'
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def from_tube_diameter(cls, tube_diameter: float) -> 'Base_Tube_Clamp':
|
||||
pass
|
||||
@@ -31,7 +31,7 @@ module tube_clamp_round_3_way_outlet_tee_176(tube_diameter) {
|
||||
rotate([90, 0, 0]) cylinder(L_shaft_long, tube_diameter / 2, tube_diameter / 2, center = true);
|
||||
}
|
||||
// Shopping
|
||||
echo("Round 3-way outlet tee 176: Tube clamp - x1");
|
||||
echo(str("Round 3-way outlet tee 176: Tube clamp Φ", tube_diameter, "mm - x1"));
|
||||
}
|
||||
|
||||
// test output
|
||||
|
||||
@@ -19,7 +19,7 @@ module tube_clamp_round_3_way_through_116(tube_diameter) {
|
||||
translate([0, L_shaft_long / 2, 0]) rotate([90, 0, 0]) cylinder(L_shaft_long, tube_diameter / 2, tube_diameter / 2, center = true);
|
||||
}
|
||||
// Shopping
|
||||
echo("Round 3-way through 116: Tube clamp - x1");
|
||||
echo(str("Round 3-way through 116: Tube clamp Φ", tube_diameter, "mm - x1"));
|
||||
}
|
||||
|
||||
// test output
|
||||
|
||||
150
models/fixings/tube_clamp_round_base_plate_132.py
Normal file
150
models/fixings/tube_clamp_round_base_plate_132.py
Normal file
@@ -0,0 +1,150 @@
|
||||
|
||||
from models.base_3d_object import Base_3D_Object
|
||||
from models.fixings.base_tube_clamp import Base_Tube_Clamp
|
||||
from models.dimensions_3d import Dimensions_3D
|
||||
from models.material import Material
|
||||
|
||||
from pydantic import Field
|
||||
# import solid
|
||||
import openpyscad as ops
|
||||
|
||||
class Tube_Clamp_Round_Base_Plate_132(Base_Tube_Clamp):
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_tube_diameter_and_parent(cls, tube_diameter: float, parent: Base_3D_Object) -> 'Tube_Clamp_Round_Base_Plate_132':
|
||||
L_shaft_with_base_plate = cls.get_L_shaft_with_base_plate(tube_diameter = tube_diameter)
|
||||
R_plate = cls.get_R_plate(tube_diameter = tube_diameter)
|
||||
y_offset_hole = cls.get_offset_hole_y(tube_diameter = tube_diameter)
|
||||
diameter_hole_bolt = cls.get_diameter_hole(tube_diameter = tube_diameter)
|
||||
|
||||
tube_clamp = cls.from_dimensions_and_material_and_parent(
|
||||
dimensions_enclosing_cube = Dimensions_3D(
|
||||
x = R_plate.x,
|
||||
y = R_plate.y,
|
||||
z = L_shaft_with_base_plate
|
||||
),
|
||||
material = cls.MATERIAL_DEFAULT,
|
||||
parent = parent,
|
||||
)
|
||||
|
||||
clamp_shaft = cls.__make_shaft_object(
|
||||
tube_diameter = tube_diameter,
|
||||
L_shaft_with_base_plate = L_shaft_with_base_plate,
|
||||
R_plate = R_plate,
|
||||
)
|
||||
clamp_shaft.translate([0, 0, L_shaft_with_base_plate / 2])
|
||||
|
||||
base_plate = cls.__make_base_plate_object(
|
||||
R_plate = R_plate,
|
||||
y_offset_hole = y_offset_hole,
|
||||
diameter_hole_bolt = diameter_hole_bolt,
|
||||
)
|
||||
base_plate.translate([0, 0, R_plate.z / 2])
|
||||
|
||||
tube_clamp.object = ops.Union()
|
||||
tube_clamp.object.append(base_plate)
|
||||
tube_clamp.object.append(clamp_shaft)
|
||||
|
||||
tube_clamp.object.color(cls.MATERIAL_DEFAULT.colour)
|
||||
return tube_clamp
|
||||
|
||||
@classmethod
|
||||
def __make_shaft_object(cls, tube_diameter: float, L_shaft_with_base_plate: float, R_plate: tuple[float, float, float]) -> ops.base.BaseObject:
|
||||
clamp_shaft = ops.Difference()
|
||||
clamp_shaft.append(
|
||||
ops.Cylinder(
|
||||
h = L_shaft_with_base_plate,
|
||||
r = tube_diameter / 2 + R_plate.z,
|
||||
)
|
||||
)
|
||||
clamp_shaft.append(
|
||||
ops.Cylinder(
|
||||
h = L_shaft_with_base_plate,
|
||||
r = tube_diameter / 2,
|
||||
)
|
||||
)
|
||||
return clamp_shaft
|
||||
@classmethod
|
||||
def __make_base_plate_object(cls, R_plate: Dimensions_3D, y_offset_hole: float, diameter_hole_bolt: float) -> ops.base.BaseObject:
|
||||
base_plate = ops.Difference()
|
||||
base_plate.append(
|
||||
ops.Cube(
|
||||
v = [R_plate.x, R_plate.y, R_plate.z],
|
||||
center = True,
|
||||
)
|
||||
)
|
||||
base_plate.append(
|
||||
ops.Cylinder(
|
||||
h = R_plate.z,
|
||||
r = diameter_hole_bolt / 2,
|
||||
center = True,
|
||||
).translate([0, y_offset_hole, 0])
|
||||
)
|
||||
base_plate.append(
|
||||
ops.Cylinder(
|
||||
h = R_plate.z,
|
||||
r = diameter_hole_bolt / 2,
|
||||
center = True,
|
||||
).translate([0, -y_offset_hole, 0])
|
||||
)
|
||||
return base_plate
|
||||
|
||||
@classmethod
|
||||
def get_L_shaft_with_base_plate(cls, tube_diameter: float) -> float:
|
||||
L_shaft = 25
|
||||
if tube_diameter == 27:
|
||||
L_shaft = 85
|
||||
elif tube_diameter == 42:
|
||||
L_shaft = 122
|
||||
return L_shaft
|
||||
|
||||
@classmethod
|
||||
def get_R_plate(cls, tube_diameter: float) -> Dimensions_3D:
|
||||
R_plate = Dimensions_3D(
|
||||
x = 10,
|
||||
y = 20,
|
||||
z = 1
|
||||
)
|
||||
if tube_diameter == 27:
|
||||
R_plate = Dimensions_3D(
|
||||
x = 64,
|
||||
y = 114,
|
||||
z = 7
|
||||
)
|
||||
elif tube_diameter == 42:
|
||||
R_plate = Dimensions_3D(
|
||||
x = 80,
|
||||
y = 140,
|
||||
z = 10
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"Unsupported tube diameter: {tube_diameter}")
|
||||
return R_plate
|
||||
|
||||
@classmethod
|
||||
def get_offset_hole_y(cls, tube_diameter: float) -> float:
|
||||
y_offset = 10
|
||||
if tube_diameter == 27:
|
||||
y_offset = 38
|
||||
elif tube_diameter == 42:
|
||||
y_offset = 50
|
||||
else:
|
||||
raise ValueError(f"Unsupported tube diameter: {tube_diameter}")
|
||||
return y_offset
|
||||
|
||||
@classmethod
|
||||
def get_diameter_hole(cls, tube_diameter: float) -> float:
|
||||
return 10
|
||||
|
||||
@classmethod
|
||||
def get_mass(cls, tube_diameter: float) -> float:
|
||||
mass = 0
|
||||
if tube_diameter == 27:
|
||||
mass = 0.5
|
||||
elif tube_diameter == 42:
|
||||
mass = 1.06
|
||||
else:
|
||||
raise ValueError(f"Unsupported tube diameter: {tube_diameter}")
|
||||
return mass
|
||||
|
||||
@@ -21,7 +21,7 @@ module tube_clamp_round_base_plate_132(tube_diameter) {
|
||||
}
|
||||
}
|
||||
// Shopping
|
||||
echo("Round base plate 132: Tube clamp - x1");
|
||||
echo(str("Round base plate 132: Tube clamp Φ", tube_diameter, "mm - x1"));
|
||||
}
|
||||
|
||||
// test output
|
||||
|
||||
@@ -16,7 +16,7 @@ module tube_clamp_round_tee_long_104(tube_diameter) {
|
||||
translate([L_shaft_short / 2, 0, 0]) rotate([0, 90, 0]) cylinder(L_shaft_short, tube_diameter / 2, tube_diameter / 2, center = true);
|
||||
}
|
||||
// Shopping
|
||||
echo("Round tee long 104: Tube clamp - x1");
|
||||
echo(str("Round tee long 104: Tube clamp Φ", tube_diameter, "mm - x1"));
|
||||
}
|
||||
|
||||
// test output
|
||||
|
||||
@@ -21,7 +21,7 @@ module tube_clamp_square_base_plate_132(beam_width) {
|
||||
}
|
||||
}
|
||||
// Shopping
|
||||
echo("Square base plate 132: Tube clamp - x1");
|
||||
echo(str("Square base plate 132: Tube clamp Φ", beam_width, "mm - x1"));
|
||||
}
|
||||
|
||||
// test output
|
||||
|
||||
7
models/material.py
Normal file
7
models/material.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
class Material(BaseModel):
|
||||
colour: str
|
||||
density: float = Field(gt = 0)
|
||||
name: str
|
||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
openpyscad
|
||||
pydantic
|
||||
# solid
|
||||
Reference in New Issue
Block a user