Spaces:
Sleeping
Sleeping
| import math | |
| import os | |
| filepath = "/mnt/36270add-d8d7-4990-b2b6-c9c5f803b31b/Hackatones/Transforming Enterprise Through AI/Repo/assets/centrifuge_v2.obj" | |
| mtlpath = "/mnt/36270add-d8d7-4990-b2b6-c9c5f803b31b/Hackatones/Transforming Enterprise Through AI/Repo/assets/centrifuge_v2.mtl" | |
| with open(mtlpath, 'w') as f: | |
| f.write("""newmtl RotorBody | |
| Kd 0.75 0.75 0.78 | |
| Ks 0.3 0.3 0.3 | |
| Ns 30 | |
| newmtl RotorHub | |
| Kd 0.25 0.25 0.25 | |
| Ks 0.8 0.8 0.8 | |
| Ns 100 | |
| newmtl Tube | |
| Kd 0.15 0.45 0.85 | |
| Ks 0.9 0.9 0.9 | |
| Ns 80 | |
| newmtl TubeCap | |
| Kd 0.9 0.1 0.1 | |
| Ks 0.5 0.5 0.5 | |
| Ns 50 | |
| """) | |
| vertices = [] | |
| faces_and_mtls = [] | |
| def add_vertex(x, y, z): | |
| vertices.append((x, y, z)) | |
| return len(vertices) | |
| def add_face(v_indices): | |
| faces_and_mtls.append(v_indices) | |
| def set_material(name): | |
| faces_and_mtls.append(f"usemtl {name}") | |
| def multiply_matrix_vector(matrix, vector): | |
| return [ | |
| matrix[0][0]*vector[0] + matrix[0][1]*vector[1] + matrix[0][2]*vector[2], | |
| matrix[1][0]*vector[0] + matrix[1][1]*vector[1] + matrix[1][2]*vector[2], | |
| matrix[2][0]*vector[0] + matrix[2][1]*vector[1] + matrix[2][2]*vector[2] | |
| ] | |
| def create_rotated_cylinder(cx, cy, cz, r_bottom, r_top, h, angle_y, angle_tilt, segments=24): | |
| mat_tilt = [ | |
| [1, 0, 0], | |
| [0, math.cos(angle_tilt), -math.sin(angle_tilt)], | |
| [0, math.sin(angle_tilt), math.cos(angle_tilt)] | |
| ] | |
| mat_y = [ | |
| [math.cos(angle_y), 0, math.sin(angle_y)], | |
| [0, 1, 0], | |
| [-math.sin(angle_y), 0, math.cos(angle_y)] | |
| ] | |
| def transform(x, y, z): | |
| v = [x, y, z] | |
| v = multiply_matrix_vector(mat_tilt, v) | |
| v = multiply_matrix_vector(mat_y, v) | |
| return (v[0]+cx, v[1]+cy, v[2]+cz) | |
| bc = add_vertex(*transform(0, 0, 0)) | |
| tc = add_vertex(*transform(0, h, 0)) | |
| base_indices = [] | |
| top_indices = [] | |
| for i in range(segments): | |
| theta = 2.0 * math.pi * i / segments | |
| lx = r_bottom * math.cos(theta) | |
| lz = r_bottom * math.sin(theta) | |
| base_indices.append(add_vertex(*transform(lx, 0, lz))) | |
| tx = r_top * math.cos(theta) | |
| tz = r_top * math.sin(theta) | |
| top_indices.append(add_vertex(*transform(tx, h, tz))) | |
| for i in range(segments): | |
| n1 = i | |
| n2 = (i+1)%segments | |
| add_face([bc, base_indices[n2], base_indices[n1]]) | |
| for i in range(segments): | |
| n1 = i | |
| n2 = (i+1)%segments | |
| add_face([tc, top_indices[n1], top_indices[n2]]) | |
| for i in range(segments): | |
| n1 = i | |
| n2 = (i+1)%segments | |
| add_face([base_indices[n1], base_indices[n2], top_indices[n2], top_indices[n1]]) | |
| def create_cylinder(x, y, z, r_bottom, r_top, h, segments=48): | |
| create_rotated_cylinder(x, y, z, r_bottom, r_top, h, 0, 0, segments) | |
| # Build the geometry | |
| set_material("RotorBody") | |
| # Base flat cylinder | |
| create_cylinder(0, 0, 0, 1.2, 1.2, 0.15, 64) | |
| # Main conical body | |
| create_cylinder(0, 0.15, 0, 1.2, 0.7, 0.6, 64) | |
| # Top flat part | |
| create_cylinder(0, 0.75, 0, 0.7, 0.6, 0.1, 64) | |
| set_material("RotorHub") | |
| # Hub spindle | |
| create_cylinder(0, 0.85, 0, 0.15, 0.15, 0.15, 32) | |
| # Spindle nut | |
| create_cylinder(0, 1.0, 0, 0.08, 0.08, 0.08, 16) | |
| # Create tubes (angled) | |
| num_tubes = 12 | |
| tube_radius = 0.14 | |
| tube_height = 0.4 | |
| tilt = math.radians(40) # 40 degrees tilt | |
| for i in range(num_tubes): | |
| angle_y = 2.0 * math.pi * i / num_tubes | |
| # Position: shift outwards and upwards | |
| # We want the tubes to be embedded in the sloped face. | |
| # The sloped face goes from r=1.2 at y=0.15 to r=0.7 at y=0.75. | |
| # Let's put the center of the tube cap at r=0.8, y=0.65 | |
| r_pos = 0.85 | |
| y_pos = 0.6 | |
| cx = r_pos * math.cos(angle_y) | |
| cz = -r_pos * math.sin(angle_y) # negative to match rotation direction if needed | |
| set_material("Tube") | |
| # Actually the tube goes INWARDS. So the cylinder should start at cap and go down? | |
| # Our cylinder starts at (cx, cy, cz) and goes UP locally. | |
| # If we want it to go down, we can start low and go up to cap. | |
| # Let's start the tube deep inside and go up to the cap surface. | |
| # To do this, we'll start at cx, cy, cz and go UP by tube_height. | |
| # Wait, the tilt is around X axis. Positive tilt tilts +Y towards +Z. | |
| # Let's just adjust the start position so it protrudes perfectly. | |
| start_r = 0.5 | |
| start_y = 0.3 | |
| sx = start_r * math.cos(angle_y) | |
| sz = start_r * math.sin(angle_y) | |
| create_rotated_cylinder(sx, start_y, sz, tube_radius, tube_radius, tube_height, -angle_y, tilt, 16) | |
| # Add a tube cap | |
| set_material("TubeCap") | |
| # Cap is at local top. | |
| # We can just create another small cylinder at the top of the tube. | |
| # The local Y of the top is tube_height. We can just shift our start position locally. | |
| # Local shift: | |
| # v = [0, tube_height, 0] | |
| # transformed: | |
| mat_tilt = [ | |
| [1, 0, 0], | |
| [0, math.cos(tilt), -math.sin(tilt)], | |
| [0, math.sin(tilt), math.cos(tilt)] | |
| ] | |
| mat_y = [ | |
| [math.cos(-angle_y), 0, math.sin(-angle_y)], | |
| [0, 1, 0], | |
| [-math.sin(-angle_y), 0, math.cos(-angle_y)] | |
| ] | |
| v = multiply_matrix_vector(mat_tilt, [0, tube_height, 0]) | |
| v = multiply_matrix_vector(mat_y, v) | |
| cap_x = sx + v[0] | |
| cap_y = start_y + v[1] | |
| cap_z = sz + v[2] | |
| create_rotated_cylinder(cap_x, cap_y, cap_z, tube_radius*1.1, tube_radius*1.1, 0.05, -angle_y, tilt, 16) | |
| with open(filepath, 'w') as f: | |
| f.write(f"mtllib centrifuge_v2.mtl\n") | |
| f.write("o CentrifugeRotor\n") | |
| for v in vertices: | |
| f.write(f"v {v[0]:.5f} {v[1]:.5f} {v[2]:.5f}\n") | |
| for item in faces_and_mtls: | |
| if isinstance(item, str): | |
| f.write(item + "\n") | |
| else: | |
| f.write("f " + " ".join(str(idx) for idx in item) + "\n") | |
| print("Detailed 3D model generated.") | |