mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-05-14 20:51:41 +08:00
In the case of infinite point due to not enough machine precision the distance from the point to each edge of the face is computed the same, and the algorithm cannot correctly select the nearest edge. To solve this problem checking of point was added, if the point is located too far from the bounding box of the face, then it will be replaced with another point located on the line between the point and the center of the bounding box.
The new point has the same state as initial one but its state can be resolved without ambiguity.
Corrections in CheckPoint method
Small correction of test case for issue CR27434
192 lines
5.5 KiB
Plaintext
192 lines
5.5 KiB
Plaintext
// Created on: 1992-11-18
|
|
// Created by: Remi LEQUETTE
|
|
// Copyright (c) 1992-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
// Modified by skv - Thu Jul 13 18:00:34 2006 OCC12627
|
|
// The method Perform is totally rewroted.
|
|
|
|
#include <IntRes2d_IntersectionSegment.hxx>
|
|
#include <IntRes2d_IntersectionPoint.hxx>
|
|
|
|
//=======================================================================
|
|
//function : TopClass_FaceClassifier
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopClass_FaceClassifier::TopClass_FaceClassifier() :
|
|
myEdgeParameter(0.0),
|
|
rejected(Standard_False),
|
|
nowires(Standard_True)
|
|
{
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TopClass_FaceClassifier
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopClass_FaceClassifier::TopClass_FaceClassifier(TheFaceExplorer& FExp,
|
|
const gp_Pnt2d& P,
|
|
const Standard_Real Tol) :
|
|
myEdgeParameter(0.0),
|
|
rejected(Standard_False),
|
|
nowires(Standard_True)
|
|
{
|
|
Perform(FExp,P,Tol);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Perform
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopClass_FaceClassifier::Perform(TheFaceExplorer& Fexp,
|
|
const gp_Pnt2d& P,
|
|
const Standard_Real Tol)
|
|
{
|
|
gp_Pnt2d aPoint(P);
|
|
Standard_Boolean aResOfPointCheck = Standard_False;
|
|
while (aResOfPointCheck == Standard_False)
|
|
{
|
|
aResOfPointCheck = Fexp.CheckPoint(aPoint);
|
|
}
|
|
|
|
// Test for rejection.
|
|
rejected = Fexp.Reject(aPoint);
|
|
|
|
if (rejected)
|
|
return;
|
|
|
|
gp_Lin2d aLine;
|
|
Standard_Real aParam;
|
|
Standard_Boolean IsValidSegment = Fexp.Segment(aPoint, aLine, aParam);
|
|
TheEdge anEdge;
|
|
TopAbs_Orientation anEdgeOri;
|
|
Standard_Integer aClosestInd;
|
|
IntRes2d_IntersectionPoint aPInter;
|
|
TopAbs_State aState = TopAbs_UNKNOWN;
|
|
Standard_Boolean IsWReject;
|
|
Standard_Boolean IsEReject;
|
|
|
|
nowires = Standard_True;
|
|
|
|
while (IsValidSegment) {
|
|
myClassifier.Reset(aLine, aParam, Tol);
|
|
|
|
for (Fexp.InitWires(); Fexp.MoreWires(); Fexp.NextWire()) {
|
|
nowires = Standard_False;
|
|
IsWReject = Fexp.RejectWire(aLine, myClassifier.Parameter());
|
|
|
|
if (!IsWReject) {
|
|
// test this wire
|
|
for (Fexp.InitEdges(); Fexp.MoreEdges(); Fexp.NextEdge()) {
|
|
IsEReject = Fexp.RejectEdge(aLine, myClassifier.Parameter());
|
|
|
|
if (!IsEReject) {
|
|
// test this edge
|
|
Fexp.CurrentEdge(anEdge, anEdgeOri);
|
|
|
|
if (anEdgeOri == TopAbs_FORWARD || anEdgeOri == TopAbs_REVERSED) {
|
|
myClassifier.Compare(anEdge, anEdgeOri);
|
|
aClosestInd = myClassifier.ClosestIntersection();
|
|
|
|
if (aClosestInd != 0) {
|
|
// save the closest edge
|
|
TheIntersection2d &anIntersector = myClassifier.Intersector();
|
|
Standard_Integer aNbPnts = anIntersector.NbPoints();
|
|
|
|
myEdge = anEdge;
|
|
|
|
if (aClosestInd <= aNbPnts) {
|
|
aPInter = anIntersector.Point(aClosestInd);
|
|
} else {
|
|
aClosestInd -= aNbPnts;
|
|
|
|
if (aClosestInd&1) {
|
|
aPInter = anIntersector.
|
|
Segment((aClosestInd + 1)/2).FirstPoint();
|
|
} else {
|
|
aPInter = anIntersector.
|
|
Segment((aClosestInd + 1)/2).LastPoint();
|
|
}
|
|
}
|
|
|
|
myPosition = aPInter.
|
|
TransitionOfSecond().PositionOnCurve();
|
|
myEdgeParameter = aPInter.ParamOnSecond();
|
|
}
|
|
// if we are ON, we stop
|
|
aState = myClassifier.State();
|
|
|
|
if (aState == TopAbs_ON)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we are out of the wire we stop
|
|
aState = myClassifier.State();
|
|
|
|
if (aState == TopAbs_OUT)
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!myClassifier.IsHeadOrEnd() && aState != TopAbs_UNKNOWN)
|
|
break;
|
|
|
|
// Bad case for classification. Trying to get another segment.
|
|
IsValidSegment = Fexp.OtherSegment(aPoint, aLine, aParam);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : State
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopAbs_State TopClass_FaceClassifier::State() const
|
|
{
|
|
if (rejected) return TopAbs_OUT;
|
|
else if (nowires) return TopAbs_IN;
|
|
else return myClassifier.State();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Edge
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const TheEdge& TopClass_FaceClassifier::Edge() const
|
|
{
|
|
Standard_DomainError_Raise_if(rejected,
|
|
"TopClass_FaceClassifier::Edge:rejected");
|
|
return myEdge;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : EdgeParameter
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Real TopClass_FaceClassifier::EdgeParameter() const
|
|
{
|
|
Standard_DomainError_Raise_if(rejected,
|
|
"TopClass_FaceClassifier::EdgeParameter:rejected");
|
|
return myEdgeParameter;
|
|
}
|
|
|