コード例 #1
0
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();
}