diff --git a/.gitignore b/.gitignore
index ba74660..7f67d86 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,3 +55,6 @@ docs/_build/
# PyBuilder
target/
+
+# VScode
+.vscode/launch.json
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..a727744
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,64 @@
+sudo: false
+
+language: cpp
+
+matrix:
+ include:
+ - env: PYTHON="3.6" CONDA_PY=36
+ os: linux
+ dist: bionic
+ - env: PYTHON="3.6" CONDA_PY=36
+ os: osx
+ osx_image: xcode9.4
+ - env: PYTHON="3.7" CONDA_PY=37
+ os: linux
+ dist: bionic
+ - env: PYTHON="3.7" CONDA_PY=37
+ os: osx
+ osx_image: xcode9.4
+
+
+install:
+ - if [ ${PYTHON:0:1} == "2" ]; then
+ if [ "$TRAVIS_OS_NAME" == "linux" ]; then
+ wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh;
+ else
+ wget https://repo.continuum.io/miniconda/Miniconda2-latest-MacOSX-x86_64.sh -O miniconda.sh;
+ fi;
+ else
+ if [ "$TRAVIS_OS_NAME" == "linux" ]; then
+ wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
+ else
+ wget https://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -O miniconda.sh;
+ fi;
+ fi;
+ - chmod +x miniconda.sh
+ # When we are installing the 32 Bit conda on a 64 Bit system, the miniconda
+ # installer will ask for a "yes" despite the -b flag, so we pipe in a yes
+ - yes | ./miniconda.sh -b -p $HOME/miniconda
+ #- bash miniconda.sh -b -p -f $HOME/miniconda
+ - export PATH="$HOME/miniconda/bin:$HOME/miniconda/lib:$PATH"
+ - hash -r
+ - conda config --set always_yes yes --set changeps1 no
+ # Useful for debugging any issues with conda
+ - conda info -a
+ # osx needs a dedicate environment
+ - if [ "$TRAVIS_OS_NAME" == "osx" ]; then
+ conda create -n pythonocc-utils-test;
+ source activate pythonocc-utils-test;
+ fi;
+ - conda install -c dlr-sc -c pythonocc pythonocc-core=7.4.0rc1
+
+script:
+ # osx needs a dedicate environment
+ - if [ "$TRAVIS_OS_NAME" == "osx" ]; then
+ source activate pythonocc-utils-test;
+ fi;
+ - python setup.py build install
+ - cd test
+ - python occutils_test.py
+
+branches:
+ only:
+ - master
+ - /^review/
diff --git a/OCCUtils/Adapt.py b/OCCUtils/Adapt.py
deleted file mode 100644
index e94700b..0000000
--- a/OCCUtils/Adapt.py
+++ /dev/null
@@ -1,32 +0,0 @@
-##Copyright 2008-2015 Jelle Feringa (jelleferinga@gmail.com)
-##
-##This file is part of pythonOCC.
-##
-##pythonOCC is free software: you can redistribute it and/or modify
-##it under the terms of the GNU Lesser General Public License as published by
-##the Free Software Foundation, either version 3 of the License, or
-##(at your option) any later version.
-##
-##pythonOCC is distributed in the hope that it will be useful,
-##but WITHOUT ANY WARRANTY; without even the implied warranty of
-##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-##GNU Lesser General Public License for more details.
-##
-##You should have received a copy of the GNU Lesser General Public License
-##along with pythonOCC. If not, see .
-
-from OCC.BRepAdaptor import *
-
-
-def adapt_edge_to_curve(edg):
- '''
- returns a curve adaptor from an edge
- @param edg: TopoDS_Edge
- '''
- return BRepAdaptor_Curve(edg)
-
-
-def adapt_edge_to_hcurve(edg):
- c = BRepAdaptor_HCurve()
- c.ChangeCurve().Initialize(edg)
- return c
diff --git a/OCCUtils/Common.py b/OCCUtils/Common.py
index 44e17ac..f0aa418 100644
--- a/OCCUtils/Common.py
+++ b/OCCUtils/Common.py
@@ -19,68 +19,108 @@
import random
-from OCC.Bnd import *
-from OCC.BRepBndLib import *
-from OCC.TColgp import *
-from OCC.TColStd import *
-from OCC.BRepAdaptor import *
-from OCC.GeomAPI import *
-from OCC.gp import *
-from OCC.BRepBuilderAPI import *
-from OCC.TopoDS import *
-from OCC.Quantity import *
-from OCC.GProp import GProp_GProps
-from OCC.GeomAbs import *
-from OCC.BRepGProp import brepgprop_LinearProperties, brepgprop_SurfaceProperties, brepgprop_VolumeProperties
-from OCC import Graphic3d
-
-from Context import assert_isdone
-
-#===========================================================================
+from OCC.Core.Bnd import Bnd_Box
+from OCC.Core.BRepBndLib import brepbndlib_Add
+from OCC.Core.TColgp import (
+ TColgp_HArray1OfPnt,
+ TColgp_Array1OfPnt,
+ TColgp_Array1OfPnt2d,
+ TColgp_Array1OfVec,
+)
+from OCC.Core.TColStd import TColStd_HArray1OfBoolean
+from OCC.Core.BRepAdaptor import (
+ BRepAdaptor_Curve,
+ BRepAdaptor_Curve,
+ BRepAdaptor_CompCurve,
+ BRepAdaptor_CompCurve,
+)
+from OCC.Core.GeomAPI import (
+ GeomAPI_Interpolate,
+ GeomAPI_PointsToBSpline,
+ GeomAPI_ProjectPointOnCurve,
+)
+from OCC.Core.gp import gp_Pnt, gp_Vec, gp_Trsf
+from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_Transform
+from OCC.Core.TopoDS import TopoDS_Edge, TopoDS_Shape, TopoDS_Wire, TopoDS_Vertex
+from OCC.Core.Quantity import Quantity_Color, Quantity_TOC_RGB
+from OCC.Core.GProp import GProp_GProps
+from OCC.Core.GeomAbs import GeomAbs_C1, GeomAbs_C2, GeomAbs_C3
+from OCC.Core.BRepGProp import (
+ brepgprop_LinearProperties,
+ brepgprop_SurfaceProperties,
+ brepgprop_VolumeProperties,
+)
+from OCC.Core.GeomAdaptor import GeomAdaptor_Curve
+from OCC.Core.Geom import Geom_Curve
+
+from OCC.Core import Graphic3d
+
+# ===========================================================================
# No PythonOCC dependencies...
-#===========================================================================
+# ===========================================================================
+
+
+class assert_isdone(object):
+ """
+ raises an assertion error when IsDone() returns false, with the error
+ specified in error_statement
+ """
+
+ def __init__(self, to_check, error_statement):
+ self.to_check = to_check
+ self.error_statement = error_statement
+
+ def __enter__(
+ self,
+ ):
+ if self.to_check.IsDone():
+ pass
+ else:
+ raise AssertionError(self.error_statement)
+
+ def __exit__(self, assertion_type, value, traceback):
+ pass
+
def roundlist(li, n_decimals=3):
return [round(i, n_decimals) for i in li]
-#===========================================================================
+
+# ===========================================================================
# CONSTANTS
-#===========================================================================
+# ===========================================================================
TOLERANCE = 1e-6
-def get_boundingbox(shape, tol=TOLERANCE, vec=False):
- '''
+def get_boundingbox(shape, tol=TOLERANCE):
+ """
:param shape: TopoDS_Shape such as TopoDS_Face
:param tol: tolerance
:return: xmin, ymin, zmin, xmax, ymax, zmax
- '''
+ """
bbox = Bnd_Box()
bbox.SetGap(tol)
- #BRepBndLib_AddClose(shape, bbox)
- tmp = brepbndlib_Add(shape, bbox)
+ brepbndlib_Add(shape, bbox)
xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get()
- if vec is False:
- return xmin, ymin, zmin, xmax, ymax, zmax
- else:
- return gp_Vec(xmin, ymin, zmin), gp_Vec(xmax, ymax, zmax)
+ return xmin, ymin, zmin, xmax, ymax, zmax
def smooth_pnts(pnts):
smooth = [pnts[0]]
- for i in range(1, len(pnts)-1):
- prev = pnts[i-1]
+ for i in range(1, len(pnts) - 1):
+ prev = pnts[i - 1]
this = pnts[i]
- next = pnts[i+1]
- pt = (prev+this+next) / 3.0
+ next_pnt = pnts[i + 1]
+ pt = (prev + this + next_pnt) / 3.0
smooth.append(pt)
smooth.append(pnts[-1])
return smooth
-#===========================================================================
+
+# ===========================================================================
# Data type utilities
-#===========================================================================
+# ===========================================================================
def color(r, g, b):
@@ -88,20 +128,21 @@ def color(r, g, b):
def to_string(_string):
- from OCC.TCollection import TCollection_ExtendedString
+ from OCC.Core.TCollection import TCollection_ExtendedString
+
return TCollection_ExtendedString(_string)
-def to_tcol_(_list, type):
- array = type(1, len(_list)+1)
+def to_tcol_(_list, collection_type):
+ array = collection_type(1, len(_list) + 1)
for n, i in enumerate(_list):
- array.SetValue(n+1, i)
- return array.GetHandle()
+ array.SetValue(n + 1, i)
+ return array
def _Tcol_dim_1(li, _type):
- '''function factory for 1-dimensional TCol* types'''
- pts = _type(0, len(li)-1)
+ """function factory for 1-dimensional TCol* types"""
+ pts = _type(0, len(li) - 1)
for n, i in enumerate(li):
pts.SetValue(n, i)
pts.thisown = False
@@ -109,7 +150,7 @@ def _Tcol_dim_1(li, _type):
def point_list_to_TColgp_Array1OfPnt(li):
- pts = TColgp_Array1OfPnt(0, len(li)-1)
+ pts = TColgp_Array1OfPnt(0, len(li) - 1)
for n, i in enumerate(li):
pts.SetValue(n, i)
return pts
@@ -118,16 +159,17 @@ def point_list_to_TColgp_Array1OfPnt(li):
def point2d_list_to_TColgp_Array1OfPnt2d(li):
return _Tcol_dim_1(li, TColgp_Array1OfPnt2d)
-#===========================================================================
+
+# ===========================================================================
# --- INTERPOLATION ---
-#===========================================================================
+# ===========================================================================
def filter_points_by_distance(list_of_point, distance=0.1):
- '''
+ """
get rid of those point that lie within tolerance of a
consequtive series of points
- '''
+ """
tmp = [list_of_point[0]]
for a in list_of_point[1:]:
if any([a.IsEqual(i, distance) for i in tmp]):
@@ -138,24 +180,27 @@ def filter_points_by_distance(list_of_point, distance=0.1):
def points_to_bspline(pnts):
- '''
+ """
Points to bspline
- '''
+ """
pnts = point_list_to_TColgp_Array1OfPnt(pnts)
crv = GeomAPI_PointsToBSpline(pnts)
return crv.Curve()
-def interpolate_points_to_spline(list_of_points, start_tangent, end_tangent, filter_pts=True, tolerance=TOLERANCE):
- '''
+def interpolate_points_to_spline(
+ list_of_points, start_tangent, end_tangent, filter_pts=True, tolerance=TOLERANCE
+):
+ """
GeomAPI_Interpolate is buggy: need to use `fix` in order
to get the right points in...
- '''
+ """
+
def fix(li, _type):
- '''function factory for 1-dimensional TCol* types'''
+ """function factory for 1-dimensional TCol* types"""
pts = _type(1, len(li))
for n, i in enumerate(li):
- pts.SetValue(n+1, i)
+ pts.SetValue(n + 1, i)
pts.thisown = False
return pts
@@ -164,34 +209,40 @@ def fix(li, _type):
fixed_points = fix(list_of_points, TColgp_HArray1OfPnt)
try:
- interp = GeomAPI_Interpolate(fixed_points.GetHandle(), False, tolerance)
+ interp = GeomAPI_Interpolate(fixed_points, False, tolerance)
interp.Load(start_tangent, end_tangent, False)
interp.Perform()
if interp.IsDone():
return interp.Curve()
except RuntimeError:
- print 'FAILED TO INTERPOLATE THE SHOWN POINTS'
+ print("Failed to interpolate the shown points")
-def interpolate_points_vectors_to_spline(list_of_points, list_of_vectors, vector_mask=[], tolerance=TOLERANCE):
- '''
+def interpolate_points_vectors_to_spline(
+ list_of_points, list_of_vectors, vector_mask=None, tolerance=TOLERANCE
+):
+ """
build a curve from a set of points and vectors
the vectors describe the tangent vector at the corresponding point
- '''
+ """
# GeomAPI_Interpolate is buggy: need to use `fix` in order to
# get the right points in...
- assert len(list_of_points) == len(list_of_vectors), 'vector and point list not of same length'
-
+ assert len(list_of_points) == len(
+ list_of_vectors
+ ), "vector and point list not of same length"
+
def fix(li, _type):
- '''function factory for 1-dimensional TCol* types'''
+ """function factory for 1-dimensional TCol* types"""
pts = _type(1, len(li))
for n, i in enumerate(li):
- pts.SetValue(n+1,i)
+ pts.SetValue(n + 1, i)
pts.thisown = False
return pts
- if not vector_mask == []:
- assert len(vector_mask) == len(list_of_points), 'length vector mask is not of length points list nor []'
+ if vector_mask is not None:
+ assert len(vector_mask) == len(
+ list_of_points
+ ), "length vector mask is not of length points list nor []"
else:
vector_mask = [True for i in range(len(list_of_points))]
@@ -200,95 +251,101 @@ def fix(li, _type):
fixed_vectors = fix(list_of_vectors, TColgp_Array1OfVec)
try:
- interp = GeomAPI_Interpolate(fixed_points.GetHandle(), False, tolerance)
- interp.Load(fixed_vectors, fixed_mask.GetHandle(), False)
+ interp = GeomAPI_Interpolate(fixed_points, False, tolerance)
+ interp.Load(fixed_vectors, fixed_mask, False)
interp.Perform()
if interp.IsDone():
return interp.Curve()
except RuntimeError:
# the exception was unclear
- raise RuntimeError('FAILED TO INTERPOLATE THE POINTS')
+ raise RuntimeError("FAILED TO INTERPOLATE THE POINTS")
-def interpolate_points_to_spline_no_tangency(list_of_points, filter=True, closed=False, tolerance=TOLERANCE):
- '''
+def interpolate_points_to_spline_no_tangency(
+ list_of_points, filter_pts=True, closed=False, tolerance=TOLERANCE
+):
+ """
GeomAPI_Interpolate is buggy: need to use `fix`
in order to get the right points in...
- '''
+ """
+
def fix(li, _type):
- '''function factory for 1-dimensional TCol* types'''
+ """function factory for 1-dimensional TCol* types"""
pts = _type(1, len(li))
- for n, i in enumerate(li):
- pts.SetValue(n+1, i)
+ for n, i in enumerate(li):
+ pts.SetValue(n + 1, i)
pts.thisown = False
return pts
- list_of_points = filter_points_by_distance(list_of_points, 0.1)
+ if filter_pts:
+ list_of_points = filter_points_by_distance(list_of_points, 0.1)
+
fixed_points = fix(list_of_points, TColgp_HArray1OfPnt)
try:
- interp = GeomAPI_Interpolate(fixed_points.GetHandle(), closed, tolerance)
+ interp = GeomAPI_Interpolate(fixed_points, closed, tolerance)
interp.Perform()
if interp.IsDone():
return interp.Curve()
except RuntimeError:
# the exception was unclear
- raise RuntimeError('FAILED TO INTERPOLATE THE POINTS')
+ raise RuntimeError("FAILED TO INTERPOLATE THE POINTS")
-#===========================================================================
+
+# ===========================================================================
# --- RANDOMNESS ---
-#===========================================================================
+# ===========================================================================
def random_vec():
- import random
x, y, z = [random.uniform(-1, 1) for i in range(3)]
return gp_Vec(x, y, z)
def random_colored_material_aspect():
- import random
- clrs = [i for i in dir(Graphic3d) if i.startswith('Graphic3d_NOM_')]
+ clrs = [i for i in dir(Graphic3d) if i.startswith("Graphic3d_NOM_")]
color = random.sample(clrs, 1)[0]
- print 'color', color
+ print("color", color)
return Graphic3d.Graphic3d_MaterialAspect(getattr(Graphic3d, color))
def random_color():
return color(random.random(), random.random(), random.random())
-#===========================================================================
+
+# ===========================================================================
# --- BUILD PATCHES ---
-#===========================================================================
+# ===========================================================================
def common_vertex(edg1, edg2):
- from OCC.TopExp import topexp_CommonVertex
+ from OCC.Core.TopExp import topexp_CommonVertex
+
vert = TopoDS_Vertex()
if topexp_CommonVertex(edg1, edg2, vert):
return vert
else:
- raise ValueError('no common vertex found')
+ raise ValueError("no common vertex found")
def midpoint(pntA, pntB):
- '''
+ """
computes the point that lies in the middle between pntA and pntB
@param pntA: gp_Pnt
@param pntB: gp_Pnt
- '''
+ """
vec1 = gp_Vec(pntA.XYZ())
vec2 = gp_Vec(pntB.XYZ())
- veccie = (vec1+vec2)/2.
+ veccie = (vec1 + vec2) / 2.0
return gp_Pnt(veccie.XYZ())
def center_boundingbox(shape):
- '''
+ """
compute the center point of a TopoDS_Shape, based on its bounding box
@param shape: TopoDS_* instance
returns a gp_Pnt instance
- '''
+ """
xmin, ymin, zmin, xmax, ymax, zmax = get_boundingbox(shape, 1e-6)
return midpoint(gp_Pnt(xmin, ymin, zmin), gp_Pnt(xmax, ymax, zmax))
@@ -304,8 +361,8 @@ def point_in_boundingbox(solid, pnt, tolerance=1e-5):
"""
bbox = Bnd_Box()
bbox.SetGap(tolerance)
- tmp = brepbndlib_Add(solid, bbox)
- return not(bbox.IsOut(pnt))
+ brepbndlib_Add(solid, bbox)
+ return not bbox.IsOut(pnt)
def point_in_solid(solid, pnt, tolerance=1e-5):
@@ -316,39 +373,42 @@ def point_in_solid(solid, pnt, tolerance=1e-5):
Returns: bool
"""
- from OCC.BRepClass3d import BRepClass3d_SolidClassifier
- from OCC.TopAbs import TopAbs_ON, TopAbs_OUT, TopAbs_IN
+ from OCC.Core.BRepClass3d import BRepClass3d_SolidClassifier
+ from OCC.Core.TopAbs import TopAbs_ON, TopAbs_OUT, TopAbs_IN
+
_in_solid = BRepClass3d_SolidClassifier(solid, pnt, tolerance)
- print 'STATE', _in_solid.State()
+ print("State", _in_solid.State())
if _in_solid.State() == TopAbs_ON:
- return None, 'on'
+ return None, "on"
if _in_solid.State() == TopAbs_OUT:
- return False, 'out'
+ return False, "out"
if _in_solid.State() == TopAbs_IN:
- return True, 'in'
+ return True, "in"
def intersection_from_three_planes(planeA, planeB, planeC):
- '''
+ """
intersection from 3 planes
accepts both Geom_Plane and gp_Pln
@param planeA:
@param planeB:
@param planeC:
@param show:
- '''
- from OCC.IntAna import IntAna_Int3Pln
+ """
+ from OCC.Core.IntAna import IntAna_Int3Pln
- planeA = planeA if not hasattr(planeA, 'Pln') else planeA.Pln()
- planeB = planeB if not hasattr(planeB, 'Pln') else planeB.Pln()
- planeC = planeC if not hasattr(planeC, 'Pln') else planeC.Pln()
+ planeA = planeA if not hasattr(planeA, "Pln") else planeA.Pln()
+ planeB = planeB if not hasattr(planeB, "Pln") else planeB.Pln()
+ planeC = planeC if not hasattr(planeC, "Pln") else planeC.Pln()
intersection_planes = IntAna_Int3Pln(planeA, planeB, planeC)
pnt = intersection_planes.Value()
return pnt
-def intersect_shape_by_line(topods_shape, line, low_parameter=0.0, hi_parameter=float("+inf")):
+def intersect_shape_by_line(
+ topods_shape, line, low_parameter=0.0, hi_parameter=float("+inf")
+):
"""
finds the intersection of a shape and a line
@@ -364,83 +424,85 @@ def intersect_shape_by_line(topods_shape, line, low_parameter=0.0, hi_parameter=
and the u,v,w parameters of the intersection point
:raise:
"""
- from OCC.IntCurvesFace import IntCurvesFace_ShapeIntersector
+ from OCC.Core.IntCurvesFace import IntCurvesFace_ShapeIntersector
+
shape_inter = IntCurvesFace_ShapeIntersector()
shape_inter.Load(topods_shape, TOLERANCE)
shape_inter.PerformNearest(line, low_parameter, hi_parameter)
with assert_isdone(shape_inter, "failed to computer shape / line intersection"):
- return (shape_inter.Pnt(1),
- shape_inter.Face(1),
- shape_inter.UParameter(1),
- shape_inter.VParameter(1),
- shape_inter.WParameter(1))
-
-#===========================================================================
-# --- TRANSFORM ---
-#===========================================================================
-
-
-def translate_topods_from_vector(brep, vec, copy=False):
- '''
- translate a brep over a vector
- @param brep: the Topo_DS to translate
- @param vec: the vector defining the translation
- @param copy: copies to brep if True
- '''
- trns = gp_Trsf()
- trns.SetTranslation(vec)
- brep_trns = BRepBuilderAPI_Transform(brep, trns, copy)
- brep_trns.Build()
- return brep_trns.Shape()
-
-
-def normal_vector_from_plane(plane, vec_length=1):
- '''
+ return (
+ shape_inter.Pnt(1),
+ shape_inter.Face(1),
+ shape_inter.UParameter(1),
+ shape_inter.VParameter(1),
+ shape_inter.WParameter(1),
+ )
+
+
+def normal_vector_from_plane(plane, vec_length=1.0):
+ """
returns a vector normal to the plane of length vec_length
@param plane:
- '''
+ """
trns = gp_Vec(plane.Axis().Direction())
- trns.Normalized() * vec_length
- return trns
+ return trns.Normalized() * vec_length
+
-#===========================================================================
+# ===========================================================================
# FIX
-#===========================================================================
+# ===========================================================================
def fix_tolerance(shape, tolerance=TOLERANCE):
- from OCC.ShapeFix import ShapeFix_ShapeTolerance
+ from OCC.Core.ShapeFix import ShapeFix_ShapeTolerance
+
ShapeFix_ShapeTolerance().SetTolerance(shape, tolerance)
def fix_continuity(edge, continuity=1):
- from OCC.ShapeUpgrade import ShapeUpgrade_ShapeDivideContinuity
+ from OCC.Core.ShapeUpgrade import ShapeUpgrade_ShapeDivideContinuity
+
su = ShapeUpgrade_ShapeDivideContinuity(edge)
- su.SetBoundaryCriterion(eval('GeomAbs_C'+str(continuity)))
+ su.SetBoundaryCriterion(eval("GeomAbs_C" + str(continuity)))
su.Perform()
te = st(su.Result())
return te
-def resample_curve_with_uniform_deflection(curve, deflection=0.5, degreeMin=3, degreeMax=8, continuity=GeomAbs_C2, tolerance=1e-4):
- '''
+def resample_curve_with_uniform_deflection(
+ curve,
+ deflection=0.5,
+ degreeMin=3,
+ degreeMax=8,
+ continuity=GeomAbs_C2,
+ tolerance=1e-4,
+):
+ """
fits a bspline through the samples on `curve`
@param curve: TopoDS_Wire, TopoDS_Edge, curve
@param n_samples:
- '''
- from OCC.GCPnts import GCPnts_UniformDeflection
+ """
+ from OCC.Core.GCPnts import GCPnts_UniformDeflection
+
crv = to_adaptor_3d(curve)
defl = GCPnts_UniformDeflection(crv, deflection)
- with assert_isdone(defl, 'failed to compute UniformDeflection'):
- print 'number of points:', defl.NbPoints()
- sampled_pnts = [defl.Value(i) for i in xrange(1, defl.NbPoints())]
- resampled_curve = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(sampled_pnts), degreeMin, degreeMax, continuity, tolerance)
+ with assert_isdone(defl, "failed to compute UniformDeflection"):
+ print("Number of points:", defl.NbPoints())
+ sampled_pnts = [defl.Value(i) for i in range(1, defl.NbPoints())]
+ resampled_curve = GeomAPI_PointsToBSpline(
+ point_list_to_TColgp_Array1OfPnt(sampled_pnts),
+ degreeMin,
+ degreeMax,
+ continuity,
+ tolerance,
+ )
return resampled_curve.Curve().GetObject()
-#===========================================================================
+
+# ===========================================================================
# global properties
-#===========================================================================
+# ===========================================================================
class GpropsFromShape(object):
@@ -449,42 +511,40 @@ def __init__(self, shape, tolerance=1e-5):
self.tolerance = tolerance
def volume(self):
- '''returns the volume of a solid
- '''
+ """returns the volume of a solid"""
prop = GProp_GProps()
- error = brepgprop_VolumeProperties(self.shape, prop, self.tolerance)
+ brepgprop_VolumeProperties(self.shape, prop, self.tolerance)
return prop
def surface(self):
- '''returns the area of a surface
- '''
+ """returns the area of a surface"""
prop = GProp_GProps()
- error = brepgprop_SurfaceProperties(self.shape, prop, self.tolerance)
+ brepgprop_SurfaceProperties(self.shape, prop, self.tolerance)
return prop
def linear(self):
- '''returns the length of a wire or edge
- '''
+ """returns the length of a wire or edge"""
prop = GProp_GProps()
- error = brepgprop_LinearProperties(self.shape, prop)
+ brepgprop_LinearProperties(self.shape, prop)
return prop
def curve_length(crv):
- '''
+ """
get the length from a TopoDS_Edge or TopoDS_Wire
- '''
- assert isinstance(crv, (TopoDS_Wire, TopoDS_Edge)), 'either a wire or edge...'
+ """
+ assert isinstance(crv, (TopoDS_Wire, TopoDS_Edge)), "either a wire or edge..."
gprop = GpropsFromShape(crv)
return gprop.linear().Mass()
-#=======================================================================
+# =======================================================================
# Distance
-#=======================================================================
+# =======================================================================
+
def minimum_distance(shp1, shp2):
- '''
+ """
compute minimum distance between 2 BREP's
@param shp1: any TopoDS_*
@param shp2: any TopoDS_*
@@ -492,95 +552,113 @@ def minimum_distance(shp1, shp2):
@return: minimum distance,
minimum distance points on shp1
minimum distance points on shp2
- '''
- from OCC.BRepExtrema import BRepExtrema_DistShapeShape
+ """
+ from OCC.Core.BRepExtrema import BRepExtrema_DistShapeShape
+
bdss = BRepExtrema_DistShapeShape(shp1, shp2)
bdss.Perform()
- with assert_isdone(bdss, 'failed computing minimum distances'):
+ with assert_isdone(bdss, "failed computing minimum distances"):
min_dist = bdss.Value()
min_dist_shp1, min_dist_shp2 = [], []
- for i in range(1, bdss.NbSolution()+1):
+ for i in range(1, bdss.NbSolution() + 1):
min_dist_shp1.append(bdss.PointOnShape1(i))
min_dist_shp2.append(bdss.PointOnShape2(i))
return min_dist, min_dist_shp1, min_dist_shp2
def vertex2pnt(vertex):
- '''returns a gp_Pnt from a TopoDS_Vertex
- '''
- from OCC.BRep import BRep_Tool
+ """returns a gp_Pnt from a TopoDS_Vertex"""
+ from OCC.Core.Core.BRep import BRep_Tool
+
return BRep_Tool.Pnt(vertex)
+def adapt_edge_to_curve(edg):
+ """
+ returns a curve adaptor from an edge
+ @param edg: TopoDS_Edge
+ """
+ return BRepAdaptor_Curve(edg)
+
+
+def adapt_edge_to_hcurve(edg):
+ c = BRepAdaptor_Curve()
+ c.ChangeCurve().Initialize(edg)
+ return c
+
+
def to_adaptor_3d(curveType):
- '''
+ """
abstract curve like type into an adaptor3d
@param curveType:
- '''
- from OCC.BRepAdaptor import BRepAdaptor_CompCurve
- from OCC.GeomAdaptor import GeomAdaptor_Curve
- from OCC.Geom import Geom_Curve
+ """
if isinstance(curveType, TopoDS_Wire):
return BRepAdaptor_CompCurve(curveType)
elif isinstance(curveType, TopoDS_Edge):
return BRepAdaptor_Curve(curveType)
elif issubclass(curveType.__class__, Geom_Curve):
- return GeomAdaptor_Curve(curveType.GetHandle())
- elif hasattr(curveType, 'GetObject'):
+ return GeomAdaptor_Curve(curveType)
+ elif hasattr(curveType, "GetObject"):
_crv = curveType.GetObject()
if issubclass(_crv.__class__, Geom_Curve):
return GeomAdaptor_Curve(curveType)
else:
- raise TypeError('allowed types are Wire, Edge or a subclass of Geom_Curve\nGot a %s' % (curveType.__class__))
+ raise TypeError(
+ "allowed types are Wire, Edge or a subclass of Geom_Curve\nGot a %s"
+ % (curveType.__class__)
+ )
def project_point_on_curve(crv, pnt):
if isinstance(crv, TopoDS_Shape):
- # get the curve handle...
+ # get the curve
crv = adapt_edge_to_curve(crv).Curve().Curve()
else:
- raise NotImplementedError('expected a TopoDS_Edge...')
- from OCC.GeomAPI import GeomAPI_ProjectPointOnCurve
+ raise NotImplementedError("expected a TopoDS_Edge...")
rrr = GeomAPI_ProjectPointOnCurve(pnt, crv)
return rrr.LowerDistanceParameter(), rrr.NearestPoint()
def project_point_on_plane(plane, point):
- '''
+ """
project point on plane
@param plane: Geom_Plane
@param point: gp_Pnt
- '''
- from OCC.ProjLib import projlib_Project
+ """
+ from OCC.Core.ProjLib import projlib_Project
+
pl = plane.Pln()
aa, bb = projlib_Project(pl, point).Coord()
point = plane.Value(aa, bb)
return point
-def wire_to_curve(wire, tolerance=TOLERANCE, order=GeomAbs_C2, max_segment=200, max_order=12):
- '''
+def wire_to_curve(
+ wire, tolerance=TOLERANCE, order=GeomAbs_C2, max_segment=200, max_order=12
+):
+ """
a wire can consist of many edges.
these edges are merged given a tolerance and a curve
@param wire:
- '''
+ """
adap = BRepAdaptor_CompCurve(wire)
- hadap = BRepAdaptor_HCompCurve(adap)
- from OCC.Approx import Approx_Curve3d
- approx = Approx_Curve3d(hadap.GetHandle(), tolerance, order, max_segment, max_order)
- with assert_isdone(approx, 'not able to compute approximation from wire'):
+ hadap = BRepAdaptor_CompCurve(adap)
+ from OCC.Core.Approx import Approx_Curve3d
+
+ approx = Approx_Curve3d(hadap, tolerance, order, max_segment, max_order)
+ with assert_isdone(approx, "not able to compute approximation from wire"):
return approx.Curve().GetObject()
def adapt_edge_to_curve(edg):
- '''
+ """
returns a curve adaptor from an edge
@param edg: TopoDS_Edge
- '''
+ """
return BRepAdaptor_Curve(edg)
def adapt_edge_to_hcurve(edg):
- c = BRepAdaptor_HCurve()
+ c = BRepAdaptor_Curve()
c.ChangeCurve().Initialize(edg)
return c
diff --git a/OCCUtils/Construct.py b/OCCUtils/Construct.py
index cab3d13..4e9587b 100644
--- a/OCCUtils/Construct.py
+++ b/OCCUtils/Construct.py
@@ -17,34 +17,82 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see .
-'''
+"""
This modules makes the construction of geometry a little easier
-'''
+"""
from __future__ import with_statement
from functools import wraps
import warnings
-
-from OCC.BRep import BRep_Tool
-from OCC.BRepOffset import BRepOffset_Skin
-from OCC.Geom import Geom_TrimmedCurve
-from OCC.GeomConvert import GeomConvert_ApproxCurve
-from OCC.GeomLProp import *
-from OCC.BRepBuilderAPI import *
-from OCC.BRepPrimAPI import *
-from OCC.BRepOffsetAPI import BRepOffsetAPI_MakeEvolved
-from OCC.GeomAbs import *
-from OCC.TopAbs import *
-from OCC.TopoDS import *
-from OCC.gp import *
-
-from Common import *
-from Context import assert_isdone
-from types_lut import ShapeToTopology
-
import operator
import math
+from OCC.Core.BRep import BRep_Tool
+from OCC.Core.BRepAdaptor import BRepAdaptor_Curve
+from OCC.Core.BRepOffset import BRepOffset_Skin
+from OCC.Core.Geom import Geom_TrimmedCurve
+from OCC.Core.GeomConvert import GeomConvert_ApproxCurve
+from OCC.Core.GeomLProp import GeomLProp_SLProps
+from OCC.Core.BRepBuilderAPI import (
+ BRepBuilderAPI_MakeFace,
+ BRepBuilderAPI_Transform,
+ BRepBuilderAPI_Sewing,
+ BRepBuilderAPI_MakePolygon,
+ BRepBuilderAPI_MakeWire,
+ BRepBuilderAPI_MakeSolid,
+ BRepBuilderAPI_MakeShell,
+ BRepBuilderAPI_MakeEdge2d,
+ BRepBuilderAPI_MakeEdge,
+ BRepBuilderAPI_MakeVertex,
+ BRepBuilderAPI_FindPlane,
+)
+from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakePrism
+from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakeEvolved
+from OCC.Core.GeomAbs import (
+ GeomAbs_Arc,
+ GeomAbs_C2,
+ GeomAbs_C0,
+ GeomAbs_Tangent,
+ GeomAbs_Intersection,
+ GeomAbs_G1,
+ GeomAbs_G2,
+ GeomAbs_C1,
+)
+from OCC.Core.TopAbs import TopAbs_REVERSED
+from OCC.Core.TopoDS import (
+ TopoDS_Wire,
+ TopoDS_Solid,
+ TopoDS_Vertex,
+ TopoDS_Shape,
+ TopoDS_Builder,
+ TopoDS_Compound,
+)
+from OCC.Core.TColgp import TColgp_SequenceOfVec, TColgp_HArray1OfPnt
+from OCC.Core.gp import (
+ gp_Vec,
+ gp_Pnt,
+ gp_Dir,
+ gp_Trsf,
+ gp_Ax1,
+ gp_Quaternion,
+ gp_Circ,
+ gp_Pln,
+)
+
+from OCCUtils.Common import (
+ TOLERANCE,
+ assert_isdone,
+ to_tcol_,
+ to_adaptor_3d,
+ vertex2pnt,
+ smooth_pnts,
+ points_to_bspline,
+ project_point_on_curve,
+)
+from OCCUtils.types_lut import ShapeToTopology
+from OCCUtils.Topology import Topo
+
+
EPSILON = TOLERANCE = 1e-6
ST = ShapeToTopology()
@@ -70,18 +118,18 @@ def add_vector_to_point(self, vec):
def gp_Pnt_get_state(self):
- '''pack as a tuple
+ """pack as a tuple
used for copying / serializing the instance
- '''
+ """
return self.XYZ().Coord()
def gp_Pnt_set_state(self, state):
- '''unpack tuple and return instance...
+ """unpack tuple and return instance...
used for copying / serializing the instance
- '''
+ """
self.__init__(*state)
@@ -93,7 +141,7 @@ def gp_pnt_print(self):
x = self.X()
y = self.Y()
z = self.Z()
- return '< gp_Pnt: {0}, {1}, {2} >'.format(x, y, z)
+ return "< gp_Pnt: {0}, {1}, {2} >".format(x, y, z)
def gp_vec_print(self):
@@ -101,13 +149,15 @@ def gp_vec_print(self):
y = self.Y()
z = self.Z()
magn = self.Magnitude()
- return '< gp_Vec: {0}, {1}, {2}, magnitude: {3} >'.format(x, y, z, magn)
+ return "< gp_Vec: {0}, {1}, {2}, magnitude: {3} >".format(x, y, z, magn)
def gp_ax1_print(self):
pX, pY, pZ = self.Location().Coord()
dX, dY, dZ = self.Direction().Coord()
- return "< gp_Ax1: location: {pX}, {pY}, {pZ}, direction: {dX}, {dY}, {dZ} >".format(**vars())
+ return "< gp_Ax1: location: {pX}, {pY}, {pZ}, direction: {dX}, {dY}, {dZ} >".format(
+ **vars()
+ )
def gp_trsf_print(self):
@@ -115,14 +165,18 @@ def gp_trsf_print(self):
a, b, c, d = _f(1)
e, f, g, h = _f(2)
i, j, k, l = _f(3)
- return "< gp_Trsf:\n {a:.3f}, {b:.3f}, {c:.3f}, {d:.3f}\n {e:.3f}, {f:.3f}, {g:.3f}, {h:.3f}\n {i:.3f}, {j:.3f}, {k:.3f}, {l:.3f} >".format(**vars())
+ return "< gp_Trsf:\n {a:.3f}, {b:.3f}, {c:.3f}, {d:.3f}\n {e:.3f}, {f:.3f}, {g:.3f}, {h:.3f}\n {i:.3f}, {j:.3f}, {k:.3f}, {l:.3f} >".format(
+ **vars()
+ )
def gp_quat_print(self):
w, x, y, z = self.W(), self.X(), self.Y(), self.Z()
vec = gp_Vec()
angle = math.degrees(self.GetVectorAndAngle(vec))
- return "< gp_Quaternion: w:{w}, x:{x}, y:{y}, z:{z} >\nvector:{vec} angle:{angle}".format(**vars())
+ return "< gp_Quaternion: w:{w}, x:{x}, y:{y}, z:{z} >\nvector:{vec} angle:{angle}".format(
+ **vars()
+ )
def _apply(pnt, other, _operator):
@@ -172,23 +226,22 @@ def gp_pnt_div(self, other):
gp_Trsf.__str__ = gp_trsf_print
gp_Quaternion.__repr__ = gp_quat_print
gp_Quaternion.__str__ = gp_quat_print
-#gp_Pnt.__eq__ = gp_equal
+# gp_Pnt.__eq__ = gp_equal
gp_Pnt.__add__ = gp_pnt_add
gp_Pnt.__sub__ = gp_pnt_sub
gp_Pnt.__mul__ = gp_pnt_mul
gp_Pnt.__div__ = gp_pnt_div
-#===========================================================================
+# ===========================================================================
# ---TOPOLOGY---
-#===========================================================================
+# ===========================================================================
@wraps(BRepBuilderAPI_MakeSolid)
def make_solid(*args):
sld = BRepBuilderAPI_MakeSolid(*args)
- with assert_isdone(sld, 'failed to produce solid'):
+ with assert_isdone(sld, "failed to produce solid"):
result = sld.Solid()
- sld.Delete()
return result
@@ -196,45 +249,40 @@ def make_solid(*args):
def make_shell(*args):
shell = BRepBuilderAPI_MakeShell(*args)
st = ShapeToTopology()
- with assert_isdone(shell, 'failed to produce shell'):
+ with assert_isdone(shell, "failed to produce shell"):
result = shell.Shell()
- shell.Delete()
return st(result)
@wraps(BRepBuilderAPI_MakeFace)
def make_face(*args):
face = BRepBuilderAPI_MakeFace(*args)
- with assert_isdone(face, 'failed to produce face'):
+ with assert_isdone(face, "failed to produce face"):
result = face.Face()
- face.Delete()
return result
@wraps(BRepBuilderAPI_MakeEdge2d)
def make_edge2d(*args):
edge = BRepBuilderAPI_MakeEdge2d(*args)
- with assert_isdone(edge, 'failed to produce edge'):
+ with assert_isdone(edge, "failed to produce edge"):
result = edge.Edge()
- edge.Delete()
return result
@wraps(BRepBuilderAPI_MakeEdge)
def make_edge(*args):
edge = BRepBuilderAPI_MakeEdge(*args)
- with assert_isdone(edge, 'failed to produce edge'):
+ with assert_isdone(edge, "failed to produce edge"):
result = edge.Edge()
- edge.Delete()
return result
@wraps(BRepBuilderAPI_MakeVertex)
def make_vertex(*args):
vert = BRepBuilderAPI_MakeVertex(*args)
- with assert_isdone(vert, 'failed to produce vertex'):
+ with assert_isdone(vert, "failed to produce vertex"):
result = vert.Vertex()
- vert.Delete()
return result
@@ -243,15 +291,14 @@ def make_wire(*args):
# if we get an iterable, than add all edges to wire builder
if isinstance(args[0], list) or isinstance(args[0], tuple):
wire = BRepBuilderAPI_MakeWire()
- #from OCC.TopTools import TopTools_ListOfShape
for i in args[0]:
- wire.Add(i)
+ wire.Add(i)
wire.Build()
return wire.Wire()
wire = BRepBuilderAPI_MakeWire(*args)
wire.Build()
- with assert_isdone(wire, 'failed to produce wire'):
+ with assert_isdone(wire, "failed to produce wire"):
result = wire.Wire()
return result
@@ -270,7 +317,7 @@ def make_polygon(args, closed=False):
poly.Close()
poly.Build()
- with assert_isdone(poly, 'failed to produce wire'):
+ with assert_isdone(poly, "failed to produce wire"):
result = poly.Wire()
return result
@@ -286,21 +333,22 @@ def make_closed_polygon(*args):
poly.Add(pt)
poly.Build()
poly.Close()
- with assert_isdone(poly, 'failed to produce wire'):
+ with assert_isdone(poly, "failed to produce wire"):
result = poly.Wire()
return result
-#===========================================================================
+
+# ===========================================================================
# PRIMITIVES
-#===========================================================================
+# ===========================================================================
def make_circle(pnt, radius):
- '''
- returns an edge
+ """
+ returns an edge
@param pnt:
@param radius:
- '''
+ """
circ = gp_Circ()
circ.SetLocation(pnt)
circ.SetRadius(radius)
@@ -313,66 +361,65 @@ def make_line(pnt1, pnt2):
def make_evolved(spine, profile):
evol = BRepOffsetAPI_MakeEvolved(spine, profile)
- with assert_isdone(evol, 'failed buillding evolved'):
+ with assert_isdone(evol, "failed buillding evolved"):
evol.Build()
return evol.Evolved()
def make_pipe(spine, profile):
- from OCC.BRepOffsetAPI import BRepOffsetAPI_MakePipe
+ from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakePipe
+
pipe = BRepOffsetAPI_MakePipe(spine, profile)
- with assert_isdone(pipe, 'failed building pipe'):
+ with assert_isdone(pipe, "failed building pipe"):
pipe.Build()
return pipe.Shape()
def make_prism(profile, vec):
- '''
+ """
makes a finite prism
- '''
- pri = BRepPrimAPI_MakePrism(profile, vec, True)
- with assert_isdone(pri, 'failed building prism'):
+ """
+ pri = BRepPrimAPI_MakePrism(profile, vec, True)
+ with assert_isdone(pri, "failed building prism"):
pri.Build()
return pri.Shape()
-def make_prism_shell(profile, vec):
- '''
- makes a finite prism
- '''
- from OCC.BRepOffsetAPI import BRepOffsetAPI_MakePipeShell
- return BRepOffsetAPI_MakePipeShell()
-
-
-def make_offset_shape(shapeToOffset, offsetDistance, tolerance=TOLERANCE,
- offsetMode=BRepOffset_Skin, intersection=False,
- selfintersection=False, joinType=GeomAbs_Arc):
- # TODO: refactor assert_isdone
- '''
+def make_offset_shape(
+ shapeToOffset,
+ offsetDistance,
+ tolerance=TOLERANCE,
+ offsetMode=BRepOffset_Skin,
+ intersection=False,
+ selfintersection=False,
+ joinType=GeomAbs_Arc,
+):
+ """
builds an offsetted shell from a shape
construct an offsetted version of the shape
- '''
- from OCC.BRepOffsetAPI import BRepOffsetAPI_MakeOffsetShape
+ """
+ from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakeOffsetShape
+
try:
- offset = BRepOffsetAPI_MakeOffsetShape(shapeToOffset,
- offsetDistance,
- tolerance,
- offsetMode,
- intersection,
- selfintersection,
- joinType
- )
+ offset = BRepOffsetAPI_MakeOffsetShape(
+ shapeToOffset,
+ offsetDistance,
+ tolerance,
+ offsetMode,
+ intersection,
+ selfintersection,
+ joinType,
+ )
if offset.IsDone():
return offset.Shape()
else:
return None
- except RuntimeError('failed to offset shape'):
+ except RuntimeError("failed to offset shape"):
return None
def make_offset(wire_or_face, offsetDistance, altitude=0, joinType=GeomAbs_Arc):
- # TODO: refactor assert_isdone
- '''
+ """
builds a offsetted wire or face from a wire or face
construct an offsetted version of the shape
@@ -385,10 +432,11 @@ def make_offset(wire_or_face, offsetDistance, altitude=0, joinType=GeomAbs_Arc):
note: a shape that has a negative offsetDistance will return
a sharp corner
- '''
- from OCC.BRepOffsetAPI import BRepOffsetAPI_MakeOffset
+ """
+ from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakeOffset
+
_joints = [GeomAbs_Arc, GeomAbs_Tangent, GeomAbs_Intersection]
- assert joinType in _joints, '%s is not one of %s' % (joinType, _joints)
+ assert joinType in _joints, "%s is not one of %s" % (joinType, _joints)
try:
offset = BRepOffsetAPI_MakeOffset(wire_or_face, joinType)
offset.Perform(offsetDistance, altitude)
@@ -396,26 +444,19 @@ def make_offset(wire_or_face, offsetDistance, altitude=0, joinType=GeomAbs_Arc):
return ST(offset.Shape())
else:
return None
- except RuntimeError('failed to offset shape'):
+ except RuntimeError("failed to offset shape"):
return None
-def make_draft(profile, vec):
- '''
- makes a finite prism
- '''
- raise NotImplementedError
-
+def make_loft(
+ elements,
+ ruled=False,
+ tolerance=TOLERANCE,
+ continuity=GeomAbs_C2,
+ check_compatibility=True,
+):
+ from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_ThruSections
-def make_filling(profile, vec):
- '''
- makes a n-sided patch from constraints
- '''
- raise NotImplementedError
-
-
-def make_loft(elements, ruled=False, tolerance=TOLERANCE, continuity=GeomAbs_C2, check_compatibility=True):
- from OCC.BRepOffsetAPI import BRepOffsetAPI_ThruSections
sections = BRepOffsetAPI_ThruSections(False, ruled, tolerance)
for i in elements:
if isinstance(i, TopoDS_Wire):
@@ -423,43 +464,39 @@ def make_loft(elements, ruled=False, tolerance=TOLERANCE, continuity=GeomAbs_C2,
elif isinstance(i, TopoDS_Vertex):
sections.AddVertex(i)
else:
- raise TypeError('elements is a list of TopoDS_Wire or TopoDS_Vertex, found a %s fool' % ( i.__class__ ))
+ raise TypeError(
+ "elements is a list of TopoDS_Wire or TopoDS_Vertex, found a %s fool"
+ % i.__class__
+ )
sections.CheckCompatibility(check_compatibility)
sections.SetContinuity(continuity)
sections.Build()
- with assert_isdone(sections, 'failed lofting'):
+ with assert_isdone(sections, "failed lofting"):
te = ShapeToTopology()
loft = te(sections.Shape())
return loft
def make_ruled(edgeA, edgeB):
- from OCC.BRepFill import brepfill_Face
- return brepfill_Face(edgeA, edgeB)
+ from OCC.Core.BRepFill import brepfill_Face
-#===========================================================================
-# ---CONVENIENCE---
-#===========================================================================
+ return brepfill_Face(edgeA, edgeB)
-def make_plane(center=gp_Pnt(0,0,0),
- vec_normal=gp_Vec(0,0,1),
- extent_x_min=-100.,
- extent_x_max=100.,
- extent_y_min=-100.,
- extent_y_max=100.,
- depth=0.
- ):
+def make_plane(
+ center=gp_Pnt(0, 0, 0),
+ vec_normal=gp_Vec(0, 0, 1),
+ extent_x_min=-100.0,
+ extent_x_max=100.0,
+ extent_y_min=-100.0,
+ extent_y_max=100.0,
+ depth=0.0,
+):
if depth != 0:
- P1 = center.add_vec(gp_Vec(0, 0, depth))
+ center = center.add_vec(gp_Vec(0, 0, depth))
PL = gp_Pln(center, vec_normal.as_dir())
- face = make_face(PL,
- extent_x_min,
- extent_x_max,
- extent_y_min,
- extent_y_max,
- )
+ face = make_face(PL, extent_x_min, extent_x_max, extent_y_min, extent_y_max)
return face
@@ -475,13 +512,17 @@ def make_oriented_box(v_corner, v_x, v_y, v_z):
:param v_z: gp_Vec that describes the Z-axis
:return: TopoDS_Solid
"""
- from OCC.BRepOffsetAPI import BRepOffsetAPI_MakePipe
- verts = map(lambda x: x.as_pnt(), [v_corner, v_corner+v_x, v_corner+v_x+v_y, v_corner+v_y])
+ from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakePipe
+
+ verts = map(
+ lambda x: x.as_pnt(),
+ [v_corner, v_corner + v_x, v_corner + v_x + v_y, v_corner + v_y],
+ )
p = make_polygon(verts, closed=True)
- li = make_line(v_corner.as_pnt(), (v_corner+v_z).as_pnt())
- ooo = BRepOffsetAPI_MakePipe(p, li)
- ooo.Build()
- shp = ooo.Shape()
+ li = make_line(v_corner.as_pnt(), (v_corner + v_z).as_pnt())
+ bmp = BRepOffsetAPI_MakePipe(p, li)
+ bmp.Build()
+ shp = bmp.Shape()
bottom = make_face(p)
top = translate_topods_from_vector(bottom, v_z, True)
@@ -493,26 +534,10 @@ def make_oriented_box(v_corner, v_x, v_y, v_z):
def make_box(*args):
box = BRepPrimAPI_MakeBox(*args)
box.Build()
- with assert_isdone(box, 'failed to built a cube...'):
+ with assert_isdone(box, "failed to built a cube..."):
return box.Shape()
-def make_spline(pnts=[''], tangents=[''], epsilon=EPSILON):
- '''
- @param pnts: list_of_gp_Pnts
- @param tangents: list_of_tangent_vecs_at_gp_Pnts
- None where we do not care about tangency
- None or empty list if we don't care about tangency at all
- @param epsilon: tolerence
- '''
- raise NotImplementedError
-
-
-#===========================================================================
-# NEW
-#===========================================================================
-
-
def make_n_sided(edges, points, continuity=GeomAbs_C0):
"""
builds an n-sided patch, respecting the constraints defined by *edges*
@@ -538,7 +563,8 @@ def make_n_sided(edges, points, continuity=GeomAbs_C0):
:param continuity: GeomAbs_0, 1, 2
:return: TopoDS_Face
"""
- from OCC.BRepFill import BRepFill_Filling
+ from OCC.Core.BRepFill import BRepFill_Filling
+
n_sided = BRepFill_Filling()
for edg in edges:
n_sided.Add(edg, continuity)
@@ -550,8 +576,9 @@ def make_n_sided(edges, points, continuity=GeomAbs_C0):
def make_n_sections(edges):
- from OCC.TopTools import TopTools_SequenceOfShape
- from OCC.BRepFill import BRepFill_NSections
+ from OCC.Core.TopTools import TopTools_SequenceOfShape
+ from OCC.Core.BRepFill import BRepFill_NSections
+
seq = TopTools_SequenceOfShape()
for i in edges:
seq.Append(i)
@@ -561,7 +588,7 @@ def make_n_sections(edges):
def make_coons(edges):
from OCC.GeomFill import GeomFill_BSplineCurves, GeomFill_StretchStyle
- bt = BRep_Tool()
+
if len(edges) == 4:
spl1, spl2, spl3, spl4 = edges
srf = GeomFill_BSplineCurves(spl1, spl2, spl3, spl4, GeomFill_StretchStyle)
@@ -572,51 +599,46 @@ def make_coons(edges):
spl1, spl2 = edges
srf = GeomFill_BSplineCurves(spl1, spl2, GeomFill_StretchStyle)
else:
- raise ValueError('give 2,3 or 4 curves')
+ raise ValueError("give 2,3 or 4 curves")
return srf.Surface()
def make_constrained_surface_from_edges(edges):
- '''
+ """
DOESNT RESPECT BOUNDARIES
- '''
- from OCC.BRepAdaptor import BRepAdaptor_HCurve
+ """
from OCC.GeomPlate import GeomPlate_MakeApprox, GeomPlate_BuildPlateSurface
- from OCC.BRepFill import BRepFill_CurveConstraint
+ from OCC.Core.BRepFill import BRepFill_CurveConstraint
+
bpSrf = GeomPlate_BuildPlateSurface(3, 15, 2)
for edg in edges:
- c = BRepAdaptor_HCurve()
+ c = BRepAdaptor_Curve()
c.ChangeCurve().Initialize(edg)
- constraint = BRepFill_CurveConstraint(c.GetHandle(), 0)
- bpSrf.Add(constraint.GetHandle())
+ constraint = BRepFill_CurveConstraint(c, 0)
+ bpSrf.Add(constraint)
bpSrf.Perform()
maxSeg, maxDeg, critOrder = 9, 8, 0
tol = 1e-4
srf = bpSrf.Surface()
plate = GeomPlate_MakeApprox(srf, tol, maxSeg, maxDeg, tol, critOrder)
- uMin, uMax, vMin, vMax = srf.GetObject().Bounds()
+ uMin, uMax, vMin, vMax = srf.Bounds()
face = make_face(plate.Surface(), uMin, uMax, vMin, vMax)
return face
-#===========================================================================
-# NEW
-#===========================================================================
-
def add_wire_to_face(face, wire, reverse=False):
- '''
+ """
apply a wire to a face
use reverse to set the orientation of the wire to opposite
@param face:
@param wire:
@param reverse:
- '''
+ """
face = BRepBuilderAPI_MakeFace(face)
if reverse:
wire.Reverse()
face.Add(wire)
result = face.Face()
- face.Delete()
return result
@@ -629,44 +651,49 @@ def sew_shapes(shapes, tolerance=0.001):
else:
sew.Add(shp)
sew.Perform()
- print 'n degenerated shapes', sew.NbDegeneratedShapes()
- print 'n deleted faces:', sew.NbDeletedFaces()
- print 'n free edges', sew.NbFreeEdges()
- print 'n multiple edges:', sew.NbMultipleEdges()
+ print("n degenerated shapes", sew.NbDegeneratedShapes())
+ print("n deleted faces:", sew.NbDeletedFaces())
+ print("n free edges", sew.NbFreeEdges())
+ print("n multiple edges:", sew.NbMultipleEdges())
result = ShapeToTopology()(sew.SewedShape())
return result
-#===========================================================================
+
+# ===========================================================================
# ---BOOL---
-#===========================================================================
+# ===========================================================================
+
def boolean_cut(shapeToCutFrom, cuttingShape):
- from OCC.BRepAlgoAPI import BRepAlgoAPI_Cut
+ from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut
+
try:
cut = BRepAlgoAPI_Cut(shapeToCutFrom, cuttingShape)
- print 'can work?', cut.BuilderCanWork()
- _error = {0: '- Ok',
- 1: '- The Object is created but Nothing is Done',
- 2: '- Null source shapes is not allowed',
- 3: '- Check types of the arguments',
- 4: '- Can not allocate memory for the DSFiller',
- 5: '- The Builder can not work with such types of arguments',
- 6: '- Unknown operation is not allowed',
- 7: '- Can not allocate memory for the Builder',
- }
- print 'error status:', _error[cut.ErrorStatus()]
+ print("Can work?", cut.BuilderCanWork())
+ _error = {
+ 0: "- Ok",
+ 1: "- The Object is created but Nothing is Done",
+ 2: "- Null source shapes is not allowed",
+ 3: "- Check types of the arguments",
+ 4: "- Can not allocate memory for the DSFiller",
+ 5: "- The Builder can not work with such types of arguments",
+ 6: "- Unknown operation is not allowed",
+ 7: "- Can not allocate memory for the Builder",
+ }
+ print("Error status:", _error[cut.ErrorStatus()])
cut.RefineEdges()
cut.FuseEdges()
shp = cut.Shape()
cut.Destroy()
return shp
except:
- print 'FAILED TO BOOLEAN CUT'
+ print("Failed to boolean cut")
return shapeToCutFrom
def boolean_fuse(shapeToCutFrom, joiningShape):
- from OCC.BRepAlgoAPI import BRepAlgoAPI_Fuse
+ from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Fuse
+
join = BRepAlgoAPI_Fuse(shapeToCutFrom, joiningShape)
join.RefineEdges()
join.FuseEdges()
@@ -676,35 +703,37 @@ def boolean_fuse(shapeToCutFrom, joiningShape):
def trim_wire(wire, shapeLimit1, shapeLimit2, periodic=False):
- '''return the trimmed wire that lies between `shapeLimit1`
+ """return the trimmed wire that lies between `shapeLimit1`
and `shapeLimit2`
returns TopoDS_Edge
- '''
+ """
adap = to_adaptor_3d(wire)
bspl = adap.BSpline()
if periodic:
- spl = bspl.GetObject()
- if spl.IsClosed():
- spl.SetPeriodic()
+ if bspl.IsClosed():
+ bspl.SetPeriodic()
else:
- warnings.warn('the wire to be trimmed is not closed, hence cannot be made periodic')
+ warnings.warn(
+ "the wire to be trimmed is not closed, hence cannot be made periodic"
+ )
p1 = project_point_on_curve(bspl, shapeLimit1)[0]
p2 = project_point_on_curve(bspl, shapeLimit2)[0]
a, b = sorted([p1, p2])
- tr = Geom_TrimmedCurve(bspl, a, b).GetHandle()
+ tr = Geom_TrimmedCurve(bspl, a, b)
return make_edge(tr)
-#===========================================================================
+
+# ===========================================================================
# ---FIXES---
-#===========================================================================
+# ===========================================================================
def fix_shape(shp, tolerance=1e-3):
from OCC.ShapeFix import ShapeFix_Shape
- te = ShapeToTopology()
+
fix = ShapeFix_Shape(shp)
fix.SetFixFreeShellMode(True)
- sf = fix.FixShellTool().GetObject()
+ sf = fix.FixShellTool()
sf.SetFixOrientationMode(True)
fix.LimitTolerance(tolerance)
fix.Perform()
@@ -713,23 +742,25 @@ def fix_shape(shp, tolerance=1e-3):
def fix_face(shp, tolerance=1e-3):
from OCC.ShapeFix import ShapeFix_Face
+
fix = ShapeFix_Face(shp)
fix.SetMaxTolerance(tolerance)
fix.Perform()
return fix.Face()
-#===========================================================================
+
+# ===========================================================================
# --- TRANSFORM ---
-#===========================================================================
+# ===========================================================================
def translate_topods_from_vector(brep_or_iterable, vec, copy=False):
- '''
+ """
translate a brep over a vector
@param brep: the Topo_DS to translate
@param vec: the vector defining the translation
@param copy: copies to brep if True
- '''
+ """
st = ShapeToTopology()
trns = gp_Trsf()
trns.SetTranslation(vec)
@@ -738,21 +769,20 @@ def translate_topods_from_vector(brep_or_iterable, vec, copy=False):
brep_trns.Build()
return st(brep_trns.Shape())
else:
- return [translate_topods_from_vector(brep_or_iterable, vec, copy) for i in brep_or_iterable]
-
-
-def scale_non_uniformal():
- raise NotImplementedError
+ return [
+ translate_topods_from_vector(brep_or_iterable, vec, copy)
+ for i in brep_or_iterable
+ ]
def scale_uniformal(brep, pnt, factor, copy=False):
- '''
+ """
translate a brep over a vector
@param brep: the Topo_DS to translate
@param pnt: a gp_Pnt
@param triple: scaling factor
@param copy: copies to brep if True
- '''
+ """
trns = gp_Trsf()
trns.SetScale(pnt, factor)
brep_trns = BRepBuilderAPI_Transform(brep, trns, copy)
@@ -761,55 +791,60 @@ def scale_uniformal(brep, pnt, factor, copy=False):
def mirror_pnt_dir(brep, pnt, direction, copy=False):
- '''
+ """
@param brep:
@param line:
- '''
+ """
trns = gp_Trsf()
trns.SetMirror(gp_Ax1(pnt, direction))
brep_trns = BRepBuilderAPI_Transform(brep, trns, copy)
- with assert_isdone(brep_trns, 'could not produce mirror'):
+ with assert_isdone(brep_trns, "could not produce mirror"):
brep_trns.Build()
return brep_trns.Shape()
def mirror_axe2(brep, axe2, copy=False):
- '''
+ """
@param brep:
@param line:
- '''
+ """
trns = gp_Trsf()
trns.SetMirror(axe2)
brep_trns = BRepBuilderAPI_Transform(brep, trns, copy)
- with assert_isdone(brep_trns, 'could not produce mirror'):
+ with assert_isdone(brep_trns, "could not produce mirror"):
brep_trns.Build()
return brep_trns.Shape()
def rotate(brep, axe, degree, copy=False):
- '''
+ """
@param brep:
@param axe:
@param degree:
- '''
+ """
from math import radians
+
trns = gp_Trsf()
trns.SetRotation(axe, radians(degree))
brep_trns = BRepBuilderAPI_Transform(brep, trns, copy)
- with assert_isdone(brep_trns, 'could not produce rotation'):
+ with assert_isdone(brep_trns, "could not produce rotation"):
brep_trns.Build()
return ST(brep_trns.Shape())
-#=============================================================================
+
+# =============================================================================
# Not so sure where this should be located
-#=============================================================================
+# =============================================================================
def face_normal(face):
- from OCC.BRepTools import breptools_UVBounds
+ from OCC.Core.BRepTools import breptools_UVBounds
+
umin, umax, vmin, vmax = breptools_UVBounds(face)
surf = BRep_Tool().Surface(face)
- props = GeomLProp_SLProps(surf, (umin+umax)/2., (vmin+vmax)/2., 1, TOLERANCE)
+ props = GeomLProp_SLProps(
+ surf, (umin + umax) / 2.0, (vmin + vmax) / 2.0, 1, TOLERANCE
+ )
norm = props.Normal()
if face.Orientation() == TopAbs_REVERSED:
norm.Reverse()
@@ -818,7 +853,12 @@ def face_normal(face):
def face_from_plane(_geom_plane, lowerLimit=-1000, upperLimit=1000):
from OCC.Geom import Geom_RectangularTrimmedSurface
- _trim_plane = make_face(Geom_RectangularTrimmedSurface(_geom_plane.GetHandle(), lowerLimit, upperLimit, lowerLimit, upperLimit).GetHandle())
+
+ _trim_plane = make_face(
+ Geom_RectangularTrimmedSurface(
+ _geom_plane, lowerLimit, upperLimit, lowerLimit, upperLimit
+ )
+ )
return _trim_plane
@@ -826,11 +866,11 @@ def find_plane_from_shape(shape, tolerance=-1):
try:
fpl = BRepBuilderAPI_FindPlane(shape, tolerance)
if fpl.Found():
- return fpl.Plane().GetObject()
+ return fpl.Plane()
else:
return None
except:
- raise AssertionError('couldnt find plane in %s' % (shape))
+ raise AssertionError("couldnt find plane in %s" % (shape))
def fit_plane_through_face_vertices(_face):
@@ -839,9 +879,10 @@ def fit_plane_through_face_vertices(_face):
:return: Geom_Plane
"""
from OCC.GeomPlate import GeomPlate_BuildAveragePlane
- from Topology import Topo
- uvs_from_vertices = [_face.project_vertex(vertex2pnt(i)) for i in Topo(_face).vertices()]
+ uvs_from_vertices = [
+ _face.project_vertex(vertex2pnt(i)) for i in Topo(_face).vertices()
+ ]
normals = [gp_Vec(_face.DiffGeom.normal(*uv[0])) for uv in uvs_from_vertices]
points = [i[1] for i in uvs_from_vertices]
@@ -849,7 +890,7 @@ def fit_plane_through_face_vertices(_face):
[NORMALS.Append(i) for i in normals]
POINTS = to_tcol_(points, TColgp_HArray1OfPnt)
- pl = GeomPlate_BuildAveragePlane(NORMALS, POINTS).Plane().GetObject()
+ pl = GeomPlate_BuildAveragePlane(NORMALS, POINTS).Plane()
vec = gp_Vec(pl.Location(), _face.GlobalProperties.centre())
pt = (pl.Location().as_vec() + vec).as_pnt()
pl.SetLocation(pt)
@@ -863,21 +904,26 @@ def project_edge_onto_plane(edg, plane):
:return: TopoDS_Edge projected on the plane
"""
from OCC.GeomProjLib import geomprojlib_ProjectOnPlane
- proj = geomprojlib_ProjectOnPlane(edg.adaptor.Curve().Curve(), plane.GetHandle(), plane.Axis().Direction(), 1 )
+
+ proj = geomprojlib_ProjectOnPlane(
+ edg.adaptor.Curve().Curve(), plane, plane.Axis().Direction(), 1
+ )
return make_edge(proj)
-def curve_to_bspline(crv_handle, tolerance=TOLERANCE, continuity=GeomAbs_C1, sections=300, degree=12):
- approx_curve = GeomConvert_ApproxCurve(crv_handle, tolerance, continuity, sections, degree)
- with assert_isdone(approx_curve, 'could not compute bspline from curve'):
+def curve_to_bspline(
+ crv, tolerance=TOLERANCE, continuity=GeomAbs_C1, sections=300, degree=12
+):
+ approx_curve = GeomConvert_ApproxCurve(crv, tolerance, continuity, sections, degree)
+ with assert_isdone(approx_curve, "could not compute bspline from curve"):
return approx_curve.Curve()
def compound(topo):
- '''
+ """
accumulate a bunch of TopoDS_* in list `topo` to a TopoDS_Compound
@param topo: list of TopoDS_* instances
- '''
+ """
bd = TopoDS_Builder()
comp = TopoDS_Compound()
bd.MakeCompound(comp)
@@ -886,7 +932,9 @@ def compound(topo):
return comp
-def geodesic_path(pntA, pntB, edgA, edgB, kbe_face, n_segments=20, _tolerance=0.1, n_iter=20):
+def geodesic_path(
+ pntA, pntB, edgA, edgB, kbe_face, n_segments=20, _tolerance=0.1, n_iter=20
+):
"""
:param pntA: point to start from
:param pntB: point to move towards
@@ -898,19 +946,20 @@ def geodesic_path(pntA, pntB, edgA, edgB, kbe_face, n_segments=20, _tolerance=0.
:param n_iter: maximum number of iterations
:return: TopoDS_Edge
"""
- from Common import smooth_pnts
uvA, srf_pnt_A = kbe_face.project_vertex(pntA)
uvB, srf_pnt_B = kbe_face.project_vertex(pntB)
path = []
for i in range(n_segments):
t = i / float(n_segments)
- u = uvA[0] + t*(uvB[0] - uvA[0])
- v = uvA[1] + t*(uvB[1] - uvA[1])
+ u = uvA[0] + t * (uvB[0] - uvA[0])
+ v = uvA[1] + t * (uvB[1] - uvA[1])
path.append(kbe_face.parameter_to_point(u, v))
project_pnts = lambda x: [kbe_face.project_vertex(i)[1] for i in x]
- poly_length = lambda x: sum([x[i].Distance(x[i+1]) for i in range(len(x)-1)]) / len(x)
+ poly_length = lambda x: sum(
+ [x[i].Distance(x[i + 1]) for i in range(len(x) - 1)]
+ ) / len(x)
length = poly_length(path)
@@ -919,7 +968,7 @@ def geodesic_path(pntA, pntB, edgA, edgB, kbe_face, n_segments=20, _tolerance=0.
path = smooth_pnts(path)
path = project_pnts(path)
newlength = poly_length(path)
- if abs(newlength-length) < _tolerance or n == n_iter:
+ if abs(newlength - length) < _tolerance or n == n_iter:
crv = points_to_bspline(path)
return make_edge(crv)
n += 1
diff --git a/OCCUtils/Context.py b/OCCUtils/Context.py
deleted file mode 100644
index dc9c12a..0000000
--- a/OCCUtils/Context.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-
-##Copyright 2008-2015 Jelle Feringa (jelleferinga@gmail.com)
-##
-##This file is part of pythonOCC.
-##
-##pythonOCC is free software: you can redistribute it and/or modify
-##it under the terms of the GNU Lesser General Public License as published by
-##the Free Software Foundation, either version 3 of the License, or
-##(at your option) any later version.
-##
-##pythonOCC is distributed in the hope that it will be useful,
-##but WITHOUT ANY WARRANTY; without even the implied warranty of
-##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-##GNU Lesser General Public License for more details.
-##
-##You should have received a copy of the GNU Lesser General Public License
-##along with pythonOCC. If not, see .
-
-
-class assert_isdone(object):
- '''
- raises an assertion error when IsDone() returns false, with the error
- specified in error_statement
- '''
- def __init__(self, to_check, error_statement):
- self.to_check = to_check
- self.error_statement = error_statement
-
- def __enter__(self, ):
- if self.to_check.IsDone():
- pass
- else:
- raise AssertionError(self.error_statement)
-
- def __exit__(self, type, value, traceback):
- pass
diff --git a/OCCUtils/Decorators.py b/OCCUtils/Decorators.py
deleted file mode 100644
index 32f3e17..0000000
--- a/OCCUtils/Decorators.py
+++ /dev/null
@@ -1,23 +0,0 @@
-##Copyright 2008-2015 Jelle Feringa (jelleferinga@gmail.com)
-##
-##This file is part of pythonOCC.
-##
-##pythonOCC is free software: you can redistribute it and/or modify
-##it under the terms of the GNU Lesser General Public License as published by
-##the Free Software Foundation, either version 3 of the License, or
-##(at your option) any later version.
-##
-##pythonOCC is distributed in the hope that it will be useful,
-##but WITHOUT ANY WARRANTY; without even the implied warranty of
-##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-##GNU Lesser General Public License for more details.
-##
-##You should have received a copy of the GNU Lesser General Public License
-##along with pythonOCC. If not, see .
-
-from OCC.Standard import Handle_Standard_Transient
-
-
-def Downcast(handle_type):
- assert isinstance(handle_type, Handle_Standard_Transient), '% is not a valid handle type, not DownCast method found' % (handle_type.__class__)
- pass
diff --git a/OCCUtils/Image.py b/OCCUtils/Image.py
index 898014e..2ad4f82 100644
--- a/OCCUtils/Image.py
+++ b/OCCUtils/Image.py
@@ -26,6 +26,7 @@ class Texture(object):
This class encapsulates the necessary texture properties:
Filename, toScaleU, etc.
"""
+
def __init__(self, filename):
if not os.path.isfile(filename):
raise IOError("File %s not found.\n" % filename)
@@ -50,7 +51,12 @@ def TextureOrigin(self, originU, originV):
self._originV = originV
def GetProperties(self):
- return (self._filename,
- self._toScaleU, self._toScaleV,
- self._toRepeatU, self._toRepeatV,
- self._originU, self._originV)
+ return (
+ self._filename,
+ self._toScaleU,
+ self._toScaleV,
+ self._toRepeatU,
+ self._toRepeatV,
+ self._originU,
+ self._originV,
+ )
diff --git a/OCCUtils/Iteration.py b/OCCUtils/Iteration.py
index ba07784..be81b17 100644
--- a/OCCUtils/Iteration.py
+++ b/OCCUtils/Iteration.py
@@ -15,42 +15,46 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see .
-'''
+"""
This module helps looping through topology
-'''
-from OCC.BRep import BRep_Tool
+"""
+from OCC.Core.BRep import BRep_Tool
-from Topology import WireExplorer, Topo
-from edge import Edge
+from OCCUtils.Topology import WireExplorer, Topo
+from OCCUtils.edge import Edge
class EdgePairsFromWire(object):
- '''
+ """
helper class to loop through a wire and return ordered pairs of edges
- '''
+ """
+
def __init__(self, wire):
self.wire = wire
self.edge_pairs = []
self.prev_edge = None
self.we = WireExplorer(self.wire).ordered_edges()
self.number_of_edges = self.we.__length_hint__()
+ self.previous_edge = None
+ self.current_edge = None
+ self.first_edge = None
self.index = 0
def next(self):
if self.index == 0:
# first edge, need to set self.previous_edge
- self.previous_edge = self.we.next()
- self.current_edge = self.we.next()
- self.first_edge = self.previous_edge # for the last iteration
+ self.previous_edge = next(self.we)
+ self.current_edge = next(self.we)
+ self.first_edge = self.previous_edge # for the last iteration
self.index += 1
return [self.previous_edge, self.current_edge]
- elif self.index == self.number_of_edges-1:
+ elif self.index == self.number_of_edges - 1:
# no next edge
self.index += 1
return [self.current_edge, self.first_edge]
else:
self.previous_edge = self.current_edge
- self.current_edge = self.we.next()
+ self.current_edge = next(self.we)
self.index += 1
return [self.previous_edge, self.current_edge]
@@ -59,10 +63,11 @@ def __iter__(self):
class LoopWirePairs(object):
- '''
+ """
for looping through consequtive wires
assures that the returned edge pairs are ordered
- '''
+ """
+
def __init__(self, wireA, wireB):
self.wireA = wireA
self.wireB = wireB
@@ -95,8 +100,8 @@ def next(self):
closest = self.closest_point(vert)
edges_a = self.tp_A.edges_from_vertex(vert)
edges_b = self.tp_B.edges_from_vertex(closest)
- a1, a2 = Edge(edges_a.next()), Edge(edges_a.next())
- b1, b2 = Edge(edges_b.next()), Edge(edges_b.next())
+ a1, a2 = Edge(next(edges_a)), Edge(next(edges_a))
+ b1, b2 = Edge(next(edges_b)), Edge(next(edges_b))
mpA = a1.mid_point()
self.index += 1
diff --git a/OCCUtils/Topology.py b/OCCUtils/Topology.py
index 7a20b0f..adcb679 100644
--- a/OCCUtils/Topology.py
+++ b/OCCUtils/Topology.py
@@ -19,30 +19,50 @@
from __future__ import print_function
-__all__ = ['Topo', 'WireExplorer', 'dumpTopology']
-
-from OCC.BRep import BRep_Tool
-
-from OCC.BRepTools import BRepTools_WireExplorer
-from OCC.TopAbs import (TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE, TopAbs_WIRE,
- TopAbs_SHELL, TopAbs_SOLID, TopAbs_COMPOUND,
- TopAbs_COMPSOLID)
-from OCC.TopExp import TopExp_Explorer, topexp_MapShapesAndAncestors
-from OCC.TopTools import (TopTools_ListOfShape,
- TopTools_ListIteratorOfListOfShape,
- TopTools_IndexedDataMapOfShapeListOfShape)
-from OCC.TopoDS import (topods, TopoDS_Wire, TopoDS_Vertex, TopoDS_Edge,
- TopoDS_Face, TopoDS_Shell, TopoDS_Solid,
- TopoDS_Compound, TopoDS_CompSolid, topods_Edge,
- topods_Vertex, TopoDS_Iterator)
+__all__ = ["Topo", "WireExplorer", "dumpTopology"]
+
+from OCC.Core.BRep import BRep_Tool
+
+from OCC.Core.BRepTools import BRepTools_WireExplorer
+from OCC.Core.TopAbs import (
+ TopAbs_VERTEX,
+ TopAbs_EDGE,
+ TopAbs_FACE,
+ TopAbs_WIRE,
+ TopAbs_SHELL,
+ TopAbs_SOLID,
+ TopAbs_COMPOUND,
+ TopAbs_COMPSOLID,
+)
+from OCC.Core.TopExp import TopExp_Explorer, topexp_MapShapesAndAncestors
+from OCC.Core.TopTools import (
+ TopTools_ListOfShape,
+ TopTools_ListIteratorOfListOfShape,
+ TopTools_IndexedDataMapOfShapeListOfShape,
+)
+from OCC.Core.TopoDS import (
+ topods,
+ TopoDS_Wire,
+ TopoDS_Vertex,
+ TopoDS_Edge,
+ TopoDS_Face,
+ TopoDS_Shell,
+ TopoDS_Solid,
+ TopoDS_Compound,
+ TopoDS_CompSolid,
+ topods_Edge,
+ topods_Vertex,
+ TopoDS_Iterator,
+)
class WireExplorer(object):
- '''
+ """
Wire traversal
- '''
+ """
+
def __init__(self, wire):
- assert isinstance(wire, TopoDS_Wire), 'not a TopoDS_Wire'
+ assert isinstance(wire, TopoDS_Wire), "not a TopoDS_Wire"
self.wire = wire
self.wire_explorer = BRepTools_WireExplorer(self.wire)
self.done = False
@@ -88,9 +108,9 @@ def ordered_vertices(self):
class Topo(object):
- '''
+ """
Topology traversal
- '''
+ """
def __init__(self, myShape, ignore_orientation=False):
"""
@@ -133,26 +153,33 @@ def __init__(self, myShape, ignore_orientation=False):
TopAbs_SHELL: topods.Shell,
TopAbs_SOLID: topods.Solid,
TopAbs_COMPOUND: topods.Compound,
- TopAbs_COMPSOLID: topods.CompSolid
+ TopAbs_COMPSOLID: topods.CompSolid,
}
- def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None):
- '''
+ def _loop_topo(
+ self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None
+ ):
+ """
this could be a faces generator for a python TopoShape class
that way you can just do:
for face in srf.faces:
processFace(face)
- '''
- topoTypes = {TopAbs_VERTEX: TopoDS_Vertex,
- TopAbs_EDGE: TopoDS_Edge,
- TopAbs_FACE: TopoDS_Face,
- TopAbs_WIRE: TopoDS_Wire,
- TopAbs_SHELL: TopoDS_Shell,
- TopAbs_SOLID: TopoDS_Solid,
- TopAbs_COMPOUND: TopoDS_Compound,
- TopAbs_COMPSOLID: TopoDS_CompSolid}
-
- assert topologyType in topoTypes.keys(), '%s not one of %s' % (topologyType, topoTypes.keys())
+ """
+ topoTypes = {
+ TopAbs_VERTEX: TopoDS_Vertex,
+ TopAbs_EDGE: TopoDS_Edge,
+ TopAbs_FACE: TopoDS_Face,
+ TopAbs_WIRE: TopoDS_Wire,
+ TopAbs_SHELL: TopoDS_Shell,
+ TopAbs_SOLID: TopoDS_Solid,
+ TopAbs_COMPOUND: TopoDS_Compound,
+ TopAbs_COMPSOLID: TopoDS_CompSolid,
+ }
+
+ assert topologyType in topoTypes.keys(), "%s not one of %s" % (
+ topologyType,
+ topoTypes.keys(),
+ )
self.topExp = TopExp_Explorer()
# use self.myShape if nothing is specified
if topologicalEntity is None and topologyTypeToAvoid is None:
@@ -162,9 +189,7 @@ def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=N
elif topologyTypeToAvoid is None:
self.topExp.Init(topologicalEntity, topologyType)
elif topologyTypeToAvoid:
- self.topExp.Init(topologicalEntity,
- topologyType,
- topologyTypeToAvoid)
+ self.topExp.Init(topologicalEntity, topologyType, topologyTypeToAvoid)
seq = []
hashes = [] # list that stores hashes to avoid redundancy
occ_seq = TopTools_ListOfShape()
@@ -201,9 +226,9 @@ def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=N
return iter(seq)
def faces(self):
- '''
+ """
loops over all faces
- '''
+ """
return self._loop_topo(TopAbs_FACE)
def _number_of_topo(self, iterable):
@@ -216,72 +241,72 @@ def number_of_faces(self):
return self._number_of_topo(self.faces())
def vertices(self):
- '''
+ """
loops over all vertices
- '''
+ """
return self._loop_topo(TopAbs_VERTEX)
def number_of_vertices(self):
return self._number_of_topo(self.vertices())
def edges(self):
- '''
+ """
loops over all edges
- '''
+ """
return self._loop_topo(TopAbs_EDGE)
def number_of_edges(self):
return self._number_of_topo(self.edges())
def wires(self):
- '''
+ """
loops over all wires
- '''
+ """
return self._loop_topo(TopAbs_WIRE)
def number_of_wires(self):
return self._number_of_topo(self.wires())
def shells(self):
- '''
+ """
loops over all shells
- '''
+ """
return self._loop_topo(TopAbs_SHELL, None)
def number_of_shells(self):
return self._number_of_topo(self.shells())
def solids(self):
- '''
+ """
loops over all solids
- '''
+ """
return self._loop_topo(TopAbs_SOLID, None)
def number_of_solids(self):
return self._number_of_topo(self.solids())
def comp_solids(self):
- '''
+ """
loops over all compound solids
- '''
+ """
return self._loop_topo(TopAbs_COMPSOLID)
def number_of_comp_solids(self):
return self._number_of_topo(self.comp_solids())
def compounds(self):
- '''
+ """
loops over all compounds
- '''
+ """
return self._loop_topo(TopAbs_COMPOUND)
def number_of_compounds(self):
return self._number_of_topo(self.compounds())
def ordered_vertices_from_wire(self, wire):
- '''
+ """
@param wire: TopoDS_Wire
- '''
+ """
we = WireExplorer(wire)
return we.ordered_vertices()
@@ -289,9 +314,9 @@ def number_of_ordered_vertices_from_wire(self, wire):
return self._number_of_topo(self.ordered_vertices_from_wire(wire))
def ordered_edges_from_wire(self, wire):
- '''
+ """
@param wire: TopoDS_Wire
- '''
+ """
we = WireExplorer(wire)
return we.ordered_edges()
@@ -299,17 +324,17 @@ def number_of_ordered_edges_from_wire(self, wire):
return self._number_of_topo(self.ordered_edges_from_wire(wire))
def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity):
- '''
+ """
using the same method
@param topoTypeA:
@param topoTypeB:
@param topologicalEntity:
- '''
+ """
topo_set = set()
_map = TopTools_IndexedDataMapOfShapeListOfShape()
topexp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map)
results = _map.FindFromKey(topologicalEntity)
- if results.IsEmpty():
+ if results.Size() == 0:
yield None
topology_iterator = TopTools_ListIteratorOfListOfShape(results)
@@ -335,19 +360,19 @@ def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity):
topology_iterator.Next()
def _number_shapes_ancestors(self, topoTypeA, topoTypeB, topologicalEntity):
- '''returns the number of shape ancestors
+ """returns the number of shape ancestors
If you want to know how many edges a faces has:
_number_shapes_ancestors(self, TopAbs_EDGE, TopAbs_FACE, edg)
- will return the number of edges a faces has
+ will return the number of edges a faces has
@param topoTypeA:
@param topoTypeB:
@param topologicalEntity:
- '''
+ """
topo_set = set()
_map = TopTools_IndexedDataMapOfShapeListOfShape()
topexp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map)
results = _map.FindFromKey(topologicalEntity)
- if results.IsEmpty():
+ if results.Size() == 0:
return None
topology_iterator = TopTools_ListIteratorOfListOfShape(results)
while topology_iterator.More():
@@ -484,13 +509,16 @@ def number_of_faces_from_solids(self, solid):
def dumpTopology(shape, level=0):
"""
- Print the details of an object from the top down
+ Print the details of an object from the top down
"""
brt = BRep_Tool()
s = shape.ShapeType()
if s == TopAbs_VERTEX:
pnt = brt.Pnt(topods_Vertex(shape))
- print(".." * level + "" % (hash(shape), pnt.X(), pnt.Y(), pnt.Z()))
+ print(
+ ".." * level
+ + "" % (hash(shape), pnt.X(), pnt.Y(), pnt.Z())
+ )
else:
print(".." * level, end="")
print(shapeTypeString(shape))
diff --git a/OCCUtils/__init__.py b/OCCUtils/__init__.py
index 8433ff5..0bda40f 100644
--- a/OCCUtils/__init__.py
+++ b/OCCUtils/__init__.py
@@ -1,3 +1,2 @@
-from Common import get_boundingbox
-from Topology import Topo
-from Decorators import Downcast
+from OCCUtils.Common import get_boundingbox
+from OCCUtils.Topology import Topo
diff --git a/OCCUtils/base.py b/OCCUtils/base.py
index a112a38..1e85077 100644
--- a/OCCUtils/base.py
+++ b/OCCUtils/base.py
@@ -15,9 +15,7 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see
-'''
-Sketch for a high-level API for pythonOCC
-
+"""
Please note the following;
@readonly
means that the decorated method is a readonly descriptor
@@ -35,23 +33,34 @@
Can be a module, class or namespace.
-'''
-# occ
-from OCC.BRepBuilderAPI import BRepBuilderAPI_Copy
-from OCC.BRepGProp import brepgprop_VolumeProperties, brepgprop_LinearProperties, brepgprop_SurfaceProperties
-from OCC.BRepCheck import *
-# occ high level
-from OCC.Display.SimpleGui import init_display
-from Construct import *
-# KBE
-from types_lut import shape_lut, topo_lut, orient_lut, state_lut, curve_lut, surface_lut
-# stdlib
+"""
+
import functools
+from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_Copy
+from OCC.Core.BRepGProp import (
+ brepgprop_VolumeProperties,
+ brepgprop_LinearProperties,
+ brepgprop_SurfaceProperties,
+)
+from OCC.Core.BRepCheck import (
+ BRepCheck_Vertex,
+ BRepCheck_Edge,
+ BRepCheck_Wire,
+ BRepCheck_Face,
+ BRepCheck_Shell,
+ BRepCheck_Analyzer,
+)
+from OCC.Core.GProp import GProp_GProps
+from OCC.Display.SimpleGui import init_display
-#===========================================================================
+from OCCUtils.Common import get_boundingbox
+from OCCUtils.Construct import make_vertex, TOLERANCE
+from OCCUtils.types_lut import shape_lut, topo_lut, curve_lut, surface_lut
+
+# ===========================================================================
# DISPLAY
-#===========================================================================
+# ===========================================================================
global display
@@ -70,30 +79,36 @@ def __call__(self, *args, **kwargs):
@singleton
class Display(object):
def __init__(self):
- self.display, self.start_display, self.add_menu, self.add_function_to_menu = init_display()
-
+ (
+ self.display,
+ self.start_display,
+ self.add_menu,
+ self.add_function_to_menu,
+ ) = init_display()
+
def __call__(self, *args, **kwargs):
return self.display.DisplayShape(*args, **kwargs)
-#============
+
+# ============
# base class
-#============
+# ============
-class KbeObject(object):
- """base class for all KBE objects"""
- def __init__(self, name=None):
- """Constructor for KbeObject"""
+class BaseObject(object):
+ """base class for all objects"""
+
+ def __init__(self, name=None, tolerance=TOLERANCE):
self.GlobalProperties = GlobalProperties(self)
self.name = name
self._dirty = False
- self.tolerance = TOLERANCE
+ self.tolerance = tolerance
self.display_set = False
@property
def is_dirty(self):
- '''when an object is dirty, its topology will be
- rebuild when update is called'''
+ """when an object is dirty, its topology will be
+ rebuild when update is called"""
return self._dirty
@is_dirty.setter
@@ -106,26 +121,29 @@ def topo_type(self):
@property
def geom_type(self):
- if self.topo_type == 'edge':
+ if self.topo_type == "edge":
return curve_lut[self.ShapeType()]
- if self.topo_type == 'face':
+ if self.topo_type == "face":
return surface_lut[self.adaptor.GetType()]
else:
- raise ValueError('geom_type works only for edges and faces...')
+ raise ValueError("geom_type works only for edges and faces...")
def set_display(self, display):
- if hasattr(display, 'DisplayShape'):
+ if hasattr(display, "DisplayShape"):
self.display_set = True
self.display = display
else:
- raise ValueError('not a display')
+ raise ValueError("not a display")
def check(self):
- """
- """
- _check = dict(vertex=BRepCheck_Vertex, edge=BRepCheck_Edge,
- wire=BRepCheck_Wire, face=BRepCheck_Face,
- shell=BRepCheck_Shell)
+ """ """
+ _check = dict(
+ vertex=BRepCheck_Vertex,
+ edge=BRepCheck_Edge,
+ wire=BRepCheck_Wire,
+ face=BRepCheck_Face,
+ shell=BRepCheck_Shell,
+ )
_check[self.topo_type]
# TODO: BRepCheck will be able to inform *what* actually is the matter,
# though implementing this still is a bit of work...
@@ -152,13 +170,13 @@ def copy(self):
return _copy
def distance(self, other):
- '''
+ """
return the minimum distance
:return: minimum distance,
minimum distance points on shp1
minimum distance points on shp2
- '''
+ """
return minimum_distance(self, other)
def show(self, *args, **kwargs):
@@ -173,20 +191,21 @@ def show(self, *args, **kwargs):
self.disp.DisplayShape(*args, **kwargs)
def build(self):
- if self.name.startswith('Vertex'):
+ if self.name.startswith("Vertex"):
self = make_vertex(self)
def __eq__(self, other):
return self.IsEqual(other)
def __ne__(self, other):
- return not(self.__eq__(other))
+ return not self.__eq__(other)
class GlobalProperties(object):
- '''
+ """
global properties for all topologies
- '''
+ """
+
def __init__(self, instance):
self.instance = instance
@@ -195,11 +214,11 @@ def system(self):
self._system = GProp_GProps()
# todo, type should be abstracted with TopoDS...
_topo_type = self.instance.topo_type
- if _topo_type == 'face' or _topo_type == 'shell':
+ if _topo_type == "face" or _topo_type == "shell":
brepgprop_SurfaceProperties(self.instance, self._system)
- elif _topo_type == 'edge':
+ elif _topo_type == "edge":
brepgprop_LinearProperties(self.instance, self._system)
- elif _topo_type == 'solid':
+ elif _topo_type == "solid":
brepgprop_VolumeProperties(self.instance, self._system)
return self._system
@@ -210,24 +229,15 @@ def centre(self):
return self.system.CentreOfMass()
def inertia(self):
- '''returns the inertia matrix'''
+ """returns the inertia matrix"""
return self.system.MatrixOfInertia(), self.system.MomentOfInertia()
def area(self):
- '''returns the area of the surface'''
+ """returns the area of the surface"""
return self.system.Mass()
def bbox(self):
- '''
- returns the bounding box of the face
- '''
- return get_boundingbox(self.instance)
-
- def oriented_bbox(self):
"""
- return the minimal bounding box
-
- has dependencies with scipy.spatial
- [ has an implementation at hb-robo-code ]
+ returns the bounding box of the face
"""
- pass
+ return get_boundingbox(self.instance)
diff --git a/OCCUtils/edge.py b/OCCUtils/edge.py
index f6b1ea6..c85a651 100644
--- a/OCCUtils/edge.py
+++ b/OCCUtils/edge.py
@@ -15,44 +15,42 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see
-from OCC.BRepAdaptor import BRepAdaptor_Curve, BRepAdaptor_HCurve
-from OCC.GCPnts import GCPnts_UniformAbscissa
-from OCC.Geom import Geom_OffsetCurve, Geom_TrimmedCurve
-from OCC.TopExp import topexp
-from OCC.TopoDS import TopoDS_Edge, TopoDS_Vertex, TopoDS_Face
-from OCC.gp import *
-from OCC.GeomLProp import GeomLProp_CurveTool
-from OCC.BRepLProp import BRepLProp_CLProps
-from OCC.GeomLib import geomlib
-from OCC.GCPnts import GCPnts_AbscissaPoint
-from OCC.GeomAPI import GeomAPI_ProjectPointOnCurve
-from OCC.ShapeAnalysis import ShapeAnalysis_Edge
-from OCC.BRep import *
+from OCC.Core.BRepAdaptor import BRepAdaptor_Curve, BRepAdaptor_Curve
+from OCC.Core.GCPnts import GCPnts_UniformAbscissa
+from OCC.Core.Geom import Geom_OffsetCurve, Geom_TrimmedCurve
+from OCC.Core.TopExp import topexp
+from OCC.Core.TopoDS import TopoDS_Edge, TopoDS_Vertex, TopoDS_Face
+from OCC.Core.gp import gp_Vec, gp_Dir, gp_Pnt
+from OCC.Core.GeomLProp import GeomLProp_CurveTool
+from OCC.Core.BRepLProp import BRepLProp_CLProps
+from OCC.Core.GeomLib import geomlib
+from OCC.Core.GCPnts import GCPnts_AbscissaPoint
+from OCC.Core.GeomAPI import GeomAPI_ProjectPointOnCurve
+from OCC.Core.ShapeAnalysis import ShapeAnalysis_Edge
+from OCC.Core.BRep import BRep_Tool, BRep_Tool_Continuity
+from OCC.Core.BRepIntCurveSurface import BRepIntCurveSurface_Inter
# high-level
-from Common import vertex2pnt, minimum_distance
-from Construct import make_edge, fix_continuity
-from Context import assert_isdone
-from vertex import Vertex
-from types_lut import geom_lut
-from base import KbeObject
+from OCCUtils.Common import vertex2pnt, minimum_distance, assert_isdone, fix_continuity
+from OCCUtils.Construct import make_edge
+from OCCUtils.types_lut import geom_lut
+from OCCUtils.base import BaseObject
class IntersectCurve(object):
def __init__(self, instance):
self.instance = instance
- def intersect(self, other, disp, tolerance=1e-2):
- '''Intersect self with a point, curve, edge, face, solid
+ def intersect(self, other, tolerance=1e-2):
+ """Intersect self with a point, curve, edge, face, solid
method wraps dealing with the various topologies
- '''
+ """
if isinstance(other, TopoDS_Face):
- from OCC.BRepIntCurveSurface import BRepIntCurveSurface_Inter
face_curve_intersect = BRepIntCurveSurface_Inter()
face_curve_intersect.Init(other, self.instance.adaptor.Curve(), tolerance)
pnts = []
while face_curve_intersect.More():
- face_curve_intersect.Next()
+ next(face_curve_intersect)
pnts.append(face_curve_intersect.Pnt())
return pnts
@@ -60,16 +58,16 @@ def intersect(self, other, disp, tolerance=1e-2):
class DiffGeomCurve(object):
def __init__(self, instance):
self.instance = instance
- self._local_props = BRepLProp_CLProps(self.instance.adaptor, 2, self.instance.tolerance)
- # initialize with random parameter: 0
+ self._local_props = BRepLProp_CLProps(
+ self.instance.adaptor, 2, self.instance.tolerance
+ )
@property
def _curvature(self):
return self._local_props
def radius(self, u):
- '''returns the radius at u
- '''
+ """returns the radius at u"""
# NOT SO SURE IF THIS IS THE SAME THING!!!
self._curvature.SetParameter(u)
pnt = gp_Pnt()
@@ -82,85 +80,78 @@ def curvature(self, u):
return self._curvature.Curvature()
def tangent(self, u):
- '''sets or gets ( iff vector ) the tangency at the u parameter
+ """sets or gets ( iff vector ) the tangency at the u parameter
tangency can be constrained so when setting the tangency,
you're constrainting it in fact
- '''
+ """
self._curvature.SetParameter(u)
if self._curvature.IsTangentDefined():
ddd = gp_Dir()
self._curvature.Tangent(ddd)
return ddd
else:
- raise ValueError('no tangent defined')
+ raise ValueError("no tangent defined")
def normal(self, u):
- '''returns the normal at u
+ """returns the normal at u
computes the main normal if no normal is found
see:
www.opencascade.org/org/forum/thread_645+&cd=10&hl=nl&ct=clnk&gl=nl
- '''
+ """
try:
self._curvature.SetParameter(u)
- ddd = gp_Dir()
- self._curvature.Normal(ddd)
- return ddd
+ a_dir = gp_Dir()
+ self._curvature.Normal(a_dir)
+ return a_dir
except:
- raise ValueError('no normal was found')
+ raise ValueError("no normal was found")
def derivative(self, u, n):
- '''
+ """
returns n derivatives at parameter b
- '''
+ """
self._curvature.SetParameter(u)
- deriv = {1: self._curvature.D1,
- 2: self._curvature.D2,
- 3: self._curvature.D3,
- }
+ deriv = {
+ 1: self._curvature.D1,
+ 2: self._curvature.D2,
+ 3: self._curvature.D3,
+ }
try:
return deriv[n]
except KeyError:
- raise AssertionError('n of derivative is one of [1,2,3]')
+ raise AssertionError("n of derivative is one of [1,2,3]")
def points_from_tangential_deflection(self):
pass
-#===========================================================================
+
+# ===========================================================================
# Curve.Construct
-#===========================================================================
+# ===========================================================================
-class ConstructFromCurve():
+class ConstructFromCurve:
def __init__(self, instance):
self.instance = instance
- def make_face(self):
- '''returns a brep face iff self.closed()
- '''
- raise NotImplementedError
-
def make_offset(self, offset, vec):
- '''
+ """
returns an offsetted curve
@param offset: the distance between self.crv and the curve to offset
@param vec: offset direction
- '''
+ """
return Geom_OffsetCurve(self.instance.h_crv, offset, vec)
- def approximate_on_surface(self):
- '''
- approximation of a curve on surface
- '''
- raise NotImplementedError
-
-class Edge(TopoDS_Edge, KbeObject):
+class Edge(TopoDS_Edge, BaseObject):
def __init__(self, edge):
- assert isinstance(edge, TopoDS_Edge), 'need a TopoDS_Edge, got a %s' % edge.__class__
+ assert isinstance(edge, TopoDS_Edge), (
+ "need a TopoDS_Edge, got a %s" % edge.__class__
+ )
assert not edge.IsNull()
super(Edge, self).__init__()
- KbeObject.__init__(self, 'edge')
+ BaseObject.__init__(self, "edge")
# we need to copy the base shape using the following three
# lines
assert self.IsNull()
@@ -173,10 +164,8 @@ def __init__(self, edge):
self._local_properties_init = False
self._curvature_init = False
self._geometry_lookup_init = False
- self._curve_handle = None
self._curve = None
self._adaptor = None
- self._adaptor_handle = None
# instantiating cooperative classes
# cooperative classes are distinct through CamelCaps from
@@ -184,7 +173,6 @@ def __init__(self, edge):
self.DiffGeom = DiffGeomCurve(self)
self.Intersect = IntersectCurve(self)
self.Construct = ConstructFromCurve(self)
- #self.graphic = GraphicCurve(self)
# GeomLProp object
self._curvature = None
@@ -202,9 +190,9 @@ def continuity(self):
return self.adaptor.Continuity
def degree(self):
- if 'line' in self.type:
+ if "line" in self.type:
return 1
- elif 'curve' in self.type:
+ elif "curve" in self.type:
return self.adaptor.Degree()
else:
# hyperbola, parabola, circle
@@ -221,46 +209,17 @@ def curve(self):
if self._curve is not None and not self.is_dirty:
pass
else:
- self._curve_handle = BRep_Tool().Curve(self)[0]
- self._curve = self._curve_handle.GetObject()
+ self._curve = BRep_Tool().Curve(self)[0]
return self._curve
- @property
- def curve_handle(self):
- if self._curve_handle is not None and not self.is_dirty:
- pass
- else:
- self.curve
- return self._curve_handle
-
@property
def adaptor(self):
if self._adaptor is not None and not self.is_dirty:
pass
else:
self._adaptor = BRepAdaptor_Curve(self)
- self._adaptor_handle = BRepAdaptor_HCurve(self._adaptor)
return self._adaptor
- @property
- def adaptor_handle(self):
- if self._adaptor_handle is not None and not self.is_dirty:
- pass
- else:
- self.adaptor
- return self._adaptor_handle
-
- @property
- def geom_curve_handle(self):
- """
- :return: Handle_Geom_Curve adapted from `self`
- """
- if self._adaptor_handle is not None and not self.is_dirty:
- pass
- else:
- self.adaptor
- return self._adaptor.Curve().Curve()
-
@property
def type(self):
return geom_lut[self.adaptor.Curve().GetType()]
@@ -271,90 +230,93 @@ def pcurve(self, face):
:return: Geom2d_Curve, u, v
"""
crv, u, v = BRep_Tool().CurveOnSurface(self, face)
- return crv.GetObject(), u, v
+ return crv, u, v
def _local_properties(self):
self._lprops_curve_tool = GeomLProp_CurveTool()
self._local_properties_init = True
def domain(self):
- '''returns the u,v domain of the curve'''
+ """returns the u,v domain of the curve"""
return self.adaptor.FirstParameter(), self.adaptor.LastParameter()
- def project(self, other):
- '''projects self with a point, curve, edge, face, solid
- method wraps dealing with the various topologies
- '''
- raise NotImplementedError
-
-#===========================================================================
-# Curve.GlobalProperties
-#===========================================================================
+ # ===========================================================================
+ # Curve.GlobalProperties
+ # ===========================================================================
def length(self, lbound=None, ubound=None, tolerance=1e-5):
- '''returns the curve length
+ """returns the curve length
if either lbound | ubound | both are given, than the length
of the curve will be measured over that interval
- '''
+ """
_min, _max = self.domain()
if _min < self.adaptor.FirstParameter():
- raise ValueError('the lbound argument is lower than the first parameter of the curve: %s ' % (self.adaptor.FirstParameter()))
+ raise ValueError(
+ "the lbound argument is lower than the first parameter of the curve: %s "
+ % (self.adaptor.FirstParameter())
+ )
if _max > self.adaptor.LastParameter():
- raise ValueError('the ubound argument is greater than the last parameter of the curve: %s ' % (self.adaptor.LastParameter()))
+ raise ValueError(
+ "the ubound argument is greater than the last parameter of the curve: %s "
+ % (self.adaptor.LastParameter())
+ )
lbound = _min if lbound is None else lbound
ubound = _max if ubound is None else ubound
return GCPnts_AbscissaPoint().Length(self.adaptor, lbound, ubound, tolerance)
-#===========================================================================
-# Curve.modify
-#===========================================================================
+ # ===========================================================================
+ # Curve.modify
+ # ===========================================================================
- def trim(self, lbound, ubound, periodic=False):
- '''
+ def trim(self, lbound, ubound):
+ """
trim the curve
@param lbound:
@param ubound:
- '''
+ """
a, b = sorted([lbound, ubound])
- tr = Geom_TrimmedCurve(self.adaptor.Curve().Curve(), a, b).GetHandle()
+ tr = Geom_TrimmedCurve(self.adaptor.Curve().Curve(), a, b)
return Edge(make_edge(tr))
def extend_by_point(self, pnt, degree=3, beginning=True):
- '''extends the curve to point
+ """extends the curve to point
does not extend if the degree of self.curve > 3
@param pnt:
@param degree:
@param beginning:
- '''
+ """
if self.degree > 3:
- raise ValueError('to extend you self.curve should be <= 3, is %s' % (self.degree))
+ raise ValueError(
+ "to extend you self.curve should be <= 3, is %s" % (self.degree)
+ )
return geomlib.ExtendCurveToPoint(self.curve, pnt, degree, beginning)
-#===========================================================================
-# Curve.
-#===========================================================================
+ # ===========================================================================
+ # Curve.
+ # ===========================================================================
def closest(self, other):
return minimum_distance(self, other)
def project_vertex(self, pnt_or_vertex):
- ''' returns the closest orthogonal project on `pnt` on edge
- '''
+ """returns the closest orthogonal project on `pnt` on edge"""
if isinstance(pnt_or_vertex, TopoDS_Vertex):
pnt_or_vertex = vertex2pnt(pnt_or_vertex)
- poc = GeomAPI_ProjectPointOnCurve(pnt_or_vertex, self.curve_handle)
+ poc = GeomAPI_ProjectPointOnCurve(pnt_or_vertex, self.curve)
return poc.LowerDistanceParameter(), poc.NearestPoint()
- def distance_on_curve(self, distance, close_parameter, estimate_parameter, check_seam=True):
- '''returns the parameter if there is a parameter
+ def distance_on_curve(self, distance, close_parameter, estimate_parameter):
+ """returns the parameter if there is a parameter
on the curve with a distance length from u
raises OutOfBoundary if no such parameter exists
- '''
- ccc = GCPnts_AbscissaPoint(self.adaptor, distance, close_parameter, estimate_parameter, 1e-5)
- with assert_isdone(ccc, 'couldnt compute distance on curve'):
- return ccc.Parameter()
+ """
+ gcpa = GCPnts_AbscissaPoint(
+ self.adaptor, distance, close_parameter, estimate_parameter, 1e-5
+ )
+ with assert_isdone(gcpa, "couldnt compute distance on curve"):
+ return gcpa.Parameter()
def mid_point(self):
"""
@@ -362,20 +324,19 @@ def mid_point(self):
its corresponding gp_Pnt
"""
_min, _max = self.domain()
- _mid = (_min+_max) / 2.
+ _mid = (_min + _max) / 2.0
return _mid, self.adaptor.Value(_mid)
def divide_by_number_of_points(self, n_pts, lbound=None, ubound=None):
- '''returns a nested list of parameters and points on the edge
+ """returns a nested list of parameters and points on the edge
at the requested interval [(param, gp_Pnt),...]
- '''
+ """
_lbound, _ubound = self.domain()
if lbound:
_lbound = lbound
elif ubound:
_ubound = ubound
-
# minimally two points or a Standard_ConstructionError is raised
if n_pts <= 1:
n_pts = 2
@@ -383,10 +344,10 @@ def divide_by_number_of_points(self, n_pts, lbound=None, ubound=None):
try:
npts = GCPnts_UniformAbscissa(self.adaptor, n_pts, _lbound, _ubound)
except:
- print "Warning : GCPnts_UniformAbscissa failed"
+ print("Warning : GCPnts_UniformAbscissa failed")
if npts.IsDone():
tmp = []
- for i in xrange(1, npts.NbPoints()+1):
+ for i in xrange(1, npts.NbPoints() + 1):
param = npts.Parameter(i)
pnt = self.adaptor.Value(param)
tmp.append((param, pnt))
@@ -394,41 +355,16 @@ def divide_by_number_of_points(self, n_pts, lbound=None, ubound=None):
else:
return None
- @property
- def weight(self, indx):
- '''descriptor sets or gets the weight of a control point at the index
- '''
- #TODO self.curve has to be generalized to a bspline for this...
- raise NotImplementedError
-
- def control_pt_coord(self, indx):
- #TODO confused; vertices != control points
- '''descriptor setting or getting the coordinate of a
- control point at indx'''
- raise NotImplementedError
-
- def greville_points(self):
- #TODO confused; vertices != greville points
- '''descriptor setting or getting the coordinate
- of a control point at indx'''
- raise NotImplementedError
-
- def control_point(self, indx, pt=None):
- '''gets or sets the coordinate of the control point
- '''
- raise NotImplementedError
-
def __eq__(self, other):
- if hasattr(other, 'topo'):
+ if hasattr(other, "topo"):
return self.IsEqual(other)
else:
return self.IsEqual(other)
def __ne__(self, other):
- return not(self.__eq__(other))
+ return not self.__eq__(other)
def first_vertex(self):
- # TODO: should return Vertex, not TopoDS_Vertex
return topexp.FirstVertex(self)
def last_vertex(self):
@@ -446,27 +382,18 @@ def as_vec(self):
first, last = map(vertex2pnt, [self.first_vertex(), self.last_vertex()])
return gp_Vec(first, last)
else:
- raise ValueError("edge is not a line, hence no meaningful vector can be returned")
+ raise ValueError(
+ "edge is not a line, hence no meaningful vector can be returned"
+ )
-#===========================================================================
-# Curve.
-#===========================================================================
+ # ===========================================================================
+ # Curve.
+ # ===========================================================================
def parameter_to_point(self, u):
- '''returns the coordinate at parameter u
- '''
+ """returns the coordinate at parameter u"""
return self.adaptor.Value(u)
- def point_to_parameter(self, coord):
- '''returns the parameters / pnt on edge at world coordinate `coord`
- '''
- raise NotImplementedError
-
- def transform(self, transform):
- '''affine transform
- '''
- raise NotImplementedError
-
def fix_continuity(self, continuity):
"""
splits an edge to achieve a level of continuity
@@ -474,42 +401,15 @@ def fix_continuity(self, continuity):
"""
return fix_continuity(self, continuity)
- def continuity_to_another_curve(self, other):
- '''returns continuity between self and another curve
- '''
- raise NotImplementedError
-
def continuity_from_faces(self, f1, f2):
return BRep_Tool_Continuity(self, f1, f2)
-#===========================================================================
-# Curve.loop
-#===========================================================================
-
- def iter_control_points(self):
- '''iterator over the control points
- '''
- raise NotImplementedError
-
- def iter_weights(self):
- '''iterator over the weights
- '''
- raise NotImplementedError
-
-#===========================================================================
-# Curve.
-#===========================================================================
- def is_trimmed(self):
- '''checks if curve is trimmed
-
- check if the underlying geom type is trimmed
+ # ===========================================================================
+ # Curve.
+ # ===========================================================================
- '''
- raise NotImplementedError
-
- def is_line(self, tolerance=None):
- '''checks if the curve is planar within a tolerance
- '''
+ def is_line(self):
+ """checks if the curve is planar"""
if self.nb_knots() == 2 and self.nb_poles() == 2:
return True
else:
@@ -524,43 +424,28 @@ def is_seam(self, face):
return sae.IsSeam(self, face)
def is_edge_on_face(self, face):
- '''checks whether curve lies on a surface or a face
- '''
+ """checks whether curve lies on a surface or a face"""
return ShapeAnalysis_Edge().HasPCurve(self, face)
- def on_edge(self, edge):
- '''checks if the curve lies on an edge or a border
- '''
- raise NotImplementedError
-
-#===========================================================================
-# Curve.graphic
-#===========================================================================
- def show(self, poles=False, vertices=False, knots=False):
- '''
+ # ===========================================================================
+ # Curve.graphic
+ # ===========================================================================
+ def show(self):
+ """
poles, knots, should render all slightly different.
here's how...
http://www.opencascade.org/org/forum/thread_1125/
- '''
- show = super(Edge, self).show()
+ """
+ super(Edge, self).show()
- def update(self, context):
- '''updates the graphic presentation when called
- '''
- raise NotImplementedError
- @property
- def color(self, *rgb):
- '''color descriptor for the curve
- '''
- raise NotImplementedError
-
-if __name__ == '__main__':
- from OCC.BRepPrimAPI import *
- from Topology import Topo
+if __name__ == "__main__":
+ from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
+ from OCCUtils.Topology import Topo
+
b = BRepPrimAPI_MakeBox(10, 20, 30).Shape()
t = Topo(b)
- ed = t.edges().next()
+ ed = next(t.edges())
my_e = Edge(ed)
print(my_e.tolerance)
diff --git a/OCCUtils/face.py b/OCCUtils/face.py
index 46d2142..0154196 100644
--- a/OCCUtils/face.py
+++ b/OCCUtils/face.py
@@ -15,44 +15,26 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see
-from OCC.BRep import BRep_Tool_Surface, BRep_Tool
-from OCC.BRepIntCurveSurface import BRepIntCurveSurface_Inter
-from OCC.BRepTopAdaptor import BRepTopAdaptor_FClass2d
-from OCC.Geom import Geom_Curve
-from OCC.GeomAPI import GeomAPI_ProjectPointOnSurf
-from OCC.GeomLib import GeomLib_IsPlanarSurface
-from OCC.TopAbs import TopAbs_IN
-from OCC.TopExp import topexp
-from OCC.TopoDS import *
-from OCC.GeomLProp import GeomLProp_SLProps
-from OCC.BRepCheck import BRepCheck_Face
-from OCC.BRepTools import breptools_UVBounds
-from OCC.BRepAdaptor import BRepAdaptor_Surface, BRepAdaptor_HSurface
-from OCC.ShapeAnalysis import ShapeAnalysis_Surface
-from OCC.IntTools import IntTools_FaceFace
-from OCC.ShapeAnalysis import ShapeAnalysis_Surface
-from OCC.GeomProjLib import geomprojlib
-from OCC.Adaptor3d import Adaptor3d_IsoCurve
-
-from base import Display, KbeObject, GlobalProperties
-from edge import Edge
-from Construct import *
-from Topology import Topo, WireExplorer
-
-'''
-
-TODO:
-
-use IntTools_FaceFace to compute intersection between 2 faces
-also useful to test if 2 faces are tangent
-
-inflection point -> scipy.fsolve
-radius / centre of circle
-divide curve by circles
-frenet frame
-
-
-'''
+from OCC.Core.BRep import BRep_Tool_Surface, BRep_Tool
+from OCC.Core.BRepTopAdaptor import BRepTopAdaptor_FClass2d
+from OCC.Core.Geom import Geom_Curve
+from OCC.Core.GeomAPI import GeomAPI_ProjectPointOnSurf
+from OCC.Core.GeomLib import GeomLib_IsPlanarSurface
+from OCC.Core.TopAbs import TopAbs_IN
+from OCC.Core.TopExp import topexp
+from OCC.Core.TopoDS import TopoDS_Vertex, TopoDS_Face, TopoDS_Edge
+from OCC.Core.GeomLProp import GeomLProp_SLProps
+from OCC.Core.BRepTools import breptools_UVBounds
+from OCC.Core.BRepAdaptor import BRepAdaptor_Surface
+from OCC.Core.ShapeAnalysis import ShapeAnalysis_Surface
+from OCC.Core.GeomProjLib import geomprojlib
+from OCC.Core.Adaptor3d import Adaptor3d_IsoCurve
+from OCC.Core.gp import gp_Pnt2d, gp_Dir
+
+from OCCUtils.base import BaseObject
+from OCCUtils.edge import Edge
+from OCCUtils.Construct import TOLERANCE, to_adaptor_3d
+from OCCUtils.Topology import Topo, WireExplorer
class DiffGeomSurface(object):
@@ -62,7 +44,7 @@ def __init__(self, instance):
self._curvature_initiated = False
def curvature(self, u, v):
- '''returns the curvature at the u parameter
+ """returns the curvature at the u parameter
the curvature object can be returned too using
curvatureType == curvatureType
curvatureTypes are:
@@ -71,25 +53,27 @@ def curvature(self, u, v):
maximum
mean
curvatureType
- '''
+ """
if not self._curvature_initiated:
- self._curvature = GeomLProp_SLProps(self.instance.surface_handle, u, v, 1, 1e-6)
+ self._curvature = GeomLProp_SLProps(self.instance.surface, u, v, 2, 1e-7)
_domain = self.instance.domain()
if u in _domain or v in _domain:
- print('<<>>')
+ print("<<>>")
div = 1000
- delta_u, delta_v = (_domain[0] - _domain[1])/div, (_domain[2] - _domain[3])/div
+ delta_u, delta_v = (_domain[0] - _domain[1]) / div, (
+ _domain[2] - _domain[3]
+ ) / div
if u in _domain:
- low, hi = u-_domain[0], u-_domain[1]
+ low, hi = u - _domain[0], u - _domain[1]
if low < hi:
u = u - delta_u
else:
u = u + delta_u
if v in _domain:
- low, hi = v-_domain[2], v-_domain[3]
+ low, hi = v - _domain[2], v - _domain[3]
if low < hi:
v = v - delta_v
else:
@@ -118,7 +102,7 @@ def normal(self, u, v):
if curv.IsNormalDefined():
return curv.Normal()
else:
- raise ValueError('normal is not defined at u,v: {0}, {1}'.format(u, v))
+ raise ValueError("normal is not defined at u,v: {0}, {1}".format(u, v))
def tangent(self, u, v):
dU, dV = gp_Dir(), gp_Dir()
@@ -130,70 +114,34 @@ def tangent(self, u, v):
return None, None
def radius(self, u, v):
- '''returns the radius at u
- '''
+ """returns the radius at u"""
# TODO: SHOULD WE RETURN A SIGNED RADIUS? ( get rid of abs() )?
try:
- _crv_min = 1./self.min_curvature(u, v)
+ _crv_min = 1.0 / self.min_curvature(u, v)
except ZeroDivisionError:
- _crv_min = 0.
+ _crv_min = 0.0
try:
- _crv_max = 1./self.max_curvature(u, v)
+ _crv_max = 1.0 / self.max_curvature(u, v)
except ZeroDivisionError:
- _crv_max = 0.
- return abs((_crv_min+_crv_max)/2.)
-
- def frenet_frame(self, u, v):
- '''returns the frenet frame ( the 2 tangency directions + normal )
- syntax sugar
- '''
- raise NotImplementedError
-
- def derivative_u(self, u, n):
- '''return n derivatives of u
- '''
- raise NotImplementedError
-
- def derivative_v(self, v, n):
- '''return n derivatives of v
- '''
- raise NotImplementedError
-
- def torsion(self, u, v):
- '''returns the torsion at the parameter
- http://en.wikipedia.org/wiki/Frenet-Serret_formulas
- '''
- raise NotImplementedError
-
- def continuity(self, face):
- '''returns continuity between self and another surface
- '''
- # add dictionary mapping which G / C continuity it is...
- raise NotImplementedError
-
- def inflection_parameters(self):
- """
- :return: a list of tuples (u,v) of parameters
- where there are inflection points on the edge
-
- returns None if no inflection parameters are found
- """
- raise NotImplementedError
+ _crv_max = 0.0
+ return abs((_crv_min + _crv_max) / 2.0)
-class Face(TopoDS_Face, KbeObject):
+class Face(TopoDS_Face, BaseObject):
"""high level surface API
object is a Face if part of a Solid
otherwise the same methods do apply, apart from the topology obviously
"""
+
def __init__(self, face):
- '''
- '''
- assert isinstance(face, TopoDS_Face), 'need a TopoDS_Face, got a %s' % edge.__class__
+ """ """
+ assert isinstance(face, TopoDS_Face), (
+ "need a TopoDS_Face, got a %s" % face.__class__
+ )
assert not face.IsNull()
super(Face, self).__init__()
- KbeObject.__init__(self, 'face')
+ BaseObject.__init__(self, "face")
# we need to copy the base shape using the following three
# lines
assert self.IsNull()
@@ -209,14 +157,15 @@ def __init__(self, face):
self._curvature_initiated = False
self._geometry_lookup_init = False
- #===================================================================
+ # ===================================================================
# properties
- #===================================================================
+ # ===================================================================
self._h_srf = None
self._srf = None
self._adaptor = None
- self._adaptor_handle = None
- self._classify_uv = None # cache the u,v classifier, no need to rebuild for every sample
+ self._classify_uv = (
+ None # cache the u,v classifier, no need to rebuild for every sample
+ )
self._topo = None
# aliasing of useful methods
@@ -251,9 +200,9 @@ def v_continuity(self):
return self.adaptor.VContinuity()
def domain(self):
- '''the u,v domain of the curve
+ """the u,v domain of the curve
:return: UMin, UMax, VMin, VMax
- '''
+ """
return breptools_UVBounds(self)
def mid_point(self):
@@ -262,10 +211,9 @@ def mid_point(self):
and its corresponding gp_Pnt
"""
u_min, u_max, v_min, v_max = self.domain()
- u_mid = (u_min + u_max) / 2.
- v_mid = (v_min + v_max) / 2.
- pnt = self.parameter_to_point(u_mid, v_mid)
- return ((u_mid, v_mid), self.adaptor.Value(u_mid, v_mid))
+ u_mid = (u_min + u_max) / 2.0
+ v_mid = (v_min + v_max) / 2.0
+ return ((u_mid, v_mid), self.adaptor.Value(u_mid, v_mid))
@property
def topo(self):
@@ -277,63 +225,28 @@ def topo(self):
@property
def surface(self):
- if self._srf is not None and not self.is_dirty:
- pass
- else:
- self._h_srf = BRep_Tool_Surface(self)
- self._srf = self._h_srf.GetObject()
+ if self._srf is None or self.is_dirty:
+ self._srf = BRep_Tool_Surface(self)
return self._srf
- @property
- def surface_handle(self):
- if self._h_srf is not None and not self.is_dirty:
- pass
- else:
- self.surface
- return self._h_srf
-
@property
def adaptor(self):
if self._adaptor is not None and not self.is_dirty:
pass
else:
self._adaptor = BRepAdaptor_Surface(self)
- self._adaptor_handle = BRepAdaptor_HSurface()
- self._adaptor_handle.Set(self._adaptor)
return self._adaptor
- @property
- def adaptor_handle(self):
- if self._adaptor_handle is not None and not self.is_dirty:
- pass
- else:
- self.adaptor
- return self._adaptor_handle
-
- def weight(self, indx):
- '''sets or gets the weight of a control point at the index
-
- '''
- # TODO: somehow its hard to get a Geom_SplineSurface object from a face
- # nessecary to get control points and weights
-
- raise NotImplementedError
-
- def close(self):
- '''if possible, close self'''
- raise NotImplementedError
-
def is_closed(self):
- sa = ShapeAnalysis_Surface(self.surface_handle)
- # sa.GetBoxUF()
+ sa = ShapeAnalysis_Surface(self.surface)
return sa.IsUClosed(), sa.IsVClosed()
def is_planar(self, tol=TOLERANCE):
- '''checks if the surface is planar within a tolerance
+ """checks if the surface is planar within a tolerance
:return: bool, gp_Pln
- '''
- aaa = GeomLib_IsPlanarSurface(self.surface_handle, tol)
- return aaa.IsPlanar()
+ """
+ is_planar_surface = GeomLib_IsPlanarSurface(self.surface, tol)
+ return is_planar_surface.IsPlanar()
def is_trimmed(self):
"""
@@ -345,18 +258,14 @@ def is_trimmed(self):
"""
_round = lambda x: round(x, 3)
a = map(_round, breptools_UVBounds(self))
- b = map(_round, self.adaptor.Surface().Surface().GetObject().Bounds())
+ b = map(_round, self.adaptor.Surface().Surface().Bounds())
if a != b:
- print('a,b', a, b)
+ print("a,b", a, b)
return True
return False
- def is_overlapping(self, other):
- overlap = IntTools_FaceFace()
-
def on_trimmed(self, u, v):
- '''tests whether the surface at the u,v parameter has been trimmed
- '''
+ """tests whether the surface at the u,v parameter has been trimmed"""
if self._classify_uv is None:
self._classify_uv = BRepTopAdaptor_FClass2d(self, 1e-9)
uv = gp_Pnt2d(u, v)
@@ -366,24 +275,18 @@ def on_trimmed(self, u, v):
return False
def parameter_to_point(self, u, v):
- '''returns the coordinate at u,v
- '''
+ """returns the coordinate at u,v"""
return self.surface.Value(u, v)
def point_to_parameter(self, pt):
- '''
+ """
returns the uv value of a point on a surface
@param pt:
- '''
- sas = ShapeAnalysis_Surface(self.surface_handle)
+ """
+ sas = ShapeAnalysis_Surface(self.surface)
uv = sas.ValueOfUV(pt, self.tolerance)
return uv.Coord()
- def transform(self, transform):
- '''affine transform
- '''
- raise NotImplementedError
-
def continuity_edge_face(self, edge, face):
"""
compute the continuity between two faces at :edge:
@@ -400,23 +303,23 @@ def continuity_edge_face(self, edge, face):
else:
return False, None
-#===========================================================================
-# Surface.project
-# project curve, point on face
-#===========================================================================
+ # ===========================================================================
+ # Surface.project
+ # project curve, point on face
+ # ===========================================================================
def project_vertex(self, pnt, tol=TOLERANCE):
- '''projects self with a point, curve, edge, face, solid
+ """projects self with a point, curve, edge, face, solid
method wraps dealing with the various topologies
if other is a point:
returns uv, point
- '''
+ """
if isinstance(pnt, TopoDS_Vertex):
pnt = BRep_Tool.Pnt(pnt)
- proj = GeomAPI_ProjectPointOnSurf(pnt, self.surface_handle, tol)
+ proj = GeomAPI_ProjectPointOnSurf(pnt, self.surface, tol)
uv = proj.LowerDistanceParameters()
proj_pnt = proj.NearestPoint()
@@ -424,17 +327,21 @@ def project_vertex(self, pnt, tol=TOLERANCE):
def project_curve(self, other):
# this way Geom_Circle and alike are valid too
- if (isinstance(other, TopoDS_Edge) or
- isinstance(other, Geom_Curve) or
- issubclass(other, Geom_Curve)):
- # convert edge to curve
- first, last = topexp.FirstVertex(other), topexp.LastVertex(other)
- lbound, ubound = BRep_Tool().Parameter(first, other), BRep_Tool().Parameter(last, other)
- other = BRep_Tool.Curve(other, lbound, ubound).GetObject()
- return geomprojlib.Project(other, self.surface_handle)
+ if (
+ isinstance(other, TopoDS_Edge)
+ or isinstance(other, Geom_Curve)
+ or issubclass(other, Geom_Curve)
+ ):
+ # convert edge to curve
+ first, last = topexp.FirstVertex(other), topexp.LastVertex(other)
+ lbound, ubound = BRep_Tool().Parameter(first, other), BRep_Tool().Parameter(
+ last, other
+ )
+ other = BRep_Tool.Curve(other, lbound, ubound)
+ return geomprojlib.Project(other, self.surface)
def project_edge(self, edg):
- if hasattr(edg, 'adaptor'):
+ if hasattr(edg, "adaptor"):
return self.project_curve(self, self.adaptor)
return self.project_curve(self, to_adaptor_3d(edg))
@@ -445,13 +352,12 @@ def iso_curve(self, u_or_v, param):
:param param:
:return:
"""
- uv = 0 if u_or_v == 'u' else 1
- # TODO: REFACTOR, part of the Face class now...
- iso = Adaptor3d_IsoCurve(self.adaptor_handle.GetHandle(), uv, param)
+ uv = 0 if u_or_v == "u" else 1
+ iso = Adaptor3d_IsoCurve(self.adaptor, uv, param)
return iso
- def Edges(self):
- return [Edge(i) for i in WireExplorer(self.topo.wires().next()).ordered_edges()]
+ def edges(self):
+ return [Edge(i) for i in WireExplorer(next(self.topo.wires())).ordered_edges()]
def __repr__(self):
return self.name
@@ -459,8 +365,10 @@ def __repr__(self):
def __str__(self):
return self.__repr__()
+
if __name__ == "__main__":
- from OCC.BRepPrimAPI import BRepPrimAPI_MakeSphere
+ from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeSphere
+
sph = BRepPrimAPI_MakeSphere(1, 1).Face()
fc = Face(sph)
print(fc.is_trimmed())
diff --git a/OCCUtils/plane.py b/OCCUtils/plane.py
deleted file mode 100644
index 080a2e9..0000000
--- a/OCCUtils/plane.py
+++ /dev/null
@@ -1,50 +0,0 @@
-##Copyright 2008-2013 Jelle Feringa (jelleferinga@gmail.com)
-##
-##This file is part of pythonOCC.
-##
-##pythonOCC is free software: you can redistribute it and/or modify
-##it under the terms of the GNU Lesser General Public License as published by
-##the Free Software Foundation, either version 3 of the License, or
-##(at your option) any later version.
-##
-##pythonOCC is distributed in the hope that it will be useful,
-##but WITHOUT ANY WARRANTY; without even the implied warranty of
-##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-##GNU Lesser General Public License for more details.
-##
-##You should have received a copy of the GNU Lesser General Public License
-##along with pythonOCC. If not, see
-
-from OCC.Geom import Geom_Plane
-from OCC.gp import gp_Pln
-
-
-class Plane(object): # HalfSpace
- def __init__(self, pln):
-
- self.pln = None
- self.geom_plane = None # property
-
- if isinstance(pln, gp_Pln.__class__):
- self.pln = pln
- elif isinstance(pln, Geom_Plane):
- self.pln = pln.Pln()
- self.geom_plane = pln
-
- def intersect_curve(self):
- """
- any line!
- """
- raise NotImplementedError
-
- def intersect_surface(self):
- raise NotImplementedError
-
- def intersect_plane_plane(self, pln1, pln2):
- raise NotImplementedError
-
- def project_curve(self):
- raise NotImplementedError
-
- def project_surface(self):
- raise NotImplementedError
diff --git a/OCCUtils/shell.py b/OCCUtils/shell.py
index b634ad9..1104503 100644
--- a/OCCUtils/shell.py
+++ b/OCCUtils/shell.py
@@ -15,50 +15,23 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see
-from OCC.TopoDS import TopoDS_Shell
+from OCC.Core.TopoDS import TopoDS_Shell
+from OCC.Core.ShapeAnalysis import ShapeAnalysis_Shell
-from Topology import Topo
-from base import KbeObject, GlobalProperties
+from OCCUtils.Topology import Topo
+from OCCUtils.base import BaseObject, GlobalProperties
-class DressUp(object):
- def __init__(self, instance):
- self.instance = instance
-
- def fillet_vertex_distance(self, vertex, distance):
- '''fillets 3 edges at a corner
- '''
- pass
-
- def fillet_edge_radius(self, edge, radius):
- '''fillets an edge
- '''
- pass
-
- def chamfer_vertex_distance(self, vertex, distance):
- '''chamfer 3 edges at a corner
- '''
- pass
-
- def chamfer_edge_angle(self, edge, angle):
- '''chamfers the faces on edge at angle
- '''
- pass
-
- def chamfer_edge_distance_distance(self, edge, distance_this_face, distance_other_face):
- '''chamfers the face incident on edge at a given distance
- '''
- pass
-
-
-class Shell(TopoDS_Shell, KbeObject):
+class Shell(TopoDS_Shell, BaseObject):
_n = 0
def __init__(self, shell):
- assert isinstance(shell, TopoDS_Shell), 'need a TopoDS_Shell, got a %s' % shell.__class__
+ assert isinstance(shell, TopoDS_Shell), (
+ "need a TopoDS_Shell, got a %s" % shell.__class__
+ )
assert not shell.IsNull()
super(Shell, self).__init__()
- KbeObject.__init__(self, 'shell')
+ BaseObject.__init__(self, "shell")
# we need to copy the base shape using the following three
# lines
assert self.IsNull()
@@ -68,7 +41,6 @@ def __init__(self, shell):
assert not self.IsNull()
self.GlobalProperties = GlobalProperties(self)
- self.DressUp = DressUp(self)
self._n += 1
def analyse(self):
@@ -76,7 +48,6 @@ def analyse(self):
:return:
"""
- from OCC.ShapeAnalysis import ShapeAnalysis_Shell
ss = ShapeAnalysis_Shell(self)
if ss.HasFreeEdges():
bad_edges = [e for e in Topo(ss.BadEdges()).edges()]
diff --git a/OCCUtils/solid.py b/OCCUtils/solid.py
index 78d71eb..2f28803 100644
--- a/OCCUtils/solid.py
+++ b/OCCUtils/solid.py
@@ -15,19 +15,21 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see
-from OCC.TopoDS import TopoDS_Solid
+from OCC.Core.TopoDS import TopoDS_Solid
-from Topology import Topo
-from base import GlobalProperties, KbeObject
-from shell import Shell
+from OCCUtils.Topology import Topo
+from OCCUtils.base import GlobalProperties, BaseObject
+from OCCUtils.shell import Shell
-class Solid(TopoDS_Solid, KbeObject):
+class Solid(TopoDS_Solid, BaseObject):
def __init__(self, solid):
- assert isinstance(solid, TopoDS_Solid), 'need a TopoDS_Solid, got a %s' % solid.__class__
+ assert isinstance(solid, TopoDS_Solid), (
+ "need a TopoDS_Solid, got a %s" % solid.__class__
+ )
assert not solid.IsNull()
super(Solid, self).__init__()
- KbeObject.__init__(self, 'solid')
+ BaseObject.__init__(self, "solid")
# we need to copy the base shape using the following three
# lines
assert self.IsNull()
@@ -38,39 +40,5 @@ def __init__(self, solid):
self.GlobalProperties = GlobalProperties(self)
- #=======================================================================
- # Solid.boolean
- #=======================================================================
- def add(self, other_solid):
- '''adds another_solid to self
- '''
- raise NotImplementedError
-
- def cut(self, other_solid):
- '''cuts other_solid from self
- '''
- raise NotImplementedError
-
- def intersect(self, other_solid):
- '''common space of self and other_solid
- '''
- raise NotImplementedError
-
def shells(self):
return (Shell(sh) for sh in Topo(self))
-#===========================================================================
-# Solid.graphic
-#===========================================================================
-
- @property
- def color(self, color):
- '''color all the faces
- '''
- raise NotImplementedError
-
- @property
- def tesselation(self, angle):
- '''descriptor of the parameter controlling the precision of the
- tesselation
- '''
- raise NotImplementedError
diff --git a/OCCUtils/types_lut.py b/OCCUtils/types_lut.py
index 6567946..dd08f4e 100644
--- a/OCCUtils/types_lut.py
+++ b/OCCUtils/types_lut.py
@@ -15,35 +15,36 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see
-from OCC.BRepCheck import *
-from OCC.GeomAbs import *
-from OCC.TopoDS import topods, TopoDS_Shape
-from OCC.BRep import BRep_Tool_Surface
-from OCC.TopAbs import *
-from OCC.Geom import Handle_Geom_CylindricalSurface, Handle_Geom_Plane
+from OCC.Core.BRepCheck import *
+from OCC.Core.GeomAbs import *
+from OCC.Core.TopoDS import topods, TopoDS_Shape
+from OCC.Core.BRep import BRep_Tool_Surface
+from OCC.Core.TopAbs import *
+from OCC.Core.Geom import Geom_CylindricalSurface, Geom_Plane
class ShapeToTopology(object):
- '''
+ """
looks up the topology type and returns the corresponding topological entity
- '''
+ """
+
def __init__(self):
- self.tds = topods()
- self.topoTypes = {TopAbs_VERTEX: self.tds.Vertex,
- TopAbs_EDGE: self.tds.Edge,
- TopAbs_FACE: self.tds.Face,
- TopAbs_WIRE: self.tds.Wire,
- TopAbs_SHELL: self.tds.Shell,
- TopAbs_SOLID: self.tds.Solid,
- TopAbs_COMPOUND: self.tds.Compound,
- TopAbs_COMPSOLID: self.tds.CompSolid,
- }
+ self.topoTypes = {
+ TopAbs_VERTEX: topods.Vertex,
+ TopAbs_EDGE: topods.Edge,
+ TopAbs_FACE: topods.Face,
+ TopAbs_WIRE: topods.Wire,
+ TopAbs_SHELL: topods.Shell,
+ TopAbs_SOLID: topods.Solid,
+ TopAbs_COMPOUND: topods.Compound,
+ TopAbs_COMPSOLID: topods.CompSolid,
+ }
def __call__(self, shape):
if isinstance(shape, TopoDS_Shape):
return self.topoTypes[shape.ShapeType()](shape)
else:
- raise AttributeError('shape has not method `ShapeType`')
+ raise AttributeError("shape has not method `ShapeType`")
def __getitem__(self, item):
return self(item)
@@ -53,6 +54,7 @@ class EnumLookup(object):
"""
perform bi-directional lookup of Enums'...
"""
+
def __init__(self, li_in, li_out):
self.d = {}
for a, b in zip(li_in, li_out):
@@ -63,51 +65,118 @@ def __getitem__(self, item):
return self.d[item]
-_curve_typesA = (GeomAbs_Line, GeomAbs_Circle, GeomAbs_Ellipse,
- GeomAbs_Hyperbola, GeomAbs_Parabola,
- GeomAbs_BezierCurve, GeomAbs_BSplineCurve, GeomAbs_OtherCurve)
-_curve_typesB = ('line', 'circle', 'ellipse', 'hyperbola', 'parabola',
- 'bezier', 'spline', 'other')
-_surface_typesA = (GeomAbs_Plane, GeomAbs_Cylinder, GeomAbs_Cone,
- GeomAbs_Sphere, GeomAbs_Torus, GeomAbs_BezierSurface,
- GeomAbs_BSplineSurface, GeomAbs_SurfaceOfRevolution,
- GeomAbs_SurfaceOfExtrusion,
- GeomAbs_OffsetSurface, GeomAbs_OtherSurface)
-_surface_typesB = ('plane', 'cylinder', 'cone', 'sphere', 'torus', 'bezier',
- 'spline', 'revolution', 'extrusion', 'offset', 'other')
-
-
-_stateA = ('in', 'out', 'on', 'unknown')
+_curve_typesA = (
+ GeomAbs_Line,
+ GeomAbs_Circle,
+ GeomAbs_Ellipse,
+ GeomAbs_Hyperbola,
+ GeomAbs_Parabola,
+ GeomAbs_BezierCurve,
+ GeomAbs_BSplineCurve,
+ GeomAbs_OtherCurve,
+)
+_curve_typesB = (
+ "line",
+ "circle",
+ "ellipse",
+ "hyperbola",
+ "parabola",
+ "bezier",
+ "spline",
+ "other",
+)
+_surface_typesA = (
+ GeomAbs_Plane,
+ GeomAbs_Cylinder,
+ GeomAbs_Cone,
+ GeomAbs_Sphere,
+ GeomAbs_Torus,
+ GeomAbs_BezierSurface,
+ GeomAbs_BSplineSurface,
+ GeomAbs_SurfaceOfRevolution,
+ GeomAbs_SurfaceOfExtrusion,
+ GeomAbs_OffsetSurface,
+ GeomAbs_OtherSurface,
+)
+_surface_typesB = (
+ "plane",
+ "cylinder",
+ "cone",
+ "sphere",
+ "torus",
+ "bezier",
+ "spline",
+ "revolution",
+ "extrusion",
+ "offset",
+ "other",
+)
+
+
+_stateA = ("in", "out", "on", "unknown")
_stateB = (TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN)
-_orientA = ['TopAbs_FORWARD', 'TopAbs_REVERSED', 'TopAbs_INTERNAL',
- 'TopAbs_EXTERNAL']
-_orientB = [TopAbs_FORWARD, TopAbs_REVERSED, TopAbs_INTERNAL,
- TopAbs_EXTERNAL]
-
-
-_topoTypesA = ['vertex', 'edge', 'wire', 'face', 'shell',
- 'solid', 'compsolid', 'compound', 'shape']
-_topoTypesB = [TopAbs_VERTEX, TopAbs_EDGE, TopAbs_WIRE, TopAbs_FACE,
- TopAbs_SHELL, TopAbs_SOLID,
- TopAbs_COMPSOLID, TopAbs_COMPOUND, TopAbs_SHAPE]
-
-
-_geom_types_a = ['line', 'circle', 'ellipse', 'hyperbola', 'parabola',
- 'beziercurve', 'bsplinecurve', 'othercurve']
-_geom_types_b = [GeomAbs_Line, GeomAbs_Circle, GeomAbs_Ellipse,
- GeomAbs_Hyperbola, GeomAbs_Parabola, GeomAbs_BezierCurve,
- GeomAbs_BSplineCurve, GeomAbs_OtherCurve]
+_orientA = ["TopAbs_FORWARD", "TopAbs_REVERSED", "TopAbs_INTERNAL", "TopAbs_EXTERNAL"]
+_orientB = [TopAbs_FORWARD, TopAbs_REVERSED, TopAbs_INTERNAL, TopAbs_EXTERNAL]
+
+
+_topoTypesA = [
+ "vertex",
+ "edge",
+ "wire",
+ "face",
+ "shell",
+ "solid",
+ "compsolid",
+ "compound",
+ "shape",
+]
+_topoTypesB = [
+ TopAbs_VERTEX,
+ TopAbs_EDGE,
+ TopAbs_WIRE,
+ TopAbs_FACE,
+ TopAbs_SHELL,
+ TopAbs_SOLID,
+ TopAbs_COMPSOLID,
+ TopAbs_COMPOUND,
+ TopAbs_SHAPE,
+]
+
+
+_geom_types_a = [
+ "line",
+ "circle",
+ "ellipse",
+ "hyperbola",
+ "parabola",
+ "beziercurve",
+ "bsplinecurve",
+ "othercurve",
+]
+_geom_types_b = [
+ GeomAbs_Line,
+ GeomAbs_Circle,
+ GeomAbs_Ellipse,
+ GeomAbs_Hyperbola,
+ GeomAbs_Parabola,
+ GeomAbs_BezierCurve,
+ GeomAbs_BSplineCurve,
+ GeomAbs_OtherCurve,
+]
# TODO: make a function that generalizes this, there is absolutely
# no need for 2 lists to define an EnumLookup
+
def fix_formatting(_str):
- return [i.strip() for i in _str.decode('string_escape').split(',')]
+ return [i.strip() for i in _str.split(",")]
+
-_brep_check_a = fix_formatting("NoError, InvalidPointOnCurve,\
+_brep_check_a = fix_formatting(
+ "NoError, InvalidPointOnCurve,\
InvalidPointOnCurveOnSurface, InvalidPointOnSurface,\
No3DCurve, Multiple3DCurve, Invalid3DCurve, NoCurveOnSurface,\
InvalidCurveOnSurface, InvalidCurveOnClosedSurface, InvalidSameRangeFlag,\
@@ -117,29 +186,45 @@ def fix_formatting(_str):
InvalidWire, RedundantWire, IntersectingWires, InvalidImbricationOfWires,\
EmptyShell, RedundantFace, UnorientableShape, NotClosed,\
NotConnected, SubshapeNotInShape, BadOrientation, BadOrientationOfSubshape,\
-InvalidToleranceValue, CheckFail")
-
-_brep_check_b = [BRepCheck_NoError, BRepCheck_InvalidPointOnCurve,
- BRepCheck_InvalidPointOnCurveOnSurface,
- BRepCheck_InvalidPointOnSurface,
- BRepCheck_No3DCurve, BRepCheck_Multiple3DCurve,
- BRepCheck_Invalid3DCurve, BRepCheck_NoCurveOnSurface,
- BRepCheck_InvalidCurveOnSurface,
- BRepCheck_InvalidCurveOnClosedSurface,
- BRepCheck_InvalidSameRangeFlag,
- BRepCheck_InvalidSameParameterFlag,
- BRepCheck_InvalidDegeneratedFlag, BRepCheck_FreeEdge,
- BRepCheck_InvalidMultiConnexity, BRepCheck_InvalidRange,
- BRepCheck_EmptyWire, BRepCheck_RedundantEdge,
- BRepCheck_SelfIntersectingWire, BRepCheck_NoSurface,
- BRepCheck_InvalidWire, BRepCheck_RedundantWire,
- BRepCheck_IntersectingWires,
- BRepCheck_InvalidImbricationOfWires,
- BRepCheck_EmptyShell, BRepCheck_RedundantFace,
- BRepCheck_UnorientableShape, BRepCheck_NotClosed,
- BRepCheck_NotConnected, BRepCheck_SubshapeNotInShape,
- BRepCheck_BadOrientation, BRepCheck_BadOrientationOfSubshape,
- BRepCheck_InvalidToleranceValue, BRepCheck_CheckFail]
+InvalidToleranceValue, CheckFail"
+)
+
+_brep_check_b = [
+ BRepCheck_NoError,
+ BRepCheck_InvalidPointOnCurve,
+ BRepCheck_InvalidPointOnCurveOnSurface,
+ BRepCheck_InvalidPointOnSurface,
+ BRepCheck_No3DCurve,
+ BRepCheck_Multiple3DCurve,
+ BRepCheck_Invalid3DCurve,
+ BRepCheck_NoCurveOnSurface,
+ BRepCheck_InvalidCurveOnSurface,
+ BRepCheck_InvalidCurveOnClosedSurface,
+ BRepCheck_InvalidSameRangeFlag,
+ BRepCheck_InvalidSameParameterFlag,
+ BRepCheck_InvalidDegeneratedFlag,
+ BRepCheck_FreeEdge,
+ BRepCheck_InvalidMultiConnexity,
+ BRepCheck_InvalidRange,
+ BRepCheck_EmptyWire,
+ BRepCheck_RedundantEdge,
+ BRepCheck_SelfIntersectingWire,
+ BRepCheck_NoSurface,
+ BRepCheck_InvalidWire,
+ BRepCheck_RedundantWire,
+ BRepCheck_IntersectingWires,
+ BRepCheck_InvalidImbricationOfWires,
+ BRepCheck_EmptyShell,
+ BRepCheck_RedundantFace,
+ BRepCheck_UnorientableShape,
+ BRepCheck_NotClosed,
+ BRepCheck_NotConnected,
+ BRepCheck_SubshapeNotInShape,
+ BRepCheck_BadOrientation,
+ BRepCheck_BadOrientationOfSubshape,
+ BRepCheck_InvalidToleranceValue,
+ BRepCheck_CheckFail,
+]
brepcheck_lut = EnumLookup(_brep_check_a, _brep_check_b)
curve_lut = EnumLookup(_curve_typesA, _curve_typesB)
@@ -160,21 +245,20 @@ def fix_formatting(_str):
classes = dir()
geom_classes = []
for elem in classes:
- if (elem.startswith('Geom') and not 'swig' in elem):
+ if elem.startswith("Geom") and not "swig" in elem:
geom_classes.append(elem)
def what_is_face(face):
- ''' Returns all class names for which this class can be downcasted
- '''
- if not face.ShapeType()==TopAbs_FACE:
- print '%s is not a TopAbs_FACE. Conversion impossible'
+ """Returns all class names for which this class can be downcasted"""
+ if not face.ShapeType() == TopAbs_FACE:
+ print("%s is not a TopAbs_FACE. Conversion impossible")
return None
hs = BRep_Tool_Surface(face)
obj = hs.GetObject()
result = []
for elem in classes:
- if (elem.startswith('Geom') and not 'swig' in elem):
+ if elem.startswith("Geom") and not "swig" in elem:
geom_classes.append(elem)
# Run the test for each class
for geom_class in geom_classes:
@@ -184,10 +268,9 @@ def what_is_face(face):
def face_is_plane(face):
- ''' Returns True if the TopoDS_Shape is a plane, False otherwise
- '''
+ """Returns True if the TopoDS_Shape is a plane, False otherwise"""
hs = BRep_Tool_Surface(face)
- downcast_result = Handle_Geom_Plane().DownCast(hs)
+ downcast_result = Geom_Plane().DownCast(hs)
# the handle is null if downcast failed or is not possible,
# that is to say the face is not a plane
if downcast_result.IsNull():
@@ -197,10 +280,9 @@ def face_is_plane(face):
def shape_is_cylinder(face):
- ''' Returns True is the TopoDS_Shape is a cylinder, False otherwise
- '''
+ """Returns True is the TopoDS_Shape is a cylinder, False otherwise"""
hs = BRep_Tool_Surface(face)
- downcast_result = Handle_Geom_CylindricalSurface().DownCast(hs)
+ downcast_result = Geom_CylindricalSurface().DownCast(hs)
if downcast_result.IsNull():
return False
else:
diff --git a/OCCUtils/vertex.py b/OCCUtils/vertex.py
index ea2dcb6..353326e 100644
--- a/OCCUtils/vertex.py
+++ b/OCCUtils/vertex.py
@@ -15,25 +15,25 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see
-from OCC.gp import gp_Pnt, gp_Vec, gp_Dir, gp_XYZ, gp_Pnt2d
-from OCC.TopoDS import TopoDS_Vertex
-from OCC.ShapeBuild import ShapeBuild_ReShape
+from OCC.Core.gp import gp_Pnt, gp_Vec, gp_Dir, gp_XYZ, gp_Pnt2d
+from OCC.Core.TopoDS import TopoDS_Vertex
+from OCC.Core.ShapeBuild import ShapeBuild_ReShape
-from base import KbeObject
-from Construct import make_vertex
-from Common import vertex2pnt
+from OCCUtils.base import BaseObject
+from OCCUtils.Construct import make_vertex
-class Vertex(TopoDS_Vertex, KbeObject):
+class Vertex(TopoDS_Vertex, BaseObject):
"""
wraps gp_Pnt
"""
+
_n = 0
def __init__(self, x, y, z):
super(Vertex, self).__init__()
"""Constructor for KbeVertex"""
- KbeObject.__init__(self, name='Vertex #{0}'.format(self._n))
+ BaseObject.__init__(self, name="Vertex #{0}".format(self._n))
self._n += 1 # should be a property of KbeObject
self._pnt = gp_Pnt(x, y, z)
@@ -41,27 +41,17 @@ def __init__(self, x, y, z):
TopoDS_Vertex.__init__(self, self._vertex)
def _update(self):
- """
-
- """
+ """ """
# TODO: perhaps should take an argument until which topological level
# topological entities bound to the vertex should be updated too...
reshape = ShapeBuild_ReShape()
reshape.Replace(self._vertex, make_vertex(self._pnt))
- @staticmethod
- def from_vertex(cls, vertex):
- return Vertex.from_pnt(vertex2pnt(vertex))
-
@staticmethod
def from_pnt(cls, pnt):
- x, y, z = pnt.Coord()
+ x, y, z = pnt.X(), pnt.Y(), pnt.Z()
return cls(x, y, z)
- @classmethod
- def from_vec(cls):
- raise NotImplementedError
-
@property
def x(self):
return self._pnt.X()
@@ -103,17 +93,17 @@ def __repr__(self):
@property
def as_vec(self):
- '''returns a gp_Vec version of self'''
+ """returns a gp_Vec version of self"""
return gp_Vec(*self._pnt.Coord())
@property
def as_dir(self):
- '''returns a gp_Dir version of self'''
+ """returns a gp_Dir version of self"""
return gp_Dir(*self._pnt.Coord())
@property
def as_xyz(self):
- '''returns a gp_XYZ version of self'''
+ """returns a gp_XYZ version of self"""
return gp_XYZ(*self._pnt.Coord())
@property
@@ -122,5 +112,5 @@ def as_pnt(self):
@property
def as_2d(self):
- '''returns a gp_Pnt2d version of self'''
+ """returns a gp_Pnt2d version of self"""
return gp_Pnt2d(*self._pnt.Coord()[:2])
diff --git a/OCCUtils/wire.py b/OCCUtils/wire.py
index ef72bd9..97ca4c2 100644
--- a/OCCUtils/wire.py
+++ b/OCCUtils/wire.py
@@ -17,19 +17,20 @@
##You should have received a copy of the GNU Lesser General Public License
##along with pythonOCC. If not, see
-from OCC.TopoDS import TopoDS_Wire
+from OCC.Core.TopoDS import TopoDS_Wire
-from base import KbeObject
+from OCCUtils.base import BaseObject
-class Wire(TopoDS_Wire, KbeObject):
+class Wire(TopoDS_Wire, BaseObject):
def __init__(self, wire):
- '''
- '''
- assert isinstance(wire, TopoDS_Wire), 'need a TopoDS_Wire, got a %s' % wire.__class__
+ """ """
+ assert isinstance(wire, TopoDS_Wire), (
+ "need a TopoDS_Wire, got a %s" % wire.__class__
+ )
assert not wire.IsNull()
super(Wire, self).__init__()
- KbeObject.__init__(self, 'wire')
+ BaseObject.__init__(self, "wire")
# we need to copy the base shape using the following three
# lines
assert self.IsNull()
diff --git a/README.md b/README.md
index a295631..2886ede 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,4 @@
+[](https://travis-ci.org/tpaviot/pythonocc-utils)
+
# pythonocc-utils
A python package that provides useful classes/methods for pythonocc
diff --git a/examples/occutils_geomplate.py b/examples/occutils_geomplate.py
index 5cedfa8..16795ff 100644
--- a/examples/occutils_geomplate.py
+++ b/examples/occutils_geomplate.py
@@ -28,21 +28,21 @@
import sys
import time
-from OCC.gp import gp_Pnt
-from OCC.BRepAdaptor import BRepAdaptor_HCurve
-from OCC.BRep import BRep_Tool
-from OCC.ShapeAnalysis import ShapeAnalysis_Surface
-from OCC.GeomLProp import GeomLProp_SLProps
-from OCC.BRepFill import BRepFill_CurveConstraint
-from OCC.GeomPlate import (GeomPlate_MakeApprox,
+from OCC.Core.gp import gp_Pnt
+from OCC.Core.BRepAdaptor import BRepAdaptor_Curve
+from OCC.Core.BRep import BRep_Tool
+from OCC.Core.ShapeAnalysis import ShapeAnalysis_Surface
+from OCC.Core.GeomLProp import GeomLProp_SLProps
+from OCC.Core.BRepFill import BRepFill_CurveConstraint
+from OCC.Core.GeomPlate import (GeomPlate_MakeApprox,
GeomPlate_BuildPlateSurface,
GeomPlate_PointConstraint)
-from OCC.IGESControl import IGESControl_Reader
-from OCC.IFSelect import (IFSelect_RetDone,
+from OCC.Core.IGESControl import IGESControl_Reader
+from OCC.Core.IFSelect import (IFSelect_RetDone,
IFSelect_ItemsByEntity)
from OCC.Display.SimpleGui import init_display
-from OCC.TopoDS import TopoDS_Compound
-from OCC.BRep import BRep_Builder
+from OCC.Core.TopoDS import TopoDS_Compound
+from OCC.Core.BRep import BRep_Builder
display, start_display, add_menu, add_function_to_menu = init_display()
@@ -154,7 +154,7 @@ def build_plate(polygon, points):
# add curve constraints
for poly in polygon:
for edg in WireExplorer(poly).ordered_edges():
- c = BRepAdaptor_HCurve()
+ c = BRepAdaptor_Curve()
c.ChangeCurve().Initialize(edg)
constraint = BRepFill_CurveConstraint(c.GetHandle(), 0)
bpSrf.Add(constraint.GetHandle())
@@ -270,7 +270,7 @@ def build_geom_plate(edges):
# add curve constraints
for edg in edges:
- c = BRepAdaptor_HCurve()
+ c = BRepAdaptor_Curve()
print('edge:', edg)
c.ChangeCurve().Initialize(edg)
constraint = BRepFill_CurveConstraint(c.GetHandle(), 0)
diff --git a/test/occutils_test.py b/test/occutils_test.py
index 50233fa..451a9ba 100644
--- a/test/occutils_test.py
+++ b/test/occutils_test.py
@@ -20,10 +20,11 @@
import unittest
import sys
+sys.path.append('../')
sys.path.append('../OCCUtils')
-from OCC.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeSphere
-from OCC.TopoDS import TopoDS_Face, TopoDS_Edge
+from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeSphere
+from OCC.Core.TopoDS import TopoDS_Face, TopoDS_Edge
from Topology import Topo, WireExplorer
from edge import Edge
@@ -87,59 +88,59 @@ def test_kept_reference(self):
_tmp.append(0 == f.IsNull())
for f in _faces:
_tmp.append(0 == f.IsNull())
- self.assert_(all(_tmp))
+ self.assertTrue(all(_tmp))
def test_edge_face(self):
- edg = self.topo.edges().next()
- face = self.topo.faces().next()
+ edg = next(self.topo.edges())
+ face = next(self.topo.faces())
faces_from_edge = [i for i in self.topo.faces_from_edge(edg)]
- self.assert_(len(faces_from_edge) == self.topo.number_of_faces_from_edge(edg))
+ self.assertTrue(len(faces_from_edge) == self.topo.number_of_faces_from_edge(edg))
edges_from_face = [i for i in self.topo.edges_from_face(face)]
- self.assert_(len(edges_from_face) == self.topo.number_of_edges_from_face(face))
+ self.assertTrue(len(edges_from_face) == self.topo.number_of_edges_from_face(face))
def test_edge_wire(self):
- edg = self.topo.edges().next()
- wire = self.topo.wires().next()
+ edg = next(self.topo.edges())
+ wire = next(self.topo.wires())
wires_from_edge = [i for i in self.topo.wires_from_edge(edg)]
- self.assert_(len(wires_from_edge) == self.topo.number_of_wires_from_edge(edg))
+ self.assertTrue(len(wires_from_edge) == self.topo.number_of_wires_from_edge(edg))
edges_from_wire = [i for i in self.topo.edges_from_wire(wire)]
- self.assert_(len(edges_from_wire) == self.topo.number_of_edges_from_wire(wire))
+ self.assertTrue(len(edges_from_wire) == self.topo.number_of_edges_from_wire(wire))
def test_vertex_edge(self):
- vert = self.topo.vertices().next()
- edge = self.topo.edges().next()
+ vert = next(self.topo.vertices())
+ edge = next(self.topo.edges())
verts_from_edge = [i for i in self.topo.vertices_from_edge(edge)]
- self.assert_(len(verts_from_edge) == self.topo.number_of_vertices_from_edge(edge))
+ self.assertTrue(len(verts_from_edge) == self.topo.number_of_vertices_from_edge(edge))
edges_from_vert = [i for i in self.topo.edges_from_vertex(vert)]
- self.assert_(len(edges_from_vert) == self.topo.number_of_edges_from_vertex(vert))
+ self.assertTrue(len(edges_from_vert) == self.topo.number_of_edges_from_vertex(vert))
def test_vertex_face(self):
- vert = self.topo.vertices().next()
- face = self.topo.faces().next()
+ vert = next(self.topo.vertices())
+ face = next(self.topo.faces())
faces_from_vertex = [i for i in self.topo.faces_from_vertex(vert)]
- self.assert_(len(faces_from_vertex) == self.topo.number_of_faces_from_vertex(vert))
+ self.assertTrue(len(faces_from_vertex) == self.topo.number_of_faces_from_vertex(vert))
verts_from_face = [i for i in self.topo.vertices_from_face(face)]
- self.assert_(len(verts_from_face) == self.topo.number_of_vertices_from_face(face))
+ self.assertTrue(len(verts_from_face) == self.topo.number_of_vertices_from_face(face))
def test_face_solid(self):
- face = self.topo.faces().next()
- solid = self.topo.solids().next()
+ face = next(self.topo.faces())
+ solid = next(self.topo.solids())
faces_from_solid = [i for i in self.topo.faces_from_solids(solid)]
- self.assert_(len(faces_from_solid) == self.topo.number_of_faces_from_solids(solid))
+ self.assertTrue(len(faces_from_solid) == self.topo.number_of_faces_from_solids(solid))
solids_from_face = [i for i in self.topo.solids_from_face(face)]
- self.assert_(len(solids_from_face) == self.topo.number_of_solids_from_face(face))
+ self.assertTrue(len(solids_from_face) == self.topo.number_of_solids_from_face(face))
def test_wire_face(self):
- wire = self.topo.wires().next()
- face = self.topo.faces().next()
+ wire = next(self.topo.wires())
+ face = next(self.topo.faces())
faces_from_wire = [i for i in self.topo.faces_from_wire(wire)]
- self.assert_(len(faces_from_wire) == self.topo.number_of_faces_from_wires(wire))
+ self.assertTrue(len(faces_from_wire) == self.topo.number_of_faces_from_wires(wire))
wires_from_face = [i for i in self.topo.wires_from_face(face)]
- self.assert_(len(wires_from_face) == self.topo.number_of_wires_from_face(face))
+ self.assertTrue(len(wires_from_face) == self.topo.number_of_wires_from_face(face))
def test_edges_out_of_scope(self):
# check pointers going out of scope
- face = self.topo.faces().next()
+ face = next(self.topo.faces())
_edges = []
for edg in Topo(face).edges():
_edges.append(edg)
@@ -148,7 +149,7 @@ def test_edges_out_of_scope(self):
def test_wires_out_of_scope(self):
# check pointers going out of scope
- wire = self.topo.wires().next()
+ wire = next(self.topo.wires())
_edges, _vertices = [], []
for edg in WireExplorer(wire).ordered_edges():
_edges.append(edg)
@@ -166,7 +167,7 @@ def test_creat_edge(self):
b = get_test_box_shape()
# take the first edge
t = Topo(b)
- edge_0 = t.edges().next() # it's a TopoDS_Edge
+ edge_0 = next(t.edges()) # it's a TopoDS_Edge
assert not edge_0.IsNull()
# then create an edge
my_edge = Edge(edge_0)
@@ -192,7 +193,7 @@ def test_creat_face(self):
b = get_test_box_shape()
# take the first edge
t = Topo(b)
- wire = t.wires().next()
+ wire = next(t.wires())
my_wire = Wire(wire)
assert not my_wire.IsNull()
assert my_wire.tolerance == 1e-06