60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
|
|
"""Prueba de concepto: DXF 2D -> modelo 3D (STEP y STL) por extrusion.
|
||
|
|
|
||
|
|
Uso: python conversion.py placa.dxf 10 (DXF y espesor en mm)
|
||
|
|
"""
|
||
|
|
import sys
|
||
|
|
|
||
|
|
import cadquery as cq
|
||
|
|
import ezdxf
|
||
|
|
|
||
|
|
|
||
|
|
def area(puntos):
|
||
|
|
"""Area de un poligono con la formula del area de Gauss (shoelace)."""
|
||
|
|
s = 0.0
|
||
|
|
for (x1, y1), (x2, y2) in zip(puntos, puntos[1:] + puntos[:1]):
|
||
|
|
s += x1 * y2 - x2 * y1
|
||
|
|
return abs(s) / 2
|
||
|
|
|
||
|
|
|
||
|
|
def leer_perfiles(ruta):
|
||
|
|
"""Devuelve las polilineas cerradas y los circulos del DXF."""
|
||
|
|
doc = ezdxf.readfile(ruta)
|
||
|
|
msp = doc.modelspace()
|
||
|
|
poligonos = []
|
||
|
|
for e in msp.query("LWPOLYLINE"):
|
||
|
|
if e.closed:
|
||
|
|
poligonos.append([(p[0], p[1]) for p in e.get_points()])
|
||
|
|
circulos = [(c.dxf.center.x, c.dxf.center.y, c.dxf.radius)
|
||
|
|
for c in msp.query("CIRCLE")]
|
||
|
|
return poligonos, circulos
|
||
|
|
|
||
|
|
|
||
|
|
def construir_solido(poligonos, circulos, altura):
|
||
|
|
"""El perfil de mayor area es el exterior; el resto se restan como agujeros."""
|
||
|
|
if not poligonos:
|
||
|
|
raise ValueError("El DXF no contiene ningun perfil cerrado")
|
||
|
|
exterior = max(poligonos, key=area)
|
||
|
|
solido = cq.Workplane("XY").polyline(exterior).close().extrude(altura)
|
||
|
|
for p in poligonos:
|
||
|
|
if p is not exterior:
|
||
|
|
hueco = cq.Workplane("XY").polyline(p).close().extrude(altura)
|
||
|
|
solido = solido.cut(hueco)
|
||
|
|
for x, y, r in circulos:
|
||
|
|
taladro = cq.Workplane("XY").center(x, y).circle(r).extrude(altura)
|
||
|
|
solido = solido.cut(taladro)
|
||
|
|
return solido
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
ruta, altura = sys.argv[1], float(sys.argv[2])
|
||
|
|
poligonos, circulos = leer_perfiles(ruta)
|
||
|
|
print(f"Perfiles cerrados: {len(poligonos)} · Circulos: {len(circulos)}")
|
||
|
|
solido = construir_solido(poligonos, circulos, altura)
|
||
|
|
cq.exporters.export(solido, "resultado.step")
|
||
|
|
cq.exporters.export(solido, "resultado.stl")
|
||
|
|
print("Generados resultado.step y resultado.stl")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|