1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
# Copyright (c) 2020-2022, Manfred Moitzi
# License: MIT License
import pathlib
import ezdxf
from ezdxf.render import forms
from ezdxf.addons import MengerSponge, openscad
CWD = pathlib.Path("~/Desktop/Outbox").expanduser()
if not CWD.exists():
CWD = pathlib.Path(".")
# ------------------------------------------------------------------------------
# This example shows how to utilize OpenSCAD for construction tasks by ezdxf.
# Shows the usage of the 'meshex' add-on to export/import meshes to/from OpenSCAD.
#
# docs:
# openscad: https://ezdxf.mozman.at/docs/addons/openscad.html
# meshex: https://ezdxf.mozman.at/docs/addons/meshex.html
# ------------------------------------------------------------------------------
POLYHEDRON = str(CWD / "OpenSCAD_polyhedron.dxf")
POLYGON = str(CWD / "OpenSCAD_polygon.dxf")
def polygon(filename):
doc = ezdxf.new()
doc.layers.add("NORMALS", color=3)
msp = doc.modelspace()
exterior = list(forms.square(10, center=True))
hole = list(forms.circle(16, 0.5))
holes = [
list(forms.translate(hole, (-3, 3))),
list(forms.translate(hole, (3, 3))),
list(forms.translate(hole, (-3, -3))),
list(forms.translate(hole, (3, -3))),
]
script = openscad.Script()
script.add("linear_extrude(height = 1, convexity=10)")
script.add_polygon(exterior, holes)
result = openscad.run(script.get_string())
print("Result has:")
print(f"{len(result.vertices)} vertices")
print(f"{len(result.faces)} faces")
result.render_mesh(msp)
doc.saveas(filename)
print(f"exported DXF file: '{filename}'")
# IMPORTANT:
# OpenSCAD expects clockwise ordered face-vertices to create outward pointing
# normals, unlike any other application working with meshes which use
# counter-clockwise ordered vertices to create outward pointing normals.
def polyhedron(filename: str):
doc = ezdxf.new()
doc.layers.add("NORMALS", color=3)
msp = doc.modelspace()
sponge = MengerSponge(level=3).mesh()
sponge.flip_normals() # important for OpenSCAD
sphere = forms.sphere(
count=32, stacks=16, radius=0.5, quads=True
).translate(0.25, 0.25, 1)
sphere.flip_normals() # important for OpenSCAD
script = openscad.boolean_operation(openscad.DIFFERENCE, sponge, sphere)
result = openscad.run(script)
print("Result has:")
print(f"{len(result.vertices)} vertices")
print(f"{len(result.faces)} faces")
result.render_mesh(msp)
# The exported mesh from OpenSCAD has outward pointing normals, so flipping
# normals is not necessary!
result.render_normals(msp, length=0.1, dxfattribs={"layer": "NORMALS"})
doc.set_modelspace_vport(6, center=(5, 0))
doc.saveas(filename)
print(f"exported DXF file: '{filename}'")
if __name__ == "__main__":
polyhedron(POLYHEDRON)
polygon(POLYGON)
|