Implement importBrep and vtkPolyData export (#735)

* Implement importBrep

* Implement rw to/from stream

* Implement toVtkPolyData

* Implemented VTP export

* Added normals calculation

* use VTK for rendering in jupyter

* Added orientation marker

* Assy rendering in notebooks

* Implement export to vtkjs

* Store the env in the cqgi result

* VTK-based cq directive

* Support show_object and assy

* assy vrml export via vtk

* Use vtk in the docs

* Add slot dxf file

* Add vtk.js to the static files

* Use single renderer

* Ignore cq_directive code coverage

* Ignore missing docutils stubs

* Implement select

* Disable interaction dynamically

* Mention VTP in the docs

* Add path to the test reqs
This commit is contained in:
Adam Urbańczyk
2021-06-22 10:06:50 +02:00
committed by GitHub
parent 7b1a99ca8a
commit e00ac83f98
26 changed files with 9395 additions and 47 deletions

View File

@ -3,8 +3,13 @@ import os
from itertools import product
import cadquery as cq
from cadquery.occ_impl.exporters.assembly import exportAssembly, exportCAF
from cadquery.occ_impl.exporters.assembly import (
exportAssembly,
exportCAF,
exportVTKJS,
exportVRML,
)
from cadquery.occ_impl.assembly import toJSON
from OCP.gp import gp_XYZ
@ -44,6 +49,17 @@ def nested_assy():
return assy
@pytest.fixture
def empty_top_assy():
b1 = cq.Workplane().box(1, 1, 1)
assy = cq.Assembly()
assy.add(b1, color=cq.Color("green"))
return assy
@pytest.fixture
def box_and_vertex():
@ -115,6 +131,33 @@ def test_native_export(simple_assy):
assert os.path.exists("assy.xml")
def test_vtkjs_export(nested_assy):
exportVTKJS(nested_assy, "assy")
# only sanity check for now
assert os.path.exists("assy.zip")
def test_vrml_export(simple_assy):
exportVRML(simple_assy, "assy.wrl")
# only sanity check for now
assert os.path.exists("assy.wrl")
def test_toJSON(simple_assy, nested_assy, empty_top_assy):
r1 = toJSON(simple_assy)
r2 = toJSON(simple_assy)
r3 = toJSON(empty_top_assy)
assert len(r1) == 3
assert len(r2) == 3
assert len(r3) == 1
def test_save(simple_assy, nested_assy):
simple_assy.save("simple.step")

View File

@ -4571,3 +4571,27 @@ class TestCadQuery(BaseTest):
self.assertEqual(len(edges), len(vertices) + 1)
endpoints = [e.endPoint() for e in edges]
self.assertTrue(all([v in endpoints for v in vecs]))
def testBrepImportExport(self):
# import/export to file
s = Workplane().box(1, 1, 1).val()
s.exportBrep("test.brep")
si = Shape.importBrep("test.brep")
self.assertTrue(si.isValid())
self.assertAlmostEqual(si.Volume(), 1)
# import/export to BytesIO
from io import BytesIO
bio = BytesIO()
s.exportBrep(bio)
bio.seek(0)
si = Shape.importBrep("test.brep")
self.assertTrue(si.isValid())
self.assertAlmostEqual(si.Volume(), 1)

View File

@ -3,7 +3,9 @@ import pytest
from glob import glob
from itertools import chain, count
from docutils.parsers.rst import directives, Directive
from path import Path
from docutils.parsers.rst import directives
from docutils.core import publish_doctree
from docutils.utils import Reporter
@ -12,16 +14,16 @@ from cadquery import cqgi
from cadquery.cq_directive import cq_directive
def find_examples(pattern="examples/*.py"):
def find_examples(pattern="examples/*.py", path=Path("examples")):
for p in glob(pattern):
with open(p, encoding="UTF-8") as f:
code = f.read()
yield code
yield code, path
def find_examples_in_docs(pattern="doc/*.rst"):
def find_examples_in_docs(pattern="doc/*.rst", path=Path("doc")):
# dummy CQ directive for code
class dummy_cq_directive(cq_directive):
@ -48,16 +50,17 @@ def find_examples_in_docs(pattern="doc/*.rst"):
# yield all code snippets
for c in dummy_cq_directive.codes:
yield c
yield c, path
@pytest.mark.parametrize(
"code", chain(find_examples(), find_examples_in_docs()), ids=count(0)
"code, path", chain(find_examples(), find_examples_in_docs()), ids=count(0)
)
def test_example(code):
def test_example(code, path):
# build
res = cqgi.parse(code).build()
with path:
res = cqgi.parse(code).build()
assert res.exception is None

View File

@ -98,6 +98,15 @@ class TestExporters(BaseTest):
# export again to trigger all paths in the code
exporters.export(self._box(), "out.vrml")
def testVTP(self):
exporters.export(self._box(), "out.vtp")
with open("out.vtp") as f:
res = f.read(100)
assert res.startswith('<?xml version="1.0"?>\n<VTKFile')
def testDXF(self):
exporters.export(self._box().section(), "out.dxf")

View File

@ -1,14 +1,27 @@
from tests import BaseTest
import cadquery
import cadquery as cq
from cadquery.occ_impl.jupyter_tools import display
class TestJupyter(BaseTest):
def test_repr_html(self):
cube = cadquery.Workplane("XY").box(1, 1, 1)
def test_repr_javascript(self):
cube = cq.Workplane("XY").box(1, 1, 1)
assy = cq.Assembly().add(cube)
shape = cube.val()
self.assertIsInstance(shape, cadquery.occ_impl.shapes.Solid)
# Test no exception on rendering to html
html = shape._repr_html_()
# TODO: verification improvement: test for valid html
self.assertIsInstance(shape, cq.occ_impl.shapes.Solid)
# Test no exception on rendering to js
js1 = shape._repr_javascript_()
js2 = cube._repr_javascript_()
js3 = assy._repr_javascript_()
assert "function render" in js1
assert "function render" in js2
assert "function render" in js3
def test_display_error(self):
with self.assertRaises(ValueError):
display(cq.Vector())