-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2023 CEA, EDF, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#include <BRep_Builder.hxx>
#include <BRepAdaptor_Surface.hxx>
+#include <BRepBndLib.hxx>
#include <BRepTools.hxx>
#include <BRepTools_Modifier.hxx>
#include <TColgp_SequenceOfPnt2d.hxx>
+#include <Basics_OCCTVersion.hxx>
+
+static Standard_Real ComputeMaxTolOfFace(const TopoDS_Face& theFace)
+{
+ Standard_Real MaxTol = BRep_Tool::Tolerance(theFace);
+
+ TopTools_IndexedMapOfShape aMap;
+ TopExp::MapShapes(theFace, TopAbs_EDGE, aMap);
+ for (Standard_Integer i = 1; i <= aMap.Extent(); i++)
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge(aMap(i));
+ Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
+ if (aTol > MaxTol)
+ MaxTol = aTol;
+ }
+
+ aMap.Clear();
+ TopExp::MapShapes(theFace, TopAbs_VERTEX, aMap);
+ for (Standard_Integer i = 1; i <= aMap.Extent(); i++)
+ {
+ const TopoDS_Vertex& aVertex = TopoDS::Vertex(aMap(i));
+ Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
+ if (aTol > MaxTol)
+ MaxTol = aTol;
+ }
+
+ return MaxTol;
+}
+
//=======================================================================
//function : FixResult
//purpose : auxiliary
{
Standard_Integer NbSamples = 10;
+#if OCC_VERSION_LARGE > 0x07040000
+ TopTools_IndexedDataMapOfShapeListOfShape VFmap;
+ TopExp::MapShapesAndUniqueAncestors(aShape, TopAbs_VERTEX, TopAbs_FACE, VFmap);
+#endif
+
TopTools_ListOfShape theFaces;
TopExp_Explorer Explo(aShape, TopAbs_FACE);
TopTools_ListIteratorOfListOfShape itl(theFaces);
for (; itl.More(); itl.Next())
{
- const TopoDS_Face& aFace = TopoDS::Face(itl.Value());
- BRepOffsetAPI_MakeFilling Filler;
- for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
+ TopoDS_Face aFace = TopoDS::Face(itl.Value());
+ aFace.Orientation(TopAbs_FORWARD);
+
+ //Compute proper tolerance
+ Standard_Real MaxTolOfFace = ComputeMaxTolOfFace(aFace);
+#if OCC_VERSION_LARGE > 0x07040000
+ Bnd_Box aBndBox;
+ BRepBndLib::Add(aFace, aBndBox);
+ Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
+ aBndBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
+ Standard_Real LinSize = Min(Xmax - Xmin, Min(Ymax - Ymin, Zmax - Zmin));
+ Standard_Real LinTol = Max(0.001*LinSize, 1.5*MaxTolOfFace);
+#endif
+
+ BRepAdaptor_Surface BAsurf(aFace, Standard_False);
+ BRepOffsetAPI_MakeFilling Filler(3, 10);
+ TopExp_Explorer Explo(aFace, TopAbs_EDGE);
+ for (; Explo.More(); Explo.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
- if (!BRep_Tool::Degenerated(anEdge))
- Filler.Add(anEdge, GeomAbs_C0);
+ if (BRep_Tool::Degenerated(anEdge) ||
+ BRepTools::IsReallyClosed(anEdge, aFace))
+ continue;
+
+ Filler.Add(anEdge, GeomAbs_C0);
+ //Filler.Add(anEdge, aFace, GeomAbs_G1);
}
Standard_Real Umin, Umax, Vmin, Vmax;
BRepTools::UVBounds(aFace, Umin, Umax, Vmin, Vmax);
- //Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
- Standard_Integer i, j;
- for (i = 1; i < NbSamples; i++)
- for (j = 1; j < NbSamples; j++) {
- /*
- gp_Pnt aPoint = aSurf->Value(Umin + i*(Umax-Umin)/NbSamples,
- Vmin + j*(Vmax-Vmin)/NbSamples);
- Filler.Add(aPoint);
- */
- Filler.Add(Umin + i*(Umax-Umin)/NbSamples,
- Vmin + j*(Vmax-Vmin)/NbSamples,
- aFace, GeomAbs_G1);
+ Standard_Real DeltaU = (Umax - Umin)/NbSamples,
+ DeltaV = (Vmax - Vmin)/NbSamples;
+ for (Standard_Integer i = 1; i < NbSamples; i++)
+ for (Standard_Integer j = 1; j < NbSamples; j++) {
+ Filler.Add(Umin + i*DeltaU, Vmin + j*DeltaV, aFace, GeomAbs_G1);
}
Filler.Build();
if (Filler.IsDone())
{
- for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
+ TopoDS_Face aNewFace = TopoDS::Face(Filler.Shape());
+ aNewFace.Orientation(TopAbs_FORWARD);
+ Handle(Geom_Surface) aNewSurf = BRep_Tool::Surface(aNewFace);
+ GeomAdaptor_Surface GAnewsurf(aNewSurf);
+ Extrema_ExtPS Projector;
+ Projector.Initialize(GAnewsurf, GAnewsurf.FirstUParameter(), GAnewsurf.LastUParameter(),
+ GAnewsurf.FirstVParameter(), GAnewsurf.LastVParameter(),
+ Precision::Confusion(), Precision::Confusion());
+ Standard_Real MaxSqDist = 0.;
+ for (Standard_Integer i = 0; i < NbSamples; i++)
+ for (Standard_Integer j = 0; j < NbSamples; j++)
+ {
+ gp_Pnt aPoint = BAsurf.Value(Umin + DeltaU/2 + i*DeltaU,
+ Vmin + DeltaV/2 + j*DeltaV);
+ Projector.Perform(aPoint);
+ if (Projector.IsDone())
+ {
+ Standard_Real LocalMinSqDist = RealLast();
+ for (Standard_Integer ind = 1; ind <= Projector.NbExt(); ind++)
+ {
+ Standard_Real aSqDist = Projector.SquareDistance(ind);
+ if (aSqDist < LocalMinSqDist)
+ LocalMinSqDist = aSqDist;
+ }
+ if (!Precision::IsInfinite(LocalMinSqDist) &&
+ LocalMinSqDist > MaxSqDist)
+ MaxSqDist = LocalMinSqDist;
+ }
+ }
+ Standard_Real MaxDist = Sqrt(MaxSqDist);
+#if OCC_VERSION_LARGE > 0x07040000
+ if (MaxDist < LinTol)
+#else
+ if (MaxDist < Max(1.e-4, 1.5*MaxTolOfFace))
+#endif
{
- const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
- TopTools_ListOfShape Ledge;
- if (!BRep_Tool::Degenerated(anEdge))
+ TopTools_IndexedMapOfShape Emap;
+#if OCC_VERSION_LARGE > 0x07040000
+ TopTools_MapOfShape Vmap;
+#endif
+ TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
+ for (Standard_Integer i = 1; i <= Emap.Extent(); i++)
{
- const TopTools_ListOfShape& Ledges = Filler.Generated(anEdge);
- if (!Ledges.IsEmpty()) {
- TopoDS_Shape NewEdge = Ledges.First();
- Ledge.Append(NewEdge.Oriented(TopAbs_FORWARD));
+ TopoDS_Edge anEdge = TopoDS::Edge(Emap(i));
+ anEdge.Orientation(TopAbs_FORWARD);
+#if OCC_VERSION_LARGE > 0x07040000
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices(anEdge, V1, V2);
+ TopTools_ListOfShape ListV1, ListV2;
+#endif
+ TopTools_ListOfShape Ledge;
+ if (!BRep_Tool::Degenerated(anEdge) &&
+ !BRepTools::IsReallyClosed(anEdge, aFace))
+ {
+ const TopTools_ListOfShape& Ledges = Filler.Generated(anEdge);
+ if (!Ledges.IsEmpty()) {
+ TopoDS_Edge NewEdge = TopoDS::Edge(Ledges.First());
+ Ledge.Append(NewEdge.Oriented(TopAbs_FORWARD));
+ }
+
+#if OCC_VERSION_LARGE > 0x07040000
+ TopoDS_Vertex NewV1 = TopoDS::Vertex(Filler.Generated(V1).First());
+ ListV1.Append(NewV1.Oriented(TopAbs_FORWARD));
+
+ if (!V1.IsSame(V2)) {
+ TopoDS_Vertex NewV2 = TopoDS::Vertex(Filler.Generated(V2).First());
+ ListV2.Append(NewV2.Oriented(TopAbs_FORWARD));
+ }
+#endif
+ }
+ aSubst.Substitute(anEdge, Ledge);
+#if OCC_VERSION_LARGE > 0x07040000
+ if (!Vmap.Contains(V1) &&
+ (!ListV1.IsEmpty() || VFmap.FindFromKey(V1).Extent() == 1))
+ {
+ aSubst.Substitute(V1, ListV1);
+ Vmap.Add(V1);
+ }
+ if (!Vmap.Contains(V2) &&
+ (!ListV2.IsEmpty() || VFmap.FindFromKey(V2).Extent() == 1))
+ {
+ aSubst.Substitute(V2.Oriented(TopAbs_FORWARD), ListV2);
+ Vmap.Add(V2);
}
+#endif
}
- aSubst.Substitute(anEdge, Ledge);
+ TopTools_ListOfShape Lface;
+ BRepAdaptor_Surface NewBAsurf(aNewFace);
+ gp_Pnt MidPnt;
+ gp_Vec D1U, D1V, Normal, NewNormal;
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+ aSurf->D1((Umin+Umax)*0.5, (Vmin+Vmax)*0.5, MidPnt, D1U, D1V);
+ Normal = D1U ^ D1V;
+ NewBAsurf.D1((NewBAsurf.FirstUParameter() + NewBAsurf.LastUParameter())*0.5,
+ (NewBAsurf.FirstVParameter() + NewBAsurf.LastVParameter())*0.5,
+ MidPnt, D1U, D1V);
+ NewNormal = D1U ^ D1V;
+ if (Normal * NewNormal < 0.)
+ aNewFace.Reverse();
+ Lface.Append(aNewFace);
+ aSubst.Substitute(aFace, Lface);
}
- TopTools_ListOfShape Lface;
- TopoDS_Face NewFace = TopoDS::Face(Filler.Shape());
- NewFace.Orientation(TopAbs_FORWARD);
- BRepAdaptor_Surface NewBAsurf(NewFace);
- gp_Pnt MidPnt;
- gp_Vec D1U, D1V, Normal, NewNormal;
- Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
- aSurf->D1((Umin+Umax)*0.5, (Vmin+Vmax)*0.5, MidPnt, D1U, D1V);
- Normal = D1U ^ D1V;
- NewBAsurf.D1((NewBAsurf.FirstUParameter() + NewBAsurf.LastUParameter())*0.5,
- (NewBAsurf.FirstVParameter() + NewBAsurf.LastVParameter())*0.5,
- MidPnt, D1U, D1V);
- NewNormal = D1U ^ D1V;
- if (Normal * NewNormal < 0.)
- NewFace.Reverse();
- Lface.Append(NewFace);
- aSubst.Substitute(aFace, Lface);
}
}
aSubst.Build(aShape);