mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0025298: New option of BRepOffsetAPI_MakeOffset algorithm: processing of sharp corners in mode GeomAbs_Intersection
Test cases for issue CR25298
This commit is contained in:
@@ -20,7 +20,7 @@ package MAT2d
|
||||
-- Set of geometrys from Geom2d.
|
||||
|
||||
uses
|
||||
|
||||
GeomAbs,
|
||||
MMgt,
|
||||
gp,
|
||||
Geom2d,
|
||||
|
@@ -26,7 +26,7 @@ inherits
|
||||
--
|
||||
|
||||
uses
|
||||
|
||||
JoinType from GeomAbs,
|
||||
SequenceOfInteger from TColStd,
|
||||
Geometry from Geom2d,
|
||||
SequenceOfGeometry from TColGeom2d,
|
||||
@@ -41,7 +41,8 @@ uses
|
||||
|
||||
is
|
||||
|
||||
Create(IsOpenResult : Boolean from Standard = Standard_False)
|
||||
Create(aJoinType : JoinType from GeomAbs = GeomAbs_Arc;
|
||||
IsOpenResult : Boolean from Standard = Standard_False)
|
||||
returns Circuit from MAT2d;
|
||||
|
||||
---Category: Computation
|
||||
@@ -53,6 +54,11 @@ is
|
||||
Trigo : Boolean)
|
||||
is static;
|
||||
|
||||
IsSharpCorner(me; Geom1, Geom2 : Geometry from Geom2d;
|
||||
Direction : Real from Standard)
|
||||
returns Boolean
|
||||
is static private;
|
||||
|
||||
PassByLast(me ; C1,C2 : Connexion from MAT2d)
|
||||
returns Boolean
|
||||
is static private;
|
||||
@@ -130,7 +136,8 @@ fields
|
||||
connexionMap : DataMapOfIntegerConnexion from MAT2d;
|
||||
linkRefEqui : DataMapOfBiIntSequenceOfInteger from MAT2d;
|
||||
linesLength : SequenceOfInteger from TColStd;
|
||||
myIsOpenResult : Boolean from Standard;
|
||||
myJoinType : JoinType from GeomAbs;
|
||||
myIsOpenResult : Boolean from Standard;
|
||||
|
||||
end Circuit;
|
||||
|
||||
|
@@ -67,16 +67,15 @@ static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
|
||||
const Handle(Geom2d_Geometry)& Geom2,
|
||||
Standard_Real& DotProd);
|
||||
|
||||
static Standard_Boolean IsSharpCorner (const Handle(Geom2d_Geometry)& Geom1,
|
||||
const Handle(Geom2d_Geometry)& Geom2,
|
||||
const Standard_Real& Direction);
|
||||
|
||||
//=============================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
MAT2d_Circuit::MAT2d_Circuit(const Standard_Boolean IsOpenResult)
|
||||
MAT2d_Circuit::MAT2d_Circuit(const GeomAbs_JoinType aJoinType,
|
||||
const Standard_Boolean IsOpenResult)
|
||||
{
|
||||
myJoinType = aJoinType;
|
||||
myIsOpenResult = IsOpenResult;
|
||||
}
|
||||
|
||||
@@ -204,6 +203,133 @@ void MAT2d_Circuit::Perform
|
||||
ConstructCircuit(FigItem,IndRefLine,Road);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsSharpCorner
|
||||
//purpose : Return True Si le point commun entre <Geom1> et <Geom2> est
|
||||
// une cassure saillante par rapport <Direction>
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean MAT2d_Circuit::IsSharpCorner(const Handle(Geom2d_Geometry)& Geom1,
|
||||
const Handle(Geom2d_Geometry)& Geom2,
|
||||
const Standard_Real Direction) const
|
||||
{
|
||||
Standard_Real DotProd;
|
||||
Standard_Real ProVec = CrossProd (Geom1,Geom2,DotProd);
|
||||
Standard_Integer NbTest = 1;
|
||||
Standard_Real DU = Precision::Confusion();
|
||||
Handle(Geom2d_TrimmedCurve) C1,C2;
|
||||
|
||||
C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
|
||||
C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
|
||||
// Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin
|
||||
// Add the same criterion as it is in MAT2d_Circuit::InitOpen(..)
|
||||
// Standard_Real TolAng = 1.E-5;
|
||||
Standard_Real TolAng = 1.E-8;
|
||||
// Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End
|
||||
|
||||
if (myJoinType == GeomAbs_Arc)
|
||||
{
|
||||
while (NbTest <= 10) {
|
||||
if ((ProVec)*Direction < -TolAng)
|
||||
return Standard_True; // Saillant.
|
||||
if ((ProVec)*Direction > TolAng)
|
||||
return Standard_False; // Rentrant.
|
||||
else {
|
||||
if (DotProd > 0) {
|
||||
return Standard_False; // Plat.
|
||||
}
|
||||
TolAng = 1.E-8;
|
||||
Standard_Real U1 = C1->LastParameter() - NbTest*DU;
|
||||
Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
|
||||
gp_Dir2d Dir1(C1->DN(U1,1));
|
||||
gp_Dir2d Dir2(C2->DN(U2,1));
|
||||
DotProd = Dir1.Dot(Dir2);
|
||||
ProVec = Dir1^Dir2;
|
||||
NbTest++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Rebroussement.
|
||||
// on calculde des paralleles aux deux courbes du cote du domaine
|
||||
// de calcul
|
||||
// Si pas dintersection => saillant.
|
||||
// Sinon => rentrant.
|
||||
Standard_Real D ;
|
||||
Standard_Real Tol = Precision::Confusion();
|
||||
Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5;
|
||||
Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5;
|
||||
gp_Pnt2d P = C1->Value(C1->LastParameter());
|
||||
gp_Pnt2d P1 = C1->Value(MilC1);
|
||||
gp_Pnt2d P2 = C2->Value(MilC2);
|
||||
|
||||
D = Min(P1.Distance(P),P2.Distance(P));
|
||||
D /= 10;
|
||||
|
||||
if (Direction > 0.) D = -D;
|
||||
|
||||
Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C1);
|
||||
Handle(Geom2dAdaptor_HCurve) HC2 = new Geom2dAdaptor_HCurve(C2);
|
||||
Adaptor3d_OffsetCurve OC1(HC1,D,MilC1,C1->LastParameter());
|
||||
Adaptor3d_OffsetCurve OC2(HC2,D,C2->FirstParameter(),MilC2);
|
||||
Geom2dInt_GInter Intersect;
|
||||
Intersect.Perform(OC1,OC2,Tol,Tol);
|
||||
|
||||
#ifdef DEB
|
||||
static Standard_Boolean Affich = 0;
|
||||
if (Affich) {
|
||||
#ifdef DRAW
|
||||
Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.;
|
||||
Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.;
|
||||
for (Standard_Integer ki = 0; ki <= 9; ki++) {
|
||||
gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1);
|
||||
gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2);
|
||||
Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert);
|
||||
Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge);
|
||||
dout << dr1;
|
||||
dout << dr2;
|
||||
}
|
||||
dout.Flush();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Intersect.IsDone() && !Intersect.IsEmpty()) {
|
||||
return Standard_False;
|
||||
}
|
||||
else {
|
||||
return Standard_True;
|
||||
}
|
||||
} //end of if (myJoinType == GeomAbs_Arc)
|
||||
else if (myJoinType == GeomAbs_Intersection)
|
||||
{
|
||||
if (Abs(ProVec) <= TolAng &&
|
||||
DotProd < 0)
|
||||
{
|
||||
while (NbTest <= 10)
|
||||
{
|
||||
Standard_Real U1 = C1->LastParameter() - NbTest*DU;
|
||||
Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
|
||||
gp_Dir2d Dir1(C1->DN(U1,1));
|
||||
gp_Dir2d Dir2(C2->DN(U2,1));
|
||||
DotProd = Dir1.Dot(Dir2);
|
||||
ProVec = Dir1^Dir2;
|
||||
if ((ProVec)*Direction < -TolAng)
|
||||
return Standard_True; // Saillant.
|
||||
if ((ProVec)*Direction > TolAng)
|
||||
return Standard_False; // Rentrant.
|
||||
|
||||
NbTest++;
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
else
|
||||
return Standard_False;
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SubSequence
|
||||
//purpose :
|
||||
@@ -736,103 +862,6 @@ static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : IsSharpCorner
|
||||
//purpose : Return True Si le point commun entre <Geom1> et <Geom2> est
|
||||
// une cassure saillante par rapport <Direction>
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Boolean IsSharpCorner (const Handle(Geom2d_Geometry)& Geom1,
|
||||
const Handle(Geom2d_Geometry)& Geom2,
|
||||
const Standard_Real& Direction)
|
||||
{
|
||||
Standard_Real DotProd;
|
||||
Standard_Real ProVec = CrossProd (Geom1,Geom2,DotProd);
|
||||
Standard_Integer NbTest = 1;
|
||||
Standard_Real DU = Precision::Confusion();
|
||||
Handle(Geom2d_TrimmedCurve) C1,C2;
|
||||
|
||||
C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
|
||||
C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
|
||||
// Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin
|
||||
// Add the same criterion as it is in MAT2d_Circuit::InitOpen(..)
|
||||
// Standard_Real TolAng = 1.E-5;
|
||||
Standard_Real TolAng = 1.E-8;
|
||||
// Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End
|
||||
|
||||
while (NbTest <= 10) {
|
||||
if ((ProVec)*Direction < -TolAng)
|
||||
return Standard_True; // Saillant.
|
||||
if ((ProVec)*Direction > TolAng)
|
||||
return Standard_False; // Rentrant.
|
||||
else {
|
||||
if (DotProd > 0) {
|
||||
return Standard_False; // Plat.
|
||||
}
|
||||
TolAng = 1.E-8;
|
||||
Standard_Real U1 = C1->LastParameter() - NbTest*DU;
|
||||
Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
|
||||
gp_Dir2d Dir1(C1->DN(U1,1));
|
||||
gp_Dir2d Dir2(C2->DN(U2,1));
|
||||
DotProd = Dir1.Dot(Dir2);
|
||||
ProVec = Dir1^Dir2;
|
||||
NbTest++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Rebroussement.
|
||||
// on calculde des paralleles aux deux courbes du cote du domaine
|
||||
// de calcul
|
||||
// Si pas dintersection => saillant.
|
||||
// Sinon => rentrant.
|
||||
Standard_Real D ;
|
||||
Standard_Real Tol = Precision::Confusion();
|
||||
Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5;
|
||||
Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5;
|
||||
gp_Pnt2d P = C1->Value(C1->LastParameter());
|
||||
gp_Pnt2d P1 = C1->Value(MilC1);
|
||||
gp_Pnt2d P2 = C2->Value(MilC2);
|
||||
|
||||
D = Min(P1.Distance(P),P2.Distance(P));
|
||||
D /= 10;
|
||||
|
||||
if (Direction > 0.) D = -D;
|
||||
|
||||
Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C1);
|
||||
Handle(Geom2dAdaptor_HCurve) HC2 = new Geom2dAdaptor_HCurve(C2);
|
||||
Adaptor3d_OffsetCurve OC1(HC1,D,MilC1,C1->LastParameter());
|
||||
Adaptor3d_OffsetCurve OC2(HC2,D,C2->FirstParameter(),MilC2);
|
||||
Geom2dInt_GInter Intersect;
|
||||
Intersect.Perform(OC1,OC2,Tol,Tol);
|
||||
|
||||
#ifdef DEB
|
||||
static Standard_Boolean Affich = 0;
|
||||
if (Affich) {
|
||||
#ifdef DRAW
|
||||
Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.;
|
||||
Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.;
|
||||
for (Standard_Integer ki = 0; ki <= 9; ki++) {
|
||||
gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1);
|
||||
gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2);
|
||||
Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert);
|
||||
Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge);
|
||||
dout << dr1;
|
||||
dout << dr2;
|
||||
}
|
||||
dout.Flush();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Intersect.IsDone() && !Intersect.IsEmpty()) {
|
||||
return Standard_False;
|
||||
}
|
||||
else {
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -21,7 +21,7 @@ class Tool2d from MAT2d
|
||||
|
||||
|
||||
uses
|
||||
|
||||
JoinType from GeomAbs,
|
||||
Bisec from Bisector,
|
||||
Side from MAT,
|
||||
Bisector from MAT,
|
||||
@@ -47,6 +47,9 @@ is
|
||||
--- Purpose :<aSide> defines the side of the computation of the map.
|
||||
is static;
|
||||
|
||||
SetJoinType(me : in out ; aJoinType : JoinType from GeomAbs)
|
||||
is static;
|
||||
|
||||
InitItems(me : in out ;
|
||||
aCircuit : Circuit from MAT2d )
|
||||
--- Purpose : InitItems cuts the line in Items.
|
||||
@@ -220,6 +223,7 @@ is
|
||||
fields
|
||||
|
||||
theDirection : Real;
|
||||
theJoinType : JoinType from GeomAbs;
|
||||
theNumberOfBisectors : Integer;
|
||||
theNumberOfPnts : Integer;
|
||||
theNumberOfVecs : Integer;
|
||||
|
@@ -100,6 +100,7 @@ static Standard_Real MAT2d_TOLCONF = 1.e-7;
|
||||
MAT2d_Tool2d::MAT2d_Tool2d()
|
||||
{
|
||||
theDirection = 1.;
|
||||
theJoinType = GeomAbs_Arc; //default
|
||||
theNumberOfBisectors = 0;
|
||||
theNumberOfVecs = 0;
|
||||
theNumberOfPnts = 0;
|
||||
@@ -132,6 +133,15 @@ void MAT2d_Tool2d::Sense(const MAT_Side aside)
|
||||
else theDirection = -1.;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : SetJoinType
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
void MAT2d_Tool2d::SetJoinType(const GeomAbs_JoinType aJoinType)
|
||||
{
|
||||
theJoinType = aJoinType;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : NumberOfItems
|
||||
//purpose :
|
||||
@@ -637,6 +647,9 @@ Standard_Boolean MAT2d_Tool2d::IsSameDistance (
|
||||
Standard_Real EpsDist = MAT2d_TOLCONF*100. ;
|
||||
Distance = Dist(1);
|
||||
for (Standard_Integer i = 1; i <= 4; i++){
|
||||
if (theJoinType == GeomAbs_Intersection &&
|
||||
Precision::IsInfinite(Dist(i)))
|
||||
continue;
|
||||
if (Abs(Dist(i) - Distance) > EpsDist) {
|
||||
Distance = Precision::Infinite();
|
||||
return Standard_False;
|
||||
|
Reference in New Issue
Block a user