1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0030940: BRepFilletAPI_MakeFillet algorithm fails on closed shell

1. Add check of configuration of corner in the end of spine.
2. Correct treatment of "smooth corners".
This commit is contained in:
jgv
2019-09-20 13:52:10 +03:00
committed by apn
parent bf327822d6
commit eff3eff916
33 changed files with 586 additions and 319 deletions

View File

@@ -29,6 +29,105 @@
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <BRepTools.hxx>
#include <IntTools_Tools.hxx>
static void Correct2dPoint(const TopoDS_Face& theF, gp_Pnt2d& theP2d);
//
//=======================================================================
//function : DefineConnectType
//purpose :
//=======================================================================
ChFiDS_TypeOfConcavity ChFi3d::DefineConnectType(const TopoDS_Edge& E,
const TopoDS_Face& F1,
const TopoDS_Face& F2,
const Standard_Real SinTol,
const Standard_Boolean CorrectPoint)
{
const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1);
const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2);
//
Standard_Real f,l;
Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
//For the case of seam edge
TopoDS_Edge EE = E;
if (F1.IsSame(F2))
EE.Reverse();
Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(EE,F2,f,l);
BRepAdaptor_Curve C(E);
f = C.FirstParameter();
l = C.LastParameter();
//
Standard_Real ParOnC = 0.5*(f+l);
gp_Vec T1 = C.DN(ParOnC,1);
if (T1.SquareMagnitude() <= gp::Resolution())
{
ParOnC = IntTools_Tools::IntermediatePoint(f,l);
T1 = C.DN(ParOnC,1);
}
if (T1.SquareMagnitude() > gp::Resolution()) {
T1.Normalize();
}
if (BRepTools::OriEdgeInFace(E,F1) == TopAbs_REVERSED) {
T1.Reverse();
}
if (F1.Orientation() == TopAbs_REVERSED) T1.Reverse();
gp_Pnt2d P = C1->Value(ParOnC);
gp_Pnt P3;
gp_Vec D1U,D1V;
if(CorrectPoint)
Correct2dPoint(F1, P);
//
S1->D1(P.X(),P.Y(),P3,D1U,D1V);
gp_Vec DN1(D1U^D1V);
if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
P = C2->Value(ParOnC);
if(CorrectPoint)
Correct2dPoint(F2, P);
S2->D1(P.X(),P.Y(),P3,D1U,D1V);
gp_Vec DN2(D1U^D1V);
if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
DN1.Normalize();
DN2.Normalize();
gp_Vec ProVec = DN1^DN2;
Standard_Real NormProVec = ProVec.Magnitude();
if (NormProVec < SinTol) {
// plane
if (DN1.Dot(DN2) > 0) {
//Tangent
return ChFiDS_Tangential;
}
else {
//Mixed not finished!
#ifdef OCCT_DEBUG
std::cout <<" faces locally mixed"<<std::endl;
#endif
return ChFiDS_Convex;
}
}
else {
if (NormProVec > gp::Resolution())
ProVec /= NormProVec;
Standard_Real Prod = T1.Dot(ProVec);
if (Prod > 0.) {
//
return ChFiDS_Convex;
}
else {
//reenters
return ChFiDS_Concave;
}
}
}
//=======================================================================
//function : ConcaveSide
@@ -290,3 +389,49 @@ Standard_Boolean ChFi3d::SameSide(const TopAbs_Orientation Or,
}
return (o1 == o2);
}
//=======================================================================
//function : Correct2dPoint
//purpose :
//=======================================================================
void Correct2dPoint(const TopoDS_Face& theF, gp_Pnt2d& theP2d)
{
BRepAdaptor_Surface aBAS(theF, Standard_False);
if (aBAS.GetType() < GeomAbs_BezierSurface) {
return;
}
//
const Standard_Real coeff = 0.01;
Standard_Real eps;
Standard_Real u1, u2, v1, v2;
//
aBAS.Initialize(theF, Standard_True);
u1 = aBAS.FirstUParameter();
u2 = aBAS.LastUParameter();
v1 = aBAS.FirstVParameter();
v2 = aBAS.LastVParameter();
if (!(Precision::IsInfinite(u1) || Precision::IsInfinite(u2)))
{
eps = Max(coeff*(u2 - u1), Precision::PConfusion());
if (Abs(theP2d.X() - u1) < eps)
{
theP2d.SetX(u1 + eps);
}
if (Abs(theP2d.X() - u2) < eps)
{
theP2d.SetX(u2 - eps);
}
}
if (!(Precision::IsInfinite(v1) || Precision::IsInfinite(v2)))
{
eps = Max(coeff*(v2 - v1), Precision::PConfusion());
if (Abs(theP2d.Y() - v1) < eps)
{
theP2d.SetY(v1 + eps);
}
if (Abs(theP2d.Y() - v2) < eps)
{
theP2d.SetY(v2 - eps);
}
}
}

View File

@@ -24,8 +24,10 @@
#include <Standard_Integer.hxx>
#include <TopAbs_Orientation.hxx>
#include <Standard_Boolean.hxx>
#include <ChFiDS_TypeOfConcavity.hxx>
class BRepAdaptor_Surface;
class TopoDS_Edge;
class TopoDS_Face;
class ChFi3d_Builder;
class ChFi3d_ChBuilder;
class ChFi3d_FilBuilder;
@@ -39,6 +41,12 @@ public:
DEFINE_STANDARD_ALLOC
//! Defines the type of concavity in the edge of connection of two faces
Standard_EXPORT static ChFiDS_TypeOfConcavity DefineConnectType (const TopoDS_Edge& E,
const TopoDS_Face& F1,
const TopoDS_Face& F2,
const Standard_Real SinTol,
const Standard_Boolean CorrectPoint);
//! Returns Reversed in Or1 and(or) Or2 if
//! the concave edge defined by the interior of faces F1 and F2,

View File

@@ -4611,8 +4611,12 @@ Standard_Boolean ChFi3d_isTangentFaces(const TopoDS_Edge &theEdge,
// Obtaining of pcurves of edge on two faces.
const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
(theEdge, theFace1, aFirst, aLast);
//For the case of seam edge
TopoDS_Edge EE = theEdge;
if (theFace1.IsSame(theFace2))
EE.Reverse();
const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
(theEdge, theFace2, aFirst, aLast);
(EE, theFace2, aFirst, aLast);
if (aC2d1.IsNull() || aC2d2.IsNull())
return Standard_False;

View File

@@ -680,7 +680,7 @@ void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine)
Standard_Integer NbG1Connections = 0;
for(Standard_Integer ii = 1; ii <= 2; ii++){
TopoDS_Edge E[3],Ec;
TopoDS_Edge E[3];
TopoDS_Vertex V;
ChFiDS_State sst;
Standard_Integer iedge;
@@ -705,44 +705,61 @@ void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine)
if(sst == ChFiDS_BreakPoint){
TopTools_ListIteratorOfListOfShape It;//,Jt;
Standard_Integer i = 0;
Standard_Boolean sommetpourri = Standard_False;
TopTools_IndexedMapOfShape EdgesOfV;
//to avoid repeating of edges
TopTools_IndexedMapOfOrientedShape EdgesOfV;
TopTools_MapOfShape Edges;
Edges.Add(E[0]);
EdgesOfV.Add(E[0]);
Standard_Integer IndOfE = 0;
for (It.Initialize(myVEMap(V)); It.More(); It.Next())
EdgesOfV.Add(It.Value());
for (Standard_Integer ind = 1; ind <= EdgesOfV.Extent(); ind++) {
Ec = TopoDS::Edge(EdgesOfV(ind));
Standard_Boolean bonedge = !BRep_Tool::Degenerated(Ec);
if (bonedge)
{
TopoDS_Edge anEdge = TopoDS::Edge(It.Value());
if (BRep_Tool::Degenerated(anEdge))
continue;
TopoDS_Face F1, F2;
ChFi3d_conexfaces(anEdge, F1, F2, myEFMap);
if (!F2.IsNull() && ChFi3d_isTangentFaces(anEdge, F1, F2, GeomAbs_G2)) //smooth edge
{
TopoDS_Face F1, F2;
ChFi3d_conexfaces(Ec, F1, F2, myEFMap);
if (!F2.IsNull() && ChFi3d_isTangentFaces(Ec, F1, F2, GeomAbs_G2))
if (!F1.IsSame(F2))
NbG1Connections++;
continue;
}
if (Edges.Add(anEdge))
{
EdgesOfV.Add(anEdge);
if (IndOfE < 2)
{
bonedge = Standard_False;
if (!F1.IsSame(F2))
NbG1Connections++;
IndOfE++;
E[IndOfE] = anEdge;
}
}
if(bonedge){
if (!Ec.IsSame(E[0]))
else
{
TopoDS_Vertex V1, V2;
TopExp::Vertices(anEdge, V1, V2);
if (V1.IsSame(V2)) //edge is closed - two ends of the edge in the vertex
{
if( i < 2 ){
i++;
E[i] = Ec;
}
else{
#ifdef OCCT_DEBUG
std::cout<<"top has more than 3 edges"<<std::endl;
#endif
sommetpourri = Standard_True;
break;
Standard_Integer anInd = EdgesOfV.FindIndex(anEdge);
if (anInd == 0)
anInd = EdgesOfV.FindIndex(anEdge.Reversed());
anEdge = TopoDS::Edge(EdgesOfV(anInd));
anEdge.Reverse();
if (EdgesOfV.Add(anEdge))
{
if (IndOfE < 2)
{
IndOfE++;
E[IndOfE] = anEdge;
}
}
}
}
}
}
if(i != 2) sommetpourri = Standard_True;
if (EdgesOfV.Extent() != 3)
sommetpourri = Standard_True;
if(!sommetpourri){
sst = ChFi3d_EdgeState(E,myEFMap);
}
@@ -828,6 +845,12 @@ Standard_Boolean ChFi3d_Builder::PerformElement(const Handle(ChFiDS_Spine)& Spin
ff2 = ff1; ff1 = FirstFace;
}
myEdgeFirstFace.Bind(Ec, FirstFace);
//Define concavity
ChFiDS_TypeOfConcavity TypeOfConcavity = ChFi3d::DefineConnectType(Ec, ff1, ff2,
1.e-5, Standard_True);
Spine->SetTypeOfConcavity(TypeOfConcavity);
Standard_Boolean ToRestrict = (Offset > 0)? Standard_True : Standard_False;
BRepAdaptor_Surface Sb1(ff1, ToRestrict);
BRepAdaptor_Surface Sb2(ff2, ToRestrict);
@@ -852,8 +875,11 @@ Standard_Boolean ChFi3d_Builder::PerformElement(const Handle(ChFiDS_Spine)& Spin
CEc.D1(Wl,P2,V1);
Wl = BRep_Tool::Parameter(LVEc,Ec);
CEc.D1(Wl,P2,V2);
if (V1.IsParallel(V2,ta)) {
if (FaceTangency(Ec,Ec,VStart)) {
Standard_Boolean IsFaceTangency = FaceTangency(Ec,Ec,VStart);
if (V1.IsParallel(V2,ta) ||
IsFaceTangency)
{
if (IsFaceTangency) {
CurSt = ChFiDS_Closed;
}
else {

View File

@@ -1942,13 +1942,21 @@ void ChFi3d_FilBuilder::ExtentThreeCorner(const TopoDS_Vertex& V,
Handle(ChFiDS_Spine) Spine = Stripe->Spine();
if (Spine->IsTangencyExtremity((Sens == 1))) return; //No extension on queue
Standard_Real dU = Spine->LastParameter(Spine->NbEdges());
if (Sens == 1){
Spine->SetFirstParameter(-dU*Coeff);
Spine->SetFirstTgt(0.);
if (Sens == 1){
if (!(Spine->GetTypeOfConcavity() == ChFiDS_Convex &&
Spine->FirstStatus() == ChFiDS_OnSame))
{
Spine->SetFirstParameter(-dU*Coeff);
Spine->SetFirstTgt(0.);
}
}
else{
Spine->SetLastParameter(dU*(1.+Coeff));
Spine->SetLastTgt(dU);
if (!(Spine->GetTypeOfConcavity() == ChFiDS_Convex &&
Spine->LastStatus() == ChFiDS_OnSame))
{
Spine->SetLastParameter(dU*(1.+Coeff));
Spine->SetLastTgt(dU);
}
}
check.Append(Stripe);
}