def test_cube(): c = cube(center=True) assert len(c.vertices) == 8 assert len(c.faces) == 6 c = cube(center=False) assert len(c.vertices) == 8 assert len(c.faces) == 6
def test_bolt(): shaft = cylinder_2p(count=32, base_center=(0, 0, 0), top_center=(1, 0, 0), radius=0.1) head = cone_2p(base_center=(-0.12, 0, 0), apex=(0.1, 0, 0), radius=0.25) notch1 = cube().translate(-0.1, 0, 0).scale(0.02, 0.20, 0.02) notch2 = cube().translate(-0.1, 0, 0).scale(0.02, 0.02, 0.20) bolt = CSG(shaft) + CSG(head) - CSG(notch1) - CSG(notch2)
def test_mesh(msp, basic): # draw mesh as wire frame c = cube() c.render(msp) basic.draw_entities(msp) result = basic.out.collector assert len(result) == 24 assert unique_types(result) == {'line'}
def test_polyface(msp, basic): # draw mesh as wire frame c = cube() c.render_polyface(msp) basic.draw_entities(msp) result = basic.out.collector assert len(result) == 24 entities = {e[0] for e in result} assert entities == {'line'}
def test_polyface_virtual_entities(msp): from ezdxf.render.forms import cube polyface = cube().render_polyface(msp) result = list(polyface.virtual_entities()) assert len(result) == 6 assert result[0].dxftype() == '3DFACE' vertices = set() for face in result: for vertex in face: vertices.add(vertex) assert len(vertices) == 8 assert (-0.5, -0.5, -0.5) in vertices assert (0.5, 0.5, 0.5) in vertices
def test_mesh_to_code(): from ezdxf.entities.mesh import Mesh from ezdxf.render.forms import cube entity = Mesh.new(handle='ABBA', owner='0', dxfattribs={ 'color': '7', }) c = cube() entity.vertices = c.vertices entity.edges = c.edges entity.faces = c.faces assert len(entity.vertices) == 8 new_entity = translate_to_code_and_execute(entity) assert list(entity.vertices) == list(new_entity.vertices) assert list(entity.faces) == list(new_entity.faces)
def test_poly_face_mesh_to_primitive(): from ezdxf.layouts import VirtualLayout from ezdxf.render.forms import cube vl = VirtualLayout() poly_face_mesh = cube().render_polyface(vl) assert poly_face_mesh.dxftype() == "POLYLINE" p = disassemble.make_primitive(poly_face_mesh) assert p.is_empty is False assert p.path is None mesh_builder = p.mesh assert mesh_builder is not None assert len(mesh_builder.vertices) == 8 assert len(mesh_builder.faces) == 6 assert len(list(p.vertices())) == 8
def test_mesh_entity_to_primitive(): from ezdxf.layouts import VirtualLayout from ezdxf.render.forms import cube vl = VirtualLayout() mesh_entity = cube().render(vl) assert mesh_entity.dxftype() == "MESH" p = disassemble.make_primitive(mesh_entity) assert p.is_empty is False assert p.path is None mesh_builder = p.mesh assert mesh_builder is not None assert p.is_empty is False assert len(mesh_builder.vertices) == 8 assert len(mesh_builder.faces) == 6 assert len(list(p.vertices())) == 8
def test_mesh_to_code(): from ezdxf.entities.mesh import Mesh from ezdxf.render.forms import cube entity = Mesh.new( handle="ABBA", owner="0", dxfattribs={ "color": "7", }, ) c = cube() entity.vertices = c.vertices entity.faces = c.faces assert len(entity.vertices) == 8 new_entity = translate_to_code_and_execute(entity) assert list(entity.vertices) == list(new_entity.vertices) assert list(entity.faces) == list(new_entity.faces)
def _add_mesh(layout: "GenericLayoutType", item: Item, layer: str, color: int, m: Matrix44): from ezdxf.render.forms import cube attribs = { "layer": layer, "color": color, } mesh = cube(center=False) sx, sy, sz = item.get_dimension() mesh.scale(sx, sy, sz) x, y, z = item.position mesh.translate(x, y, z) mesh.render_polyface(layout, attribs, matrix=m) text = layout.add_text(str(item.payload), height=0.25, dxfattribs={"layer": "TEXT"}) if sy > sx: text.dxf.rotation = 90 align = TextEntityAlignment.TOP_LEFT else: align = TextEntityAlignment.BOTTOM_LEFT text.set_placement((x + 0.25, y + 0.25, z + sz), align=align) text.transform(m)
import ezdxf from ezdxf.render.forms import sphere, cube from ezdxf.addons.pycsg import CSG DIR = Path('~/Desktop/Outbox').expanduser() NLENGTH = .05 doc = ezdxf.new() doc.layers.new('csg', dxfattribs={'color': 1}) doc.layers.new('normals', dxfattribs={'color': 6}) doc.set_modelspace_vport(6, center=(5, 0)) msp = doc.modelspace() cube1 = cube().translate(-.5, -.5, -.5) sphere1 = sphere(count=32, stacks=16, radius=.5, quads=True) union = (CSG(cube1) + CSG(sphere1)).mesh() union.render_mesh(msp, dxfattribs={'layer': 'csg', 'color': 1}) union.render_normals(msp, length=NLENGTH, relative=False, dxfattribs={'layer': 'normals'}) subtract = (CSG(cube1) - CSG(sphere1)).mesh().translate(2.5) subtract.render_mesh(msp, dxfattribs={'layer': 'csg', 'color': 3}) subtract.render_normals(msp, length=NLENGTH, relative=False, dxfattribs={'layer': 'normals'}) intersection = (CSG(cube1) * CSG(sphere1)).mesh().translate(4) intersection.render(msp, dxfattribs={'layer': 'csg', 'color': 5}) intersection.render_normals(msp, length=NLENGTH, relative=False, dxfattribs={'layer': 'normals'}) doc.saveas(DIR / 'csg_sphere.dxf')
import ezdxf from ezdxf.render.forms import sphere, cube from ezdxf.addons.pycsg import CSG DIR = Path("~/Desktop/Outbox").expanduser() NLENGTH = 0.05 doc = ezdxf.new() doc.layers.new("csg", dxfattribs={"color": 1}) doc.layers.new("normals", dxfattribs={"color": 6}) doc.set_modelspace_vport(6, center=(5, 0)) msp = doc.modelspace() cube1 = cube().translate(-0.5, -0.5, -0.5) sphere1 = sphere(count=32, stacks=16, radius=0.5, quads=True) union = (CSG(cube1) + CSG(sphere1)).mesh() union.render_mesh(msp, dxfattribs={"layer": "csg", "color": 1}) union.render_normals(msp, length=NLENGTH, relative=False, dxfattribs={"layer": "normals"}) subtract = (CSG(cube1) - CSG(sphere1)).mesh().translate(2.5) subtract.render_mesh(msp, dxfattribs={"layer": "csg", "color": 3}) subtract.render_normals(msp, length=NLENGTH, relative=False, dxfattribs={"layer": "normals"})
# Copyright (c) 2020, Manfred Moitzi # License: MIT License from pathlib import Path import ezdxf from ezdxf.render.forms import cube, cylinder DIR = Path('~/Desktop/Outbox').expanduser() mycube = cube().scale_uniform(10).subdivide(2) mycylinder = cylinder(12, radius=5, top_center=(0, 0, 10)).translate(0, 20) doc = ezdxf.new() msp = doc.modelspace() mycube.render(msp, dxfattribs={'color': 1}) mycube.translate(20) mycube.render_polyface(msp, dxfattribs={'color': 3}) mycube.translate(20) mycube.render_3dfaces(msp, dxfattribs={'color': 5}) mycylinder.render(msp, dxfattribs={'color': 1}) mycylinder.translate(20) mycylinder.render_polyface(msp, dxfattribs={'color': 3}) mycylinder.translate(20) mycylinder.render_3dfaces(msp, dxfattribs={'color': 5}) doc.set_modelspace_vport(30, center=(30, 20)) doc.saveas(DIR / 'meshes.dxf')
def test_spherical_envelope(): from ezdxf.render.forms import cube center, radius = spherical_envelope(cube(center=True).vertices) assert center.isclose((0, 0, 0)) assert radius == pytest.approx(0.8660254037844386)
def make_cluster(size, dx, dy, dz): return forms.cube().scale_uniform(size).translate(dx, dy, dz).vertices
# Copyright (c) 2020-2022, Manfred Moitzi # License: MIT License from pathlib import Path import ezdxf from ezdxf import colors from ezdxf.gfxattribs import GfxAttribs from ezdxf.render import forms DIR = Path("~/Desktop/Outbox").expanduser() cube = forms.cube().scale_uniform(10).subdivide(2) cylinder = forms.cylinder(12, radius=5, top_center=(0, 0, 10)).translate(0, 20) doc = ezdxf.new() msp = doc.modelspace() red = GfxAttribs(color=colors.RED) green = GfxAttribs(color=colors.GREEN) blue = GfxAttribs(color=colors.BLUE) cube.render(msp, dxfattribs=red) cube.translate(20) cube.render_polyface(msp, dxfattribs=green) cube.translate(20) cube.render_3dfaces(msp, dxfattribs=blue) cylinder.render(msp, dxfattribs=red) cylinder.translate(20) cylinder.render_polyface(msp, dxfattribs=green) cylinder.translate(20) cylinder.render_3dfaces(msp, dxfattribs=blue)
def test_scale_mesh(): mesh = cube(center=False) mesh.scale(2, 3, 4) bbox = BoundingBox(mesh.vertices) assert bbox.extmin.isclose((0, 0, 0)) assert bbox.extmax.isclose((2, 3, 4))
def cube_polyface(): layout = VirtualLayout() p = layout.add_polyface() p.append_faces(cube().faces_as_vertices()) return p
def cube_polyface(msp): p = msp.add_polyface() p.append_faces(cube().faces_as_vertices()) return p
def test_mesh_subdivide(): c = cube().scale_uniform(10).subdivide(2) assert len(c.vertices) == 2 * 25 + 3 * 16 assert len(c.faces) == 16 * 6
def test_cube_union(): a = cube() b = cube().translate(0.5, 0.5) c = CSG(mesh=a) + CSG(mesh=b)
def test_cube_intersect(): a = cube() b = cube().translate(0.5, 0.5) c = CSG(mesh=a) * CSG(mesh=b)
def test_cube_subtract(): a = cube() b = cube().translate(0.5, 0.5) _ = CSG(a) - CSG(b)
def test_rotate_x(): mesh = cube(center=False) mesh.rotate_x(radians(90)) bbox = BoundingBox(mesh.vertices) assert bbox.extmin.isclose((0, -1, 0)) assert bbox.extmax.isclose((1, 0, 1))
# Copyright (c) 2020, Manfred Moitzi # License: MIT License from pathlib import Path import ezdxf from ezdxf.addons.pycsg import CSG from ezdxf.render.forms import cube, cylinder_2p DIR = Path("~/Desktop/Outbox").expanduser() cube1 = cube() cylinder1 = cylinder_2p(count=32, base_center=(0, -1, 0), top_center=(0, 1, 0), radius=0.25) doc = ezdxf.new() doc.set_modelspace_vport(6, center=(5, 0)) msp = doc.modelspace() # build solid union union = CSG(cube1) + CSG(cylinder1) # convert to mesh and render mesh to modelspace union.mesh().render_mesh(msp, dxfattribs={"color": 1}) # build solid difference difference = CSG(cube1) - CSG(cylinder1) # convert to mesh, translate mesh and render mesh to modelspace difference.mesh().translate(1.5).render(msp, dxfattribs={"color": 3}) # build solid intersection intersection = CSG(cube1) * CSG(cylinder1)