- added "measurement lines"
This commit is contained in:
@@ -235,6 +235,93 @@ class OCGeometryKernel(GeometryKernel):
|
||||
pass
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def find_coplanar_face(
|
||||
shape: Any,
|
||||
origin: Tuple[float, float, float],
|
||||
normal: Tuple[float, float, float],
|
||||
ref_center: Optional[Tuple[float, float, float]] = None,
|
||||
angle_tol_deg: float = 5.0,
|
||||
dist_tol: float = 1e-3,
|
||||
) -> Optional[Tuple[Any, Tuple[float, float, float]]]:
|
||||
"""Find a planar face on *shape* coplanar with the given plane.
|
||||
|
||||
Iterates the faces of *shape* and returns the first planar face whose
|
||||
plane normal is parallel to *normal* (within *angle_tol_deg* degrees)
|
||||
and whose plane passes through *origin* (within *dist_tol* distance).
|
||||
When several faces match, the one whose surface centre is closest to
|
||||
*ref_center* (if provided) is preferred.
|
||||
|
||||
Returns ``(face, center)`` where *center* is the surface centroid as a
|
||||
3-tuple, or *None* if no matching face is found.
|
||||
"""
|
||||
import math
|
||||
|
||||
from OCP.TopExp import TopExp_Explorer
|
||||
from OCP.TopAbs import TopAbs_FACE
|
||||
from OCP.TopoDS import TopoDS
|
||||
from OCP.BRepAdaptor import BRepAdaptor_Surface
|
||||
from OCP.GeomAbs import GeomAbs_Plane
|
||||
from OCP.BRepGProp import BRepGProp
|
||||
from OCP.GProp import GProp_GProps
|
||||
|
||||
import numpy as np
|
||||
|
||||
if shape is None:
|
||||
return None
|
||||
n = np.asarray(normal, dtype=float)
|
||||
n = n / (np.linalg.norm(n) + 1e-30)
|
||||
ox, oy, oz = origin
|
||||
|
||||
cos_tol = math.cos(math.radians(angle_tol_deg))
|
||||
candidates: list = []
|
||||
|
||||
explorer = TopExp_Explorer(shape, TopAbs_FACE)
|
||||
while explorer.More():
|
||||
face = TopoDS.Face_s(explorer.Current())
|
||||
try:
|
||||
surf = BRepAdaptor_Surface(face)
|
||||
if surf.GetType() != GeomAbs_Plane:
|
||||
explorer.Next()
|
||||
continue
|
||||
plane = surf.Plane()
|
||||
pn = np.array(
|
||||
[
|
||||
plane.Axis().Direction().X(),
|
||||
plane.Axis().Direction().Y(),
|
||||
plane.Axis().Direction().Z(),
|
||||
],
|
||||
dtype=float,
|
||||
)
|
||||
# Check normals parallel (same or opposite direction)
|
||||
cos_angle = abs(float(np.dot(n, pn)))
|
||||
if cos_angle < cos_tol:
|
||||
explorer.Next()
|
||||
continue
|
||||
# Check distance from plane to origin
|
||||
pp = plane.Location()
|
||||
d = abs(float(np.dot(n, np.array([pp.X() - ox, pp.Y() - oy, pp.Z() - oz]))))
|
||||
if d > dist_tol:
|
||||
explorer.Next()
|
||||
continue
|
||||
# Surface centroid via GProp (SurfaceProperties for faces)
|
||||
props = GProp_GProps()
|
||||
BRepGProp.SurfaceProperties_s(face, props)
|
||||
c = props.CentreOfMass()
|
||||
center = (float(c.X()), float(c.Y()), float(c.Z()))
|
||||
candidates.append((face, center))
|
||||
except Exception:
|
||||
pass
|
||||
explorer.Next()
|
||||
|
||||
if not candidates:
|
||||
return None
|
||||
if ref_center is not None and len(candidates) > 1:
|
||||
rc = np.asarray(ref_center, dtype=float)
|
||||
best = min(candidates, key=lambda fc: float(np.linalg.norm(np.asarray(fc[1]) - rc)))
|
||||
return best
|
||||
return candidates[0]
|
||||
|
||||
def revolve(
|
||||
self,
|
||||
sketch: GeometryObject,
|
||||
|
||||
Reference in New Issue
Block a user