1 // File : FrontTrack_Projector.cxx
2 // Created : Wed Apr 26 20:33:55 2017
3 // Author : Edward AGAPOV (eap)
5 #include "FrontTrack_Projector.hxx"
7 #include <BRepAdaptor_Curve.hxx>
8 #include <BRepBndLib.hxx>
9 #include <BRepTopAdaptor_FClass2d.hxx>
10 #include <BRep_Tool.hxx>
13 #include <GCPnts_UniformDeflection.hxx>
14 #include <GeomAdaptor_Curve.hxx>
15 #include <GeomLib_IsPlanarSurface.hxx>
16 #include <ShapeAnalysis_Curve.hxx>
17 #include <ShapeAnalysis_Surface.hxx>
20 #include <TopoDS_Edge.hxx>
21 #include <TopoDS_Face.hxx>
22 #include <TopoDS_Vertex.hxx>
23 #include <gp_Circ.hxx>
24 #include <gp_Cylinder.hxx>
28 #include <gp_Sphere.hxx>
33 //-----------------------------------------------------------------------------
35 * \brief Root class of a projector of a point to a boundary shape
37 struct FT_RealProjector
39 virtual ~FT_RealProjector() {}
42 * \brief Project a point to a boundary shape
43 * \param [in] point - the point to project
44 * \param [out] newSolution - position on the shape (U or UV) found during the projection
45 * \param [in] prevSolution - position already found during the projection of a neighbor point
46 * \return gp_Pnt - the projection point
48 virtual gp_Pnt project( const gp_Pnt& point,
50 const double* prevSolution = 0) = 0;
53 * \brief Project a point to a boundary shape and check if the projection is within
55 * \param [in] point - the point to project
56 * \param [in] maxDist2 - the maximal allowed square distance between point and projection
57 * \param [out] projection - the projection point
58 * \param [out] newSolution - position on the shape (U or UV) found during the projection
59 * \param [in] prevSolution - position already found during the projection of a neighbor point
60 * \return bool - false if the projection point lies out of the shape boundary or
61 the distance the point and the projection is more than sqrt(maxDist2)
63 virtual bool projectAndClassify( const gp_Pnt& point,
64 const double maxDist2,
67 const double* prevSolution = 0) = 0;
69 // return true if a previously found solution can be used to speed up the projection
71 virtual bool canUsePrevSolution() const { return false; }
74 double _dist; // distance between the point being projected and its projection
77 namespace // actual projection algorithms
79 const double theEPS = 1e-12;
81 //================================================================================
83 * \brief Projector to any curve
85 //================================================================================
87 struct CurveProjector : public FT_RealProjector
89 BRepAdaptor_Curve _curve;
91 ShapeAnalysis_Curve _projector;
94 //-----------------------------------------------------------------------------
95 CurveProjector( const TopoDS_Edge& e, const double tol ):
96 _curve( e ), _tol( tol )
98 BRep_Tool::Range( e, _uRange[0], _uRange[1] );
101 //-----------------------------------------------------------------------------
102 // project a point to the curve
103 virtual gp_Pnt project( const gp_Pnt& P,
105 const double* prevSolution = 0)
108 std::cout << ".. project a point to the curve prevSolution = " << prevSolution << std::endl;
115 _dist = _projector.NextProject( prevSolution[0], _curve, P, _tol, proj, param );
119 _dist = _projector.Project( _curve, P, _tol, proj, param, false );
122 std::cout << ".. _dist : " << _dist << std::endl;
124 proj = _curve.Value( param );
126 newSolution[0] = param;
131 //-----------------------------------------------------------------------------
132 // project a point to a curve and check if the projection is within the curve boundary
133 virtual bool projectAndClassify( const gp_Pnt& point,
134 const double maxDist2,
137 const double* prevSolution = 0)
140 std::cout << ".. project a point to a curve and check " << std::endl;
142 projection = project( point, newSolution, prevSolution );
143 return ( _uRange[0] < newSolution[0] && newSolution[0] < _uRange[1] &&
144 _dist * _dist < maxDist2 );
147 //-----------------------------------------------------------------------------
148 // return true if a previously found solution can be used to speed up the projection
149 virtual bool canUsePrevSolution() const { return true; }
152 //================================================================================
154 * \brief Projector to a straight curve. Don't project, classify only
156 //================================================================================
158 struct LineProjector : public FT_RealProjector
162 //-----------------------------------------------------------------------------
163 LineProjector( TopoDS_Edge e )
165 e.Orientation( TopAbs_FORWARD );
166 _p0 = BRep_Tool::Pnt( TopExp::FirstVertex( e ));
167 _p1 = BRep_Tool::Pnt( TopExp::LastVertex ( e ));
170 //-----------------------------------------------------------------------------
172 virtual gp_Pnt project( const gp_Pnt& P,
174 const double* prevSolution = 0)
178 //-----------------------------------------------------------------------------
179 // check if a point lies within the line segment
180 virtual bool projectAndClassify( const gp_Pnt& point,
181 const double maxDist2,
184 const double* prevSolution = 0)
186 gp_Vec edge( _p0, _p1 );
187 gp_Vec p0p ( _p0, point );
188 double u = ( edge * p0p ) / edge.SquareMagnitude(); // param [0,1] on the edge
189 projection = ( 1. - u ) * _p0.XYZ() + u * _p1.XYZ(); // projection of the point on the edge
190 if ( u < 0 || 1 < u )
194 return point.SquareDistance( projection ) < theEPS * theEPS;
198 //================================================================================
200 * \brief Projector to a circular edge
202 //================================================================================
204 struct CircleProjector : public FT_RealProjector
209 //-----------------------------------------------------------------------------
210 CircleProjector( const gp_Circ& c, const double f, const double l ):
217 //-----------------------------------------------------------------------------
218 // project a point to the circle
219 virtual gp_Pnt project( const gp_Pnt& P,
221 const double* prevSolution = 0)
223 // assume that P is already on the the plane of circle, since
224 // it is in the middle of two points lying on the circle
226 // move P to the circle
227 const gp_Pnt& O = _circle.Location();
228 gp_Vec radiusVec( O, P );
229 double radius = radiusVec.Magnitude();
230 if ( radius < std::numeric_limits<double>::min() )
231 return P; // P in on the axe
233 gp_Pnt proj = O.Translated( radiusVec.Multiplied( _circle.Radius() / radius ));
235 _dist = _circle.Radius() - radius;
240 //-----------------------------------------------------------------------------
241 // project and check if a projection lies within the circular edge
242 virtual bool projectAndClassify( const gp_Pnt& point,
243 const double maxDist2,
246 const double* prevSolution = 0)
249 projection = project( point, newSolution );
250 if ( _dist < 0 || // ?
251 _dist * _dist > maxDist2 )
254 newSolution[0] = ElCLib::Parameter( _circle, projection );
255 return ( _uRange[0] < newSolution[0] && newSolution[0] < _uRange[1] );
259 //================================================================================
261 * \brief Projector to any surface
263 //================================================================================
265 struct SurfaceProjector : public FT_RealProjector
267 ShapeAnalysis_Surface _projector;
269 BRepTopAdaptor_FClass2d* _classifier;
271 //-----------------------------------------------------------------------------
272 SurfaceProjector( const TopoDS_Face& face, const double tol, BRepTopAdaptor_FClass2d* cls ):
273 _projector( BRep_Tool::Surface( face )),
278 //-----------------------------------------------------------------------------
279 // delete _classifier
285 //-----------------------------------------------------------------------------
286 // project a point to a surface
287 virtual gp_Pnt project( const gp_Pnt& P,
289 const double* prevSolution = 0)
295 gp_Pnt2d prevUV( prevSolution[0], prevSolution[1] );
296 uv = _projector.NextValueOfUV( prevUV, P, _tol );
300 uv = _projector.ValueOfUV( P, _tol );
303 uv.Coord( newSolution[0], newSolution[1] );
305 gp_Pnt proj = _projector.Value( uv );
307 _dist = _projector.Gap();
312 //-----------------------------------------------------------------------------
313 // project a point to a surface and check if the projection is within the surface boundary
314 virtual bool projectAndClassify( const gp_Pnt& point,
315 const double maxDist2,
318 const double* prevSolution = 0)
320 projection = project( point, newSolution, prevSolution );
321 return ( _dist * _dist < maxDist2 ) && classify( newSolution );
324 //-----------------------------------------------------------------------------
325 // check if the projection is within the shape boundary
326 bool classify( const double* newSolution )
328 TopAbs_State state = _classifier->Perform( gp_Pnt2d( newSolution[0], newSolution[1]) );
329 return ( state != TopAbs_OUT );
332 //-----------------------------------------------------------------------------
333 // return true if a previously found solution can be used to speed up the projection
334 virtual bool canUsePrevSolution() const { return true; }
337 //================================================================================
339 * \brief Projector to a plane. Don't project, classify only
341 //================================================================================
343 struct PlaneProjector : public SurfaceProjector
346 bool _isRealPlane; // false means that a surface is planar but parametrization is different
348 //-----------------------------------------------------------------------------
349 PlaneProjector( const gp_Pln& pln,
350 const TopoDS_Face& face,
351 BRepTopAdaptor_FClass2d* cls,
352 bool isRealPlane=true):
353 SurfaceProjector( face, 0, cls ),
355 _isRealPlane( isRealPlane )
358 //-----------------------------------------------------------------------------
360 virtual gp_Pnt project( const gp_Pnt& P,
362 const double* prevSolution = 0)
366 //-----------------------------------------------------------------------------
367 // check if a point lies within the boundry of the planar face
368 virtual bool projectAndClassify( const gp_Pnt& point,
369 const double maxDist2,
372 const double* prevSolution = 0)
376 ElSLib::PlaneParameters( _plane.Position(), point, newSolution[0], newSolution[1]);
377 projection = ElSLib::PlaneValue ( newSolution[0], newSolution[1], _plane.Position() );
378 if ( projection.SquareDistance( point ) > theEPS * theEPS )
381 return SurfaceProjector::classify( newSolution );
385 return SurfaceProjector::projectAndClassify( point, maxDist2, projection,
386 newSolution, prevSolution );
389 //-----------------------------------------------------------------------------
390 // return true if a previously found solution can be used to speed up the projection
391 virtual bool canUsePrevSolution() const { return false; }
394 //================================================================================
396 * \brief Projector to a cylinder
398 //================================================================================
400 struct CylinderProjector : public SurfaceProjector
402 gp_Cylinder _cylinder;
404 //-----------------------------------------------------------------------------
405 CylinderProjector( const gp_Cylinder& c,
406 const TopoDS_Face& face,
407 BRepTopAdaptor_FClass2d* cls ):
408 SurfaceProjector( face, 0, cls ),
412 //-----------------------------------------------------------------------------
413 // project a point to the cylinder
414 virtual gp_Pnt project( const gp_Pnt& P,
416 const double* prevSolution = 0)
418 // project the point P to the cylinder axis -> Pp
419 const gp_Pnt& O = _cylinder.Position().Location();
420 const gp_Dir& axe = _cylinder.Position().Direction();
421 gp_Vec trsl = gp_Vec( axe ).Multiplied( gp_Vec( O, P ).Dot( axe ));
422 gp_Pnt Pp = O.Translated( trsl );
424 // move Pp to the cylinder
425 gp_Vec radiusVec( Pp, P );
426 double radius = radiusVec.Magnitude();
427 if ( radius < std::numeric_limits<double>::min() )
428 return P; // P in on the axe
430 gp_Pnt proj = Pp.Translated( radiusVec.Multiplied( _cylinder.Radius() / radius ));
432 _dist = _cylinder.Radius() - radius;
436 //-----------------------------------------------------------------------------
437 // project a point to the cylinder and check if the projection is within the surface boundary
438 virtual bool projectAndClassify( const gp_Pnt& point,
439 const double maxDist2,
442 const double* prevSolution = 0)
444 ElSLib::CylinderParameters( _cylinder.Position(), _cylinder.Radius(), point,
445 newSolution[0], newSolution[1]);
446 projection = ElSLib::CylinderValue( newSolution[0], newSolution[1],
447 _cylinder.Position(), _cylinder.Radius() );
449 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
451 //-----------------------------------------------------------------------------
452 // return true if a previously found solution can be used to speed up the projection
453 virtual bool canUsePrevSolution() const { return false; }
456 //================================================================================
458 * \brief Projector to a cone
460 //================================================================================
462 struct ConeProjector : public SurfaceProjector
466 //-----------------------------------------------------------------------------
467 ConeProjector( const gp_Cone& c,
468 const TopoDS_Face& face,
469 BRepTopAdaptor_FClass2d* cls ):
470 SurfaceProjector( face, 0, cls ),
474 //-----------------------------------------------------------------------------
475 // project a point to the cone
476 virtual gp_Pnt project( const gp_Pnt& point,
478 const double* prevSolution = 0)
480 ElSLib::ConeParameters( _cone.Position(), _cone.RefRadius(), _cone.SemiAngle(),
481 point, newSolution[0], newSolution[1]);
482 gp_Pnt proj = ElSLib::ConeValue( newSolution[0], newSolution[1],
483 _cone.Position(), _cone.RefRadius(), _cone.SemiAngle() );
484 _dist = point.Distance( proj );
489 //-----------------------------------------------------------------------------
490 // project a point to the cone and check if the projection is within the surface boundary
491 virtual bool projectAndClassify( const gp_Pnt& point,
492 const double maxDist2,
495 const double* prevSolution = 0)
497 projection = project( point, newSolution, prevSolution );
499 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
501 //-----------------------------------------------------------------------------
502 // return true if a previously found solution can be used to speed up the projection
503 virtual bool canUsePrevSolution() const { return false; }
506 //================================================================================
508 * \brief Projector to a sphere
510 //================================================================================
512 struct SphereProjector : public SurfaceProjector
516 //-----------------------------------------------------------------------------
517 SphereProjector( const gp_Sphere& s,
518 const TopoDS_Face& face,
519 BRepTopAdaptor_FClass2d* cls ):
520 SurfaceProjector( face, 0, cls ),
524 //-----------------------------------------------------------------------------
525 // project a point to the sphere
526 virtual gp_Pnt project( const gp_Pnt& P,
528 const double* prevSolution = 0)
530 // move Pp to the Sphere
531 const gp_Pnt& O = _sphere.Location();
532 gp_Vec radiusVec( O, P );
533 double radius = radiusVec.Magnitude();
534 if ( radius < std::numeric_limits<double>::min() )
535 return P; // P is on O
537 gp_Pnt proj = O.Translated( radiusVec.Multiplied( _sphere.Radius() / radius ));
539 _dist = _sphere.Radius() - radius;
544 //-----------------------------------------------------------------------------
545 // project a point to the sphere and check if the projection is within the surface boundary
546 virtual bool projectAndClassify( const gp_Pnt& point,
547 const double maxDist2,
550 const double* prevSolution = 0)
552 ElSLib::SphereParameters( _sphere.Position(), _sphere.Radius(), point,
553 newSolution[0], newSolution[1]);
554 projection = ElSLib::SphereValue( newSolution[0], newSolution[1],
555 _sphere.Position(), _sphere.Radius() );
557 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
559 //-----------------------------------------------------------------------------
560 // return true if a previously found solution can be used to speed up the projection
561 virtual bool canUsePrevSolution() const { return false; }
564 //================================================================================
566 * \brief Projector to a torus
568 //================================================================================
570 struct TorusProjector : public SurfaceProjector
574 //-----------------------------------------------------------------------------
575 TorusProjector( const gp_Torus& t,
576 const TopoDS_Face& face,
577 BRepTopAdaptor_FClass2d* cls ):
578 SurfaceProjector( face, 0, cls ),
582 //-----------------------------------------------------------------------------
583 // project a point to the torus
584 virtual gp_Pnt project( const gp_Pnt& point,
586 const double* prevSolution = 0)
588 ElSLib::TorusParameters( _torus.Position(), _torus.MajorRadius(), _torus.MinorRadius(),
589 point, newSolution[0], newSolution[1]);
590 gp_Pnt proj = ElSLib::TorusValue( newSolution[0], newSolution[1],
591 _torus.Position(), _torus.MajorRadius(), _torus.MinorRadius() );
592 _dist = point.Distance( proj );
597 //-----------------------------------------------------------------------------
598 // project a point to the torus and check if the projection is within the surface boundary
599 virtual bool projectAndClassify( const gp_Pnt& point,
600 const double maxDist2,
603 const double* prevSolution = 0)
605 projection = project( point, newSolution, prevSolution );
607 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
609 //-----------------------------------------------------------------------------
610 // return true if a previously found solution can be used to speed up the projection
611 virtual bool canUsePrevSolution() const { return false; }
614 //================================================================================
616 * \brief Check if a curve can be considered straight
618 //================================================================================
620 bool isStraight( const GeomAdaptor_Curve& curve, const double tol )
622 // rough check: evaluate how far from a straight line connecting the curve ends
623 // stand several internal points of the curve
625 const double f = curve.FirstParameter();
626 const double l = curve.LastParameter();
627 const gp_Pnt pf = curve.Value( f );
628 const gp_Pnt pl = curve.Value( l );
629 const gp_Vec lineVec( pf, pl );
630 const double lineLen2 = lineVec.SquareMagnitude();
631 if ( lineLen2 < std::numeric_limits< double >::min() )
632 return false; // E seems closed
634 const double nbSamples = 7;
635 for ( int i = 0; i < nbSamples; ++i )
637 const double r = ( i + 1 ) / nbSamples;
638 const gp_Pnt pi = curve.Value( f * r + l * ( 1 - r ));
639 const gp_Vec vi( pf, pi );
640 const double h2 = lineVec.Crossed( vi ).SquareMagnitude() / lineLen2;
641 if ( h2 > tol * tol )
646 GCPnts_UniformDeflection divider( curve, tol );
647 return ( divider.IsDone() && divider.NbPoints() < 3 );
651 //================================================================================
653 * \brief Initialize with a boundary shape
655 //================================================================================
657 FT_Projector::FT_Projector(const TopoDS_Shape& shape)
660 setBoundaryShape( shape );
661 _tryWOPrevSolution = false;
664 //================================================================================
666 * \brief Copy another projector
668 //================================================================================
670 FT_Projector::FT_Projector(const FT_Projector& other)
673 _shape = other._shape;
674 _bndBox = other._bndBox;
675 _tryWOPrevSolution = false;
678 //================================================================================
680 * \brief Destructor. Delete _realProjector
682 //================================================================================
684 FT_Projector::~FT_Projector()
686 delete _realProjector;
689 //================================================================================
691 * \brief Initialize with a boundary shape. Compute the bounding box
693 //================================================================================
695 void FT_Projector::setBoundaryShape(const TopoDS_Shape& shape)
697 delete _realProjector; _realProjector = 0;
699 if ( shape.IsNull() )
702 BRepBndLib::Add( shape, _bndBox );
703 _bndBox.Enlarge( 1e-5 * sqrt( _bndBox.SquareExtent() ));
706 //================================================================================
708 * \brief Create a real projector
710 //================================================================================
712 void FT_Projector::prepareForProjection()
714 if ( _shape.IsNull() || _realProjector )
717 if ( _shape.ShapeType() == TopAbs_EDGE )
719 const TopoDS_Edge& edge = TopoDS::Edge( _shape );
721 double tol = 1e-6 * sqrt( _bndBox.SquareExtent() );
724 Handle(Geom_Curve) curve = BRep_Tool::Curve( edge, f,l );
725 if ( curve.IsNull() )
726 return; // degenerated edge
728 GeomAdaptor_Curve acurve( curve, f, l );
729 switch ( acurve.GetType() )
732 _realProjector = new LineProjector( edge );
735 _realProjector = new CircleProjector( acurve.Circle(), f, l );
737 case GeomAbs_BezierCurve:
738 case GeomAbs_BSplineCurve:
739 case GeomAbs_OffsetCurve:
740 case GeomAbs_OtherCurve:
741 if ( isStraight( acurve, tol ))
743 _realProjector = new LineProjector( edge );
746 case GeomAbs_Ellipse:
747 case GeomAbs_Hyperbola:
748 case GeomAbs_Parabola:
749 _realProjector = new CurveProjector( edge, tol );
752 else if ( _shape.ShapeType() == TopAbs_FACE )
754 TopoDS_Face face = TopoDS::Face( _shape );
756 Handle(Geom_Surface) surface = BRep_Tool::Surface( face );
757 if ( surface.IsNull() )
760 GeomAdaptor_Surface asurface( surface );
761 Standard_Real tol = BRep_Tool::Tolerance( face );
762 Standard_Real toluv = Min( asurface.UResolution( tol ), asurface.VResolution( tol ));
763 BRepTopAdaptor_FClass2d* classifier = new BRepTopAdaptor_FClass2d( face, toluv );
765 switch ( asurface.GetType() )
768 _realProjector = new PlaneProjector( asurface.Plane(), face, classifier );
770 case GeomAbs_Cylinder:
771 _realProjector = new CylinderProjector( asurface.Cylinder(), face, classifier );
774 _realProjector = new SphereProjector( asurface.Sphere(), face, classifier );
777 _realProjector = new ConeProjector( asurface.Cone(), face, classifier );
780 _realProjector = new TorusProjector( asurface.Torus(), face, classifier );
782 case GeomAbs_BezierSurface:
783 case GeomAbs_BSplineSurface:
784 case GeomAbs_SurfaceOfRevolution:
785 case GeomAbs_SurfaceOfExtrusion:
786 case GeomAbs_OffsetSurface:
787 case GeomAbs_OtherSurface:
788 GeomLib_IsPlanarSurface isPlaneCheck( surface, tol );
789 if ( isPlaneCheck.IsPlanar() )
791 _realProjector = new PlaneProjector( isPlaneCheck.Plan(), face, classifier,
792 /*isRealPlane=*/false);
796 _realProjector = new SurfaceProjector( face, tol, classifier );
801 if ( !_realProjector )
806 //================================================================================
808 * \brief Return true if projection is not needed
810 //================================================================================
812 bool FT_Projector::isPlanarBoundary() const
814 return ( dynamic_cast< LineProjector* >( _realProjector ) ||
815 dynamic_cast< PlaneProjector* >( _realProjector ) );
818 //================================================================================
820 * \brief Check if a point lies on the boundary shape
821 * \param [in] point - the point to check
822 * \param [in] tol2 - a square tolerance allowing to decide whether a point is on the shape
823 * \param [in] newSolution - position on the shape (U or UV) of the point found
825 * \param [in] prevSolution - position on the shape (U or UV) of a neighbor point
826 * \return bool - \c true if the point lies on the boundary shape
828 * This method is used to select a shape by checking if all neighbor nodes of a node to move
831 //================================================================================
833 bool FT_Projector::isOnShape( const gp_Pnt& point,
836 const double* prevSolution)
838 if ( _bndBox.IsOut( point ) || !_realProjector )
842 if ( isPlanarBoundary() )
843 return projectAndClassify( point, tol2, proj, newSolution, prevSolution );
845 return project( point, tol2, proj, newSolution, prevSolution );
848 //================================================================================
850 * \brief Project a point to the boundary shape
851 * \param [in] point - the point to project
852 * \param [in] maxDist2 - the maximal square distance between the point and the projection
853 * \param [out] projection - the projection
854 * \param [out] newSolution - position on the shape (U or UV) of the point found
856 * \param [in] prevSolution - already found position on the shape (U or UV) of a neighbor point
857 * \return bool - false if the distance between the point and the projection
858 * is more than sqrt(maxDist2)
860 * This method is used to project a node in the case where only one shape is found by name
862 //================================================================================
864 bool FT_Projector::project( const gp_Pnt& point,
865 const double maxDist2,
868 const double* prevSolution)
870 if ( !_realProjector )
873 _realProjector->_dist = 1e100;
874 projection = _realProjector->project( point, newSolution, prevSolution );
876 bool ok = ( _realProjector->_dist * _realProjector->_dist < maxDist2 );
877 if ( !ok && _tryWOPrevSolution && prevSolution )
879 projection = _realProjector->project( point, newSolution );
880 ok = ( _realProjector->_dist * _realProjector->_dist < maxDist2 );
885 //================================================================================
887 * \brief Project a point to the boundary shape and check if the projection lies within
889 * \param [in] point - the point to project
890 * \param [in] maxDist2 - the maximal square distance between the point and the projection
891 * \param [out] projection - the projection
892 * \param [out] newSolution - position on the shape (U or UV) of the point found
894 * \param [in] prevSolution - already found position on the shape (U or UV) of a neighbor point
895 * \return bool - false if the projection point lies out of the shape boundary or
896 * the distance between the point and the projection is more than sqrt(maxDist2)
898 * This method is used to project a node in the case where several shapes are selected for
899 * projection of a node group
901 //================================================================================
903 bool FT_Projector::projectAndClassify( const gp_Pnt& point,
904 const double maxDist2,
907 const double* prevSolution)
909 if ( _bndBox.IsOut( point ) || !_realProjector )
912 bool ok = _realProjector->projectAndClassify( point, maxDist2, projection,
913 newSolution, prevSolution );
914 if ( !ok && _tryWOPrevSolution && prevSolution )
915 ok = _realProjector->projectAndClassify( point, maxDist2, projection, newSolution );
920 //================================================================================
922 * \brief Return true if a previously found solution can be used to speed up the projection
924 //================================================================================
926 bool FT_Projector::canUsePrevSolution() const
928 return ( _realProjector && _realProjector->canUsePrevSolution() );