Got stuck while trying to generate a technical drawing in PDF with ezdxf from an OBJ model with:
- a front view, a side view and a spatial view
- some annotations if possible
- on horizontal A3 (420 x 297 mm) paper
- manage the scaling if possible
Something like this drawing but then of a teapot, simple and effective:
Very important note
I do not expect a fully detailed drawing as an answer! (But if you feel like it I won't stop you). Explanation of basic concepts or some guidance in the right direction I will consider as an answer.
The ezdxf documentation seems to assume some CAD experience but I have absolutely zero! The whole modelspace and paperspace concept is confusing to me. I have no idea what viewports are.
Minimal Working Example
To get started, get the teapot OBJ model (or any model) and convert it to faces and vertices with trimesh:
import io
import requests
import trimesh
obj_raw = requests.get(
"https://graphics.stanford.edu/courses/cs148-10-summer/as3/code/as3/teapot.obj"
).text
mesh_model = trimesh.load(
file_obj=trimesh.util.wrap_as_stream(obj_raw), file_type="obj"
)
With ezdxf I can actually read this model and print it to PDF with the qsave
method:
from ezdxf.addons.drawing import matplotlib
import ezdxf # '0.17.2'
doc = ezdxf.new("R2010")
# get the modelspace
modelspace = doc.modelspace()
mesh = modelspace.add_mesh()
with mesh.edit_data() as mesh_data:
mesh_data.vertices = mesh_model.vertices
mesh_data.faces = mesh_model.faces
matplotlib.qsave(modelspace, "teapot.pdf")
That looks beautiful! Next, we can add a box on the paperspace margins; but I have no idea how to add any viewport to the modelspace so it's completely empty:
psp = doc.layout("Layout1")
psp.page_setup(size=(420, 297), margins=(10, 10, 10, 10), units="mm")
(x0, y0), (x1, y1) = psp.get_paper_limits()
psp.add_line((x0, y0), (x1, y0))
psp.add_line((x1, y0), (x1, y1))
psp.add_line((x1, y1), (x0, y1))
psp.add_line((x0, y1), (x0, y0))
matplotlib.qsave(psp, "teapot_paper.pdf")
if usefull, the trimesh
object has some helper attributes:
>>> mesh_model.bounds
array([[-3. , 0. , -2. ],
[ 3.434, 3.15 , 2. ]])
>>> mesh_model.centroid
array([ 4.51110653e-02, 1.33032137e+00, -4.36791498e-06])