Skip to content

Commit

Permalink
OCCT7.6 (#1156)
Browse files Browse the repository at this point in the history
* CQ-specific multimethod

* Use cqmultimethod in cq.Shape

* Imports cleanup

* cqmultimethod test

* Inital 7.6 support

* Black fix

* Fix project

* Update the OCP version

* Compute normals

* Do not pin vtk

* Update the conda pkg spec

* Use correct stubs

* Additional simple test for toVtkPolyData

* Require 7.6 in setup.py
  • Loading branch information
adam-urbanczyk authored Oct 1, 2022
1 parent 3d6d2ab commit 9c525bc
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 50 deletions.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ install:
- cmd: conda init cmd.exe
- conda env create -f environment.yml
- conda activate cadquery
- pip install git+https://github.com/CadQuery/OCP-stubs.git@7.5.1
- pip install git+https://github.com/CadQuery/OCP-stubs.git@7.6.3

build: false

Expand Down
8 changes: 4 additions & 4 deletions cadquery/cq.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ def workplane(
:type invert: boolean or None=False
:type centerOption: string or None='ProjectedOrigin'
:type origin: Vector or None
:rtype: Workplane object
:rtype: Workplane object
The first element on the stack must be a face, a set of
co-planar faces or a vertex. If a vertex, then the parent
Expand Down Expand Up @@ -3019,7 +3019,7 @@ def extrude(
passed, the extrusion extends this far and a negative value is in the opposite direction
to the normal of the plane. The string "next" extrudes until the next face orthogonal to
the wire normal. "last" extrudes to the last face. If a object of type Face is passed then
the extrusion will extend until this face. **Note that the Workplane must contain a Solid for extruding to a given face.**
the extrusion will extend until this face. **Note that the Workplane must contain a Solid for extruding to a given face.**
:param combine: True or "a" to combine the resulting solid with parent solids if found, "cut" or "s" to remove the resulting solid from the parent solids if found. False to keep the resulting solid separated from the parent solids.
:param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
:param boolean both: extrude in both directions symmetrically
Expand Down Expand Up @@ -3524,7 +3524,7 @@ def loft(
:param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
:return: a Workplane object containing the created loft
"""

if self.ctx.pendingWires:
Expand Down Expand Up @@ -3765,7 +3765,7 @@ def interpPlate(
) -> T:
"""
Returns a plate surface that is 'thickness' thick, enclosed by 'surf_edge_pts' points, and going
through 'surf_pts' points. Using pushPoints directly with interpPlate and combine=True, can be
through 'surf_pts' points. Using pushPoints directly with interpPlate and combine=True, can be
very resources intensive depending on the complexity of the shape. In this case set combine=False.
:param surf_edges
Expand Down
2 changes: 1 addition & 1 deletion cadquery/occ_impl/jupyter_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
const mapper = vtk.Rendering.Core.vtkMapper.newInstance();
mapper.setInputConnection(reader.getOutputPort());
mapper.setResolveCoincidentTopologyToPolygonOffset();
mapper.setResolveCoincidentTopologyPolygonOffsetParameters(0.5,100);
mapper.setResolveCoincidentTopologyPolygonOffsetParameters(0.9,20);
const actor = vtk.Rendering.Core.vtkActor.newInstance();
actor.setMapper(mapper);
Expand Down
64 changes: 26 additions & 38 deletions cadquery/occ_impl/shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from vtkmodules.vtkCommonDataModel import vtkPolyData
from vtkmodules.vtkFiltersCore import vtkTriangleFilter, vtkPolyDataNormals


from .geom import Vector, VectorLike, BoundBox, Plane, Location, Matrix

from ..utils import cqmultimethod as multimethod
Expand Down Expand Up @@ -60,8 +59,6 @@
BRepAdaptor_Curve,
BRepAdaptor_CompCurve,
BRepAdaptor_Surface,
BRepAdaptor_HCurve,
BRepAdaptor_HCompCurve,
)

from OCP.BRepBuilderAPI import (
Expand Down Expand Up @@ -233,6 +230,10 @@
# for catching exceptions
from OCP.Standard import Standard_NoSuchObject, Standard_Failure

from OCP.Prs3d import Prs3d_IsoAspect
from OCP.Quantity import Quantity_Color
from OCP.Aspect import Aspect_TOL_SOLID

from OCP.Interface import Interface_Static

from math import pi, sqrt, inf
Expand Down Expand Up @@ -449,7 +450,7 @@ def exportStl(
:param fileName: The path and file name to write the STL output to.
:param tolerance: A linear deflection setting which limits the distance between a curve and its tessellation.
Setting this value too low will result in large meshes that can consume computing resources.
Setting the value too high can result in meshes with a level of detail that is too low.
Setting the value too high can result in meshes with a level of detail that is too low.
Default is 1e-3, which is a good starting point for a range of cases.
:param angularTolerance: Angular deflection setting which limits the angle between subsequent segments in a polyline. Default is 0.1.
:param ascii: Export the file as ASCII (True) or binary (False) STL format. Default is binary.
Expand Down Expand Up @@ -1216,7 +1217,9 @@ def tessellate(
# add vertices
vertices += [
Vector(v.X(), v.Y(), v.Z())
for v in (v.Transformed(Trsf) for v in poly.Nodes())
for v in (
poly.Node(i).Transformed(Trsf) for i in range(1, poly.NbNodes())
)
]

# add triangles
Expand All @@ -1240,17 +1243,28 @@ def tessellate(
return vertices, triangles

def toVtkPolyData(
self, tolerance: float, angularTolerance: float = 0.1, normals: bool = True
self,
tolerance: Optional[float] = None,
angularTolerance: Optional[float] = None,
normals: bool = True,
) -> vtkPolyData:
"""
Convert shape to vtkPolyData
"""

vtk_shape = IVtkOCC_Shape(self.wrapped)
shape_data = IVtkVTK_ShapeData()
shape_mesher = IVtkOCC_ShapeMesher(
tolerance, angularTolerance, theNbUIsos=0, theNbVIsos=0
)
shape_mesher = IVtkOCC_ShapeMesher()

drawer = vtk_shape.Attributes()
drawer.SetUIsoAspect(Prs3d_IsoAspect(Quantity_Color(), Aspect_TOL_SOLID, 1, 0))
drawer.SetVIsoAspect(Prs3d_IsoAspect(Quantity_Color(), Aspect_TOL_SOLID, 1, 0))

if tolerance:
drawer.SetDeviationCoefficient(tolerance)

if angularTolerance:
drawer.SetDeviationAngle(angularTolerance)

shape_mesher.Build(vtk_shape, shape_data)

Expand Down Expand Up @@ -1338,14 +1352,6 @@ class Mixin1DProtocol(ShapeProtocol, Protocol):
def _geomAdaptor(self) -> Union[BRepAdaptor_Curve, BRepAdaptor_CompCurve]:
...

def _geomAdaptorH(
self,
) -> Tuple[
Union[BRepAdaptor_Curve, BRepAdaptor_CompCurve],
Union[BRepAdaptor_HCurve, BRepAdaptor_HCompCurve],
]:
...

def paramAt(self, d: float) -> float:
...

Expand Down Expand Up @@ -1546,7 +1552,7 @@ def locationAt(
:return: A Location object representing local coordinate system at the specified distance.
"""

curve, curveh = self._geomAdaptorH()
curve = self._geomAdaptor()

if mode == "length":
param = self.paramAt(d)
Expand All @@ -1559,7 +1565,7 @@ def locationAt(
else:
law = GeomFill_CorrectedFrenet()

law.SetCurve(curveh)
law.SetCurve(curve)

tangent, normal, binormal = gp_Vec(), gp_Vec(), gp_Vec()

Expand Down Expand Up @@ -1644,15 +1650,6 @@ def _geomAdaptor(self) -> BRepAdaptor_Curve:

return BRepAdaptor_Curve(self.wrapped)

def _geomAdaptorH(self) -> Tuple[BRepAdaptor_Curve, BRepAdaptor_HCurve]:
"""
Return the underlying geometry
"""

curve = self._geomAdaptor()

return curve, BRepAdaptor_HCurve(curve)

def close(self) -> Union["Edge", "Wire"]:
"""
Close an Edge
Expand Down Expand Up @@ -1943,15 +1940,6 @@ def _geomAdaptor(self) -> BRepAdaptor_CompCurve:

return BRepAdaptor_CompCurve(self.wrapped)

def _geomAdaptorH(self) -> Tuple[BRepAdaptor_CompCurve, BRepAdaptor_HCompCurve]:
"""
Return the underlying geometry
"""

curve = self._geomAdaptor()

return curve, BRepAdaptor_HCompCurve(curve)

def close(self) -> "Wire":
"""
Close a Wire
Expand Down Expand Up @@ -2545,7 +2533,7 @@ def constructOn(cls, f: "Face", outer: "Wire", *inner: "Wire") -> "Face":
bldr = BRepBuilderAPI_MakeFace(f._geomAdaptor(), outer.wrapped)

for w in inner:
bldr.Add(TopoDS.Wire_s(w.wrapped.Reversed()))
bldr.Add(TopoDS.Wire_s(w.wrapped))

return cls(bldr.Face()).fix()

Expand Down
3 changes: 1 addition & 2 deletions conda/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ requirements:
- setuptools
run:
- python {{ environ.get('PYTHON_VERSION') }}
- ocp 7.5.3
- vtk =9.0.1
- ocp 7.6.*
- pyparsing >=2.1.9
- ezdxf
- ipython
Expand Down
3 changes: 1 addition & 2 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ channels:
dependencies:
- python>=3.8
- ipython
- ocp=7.5.3
- vtk=9.0.1
- ocp=7.6.*
- pyparsing>=2.1.9
- sphinx=5.0.1
- sphinx_rtd_theme
Expand Down
12 changes: 10 additions & 2 deletions tests/test_cadquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"""
# system modules
import math, os.path, time, tempfile
from random import choice
from random import random
from random import randrange
from itertools import product
Expand All @@ -14,7 +13,6 @@
# my modules

from cadquery import *
from cadquery import exporters
from cadquery import occ_impl
from tests import (
BaseTest,
Expand Down Expand Up @@ -5479,3 +5477,13 @@ def test_makeNSidedSurface(self):
# exception on invalid constraint
with raises(ValueError):
Face.makeNSidedSurface(outer_w, [[0, 0, 1]])

def test_toVtk(self):

from vtkmodules.vtkCommonDataModel import vtkPolyData

f = Face.makePlane(2, 2)
vtk = f.toVtkPolyData(normals=False)

assert isinstance(vtk, vtkPolyData)
assert vtk.GetNumberOfPolys() == 2

0 comments on commit 9c525bc

Please sign in to comment.