def face_normal(face): 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) norm = props.Normal() if face.Orientation() == TopAbs_REVERSED: norm.Reverse() return norm
def axs_curvature(h_surf, u=0, v=0): prop = GeomLProp_SLProps(2, 0.01) prop.SetSurface(h_surf) prop.SetParameters(u, v) d1, d2 = gp_Dir(), gp_Dir() prop.CurvatureDirections(d1, d2) vz = dir_to_vec(prop.Normal()) v1 = dir_to_vec(d1) v2 = dir_to_vec(d2) c1 = prop.MaxCurvature() c2 = prop.MinCurvature() if c1 == 0: r1 = 0 else: r1 = 1 / c1 if c2 == 0: r2 = 0 else: r2 = 1 / c2 print("Max", c1, r1, v1) print("Min", c2, r1, v2) print(v1.Dot(v2)) print(prop.Value()) return vz, v1, v2, r1, r2
def normal_to_face_center(face): u_min, u_max, v_min, v_max = breptools_UVBounds(face) u_mid = (u_min + u_max) / 2. v_mid = (v_min + v_max) / 2. surf = BRep_Tool_Surface(face) normal = GeomLProp_SLProps(surf,u_mid, v_mid,1,0.01).Normal() if face.Orientation() == TopAbs_REVERSED: normal.Reverse() return normal
def ask_point_normal_face(uv, face): """ Ask the normal vector of a point given the uv coordinate of the point on a face """ surface = BRep_Tool().Surface(face) props = GeomLProp_SLProps(surface, uv[0], uv[1], 1, 1e-6) # GeomLProp_SLProps.SetParameters(surface,uv[0],uv[1]) # GeomLProp_SLProps.SetSurface(surface) gpDir = props.Normal() # gp_Dir type if face.Orientation() == TopAbs_REVERSED: gpDir.Reverse() # print("face reversed") return gpDir.Coord()
def second_derivative(h_surf, u=0, v=0): p1 = gp_Pnt() pu, pv = gp_Vec(), gp_Vec() puu, pvv = gp_Vec(), gp_Vec() puv = gp_Vec() prop = GeomLProp_SLProps(h_surf, u, v, 1, 1) GeomLProp_SurfaceTool.D2(h_surf, u, v, p1, pu, pv, puu, pvv, puv) e0 = pu.Crossed(pv) pu.Normalize() pv.Normalize() e0.Normalize() puu.Normalize() pvv.Normalize() puv.Normalize() print(p1) print("pu", pu) print("pv", pv) print("e0", e0) print("puu", puu) print("pvv", pvv) print("puv", puv) first_form = np.array([[pu.Dot(pu), pu.Dot(pv)], [pv.Dot(pu), pv.Dot(pv)]]) secnd_form = np.array([[e0.Dot(puu), e0.Dot(puv)], [e0.Dot(puv), e0.Dot(pvv)]]) print(first_form) print(secnd_form) print(prop.GaussianCurvature()) print(prop.MeanCurvature()) d1, d2 = gp_Dir(), gp_Dir() prop.CurvatureDirections(d1, d2) a1 = gp_Ax3() v1 = dir_to_vec(d1) v2 = dir_to_vec(d2) if pu.IsParallel(v1, 1 / 1000): c1 = prop.MaxCurvature() c2 = prop.MinCurvature() print(v1.Dot(pu), v1.Dot(pv)) print(v2.Dot(pu), v2.Dot(pv)) else: c1 = prop.MinCurvature() c2 = prop.MaxCurvature() print(v1.Dot(pu), v1.Dot(pv)) print(v2.Dot(pu), v2.Dot(pv)) print(c1, 1 / c1) print(c2, 1 / c2) px = np.linspace(-1, 1, 100) * 100 p1_y = px**2 / c1 p2_y = px**2 / c1 curv1 = curv_spl(px, p1_y) curv2 = curv_spl(px, p2_y)
def __init__(self): super().__init__() self.axs = gp_Ax3() self.radi = [500, 200] self.rxyz = [1.5, 1.2, 1.5] mat = gp_Mat(self.rxyz[0], 0, 0, 0, self.rxyz[1], 0, 0, 0, self.rxyz[2]) gtrf = gp_GTrsf(mat, gp_XYZ(0, 0, 0)) #self.t = Geom_ToroidalSurface(self.axs, *self.radi) self.t = Geom_SphericalSurface(self.axs, 100.0) self.face = BRepBuilderAPI_MakeFace(self.t, 1e-6).Face() self.face = BRepBuilderAPI_GTransform(self.face, gtrf).Shape() self.surf = BRep_Tool.Surface(self.face) self.prop = GeomLProp_SLProps(self.surf, 0.0, 0.0, 1, 1.0) self.export_stp(self.face) print(self.t.UPeriod())
class Torus (plotocc): def __init__(self): super().__init__() self.axs = gp_Ax3() self.radi = [500, 200] self.rxyz = [1.0, 1.1, 1.1] mat = gp_Mat( self.rxyz[0], 0, 0, 0, self.rxyz[1], 0, 0, 0, self.rxyz[2] ) gtrf = gp_GTrsf(mat, gp_XYZ(0, 0, 0)) self.t = Geom_ToroidalSurface(self.axs, *self.radi) self.face = BRepBuilderAPI_MakeFace(self.t, 1e-6).Face() self.face = BRepBuilderAPI_GTransform(self.face, gtrf).Shape() self.surf = BRep_Tool.Surface(self.face) self.prop = GeomLProp_SLProps(self.surf, 0.0, 0.0, 1, 1.0) self.export_stp(self.face) print(self.t.UPeriod()) def get_prof(self, uv=[0, 0]): u, v = uv u1, v1 = 2 * np.pi * u, 2 * np.pi * v p, vu, vv = gp_Pnt(), gp_Vec(), gp_Vec() self.surf.D1(u1, v1, p, vu, vv) self.prop.SetParameters(u1, v1) vx = vu.Normalized() vy = vv.Normalized() vz = vx.Crossed(vy) print(u, v) print(p) print(vx) print(vy) print(vz) print(self.prop.GaussianCurvature()) print(self.prop.MaxCurvature()) print(self.prop.MinCurvature()) print(self.prop.MeanCurvature()) self.display.DisplayShape(p) self.display.DisplayVector(vz.Scaled(20), p) return p, vu, vv, vz def ShowTorus(self): self.display.DisplayShape(self.face, transparency=0.7) self.show_axs_pln(scale=100) self.show()
def radius_at_uv(face, u, v): ''' returns the mean radius at a u,v coordinate @param face: surface input @param u,v: u,v coordinate ''' h_srf = BRep_Tool().Surface(face) # uv_domain = GeomLProp_SurfaceTool().Bounds(h_srf) curvature = GeomLProp_SLProps(h_srf, u, v, 1, 1e-6) try: _crv_min = 1. / curvature.MinCurvature() except ZeroDivisionError: _crv_min = 0. try: _crv_max = 1. / curvature.MaxCurvature() except ZeroDivisionError: _crv_max = 0. return abs((_crv_min + _crv_max) / 2.)
def sample_point(face): # randomly choose a point from F u_min, u_max, v_min, v_max = breptools_UVBounds(face) u = random.uniform(u_min, u_max) v = random.uniform(v_min, v_max) itool = IntTools_FClass2d(face, 1e-6) while itool.Perform(gp_Pnt2d(u,v)) != 0: print('outside') u = random.uniform(u_min, u_max) v = random.uniform(v_min, v_max) P = BRepAdaptor_Surface(face).Value(u, v) # the normal surf = BRep_Tool_Surface(face) D = GeomLProp_SLProps(surf,u,v,1,0.01).Normal() if face.Orientation() == TopAbs_REVERSED: D.Reverse() return P, D
def curvature(self, u, v): '''returns the curvature at the u parameter the curvature object can be returned too using curvatureType == curvatureType curvatureTypes are: gaussian minimum maximum mean curvatureType ''' if not self._curvature_initiated: 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('<<<CORRECTING DOMAIN...>>>') div = 1000 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] if low < hi: u = u - delta_u else: u = u + delta_u if v in _domain: low, hi = v - _domain[2], v - _domain[3] if low < hi: v = v - delta_v else: v = v + delta_v self._curvature.SetParameters(u, v) self._curvature_initiated = True return self._curvature
def curvature_at(self, u, v): """Compute the curvature at a point on the surface. Parameters ---------- u : float v : float Returns ------- :class:`~compas.geometry.Vector` """ props = GeomLProp_SLProps(self.occ_surface, u, v, 2, 1e-6) gaussian = props.GaussianCurvature() mean = props.MeanCurvature() point = props.Value() normal = props.Normal() return gaussian, mean, Point.from_occ(point), Vector.from_occ(normal)
class DiffGeomSurface(object): def __init__(self, instance): self.instance = instance self._curvature = None self._curvature_initiated = False def curvature(self, u, v): '''returns the curvature at the u parameter the curvature object can be returned too using curvatureType == curvatureType curvatureTypes are: gaussian minimum maximum mean curvatureType ''' if not self._curvature_initiated: self._curvature = GeomLProp_SLProps(self.instance.surface_handle, u, v, 2, 1e-7) _domain = self.instance.domain() if u in _domain or v in _domain: print('<<<CORRECTING DOMAIN...>>>') div = 1000 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] if low < hi: u = u - delta_u else: u = u + delta_u if v in _domain: low, hi = v-_domain[2], v-_domain[3] if low < hi: v = v - delta_v else: v = v + delta_v self._curvature.SetParameters(u, v) self._curvature_initiated = True return self._curvature def gaussian_curvature(self, u, v): return self.curvature(u, v).GaussianCurvature() def min_curvature(self, u, v): return self.curvature(u, v).MinCurvature() def mean_curvature(self, u, v): return self.curvature(u, v).MeanCurvature() def max_curvature(self, u, v): return self.curvature(u, v).MaxCurvature() def normal(self, u, v): # TODO: should make this return a gp_Vec curv = self.curvature(u, v) if curv.IsNormalDefined(): return curv.Normal() else: 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() curv = self.curvature(u, v) if curv.IsTangentUDefined() and curv.IsTangentVDefined(): curv.TangentU(dU), curv.TangentV(dV) return dU, dV else: return None, None def radius(self, u, v): '''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) except ZeroDivisionError: _crv_min = 0. try: _crv_max = 1./self.max_curvature(u, v) except ZeroDivisionError: _crv_max = 0. return abs((_crv_min+_crv_max)/2.)
ax1 = gp_Ax3(gp_Pnt(150, 150, -20), gp_Dir(0.5, 0.1, 1.0), gp_Dir(0.0, 0.1, 1.0)) pnt = ax1.Location() api = GeomAPI_ProjectPointOnSurf(pnt, surf) print(api.NbPoints(), api.NearestPoint()) for i in range(api.NbPoints()): idx = i + 1 u, v = api.Parameters(idx) obj.display.DisplayShape(api.Point(idx)) print(idx, u, v) print(GeomAPI_IntCS(Geom_Line(ax1.Axis()), surf).NbPoints()) u, v, w = GeomAPI_IntCS(Geom_Line(ax1.Axis()), surf).Parameters(1) p, vx, vy = gp_Pnt(), gp_Vec(), gp_Vec() api = GeomLProp_SLProps(surf, u, v, 1, 0.1E-03) pnt = api.Value() dst = pnt.Distance(ax1.Location()) ax2 = obj.prop_axs(ax1, dst) rim_u = surf.UIso(u) rim_v = surf.VIso(v) print(v, rim_u.FirstParameter(), rim_u.LastParameter()) print(u, rim_v.FirstParameter(), rim_v.LastParameter()) obj.display.DisplayShape(rim_u, color="BLUE") obj.display.DisplayShape(rim_v, color="BLUE") print(api.GaussianCurvature()) print(api.MinCurvature(), api.MeanCurvature(), api.MaxCurvature()) print(dir_to_vec(api.Normal())) du, dv = gp_Dir(), gp_Dir() api.TangentU(du) api.TangentV(dv)