1 // Copyright (C) 2017-2022 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : FrontTrack_Projector.cxx
20 // Created : Wed Apr 26 20:33:55 2017
21 // Author : Edward AGAPOV (eap)
23 #include "FrontTrack_Projector.hxx"
25 #include <BRepAdaptor_Curve.hxx>
26 #include <BRepBndLib.hxx>
27 #include <BRepTopAdaptor_FClass2d.hxx>
28 #include <BRep_Tool.hxx>
31 #include <GCPnts_UniformDeflection.hxx>
32 #include <GeomAdaptor_Curve.hxx>
33 #include <GeomLib_IsPlanarSurface.hxx>
34 #include <ShapeAnalysis_Curve.hxx>
35 #include <ShapeAnalysis_Surface.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Face.hxx>
40 #include <TopoDS_Vertex.hxx>
41 #include <gp_Circ.hxx>
42 #include <gp_Cylinder.hxx>
46 #include <gp_Sphere.hxx>
51 //-----------------------------------------------------------------------------
53 * \brief Root class of a projector of a point to a boundary shape
55 struct FT_RealProjector
57 virtual ~FT_RealProjector() {}
60 * \brief Project a point to a boundary shape
61 * \param [in] point - the point to project
62 * \param [out] newSolution - position on the shape (U or UV) found during the projection
63 * \param [in] prevSolution - position already found during the projection of a neighbor point
64 * \return gp_Pnt - the projection point
66 virtual gp_Pnt project( const gp_Pnt& point,
68 const double* prevSolution = 0) = 0;
71 * \brief Project a point to a boundary shape and check if the projection is within
73 * \param [in] point - the point to project
74 * \param [in] maxDist2 - the maximal allowed square distance between point and projection
75 * \param [out] projection - the projection point
76 * \param [out] newSolution - position on the shape (U or UV) found during the projection
77 * \param [in] prevSolution - position already found during the projection of a neighbor point
78 * \return bool - false if the projection point lies out of the shape boundary or
79 the distance the point and the projection is more than sqrt(maxDist2)
81 virtual bool projectAndClassify( const gp_Pnt& point,
82 const double maxDist2,
85 const double* prevSolution = 0) = 0;
87 // return true if a previously found solution can be used to speed up the projection
89 virtual bool canUsePrevSolution() const { return false; }
92 double _dist; // distance between the point being projected and its projection
95 namespace // actual projection algorithms
97 const double theEPS = 1e-12;
99 //================================================================================
101 * \brief Projector to any curve
103 //================================================================================
105 struct CurveProjector : public FT_RealProjector
107 BRepAdaptor_Curve _curve;
109 ShapeAnalysis_Curve _projector;
112 //-----------------------------------------------------------------------------
113 CurveProjector( const TopoDS_Edge& e, const double tol ):
114 _curve( e ), _tol( tol )
116 BRep_Tool::Range( e, _uRange[0], _uRange[1] );
119 //-----------------------------------------------------------------------------
120 // project a point to the curve
121 virtual gp_Pnt project( const gp_Pnt& P,
123 const double* prevSolution = 0)
126 std::cout << ".. project a point to the curve prevSolution = " << prevSolution << std::endl;
133 _dist = _projector.NextProject( prevSolution[0], _curve, P, _tol, proj, param );
137 _dist = _projector.Project( _curve, P, _tol, proj, param, false );
140 std::cout << ".. _dist : " << _dist << std::endl;
142 proj = _curve.Value( param );
144 newSolution[0] = param;
149 //-----------------------------------------------------------------------------
150 // project a point to a curve and check if the projection is within the curve boundary
151 virtual bool projectAndClassify( const gp_Pnt& point,
152 const double maxDist2,
155 const double* prevSolution = 0)
158 std::cout << ".. project a point to a curve and check " << std::endl;
160 projection = project( point, newSolution, prevSolution );
161 return ( _uRange[0] < newSolution[0] && newSolution[0] < _uRange[1] &&
162 _dist * _dist < maxDist2 );
165 //-----------------------------------------------------------------------------
166 // return true if a previously found solution can be used to speed up the projection
167 virtual bool canUsePrevSolution() const { return true; }
170 //================================================================================
172 * \brief Projector to a straight curve. Don't project, classify only
174 //================================================================================
176 struct LineProjector : public FT_RealProjector
180 //-----------------------------------------------------------------------------
181 LineProjector( TopoDS_Edge e )
183 e.Orientation( TopAbs_FORWARD );
184 _p0 = BRep_Tool::Pnt( TopExp::FirstVertex( e ));
185 _p1 = BRep_Tool::Pnt( TopExp::LastVertex ( e ));
188 //-----------------------------------------------------------------------------
190 virtual gp_Pnt project( const gp_Pnt& P,
192 const double* prevSolution = 0)
196 //-----------------------------------------------------------------------------
197 // check if a point lies within the line segment
198 virtual bool projectAndClassify( const gp_Pnt& point,
199 const double maxDist2,
202 const double* prevSolution = 0)
204 gp_Vec edge( _p0, _p1 );
205 gp_Vec p0p ( _p0, point );
206 double u = ( edge * p0p ) / edge.SquareMagnitude(); // param [0,1] on the edge
207 projection = ( 1. - u ) * _p0.XYZ() + u * _p1.XYZ(); // projection of the point on the edge
208 if ( u < 0 || 1 < u )
212 return point.SquareDistance( projection ) < theEPS * theEPS;
216 //================================================================================
218 * \brief Projector to a circular edge
220 //================================================================================
222 struct CircleProjector : public FT_RealProjector
227 //-----------------------------------------------------------------------------
228 CircleProjector( const gp_Circ& c, const double f, const double l ):
235 //-----------------------------------------------------------------------------
236 // project a point to the circle
237 virtual gp_Pnt project( const gp_Pnt& P,
239 const double* prevSolution = 0)
241 // assume that P is already on the the plane of circle, since
242 // it is in the middle of two points lying on the circle
244 // move P to the circle
245 const gp_Pnt& O = _circle.Location();
246 gp_Vec radiusVec( O, P );
247 double radius = radiusVec.Magnitude();
248 if ( radius < std::numeric_limits<double>::min() )
249 return P; // P in on the axe
251 gp_Pnt proj = O.Translated( radiusVec.Multiplied( _circle.Radius() / radius ));
253 _dist = _circle.Radius() - radius;
258 //-----------------------------------------------------------------------------
259 // project and check if a projection lies within the circular edge
260 virtual bool projectAndClassify( const gp_Pnt& point,
261 const double maxDist2,
264 const double* prevSolution = 0)
267 projection = project( point, newSolution );
268 if ( _dist < 0 || // ?
269 _dist * _dist > maxDist2 )
272 newSolution[0] = ElCLib::Parameter( _circle, projection );
273 return ( _uRange[0] < newSolution[0] && newSolution[0] < _uRange[1] );
277 //================================================================================
279 * \brief Projector to any surface
281 //================================================================================
283 struct SurfaceProjector : public FT_RealProjector
285 ShapeAnalysis_Surface _projector;
287 BRepTopAdaptor_FClass2d* _classifier;
289 //-----------------------------------------------------------------------------
290 SurfaceProjector( const TopoDS_Face& face, const double tol, BRepTopAdaptor_FClass2d* cls ):
291 _projector( BRep_Tool::Surface( face )),
296 //-----------------------------------------------------------------------------
297 // delete _classifier
303 //-----------------------------------------------------------------------------
304 // project a point to a surface
305 virtual gp_Pnt project( const gp_Pnt& P,
307 const double* prevSolution = 0)
313 gp_Pnt2d prevUV( prevSolution[0], prevSolution[1] );
314 uv = _projector.NextValueOfUV( prevUV, P, _tol );
318 uv = _projector.ValueOfUV( P, _tol );
321 uv.Coord( newSolution[0], newSolution[1] );
323 gp_Pnt proj = _projector.Value( uv );
325 _dist = _projector.Gap();
330 //-----------------------------------------------------------------------------
331 // project a point to a surface and check if the projection is within the surface boundary
332 virtual bool projectAndClassify( const gp_Pnt& point,
333 const double maxDist2,
336 const double* prevSolution = 0)
338 projection = project( point, newSolution, prevSolution );
339 return ( _dist * _dist < maxDist2 ) && classify( newSolution );
342 //-----------------------------------------------------------------------------
343 // check if the projection is within the shape boundary
344 bool classify( const double* newSolution )
346 TopAbs_State state = _classifier->Perform( gp_Pnt2d( newSolution[0], newSolution[1]) );
347 return ( state != TopAbs_OUT );
350 //-----------------------------------------------------------------------------
351 // return true if a previously found solution can be used to speed up the projection
352 virtual bool canUsePrevSolution() const { return true; }
355 //================================================================================
357 * \brief Projector to a plane. Don't project, classify only
359 //================================================================================
361 struct PlaneProjector : public SurfaceProjector
364 bool _isRealPlane; // false means that a surface is planar but parametrization is different
366 //-----------------------------------------------------------------------------
367 PlaneProjector( const gp_Pln& pln,
368 const TopoDS_Face& face,
369 BRepTopAdaptor_FClass2d* cls,
370 bool isRealPlane=true):
371 SurfaceProjector( face, 0, cls ),
373 _isRealPlane( isRealPlane )
376 //-----------------------------------------------------------------------------
378 virtual gp_Pnt project( const gp_Pnt& P,
380 const double* prevSolution = 0)
384 //-----------------------------------------------------------------------------
385 // check if a point lies within the boundry of the planar face
386 virtual bool projectAndClassify( const gp_Pnt& point,
387 const double maxDist2,
390 const double* prevSolution = 0)
394 ElSLib::PlaneParameters( _plane.Position(), point, newSolution[0], newSolution[1]);
395 projection = ElSLib::PlaneValue ( newSolution[0], newSolution[1], _plane.Position() );
396 if ( projection.SquareDistance( point ) > theEPS * theEPS )
399 return SurfaceProjector::classify( newSolution );
403 return SurfaceProjector::projectAndClassify( point, maxDist2, projection,
404 newSolution, prevSolution );
407 //-----------------------------------------------------------------------------
408 // return true if a previously found solution can be used to speed up the projection
409 virtual bool canUsePrevSolution() const { return false; }
412 //================================================================================
414 * \brief Projector to a cylinder
416 //================================================================================
418 struct CylinderProjector : public SurfaceProjector
420 gp_Cylinder _cylinder;
422 //-----------------------------------------------------------------------------
423 CylinderProjector( const gp_Cylinder& c,
424 const TopoDS_Face& face,
425 BRepTopAdaptor_FClass2d* cls ):
426 SurfaceProjector( face, 0, cls ),
430 //-----------------------------------------------------------------------------
431 // project a point to the cylinder
432 virtual gp_Pnt project( const gp_Pnt& P,
434 const double* prevSolution = 0)
436 // project the point P to the cylinder axis -> Pp
437 const gp_Pnt& O = _cylinder.Position().Location();
438 const gp_Dir& axe = _cylinder.Position().Direction();
439 gp_Vec trsl = gp_Vec( axe ).Multiplied( gp_Vec( O, P ).Dot( axe ));
440 gp_Pnt Pp = O.Translated( trsl );
442 // move Pp to the cylinder
443 gp_Vec radiusVec( Pp, P );
444 double radius = radiusVec.Magnitude();
445 if ( radius < std::numeric_limits<double>::min() )
446 return P; // P in on the axe
448 gp_Pnt proj = Pp.Translated( radiusVec.Multiplied( _cylinder.Radius() / radius ));
450 _dist = _cylinder.Radius() - radius;
454 //-----------------------------------------------------------------------------
455 // project a point to the cylinder and check if the projection is within the surface boundary
456 virtual bool projectAndClassify( const gp_Pnt& point,
457 const double maxDist2,
460 const double* prevSolution = 0)
462 ElSLib::CylinderParameters( _cylinder.Position(), _cylinder.Radius(), point,
463 newSolution[0], newSolution[1]);
464 projection = ElSLib::CylinderValue( newSolution[0], newSolution[1],
465 _cylinder.Position(), _cylinder.Radius() );
466 _dist = point.Distance( projection );
468 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
470 //-----------------------------------------------------------------------------
471 // return true if a previously found solution can be used to speed up the projection
472 virtual bool canUsePrevSolution() const { return false; }
475 //================================================================================
477 * \brief Projector to a cone
479 //================================================================================
481 struct ConeProjector : public SurfaceProjector
485 //-----------------------------------------------------------------------------
486 ConeProjector( const gp_Cone& c,
487 const TopoDS_Face& face,
488 BRepTopAdaptor_FClass2d* cls ):
489 SurfaceProjector( face, 0, cls ),
493 //-----------------------------------------------------------------------------
494 // project a point to the cone
495 virtual gp_Pnt project( const gp_Pnt& point,
497 const double* prevSolution = 0)
499 ElSLib::ConeParameters( _cone.Position(), _cone.RefRadius(), _cone.SemiAngle(),
500 point, newSolution[0], newSolution[1]);
501 gp_Pnt proj = ElSLib::ConeValue( newSolution[0], newSolution[1],
502 _cone.Position(), _cone.RefRadius(), _cone.SemiAngle() );
503 _dist = point.Distance( proj );
508 //-----------------------------------------------------------------------------
509 // project a point to the cone and check if the projection is within the surface boundary
510 virtual bool projectAndClassify( const gp_Pnt& point,
511 const double maxDist2,
514 const double* prevSolution = 0)
516 projection = project( point, newSolution, prevSolution );
518 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
520 //-----------------------------------------------------------------------------
521 // return true if a previously found solution can be used to speed up the projection
522 virtual bool canUsePrevSolution() const { return false; }
525 //================================================================================
527 * \brief Projector to a sphere
529 //================================================================================
531 struct SphereProjector : public SurfaceProjector
535 //-----------------------------------------------------------------------------
536 SphereProjector( const gp_Sphere& s,
537 const TopoDS_Face& face,
538 BRepTopAdaptor_FClass2d* cls ):
539 SurfaceProjector( face, 0, cls ),
543 //-----------------------------------------------------------------------------
544 // project a point to the sphere
545 virtual gp_Pnt project( const gp_Pnt& P,
547 const double* prevSolution = 0)
549 // move Pp to the Sphere
550 const gp_Pnt& O = _sphere.Location();
551 gp_Vec radiusVec( O, P );
552 double radius = radiusVec.Magnitude();
553 if ( radius < std::numeric_limits<double>::min() )
554 return P; // P is on O
556 gp_Pnt proj = O.Translated( radiusVec.Multiplied( _sphere.Radius() / radius ));
558 _dist = _sphere.Radius() - radius;
563 //-----------------------------------------------------------------------------
564 // project a point to the sphere and check if the projection is within the surface boundary
565 virtual bool projectAndClassify( const gp_Pnt& point,
566 const double maxDist2,
569 const double* prevSolution = 0)
571 ElSLib::SphereParameters( _sphere.Position(), _sphere.Radius(), point,
572 newSolution[0], newSolution[1]);
573 projection = ElSLib::SphereValue( newSolution[0], newSolution[1],
574 _sphere.Position(), _sphere.Radius() );
576 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
578 //-----------------------------------------------------------------------------
579 // return true if a previously found solution can be used to speed up the projection
580 virtual bool canUsePrevSolution() const { return false; }
583 //================================================================================
585 * \brief Projector to a torus
587 //================================================================================
589 struct TorusProjector : public SurfaceProjector
593 //-----------------------------------------------------------------------------
594 TorusProjector( const gp_Torus& t,
595 const TopoDS_Face& face,
596 BRepTopAdaptor_FClass2d* cls ):
597 SurfaceProjector( face, 0, cls ),
601 //-----------------------------------------------------------------------------
602 // project a point to the torus
603 virtual gp_Pnt project( const gp_Pnt& point,
605 const double* prevSolution = 0)
607 ElSLib::TorusParameters( _torus.Position(), _torus.MajorRadius(), _torus.MinorRadius(),
608 point, newSolution[0], newSolution[1]);
609 gp_Pnt proj = ElSLib::TorusValue( newSolution[0], newSolution[1],
610 _torus.Position(), _torus.MajorRadius(), _torus.MinorRadius() );
611 _dist = point.Distance( proj );
616 //-----------------------------------------------------------------------------
617 // project a point to the torus and check if the projection is within the surface boundary
618 virtual bool projectAndClassify( const gp_Pnt& point,
619 const double maxDist2,
622 const double* prevSolution = 0)
624 projection = project( point, newSolution, prevSolution );
626 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
628 //-----------------------------------------------------------------------------
629 // return true if a previously found solution can be used to speed up the projection
630 virtual bool canUsePrevSolution() const { return false; }
633 //================================================================================
635 * \brief Check if a curve can be considered straight
637 //================================================================================
639 bool isStraight( const GeomAdaptor_Curve& curve, const double tol )
641 // rough check: evaluate how far from a straight line connecting the curve ends
642 // stand several internal points of the curve
644 const double f = curve.FirstParameter();
645 const double l = curve.LastParameter();
646 const gp_Pnt pf = curve.Value( f );
647 const gp_Pnt pl = curve.Value( l );
648 const gp_Vec lineVec( pf, pl );
649 const double lineLen2 = lineVec.SquareMagnitude();
650 if ( lineLen2 < std::numeric_limits< double >::min() )
651 return false; // E seems closed
653 const double nbSamples = 7;
654 for ( int i = 0; i < nbSamples; ++i )
656 const double r = ( i + 1 ) / nbSamples;
657 const gp_Pnt pi = curve.Value( f * r + l * ( 1 - r ));
658 const gp_Vec vi( pf, pi );
659 const double h2 = lineVec.Crossed( vi ).SquareMagnitude() / lineLen2;
660 if ( h2 > tol * tol )
665 GCPnts_UniformDeflection divider( curve, tol );
666 return ( divider.IsDone() && divider.NbPoints() < 3 );
670 //================================================================================
672 * \brief Initialize with a boundary shape
674 //================================================================================
676 FT_Projector::FT_Projector(const TopoDS_Shape& shape)
679 setBoundaryShape( shape );
680 _tryWOPrevSolution = false;
683 //================================================================================
685 * \brief Copy another projector
687 //================================================================================
689 FT_Projector::FT_Projector(const FT_Projector& other)
692 _shape = other._shape;
693 _bndBox = other._bndBox;
694 _tryWOPrevSolution = false;
697 //================================================================================
699 * \brief Destructor. Delete _realProjector
701 //================================================================================
703 FT_Projector::~FT_Projector()
705 delete _realProjector;
708 //================================================================================
710 * \brief Initialize with a boundary shape. Compute the bounding box
712 //================================================================================
714 void FT_Projector::setBoundaryShape(const TopoDS_Shape& shape)
716 delete _realProjector; _realProjector = 0;
718 if ( shape.IsNull() )
721 BRepBndLib::Add( shape, _bndBox );
722 _bndBox.Enlarge( 1e-5 * sqrt( _bndBox.SquareExtent() ));
725 //================================================================================
727 * \brief Create a real projector
729 //================================================================================
731 void FT_Projector::prepareForProjection()
733 if ( _shape.IsNull() || _realProjector )
736 if ( _shape.ShapeType() == TopAbs_EDGE )
738 const TopoDS_Edge& edge = TopoDS::Edge( _shape );
740 double tol = 1e-6 * sqrt( _bndBox.SquareExtent() );
743 Handle(Geom_Curve) curve = BRep_Tool::Curve( edge, f,l );
744 if ( curve.IsNull() )
745 return; // degenerated edge
747 GeomAdaptor_Curve acurve( curve, f, l );
748 switch ( acurve.GetType() )
751 _realProjector = new LineProjector( edge );
754 _realProjector = new CircleProjector( acurve.Circle(), f, l );
756 case GeomAbs_BezierCurve:
757 case GeomAbs_BSplineCurve:
758 case GeomAbs_OffsetCurve:
759 case GeomAbs_OtherCurve:
760 if ( isStraight( acurve, tol ))
762 _realProjector = new LineProjector( edge );
765 case GeomAbs_Ellipse:
766 case GeomAbs_Hyperbola:
767 case GeomAbs_Parabola:
768 _realProjector = new CurveProjector( edge, tol );
771 else if ( _shape.ShapeType() == TopAbs_FACE )
773 TopoDS_Face face = TopoDS::Face( _shape );
775 Handle(Geom_Surface) surface = BRep_Tool::Surface( face );
776 if ( surface.IsNull() )
779 GeomAdaptor_Surface asurface( surface );
780 Standard_Real tol = BRep_Tool::Tolerance( face );
781 Standard_Real toluv = Min( asurface.UResolution( tol ), asurface.VResolution( tol ));
782 BRepTopAdaptor_FClass2d* classifier = new BRepTopAdaptor_FClass2d( face, toluv );
784 switch ( asurface.GetType() )
787 _realProjector = new PlaneProjector( asurface.Plane(), face, classifier );
789 case GeomAbs_Cylinder:
790 _realProjector = new CylinderProjector( asurface.Cylinder(), face, classifier );
793 _realProjector = new SphereProjector( asurface.Sphere(), face, classifier );
796 _realProjector = new ConeProjector( asurface.Cone(), face, classifier );
799 _realProjector = new TorusProjector( asurface.Torus(), face, classifier );
801 case GeomAbs_BezierSurface:
802 case GeomAbs_BSplineSurface:
803 case GeomAbs_SurfaceOfRevolution:
804 case GeomAbs_SurfaceOfExtrusion:
805 case GeomAbs_OffsetSurface:
806 case GeomAbs_OtherSurface:
807 GeomLib_IsPlanarSurface isPlaneCheck( surface, tol );
808 if ( isPlaneCheck.IsPlanar() )
810 _realProjector = new PlaneProjector( isPlaneCheck.Plan(), face, classifier,
811 /*isRealPlane=*/false);
815 _realProjector = new SurfaceProjector( face, tol, classifier );
820 if ( !_realProjector )
825 //================================================================================
827 * \brief Return true if projection is not needed
829 //================================================================================
831 bool FT_Projector::isPlanarBoundary() const
833 return ( dynamic_cast< LineProjector* >( _realProjector ) ||
834 dynamic_cast< PlaneProjector* >( _realProjector ) );
837 //================================================================================
839 * \brief Check if a point lies on the boundary shape
840 * \param [in] point - the point to check
841 * \param [in] tol2 - a square tolerance allowing to decide whether a point is on the shape
842 * \param [in] newSolution - position on the shape (U or UV) of the point found
844 * \param [in] prevSolution - position on the shape (U or UV) of a neighbor point
845 * \return bool - \c true if the point lies on the boundary shape
847 * This method is used to select a shape by checking if all neighbor nodes of a node to move
850 //================================================================================
852 bool FT_Projector::isOnShape( const gp_Pnt& point,
855 const double* prevSolution)
857 if ( _bndBox.IsOut( point ) || !_realProjector )
861 if ( isPlanarBoundary() )
862 return projectAndClassify( point, tol2, proj, newSolution, prevSolution );
864 return project( point, tol2, proj, newSolution, prevSolution );
867 //================================================================================
869 * \brief Project a point to the boundary shape
870 * \param [in] point - the point to project
871 * \param [in] maxDist2 - the maximal square distance between the point and the projection
872 * \param [out] projection - the projection
873 * \param [out] newSolution - position on the shape (U or UV) of the point found
875 * \param [in] prevSolution - already found position on the shape (U or UV) of a neighbor point
876 * \return bool - false if the distance between the point and the projection
877 * is more than sqrt(maxDist2)
879 * This method is used to project a node in the case where only one shape is found by name
881 //================================================================================
883 bool FT_Projector::project( const gp_Pnt& point,
884 const double maxDist2,
887 const double* prevSolution)
889 if ( !_realProjector )
892 _realProjector->_dist = 1e100;
893 projection = _realProjector->project( point, newSolution, prevSolution );
895 bool ok = ( _realProjector->_dist * _realProjector->_dist < maxDist2 );
896 if ( !ok && _tryWOPrevSolution && prevSolution )
898 projection = _realProjector->project( point, newSolution );
899 ok = ( _realProjector->_dist * _realProjector->_dist < maxDist2 );
904 //================================================================================
906 * \brief Project a point to the boundary shape and check if the projection lies within
908 * \param [in] point - the point to project
909 * \param [in] maxDist2 - the maximal square distance between the point and the projection
910 * \param [out] projection - the projection
911 * \param [out] newSolution - position on the shape (U or UV) of the point found
913 * \param [in] prevSolution - already found position on the shape (U or UV) of a neighbor point
914 * \return bool - false if the projection point lies out of the shape boundary or
915 * the distance between the point and the projection is more than sqrt(maxDist2)
917 * This method is used to project a node in the case where several shapes are selected for
918 * projection of a node group
920 //================================================================================
922 bool FT_Projector::projectAndClassify( const gp_Pnt& point,
923 const double maxDist2,
926 const double* prevSolution)
928 if ( _bndBox.IsOut( point ) || !_realProjector )
931 bool ok = _realProjector->projectAndClassify( point, maxDist2, projection,
932 newSolution, prevSolution );
933 if ( !ok && _tryWOPrevSolution && prevSolution )
934 ok = _realProjector->projectAndClassify( point, maxDist2, projection, newSolution );
939 //================================================================================
941 * \brief Return true if a previously found solution can be used to speed up the projection
943 //================================================================================
945 bool FT_Projector::canUsePrevSolution() const
947 return ( _realProjector && _realProjector->canUsePrevSolution() );