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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user