1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // Created: Tue Dec 7 11:59:05 2004
24 // Author: Pavel DURANDIN
26 #include <BlockFix.hxx>
28 #include <BlockFix_SphereSpaceModifier.hxx>
29 #include <BlockFix_PeriodicSurfaceModifier.hxx>
32 #include <TopExp_Explorer.hxx>
34 #include <TopLoc_Location.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopoDS_Solid.hxx>
42 #include <TopoDS_Vertex.hxx>
44 #include <TopTools_ListOfShape.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopTools_MapOfShape.hxx>
47 #include <TopTools_DataMapOfShapeShape.hxx>
48 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
50 #include <BRep_Tool.hxx>
51 #include <BRep_Builder.hxx>
53 #include <BRepAdaptor_Surface.hxx>
55 #include <BRepTools.hxx>
56 #include <BRepTools_Modifier.hxx>
57 #include <BRepTools_Substitution.hxx>
59 #include <BRepOffsetAPI_MakeFilling.hxx>
61 #include <ShapeFix.hxx>
62 #include <ShapeFix_Edge.hxx>
63 #include <ShapeFix_Face.hxx>
65 #include <ShapeAnalysis.hxx>
66 #include <ShapeAnalysis_Edge.hxx>
67 #include <ShapeAnalysis_Curve.hxx>
68 #include <ShapeAnalysis_Surface.hxx>
70 #include <ShapeCustom.hxx>
72 #include <ShapeBuild_Edge.hxx>
73 #include <ShapeBuild_ReShape.hxx>
75 #include <ShapeFix_Wire.hxx>
77 #include <Geom_Surface.hxx>
78 #include <Geom_CylindricalSurface.hxx>
79 #include <Geom_ConicalSurface.hxx>
80 #include <Geom_SphericalSurface.hxx>
81 #include <Geom_ToroidalSurface.hxx>
83 #include <Geom2d_Curve.hxx>
85 #include <TColgp_SequenceOfPnt2d.hxx>
87 //=======================================================================
88 //function : FixResult
90 //=======================================================================
91 static void FixResult(const TopoDS_Shape& result,
92 Handle(ShapeBuild_ReShape)& Context,
93 const Standard_Real Tol)
95 for (TopExp_Explorer ex_f(result,TopAbs_FACE); ex_f.More(); ex_f.Next()) {
96 TopoDS_Shape aShape = Context->Apply(ex_f.Current().Oriented(TopAbs_FORWARD));
97 // face coud not be dropped or splitted on this step
98 TopoDS_Face aFace = TopoDS::Face(aShape);
100 Handle(Geom_Surface) Surf = BRep_Tool::Surface(aFace,L);
102 if( Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
103 Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ) {
105 Standard_Integer nbWires = 0;
106 for (TopExp_Explorer ex_w(aFace,TopAbs_WIRE); ex_w.More(); ex_w.Next()) {
108 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(TopoDS::Wire(ex_w.Current()),
110 Precision::Confusion());
112 if(sfw->StatusReorder ( ShapeExtend_FAIL ))
115 sfw->SetPrecision(2.*Tol);
118 Standard_Boolean isDone = sfw->LastFixStatus ( ShapeExtend_DONE );
119 isDone |= sfw->FixDegenerated();
121 // remove degenerated edges from not degenerated points
122 ShapeAnalysis_Edge sae;
123 Handle(ShapeExtend_WireData) sewd = sfw->WireData();
125 for( i = 1; i<=sewd->NbEdges();i++) {
126 TopoDS_Edge E = sewd->Edge(i);
127 if(BRep_Tool::Degenerated(E)&&!sae.HasPCurve(E,aFace)) {
129 isDone = Standard_True;
134 //isDone |= sfw->FixLacking(); // commented by skl 22.03.2005 (PAL8395)
136 // remove neighbour seam edges
138 for( i = 1; i<sewd->NbEdges();i++) {
139 if(sewd->IsSeam(i) && sewd->IsSeam(i+1)) {
140 isDone = Standard_True;
146 if(sewd->IsSeam(1) && sewd->IsSeam(sewd->NbEdges())) {
148 sewd->Remove(sewd->NbEdges());
153 TopoDS_Wire ResWire = sfw->Wire();
154 Context->Replace(ex_w.Current(), ResWire);
157 // Implement fix orientation in case of several wires
159 TopoDS_Face aFixedFace = TopoDS::Face(Context->Apply(aFace));
160 Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFixedFace);
161 if(sff->FixOrientation())
162 Context->Replace(aFixedFace,sff->Face());
168 //=======================================================================
169 //function : RotateSphereSpace
171 //=======================================================================
172 TopoDS_Shape BlockFix::RotateSphereSpace (const TopoDS_Shape& S,
173 const Standard_Real Tol)
175 // Create a modification description
176 Handle(BlockFix_SphereSpaceModifier) SR = new BlockFix_SphereSpaceModifier;
177 SR->SetTolerance(Tol);
179 TopTools_DataMapOfShapeShape context;
180 BRepTools_Modifier MD;
181 TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );
183 Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
184 FixResult(result,RS,Tol);
185 result = RS->Apply(result);
188 for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
189 TopoDS_Edge E = TopoDS::Edge(exp.Current());
190 sfe.FixVertexTolerance (E);
193 ShapeFix::SameParameter(result,Standard_False);
197 //=======================================================================
198 //function : RefillProblemFaces
200 //=======================================================================
201 TopoDS_Shape BlockFix::RefillProblemFaces (const TopoDS_Shape& aShape)
203 Standard_Integer NbSamples = 10;
205 TopTools_ListOfShape theFaces;
207 TopExp_Explorer Explo(aShape, TopAbs_FACE);
208 for (; Explo.More(); Explo.Next())
210 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
211 BRepAdaptor_Surface BAsurf(aFace);
212 GeomAbs_SurfaceType SurfType = BAsurf.GetType();
213 if (SurfType >= GeomAbs_BezierSurface)
215 TopExp_Explorer fexp(aFace, TopAbs_EDGE);
216 for (; fexp.More(); fexp.Next())
218 const TopoDS_Edge& anEdge = TopoDS::Edge(fexp.Current());
219 if (BRep_Tool::Degenerated(anEdge))
221 TopoDS_Vertex V1, V2;
222 TopExp::Vertices(anEdge, V1, V2);
225 gp_Pnt aPnt = BRep_Tool::Pnt(V1);
226 Standard_Real TolV = BRep_Tool::Tolerance(V1);
227 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
228 Handle(ShapeAnalysis_Surface) Analyser = new ShapeAnalysis_Surface(aSurf);
229 if (Analyser->IsDegenerated(aPnt, TolV))
231 theFaces.Append(aFace);
240 //Now all problem faces are collected in the list "theFaces"
241 BRepTools_Substitution aSubst;
242 TopTools_ListIteratorOfListOfShape itl(theFaces);
243 for (; itl.More(); itl.Next())
245 const TopoDS_Face& aFace = TopoDS::Face(itl.Value());
246 BRepOffsetAPI_MakeFilling Filler;
247 for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
249 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
250 if (!BRep_Tool::Degenerated(anEdge))
251 Filler.Add(anEdge, GeomAbs_C0);
253 Standard_Real Umin, Umax, Vmin, Vmax;
254 BRepTools::UVBounds(aFace, Umin, Umax, Vmin, Vmax);
255 //Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
256 Standard_Integer i, j;
257 for (i = 1; i < NbSamples; i++)
258 for (j = 1; j < NbSamples; j++) {
260 gp_Pnt aPoint = aSurf->Value(Umin + i*(Umax-Umin)/NbSamples,
261 Vmin + j*(Vmax-Vmin)/NbSamples);
264 Filler.Add(Umin + i*(Umax-Umin)/NbSamples,
265 Vmin + j*(Vmax-Vmin)/NbSamples,
272 for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
274 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
275 TopTools_ListOfShape Ledge;
276 if (!BRep_Tool::Degenerated(anEdge))
278 const TopTools_ListOfShape& Ledges = Filler.Generated(anEdge);
279 if (!Ledges.IsEmpty()) {
280 TopoDS_Shape NewEdge = Ledges.First();
281 Ledge.Append(NewEdge.Oriented(TopAbs_FORWARD));
284 aSubst.Substitute(anEdge, Ledge);
286 TopTools_ListOfShape Lface;
287 TopoDS_Face NewFace = TopoDS::Face(Filler.Shape());
288 NewFace.Orientation(TopAbs_FORWARD);
289 BRepAdaptor_Surface NewBAsurf(NewFace);
291 gp_Vec D1U, D1V, Normal, NewNormal;
292 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
293 aSurf->D1((Umin+Umax)*0.5, (Vmin+Vmax)*0.5, MidPnt, D1U, D1V);
295 NewBAsurf.D1((NewBAsurf.FirstUParameter() + NewBAsurf.LastUParameter())*0.5,
296 (NewBAsurf.FirstVParameter() + NewBAsurf.LastVParameter())*0.5,
298 NewNormal = D1U ^ D1V;
299 if (Normal * NewNormal < 0.)
301 Lface.Append(NewFace);
302 aSubst.Substitute(aFace, Lface);
305 aSubst.Build(aShape);
307 TopoDS_Shape Result = aShape;
308 if (aSubst.IsCopied(aShape))
309 Result = aSubst.Copy(aShape).First();
311 BRepTools::RemoveUnusedPCurves(Result);
316 //=======================================================================
317 //function : FixRanges
319 //=======================================================================
320 TopoDS_Shape BlockFix::FixRanges (const TopoDS_Shape& S,
321 const Standard_Real Tol)
323 // Create a modification description
324 Handle(BlockFix_PeriodicSurfaceModifier) SR = new BlockFix_PeriodicSurfaceModifier;
325 SR->SetTolerance(Tol);
327 TopTools_DataMapOfShapeShape context;
328 BRepTools_Modifier MD;
329 TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );
331 Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
332 FixResult(result,RS,Tol);
333 result = RS->Apply(result);
336 for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
337 TopoDS_Edge E = TopoDS::Edge(exp.Current());
338 sfe.FixVertexTolerance (E);
341 ShapeFix::SameParameter(result,Standard_False);