download
raw
7.24 kB
"""
Geometry API Router - CAD operations using CadQuery
"""
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import List, Optional, Literal
import json
router = APIRouter()
class BoxCreate(BaseModel):
length: float
width: float
height: float
center: Optional[List[float]] = [0, 0, 0]
class CylinderCreate(BaseModel):
radius: float
height: float
center: Optional[List[float]] = [0, 0, 0]
direction: Optional[List[float]] = [0, 0, 1]
class SphereCreate(BaseModel):
radius: float
center: Optional[List[float]] = [0, 0, 0]
class GeometryExport(BaseModel):
format: Literal["step", "stl", "brep"]
filename: Optional[str] = "geometry"
class GeometryInfo(BaseModel):
id: str
type: str
volume: float
surface_area: float
bounding_box: List[List[float]]
geometry_db = {}
@router.post("/box", response_model=GeometryInfo)
async def create_box(params: BoxCreate):
try:
import cadquery as cq
box = (
cq.Workplane("XY")
.box(params.length, params.width, params.height)
.translate(params.center)
)
shape = box.val()
geometry_id = f"box_{len(geometry_db)}"
info = GeometryInfo(
id=geometry_id,
type="box",
volume=shape.Volume(),
surface_area=shape.Area(),
bounding_box=[
[params.center[0] - params.length/2, params.center[1] - params.width/2, params.center[2] - params.height/2],
[params.center[0] + params.length/2, params.center[1] + params.width/2, params.center[2] + params.height/2]
]
)
geometry_db[geometry_id] = {
"info": info,
"cadquery": box
}
return info
except ImportError:
return GeometryInfo(
id=f"box_{len(geometry_db)}",
type="box",
volume=params.length * params.width * params.height,
surface_area=2*(params.length*params.width + params.length*params.height + params.width*params.height),
bounding_box=[
[params.center[0] - params.length/2, params.center[1] - params.width/2, params.center[2] - params.height/2],
[params.center[0] + params.length/2, params.center[1] + params.width/2, params.center[2] + params.height/2]
]
)
@router.post("/cylinder", response_model=GeometryInfo)
async def create_cylinder(params: CylinderCreate):
try:
import cadquery as cq
cylinder = (
cq.Workplane("XY")
.cylinder(height=params.height, radius=params.radius)
.translate(params.center)
)
shape = cylinder.val()
geometry_id = f"cylinder_{len(geometry_db)}"
volume = 3.14159 * params.radius**2 * params.height
surface_area = 2 * 3.14159 * params.radius * (params.radius + params.height)
info = GeometryInfo(
id=geometry_id,
type="cylinder",
volume=shape.Volume() if hasattr(shape, 'Volume') else volume,
surface_area=shape.Area() if hasattr(shape, 'Area') else surface_area,
bounding_box=[
[params.center[0] - params.radius, params.center[1] - params.radius, params.center[2]],
[params.center[0] + params.radius, params.center[1] + params.radius, params.center[2] + params.height]
]
)
geometry_db[geometry_id] = {
"info": info,
"cadquery": cylinder
}
return info
except ImportError:
volume = 3.14159 * params.radius**2 * params.height
surface_area = 2 * 3.14159 * params.radius * (params.radius + params.height)
return GeometryInfo(
id=f"cylinder_{len(geometry_db)}",
type="cylinder",
volume=volume,
surface_area=surface_area,
bounding_box=[
[params.center[0] - params.radius, params.center[1] - params.radius, params.center[2]],
[params.center[0] + params.radius, params.center[1] + params.radius, params.center[2] + params.height]
]
)
@router.post("/sphere", response_model=GeometryInfo)
async def create_sphere(params: SphereCreate):
try:
import cadquery as cq
sphere = (
cq.Workplane("XY")
.sphere(params.radius)
.translate(params.center)
)
shape = sphere.val()
geometry_id = f"sphere_{len(geometry_db)}"
volume = (4/3) * 3.14159 * params.radius**3
surface_area = 4 * 3.14159 * params.radius**2
info = GeometryInfo(
id=geometry_id,
type="sphere",
volume=shape.Volume() if hasattr(shape, 'Volume') else volume,
surface_area=shape.Area() if hasattr(shape, 'Area') else surface_area,
bounding_box=[
[params.center[0] - params.radius, params.center[1] - params.radius, params.center[2] - params.radius],
[params.center[0] + params.radius, params.center[1] + params.radius, params.center[2] + params.radius]
]
)
geometry_db[geometry_id] = {
"info": info,
"cadquery": sphere
}
return info
except ImportError:
volume = (4/3) * 3.14159 * params.radius**3
surface_area = 4 * 3.14159 * params.radius**2
return GeometryInfo(
id=f"sphere_{len(geometry_db)}",
type="sphere",
volume=volume,
surface_area=surface_area,
bounding_box=[
[params.center[0] - params.radius, params.center[1] - params.radius, params.center[2] - params.radius],
[params.center[0] + params.radius, params.center[1] + params.radius, params.center[2] + params.radius]
]
)
@router.get("/{geometry_id}", response_model=GeometryInfo)
async def get_geometry(geometry_id: str):
if geometry_id not in geometry_db:
raise HTTPException(status_code=404, detail="Geometry not found")
return geometry_db[geometry_id]["info"]
@router.get("/{geometry_id}/mesh-data")
async def get_geometry_mesh_data(geometry_id: str):
if geometry_id not in geometry_db:
raise HTTPException(status_code=404, detail="Geometry not found")
try:
import cadquery as cq
geometry = geometry_db[geometry_id]["cadquery"]
tess = geometry.val().tessellate(0.1)
vertices = [[v.X, v.Y, v.Z] for v in tess[0]]
indices = [[i.X, i.Y, i.Z] for i in tess[1]]
return {
"vertices": vertices,
"indices": indices
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.delete("/{geometry_id}")
async def delete_geometry(geometry_id: str):
if geometry_id not in geometry_db:
raise HTTPException(status_code=404, detail="Geometry not found")
del geometry_db[geometry_id]
return {"message": "Geometry deleted"}

Xet Storage Details

Size:
7.24 kB
·
Xet hash:
f0fb616ecf193bd974f17a76b964735d0dadb73916d66c0bca51fdc3e3b596e7

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.