PointOnFacesProjector::Result PointOnFacesProjector::projected(const gp_Pnt& point) const { // Find the closest node in the triangulations internal::NodeBndBoxSelector selector(point); if (d->m_ubTree.Select(selector) <= 0) return PointOnFacesProjector::Result(); const int minNodeId = selector.minDistanceNodeIndex().first; const Handle_Poly_Triangulation& triangulation = selector.minDistanceNodeIndex().second; // Find the triangle where distance is minimum const TColgp_Array1OfPnt& nodes = triangulation->Nodes(); const Poly_Array1OfTriangle& triangles = triangulation->Triangles(); double minDist = std::numeric_limits<double>::max(); const Poly_Triangle* minTriangle = NULL; gp_Pnt projectedPnt; for (int iTri = triangles.Lower(); iTri <= triangles.Upper(); iTri++) { const Poly_Triangle& t = triangles(iTri); int n1, n2, n3; t.Get(n1, n2, n3); if (minNodeId == n1 || minNodeId == n2 || minNodeId == n3) { const std::pair<gp_Pnt, bool> projPntInfo = math::projectPointOnTriangle(point, nodes(t(1)), nodes(t(2)), nodes(t(3))); const double dist = point.SquareDistance(projPntInfo.first); if (dist < minDist) { minTriangle = &t; minDist = dist; projectedPnt = projPntInfo.first; } } } if (minTriangle != NULL) { const TopoDS_Face* face = d->triangulationToFace(triangulation); const TopAbs_Orientation faceOrientation = face != NULL ? face->Orientation() : TopAbs_FORWARD; const gp_Vec triNormal = occ::MathTools::triangleNormal(nodes, *minTriangle, faceOrientation); return PointOnFacesProjector::Result(face != NULL ? *face : TopoDS_Face(), projectedPnt, triNormal); } return PointOnFacesProjector::Result(); }