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)
112 _dist = _projector.NextProject( prevSolution[0], _curve, P, _tol, proj, param );
116 _dist = _projector.Project( _curve, P, _tol, proj, param, false );
118 proj = _curve.Value( param );
120 newSolution[0] = param;
125 //-----------------------------------------------------------------------------
126 // project a point to a curve and check if the projection is within the curve boundary
127 virtual bool projectAndClassify( const gp_Pnt& point,
128 const double maxDist2,
131 const double* prevSolution = 0)
133 projection = project( point, newSolution, prevSolution );
134 return ( _uRange[0] < newSolution[0] && newSolution[0] < _uRange[1] &&
135 _dist * _dist < maxDist2 );
138 //-----------------------------------------------------------------------------
139 // return true if a previously found solution can be used to speed up the projection
140 virtual bool canUsePrevSolution() const { return true; }
143 //================================================================================
145 * \brief Projector to a straight curve. Don't project, classify only
147 //================================================================================
149 struct LineProjector : public FT_RealProjector
153 //-----------------------------------------------------------------------------
154 LineProjector( TopoDS_Edge e )
156 e.Orientation( TopAbs_FORWARD );
157 _p0 = BRep_Tool::Pnt( TopExp::FirstVertex( e ));
158 _p1 = BRep_Tool::Pnt( TopExp::LastVertex ( e ));
161 //-----------------------------------------------------------------------------
163 virtual gp_Pnt project( const gp_Pnt& P,
165 const double* prevSolution = 0)
169 //-----------------------------------------------------------------------------
170 // check if a point lies within the line segment
171 virtual bool projectAndClassify( const gp_Pnt& point,
172 const double maxDist2,
175 const double* prevSolution = 0)
177 gp_Vec edge( _p0, _p1 );
178 gp_Vec p0p ( _p0, point );
179 double u = ( edge * p0p ) / edge.SquareMagnitude(); // param [0,1] on the edge
180 projection = ( 1. - u ) * _p0.XYZ() + u * _p1.XYZ(); // projection of the point on the edge
181 if ( u < 0 || 1 < u )
185 return point.SquareDistance( projection ) < theEPS * theEPS;
189 //================================================================================
191 * \brief Projector to a circular edge
193 //================================================================================
195 struct CircleProjector : public FT_RealProjector
200 //-----------------------------------------------------------------------------
201 CircleProjector( const gp_Circ& c, const double f, const double l ):
208 //-----------------------------------------------------------------------------
209 // project a point to the circle
210 virtual gp_Pnt project( const gp_Pnt& P,
212 const double* prevSolution = 0)
214 // assume that P is already on the the plane of circle, since
215 // it is in the middle of two points lying on the circle
217 // move P to the circle
218 const gp_Pnt& O = _circle.Location();
219 gp_Vec radiusVec( O, P );
220 double radius = radiusVec.Magnitude();
221 if ( radius < std::numeric_limits<double>::min() )
222 return P; // P in on the axe
224 gp_Pnt proj = O.Translated( radiusVec.Multiplied( _circle.Radius() / radius ));
226 _dist = _circle.Radius() - radius;
231 //-----------------------------------------------------------------------------
232 // project and check if a projection lies within the circular edge
233 virtual bool projectAndClassify( const gp_Pnt& point,
234 const double maxDist2,
237 const double* prevSolution = 0)
240 projection = project( point, newSolution );
241 if ( _dist < 0 || // ?
242 _dist * _dist > maxDist2 )
245 newSolution[0] = ElCLib::Parameter( _circle, projection );
246 return ( _uRange[0] < newSolution[0] && newSolution[0] < _uRange[1] );
250 //================================================================================
252 * \brief Projector to any surface
254 //================================================================================
256 struct SurfaceProjector : public FT_RealProjector
258 ShapeAnalysis_Surface _projector;
260 BRepTopAdaptor_FClass2d* _classifier;
262 //-----------------------------------------------------------------------------
263 SurfaceProjector( const TopoDS_Face& face, const double tol, BRepTopAdaptor_FClass2d* cls ):
264 _projector( BRep_Tool::Surface( face )),
269 //-----------------------------------------------------------------------------
270 // delete _classifier
276 //-----------------------------------------------------------------------------
277 // project a point to a surface
278 virtual gp_Pnt project( const gp_Pnt& P,
280 const double* prevSolution = 0)
286 gp_Pnt2d prevUV( prevSolution[0], prevSolution[1] );
287 uv = _projector.NextValueOfUV( prevUV, P, _tol );
291 uv = _projector.ValueOfUV( P, _tol );
294 uv.Coord( newSolution[0], newSolution[1] );
296 gp_Pnt proj = _projector.Value( uv );
298 _dist = _projector.Gap();
303 //-----------------------------------------------------------------------------
304 // project a point to a surface and check if the projection is within the surface boundary
305 virtual bool projectAndClassify( const gp_Pnt& point,
306 const double maxDist2,
309 const double* prevSolution = 0)
311 projection = project( point, newSolution, prevSolution );
312 return ( _dist * _dist < maxDist2 ) && classify( newSolution );
315 //-----------------------------------------------------------------------------
316 // check if the projection is within the shape boundary
317 bool classify( const double* newSolution )
319 TopAbs_State state = _classifier->Perform( gp_Pnt2d( newSolution[0], newSolution[1]) );
320 return ( state != TopAbs_OUT );
323 //-----------------------------------------------------------------------------
324 // return true if a previously found solution can be used to speed up the projection
325 virtual bool canUsePrevSolution() const { return true; }
328 //================================================================================
330 * \brief Projector to a plane. Don't project, classify only
332 //================================================================================
334 struct PlaneProjector : public SurfaceProjector
337 bool _isRealPlane; // false means that a surface is planar but parametrization is different
339 //-----------------------------------------------------------------------------
340 PlaneProjector( const gp_Pln& pln,
341 const TopoDS_Face& face,
342 BRepTopAdaptor_FClass2d* cls,
343 bool isRealPlane=true):
344 SurfaceProjector( face, 0, cls ),
346 _isRealPlane( isRealPlane )
349 //-----------------------------------------------------------------------------
351 virtual gp_Pnt project( const gp_Pnt& P,
353 const double* prevSolution = 0)
357 //-----------------------------------------------------------------------------
358 // check if a point lies within the boundry of the planar face
359 virtual bool projectAndClassify( const gp_Pnt& point,
360 const double maxDist2,
363 const double* prevSolution = 0)
367 ElSLib::PlaneParameters( _plane.Position(), point, newSolution[0], newSolution[1]);
368 projection = ElSLib::PlaneValue ( newSolution[0], newSolution[1], _plane.Position() );
369 if ( projection.SquareDistance( point ) > theEPS * theEPS )
372 return SurfaceProjector::classify( newSolution );
376 return SurfaceProjector::projectAndClassify( point, maxDist2, projection,
377 newSolution, prevSolution );
380 //-----------------------------------------------------------------------------
381 // return true if a previously found solution can be used to speed up the projection
382 virtual bool canUsePrevSolution() const { return false; }
385 //================================================================================
387 * \brief Projector to a cylinder
389 //================================================================================
391 struct CylinderProjector : public SurfaceProjector
393 gp_Cylinder _cylinder;
395 //-----------------------------------------------------------------------------
396 CylinderProjector( const gp_Cylinder& c,
397 const TopoDS_Face& face,
398 BRepTopAdaptor_FClass2d* cls ):
399 SurfaceProjector( face, 0, cls ),
403 //-----------------------------------------------------------------------------
404 // project a point to the cylinder
405 virtual gp_Pnt project( const gp_Pnt& P,
407 const double* prevSolution = 0)
409 // project the point P to the cylinder axis -> Pp
410 const gp_Pnt& O = _cylinder.Position().Location();
411 const gp_Dir& axe = _cylinder.Position().Direction();
412 gp_Vec trsl = gp_Vec( axe ).Multiplied( gp_Vec( O, P ).Dot( axe ));
413 gp_Pnt Pp = O.Translated( trsl );
415 // move Pp to the cylinder
416 gp_Vec radiusVec( Pp, P );
417 double radius = radiusVec.Magnitude();
418 if ( radius < std::numeric_limits<double>::min() )
419 return P; // P in on the axe
421 gp_Pnt proj = Pp.Translated( radiusVec.Multiplied( _cylinder.Radius() / radius ));
423 _dist = _cylinder.Radius() - radius;
427 //-----------------------------------------------------------------------------
428 // project a point to the cylinder and check if the projection is within the surface boundary
429 virtual bool projectAndClassify( const gp_Pnt& point,
430 const double maxDist2,
433 const double* prevSolution = 0)
435 ElSLib::CylinderParameters( _cylinder.Position(), _cylinder.Radius(), point,
436 newSolution[0], newSolution[1]);
437 projection = ElSLib::CylinderValue( newSolution[0], newSolution[1],
438 _cylinder.Position(), _cylinder.Radius() );
440 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
442 //-----------------------------------------------------------------------------
443 // return true if a previously found solution can be used to speed up the projection
444 virtual bool canUsePrevSolution() const { return false; }
447 //================================================================================
449 * \brief Projector to a cone
451 //================================================================================
453 struct ConeProjector : public SurfaceProjector
457 //-----------------------------------------------------------------------------
458 ConeProjector( const gp_Cone& c,
459 const TopoDS_Face& face,
460 BRepTopAdaptor_FClass2d* cls ):
461 SurfaceProjector( face, 0, cls ),
465 //-----------------------------------------------------------------------------
466 // project a point to the cone
467 virtual gp_Pnt project( const gp_Pnt& point,
469 const double* prevSolution = 0)
471 ElSLib::ConeParameters( _cone.Position(), _cone.RefRadius(), _cone.SemiAngle(),
472 point, newSolution[0], newSolution[1]);
473 gp_Pnt proj = ElSLib::ConeValue( newSolution[0], newSolution[1],
474 _cone.Position(), _cone.RefRadius(), _cone.SemiAngle() );
475 _dist = point.Distance( proj );
480 //-----------------------------------------------------------------------------
481 // project a point to the cone and check if the projection is within the surface boundary
482 virtual bool projectAndClassify( const gp_Pnt& point,
483 const double maxDist2,
486 const double* prevSolution = 0)
488 projection = project( point, newSolution, prevSolution );
490 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
492 //-----------------------------------------------------------------------------
493 // return true if a previously found solution can be used to speed up the projection
494 virtual bool canUsePrevSolution() const { return false; }
497 //================================================================================
499 * \brief Projector to a sphere
501 //================================================================================
503 struct SphereProjector : public SurfaceProjector
507 //-----------------------------------------------------------------------------
508 SphereProjector( const gp_Sphere& s,
509 const TopoDS_Face& face,
510 BRepTopAdaptor_FClass2d* cls ):
511 SurfaceProjector( face, 0, cls ),
515 //-----------------------------------------------------------------------------
516 // project a point to the sphere
517 virtual gp_Pnt project( const gp_Pnt& P,
519 const double* prevSolution = 0)
521 // move Pp to the Sphere
522 const gp_Pnt& O = _sphere.Location();
523 gp_Vec radiusVec( O, P );
524 double radius = radiusVec.Magnitude();
525 if ( radius < std::numeric_limits<double>::min() )
526 return P; // P is on O
528 gp_Pnt proj = O.Translated( radiusVec.Multiplied( _sphere.Radius() / radius ));
530 _dist = _sphere.Radius() - radius;
535 //-----------------------------------------------------------------------------
536 // project a point to the sphere and check if the projection is within the surface boundary
537 virtual bool projectAndClassify( const gp_Pnt& point,
538 const double maxDist2,
541 const double* prevSolution = 0)
543 ElSLib::SphereParameters( _sphere.Position(), _sphere.Radius(), point,
544 newSolution[0], newSolution[1]);
545 projection = ElSLib::SphereValue( newSolution[0], newSolution[1],
546 _sphere.Position(), _sphere.Radius() );
548 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
550 //-----------------------------------------------------------------------------
551 // return true if a previously found solution can be used to speed up the projection
552 virtual bool canUsePrevSolution() const { return false; }
555 //================================================================================
557 * \brief Projector to a torus
559 //================================================================================
561 struct TorusProjector : public SurfaceProjector
565 //-----------------------------------------------------------------------------
566 TorusProjector( const gp_Torus& t,
567 const TopoDS_Face& face,
568 BRepTopAdaptor_FClass2d* cls ):
569 SurfaceProjector( face, 0, cls ),
573 //-----------------------------------------------------------------------------
574 // project a point to the torus
575 virtual gp_Pnt project( const gp_Pnt& point,
577 const double* prevSolution = 0)
579 ElSLib::TorusParameters( _torus.Position(), _torus.MajorRadius(), _torus.MinorRadius(),
580 point, newSolution[0], newSolution[1]);
581 gp_Pnt proj = ElSLib::TorusValue( newSolution[0], newSolution[1],
582 _torus.Position(), _torus.MajorRadius(), _torus.MinorRadius() );
583 _dist = point.Distance( proj );
588 //-----------------------------------------------------------------------------
589 // project a point to the torus and check if the projection is within the surface boundary
590 virtual bool projectAndClassify( const gp_Pnt& point,
591 const double maxDist2,
594 const double* prevSolution = 0)
596 projection = project( point, newSolution, prevSolution );
598 return ( _dist * _dist < maxDist2 ) && SurfaceProjector::classify( newSolution );
600 //-----------------------------------------------------------------------------
601 // return true if a previously found solution can be used to speed up the projection
602 virtual bool canUsePrevSolution() const { return false; }
605 //================================================================================
607 * \brief Check if a curve can be considered straight
609 //================================================================================
611 bool isStraight( const GeomAdaptor_Curve& curve, const double tol )
613 // rough check: evaluate how far from a straight line connecting the curve ends
614 // stand several internal points of the curve
616 const double f = curve.FirstParameter();
617 const double l = curve.LastParameter();
618 const gp_Pnt pf = curve.Value( f );
619 const gp_Pnt pl = curve.Value( l );
620 const gp_Vec lineVec( pf, pl );
621 const double lineLen2 = lineVec.SquareMagnitude();
622 if ( lineLen2 < std::numeric_limits< double >::min() )
623 return false; // E seems closed
625 const double nbSamples = 7;
626 for ( int i = 0; i < nbSamples; ++i )
628 const double r = ( i + 1 ) / nbSamples;
629 const gp_Pnt pi = curve.Value( f * r + l * ( 1 - r ));
630 const gp_Vec vi( pf, pi );
631 const double h2 = lineVec.Crossed( vi ).SquareMagnitude() / lineLen2;
632 if ( h2 > tol * tol )
637 GCPnts_UniformDeflection divider( curve, tol );
638 return ( divider.IsDone() && divider.NbPoints() < 3 );
642 //================================================================================
644 * \brief Initialize with a boundary shape
646 //================================================================================
648 FT_Projector::FT_Projector(const TopoDS_Shape& shape)
651 setBoundaryShape( shape );
652 _tryWOPrevSolution = false;
655 //================================================================================
657 * \brief Copy another projector
659 //================================================================================
661 FT_Projector::FT_Projector(const FT_Projector& other)
664 _shape = other._shape;
665 _bndBox = other._bndBox;
666 _tryWOPrevSolution = false;
669 //================================================================================
671 * \brief Destructor. Delete _realProjector
673 //================================================================================
675 FT_Projector::~FT_Projector()
677 delete _realProjector;
680 //================================================================================
682 * \brief Initialize with a boundary shape. Compute the bounding box
684 //================================================================================
686 void FT_Projector::setBoundaryShape(const TopoDS_Shape& shape)
688 delete _realProjector; _realProjector = 0;
690 if ( shape.IsNull() )
693 BRepBndLib::Add( shape, _bndBox );
694 _bndBox.Enlarge( 1e-5 * sqrt( _bndBox.SquareExtent() ));
697 //================================================================================
699 * \brief Create a real projector
701 //================================================================================
703 void FT_Projector::prepareForProjection()
705 if ( _shape.IsNull() || _realProjector )
708 if ( _shape.ShapeType() == TopAbs_EDGE )
710 const TopoDS_Edge& edge = TopoDS::Edge( _shape );
712 double tol = 1e-6 * sqrt( _bndBox.SquareExtent() );
715 Handle(Geom_Curve) curve = BRep_Tool::Curve( edge, f,l );
716 if ( curve.IsNull() )
717 return; // degenerated edge
719 GeomAdaptor_Curve acurve( curve, f, l );
720 switch ( acurve.GetType() )
723 _realProjector = new LineProjector( edge );
726 _realProjector = new CircleProjector( acurve.Circle(), f, l );
728 case GeomAbs_BezierCurve:
729 case GeomAbs_BSplineCurve:
730 case GeomAbs_OffsetCurve:
731 case GeomAbs_OtherCurve:
732 if ( isStraight( acurve, tol ))
734 _realProjector = new LineProjector( edge );
737 case GeomAbs_Ellipse:
738 case GeomAbs_Hyperbola:
739 case GeomAbs_Parabola:
740 _realProjector = new CurveProjector( edge, tol );
743 else if ( _shape.ShapeType() == TopAbs_FACE )
745 TopoDS_Face face = TopoDS::Face( _shape );
747 Handle(Geom_Surface) surface = BRep_Tool::Surface( face );
748 if ( surface.IsNull() )
751 GeomAdaptor_Surface asurface( surface );
752 Standard_Real tol = BRep_Tool::Tolerance( face );
753 Standard_Real toluv = Min( asurface.UResolution( tol ), asurface.VResolution( tol ));
754 BRepTopAdaptor_FClass2d* classifier = new BRepTopAdaptor_FClass2d( face, toluv );
756 switch ( asurface.GetType() )
759 _realProjector = new PlaneProjector( asurface.Plane(), face, classifier );
761 case GeomAbs_Cylinder:
762 _realProjector = new CylinderProjector( asurface.Cylinder(), face, classifier );
765 _realProjector = new SphereProjector( asurface.Sphere(), face, classifier );
768 _realProjector = new ConeProjector( asurface.Cone(), face, classifier );
771 _realProjector = new TorusProjector( asurface.Torus(), face, classifier );
773 case GeomAbs_BezierSurface:
774 case GeomAbs_BSplineSurface:
775 case GeomAbs_SurfaceOfRevolution:
776 case GeomAbs_SurfaceOfExtrusion:
777 case GeomAbs_OffsetSurface:
778 case GeomAbs_OtherSurface:
779 GeomLib_IsPlanarSurface isPlaneCheck( surface, tol );
780 if ( isPlaneCheck.IsPlanar() )
782 _realProjector = new PlaneProjector( isPlaneCheck.Plan(), face, classifier,
783 /*isRealPlane=*/false);
787 _realProjector = new SurfaceProjector( face, tol, classifier );
792 if ( !_realProjector )
797 //================================================================================
799 * \brief Return true if projection is not needed
801 //================================================================================
803 bool FT_Projector::isPlanarBoundary() const
805 return ( dynamic_cast< LineProjector* >( _realProjector ) ||
806 dynamic_cast< PlaneProjector* >( _realProjector ) );
809 //================================================================================
811 * \brief Check if a point lies on the boundary shape
812 * \param [in] point - the point to check
813 * \param [in] tol2 - a square tolerance allowing to decide whether a point is on the shape
814 * \param [in] newSolution - position on the shape (U or UV) of the point found
816 * \param [in] prevSolution - position on the shape (U or UV) of a neighbor point
817 * \return bool - \c true if the point lies on the boundary shape
819 * This method is used to select a shape by checking if all neighbor nodes of a node to move
822 //================================================================================
824 bool FT_Projector::isOnShape( const gp_Pnt& point,
827 const double* prevSolution)
829 if ( _bndBox.IsOut( point ) || !_realProjector )
833 if ( isPlanarBoundary() )
834 return projectAndClassify( point, tol2, proj, newSolution, prevSolution );
836 return project( point, tol2, proj, newSolution, prevSolution );
839 //================================================================================
841 * \brief Project a point to the boundary shape
842 * \param [in] point - the point to project
843 * \param [in] maxDist2 - the maximal square distance between the point and the projection
844 * \param [out] projection - the projection
845 * \param [out] newSolution - position on the shape (U or UV) of the point found
847 * \param [in] prevSolution - already found position on the shape (U or UV) of a neighbor point
848 * \return bool - false if the distance between the point and the projection
849 * is more than sqrt(maxDist2)
851 * This method is used to project a node in the case where only one shape is found by name
853 //================================================================================
855 bool FT_Projector::project( const gp_Pnt& point,
856 const double maxDist2,
859 const double* prevSolution)
861 if ( !_realProjector )
864 _realProjector->_dist = 1e100;
865 projection = _realProjector->project( point, newSolution, prevSolution );
867 bool ok = ( _realProjector->_dist * _realProjector->_dist < maxDist2 );
868 if ( !ok && _tryWOPrevSolution && prevSolution )
870 projection = _realProjector->project( point, newSolution );
871 ok = ( _realProjector->_dist * _realProjector->_dist < maxDist2 );
876 //================================================================================
878 * \brief Project a point to the boundary shape and check if the projection lies within
880 * \param [in] point - the point to project
881 * \param [in] maxDist2 - the maximal square distance between the point and the projection
882 * \param [out] projection - the projection
883 * \param [out] newSolution - position on the shape (U or UV) of the point found
885 * \param [in] prevSolution - already found position on the shape (U or UV) of a neighbor point
886 * \return bool - false if the projection point lies out of the shape boundary or
887 * the distance between the point and the projection is more than sqrt(maxDist2)
889 * This method is used to project a node in the case where several shapes are selected for
890 * projection of a node group
892 //================================================================================
894 bool FT_Projector::projectAndClassify( const gp_Pnt& point,
895 const double maxDist2,
898 const double* prevSolution)
900 if ( _bndBox.IsOut( point ) || !_realProjector )
903 bool ok = _realProjector->projectAndClassify( point, maxDist2, projection,
904 newSolution, prevSolution );
905 if ( !ok && _tryWOPrevSolution && prevSolution )
906 ok = _realProjector->projectAndClassify( point, maxDist2, projection, newSolution );
911 //================================================================================
913 * \brief Return true if a previously found solution can be used to speed up the projection
915 //================================================================================
917 bool FT_Projector::canUsePrevSolution() const
919 return ( _realProjector && _realProjector->canUsePrevSolution() );