Salome HOME
Typo-fix by Kunda
[modules/geom.git] / src / BlockFix / BlockFix.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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, or (at your option) any later version.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File:        BlockFix.cxx
24 // Created:     Tue Dec  7 11:59:05 2004
25 // Author:      Pavel DURANDIN
26
27 #include <BlockFix.hxx>
28
29 #include <BlockFix_SphereSpaceModifier.hxx>
30 #include <BlockFix_PeriodicSurfaceModifier.hxx>
31
32 #include <TopExp.hxx>
33 #include <TopExp_Explorer.hxx>
34
35 #include <TopLoc_Location.hxx>
36
37 #include <TopoDS.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Face.hxx>
40 #include <TopoDS_Wire.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopoDS_Solid.hxx>
43 #include <TopoDS_Vertex.hxx>
44
45 #include <TopTools_ListOfShape.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <TopTools_MapOfShape.hxx>
48 #include <TopTools_DataMapOfShapeShape.hxx>
49 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
50
51 #include <BRep_Tool.hxx>
52 #include <BRep_Builder.hxx>
53
54 #include <BRepAdaptor_Surface.hxx>
55
56 #include <BRepTools.hxx>
57 #include <BRepTools_Modifier.hxx>
58 #include <BRepTools_Substitution.hxx>
59
60 #include <BRepOffsetAPI_MakeFilling.hxx>
61
62 #include <ShapeFix.hxx>
63 #include <ShapeFix_Edge.hxx>
64 #include <ShapeFix_Face.hxx>
65
66 #include <ShapeAnalysis.hxx>
67 #include <ShapeAnalysis_Edge.hxx>
68 #include <ShapeAnalysis_Curve.hxx>
69 #include <ShapeAnalysis_Surface.hxx>
70
71 #include <ShapeCustom.hxx>
72
73 #include <ShapeBuild_Edge.hxx>
74 #include <ShapeBuild_ReShape.hxx>
75
76 #include <ShapeFix_Wire.hxx>
77
78 #include <Geom_Surface.hxx>
79 #include <Geom_CylindricalSurface.hxx>
80 #include <Geom_ConicalSurface.hxx>
81 #include <Geom_SphericalSurface.hxx>
82 #include <Geom_ToroidalSurface.hxx>
83
84 #include <Geom2d_Curve.hxx>
85
86 #include <TColgp_SequenceOfPnt2d.hxx>
87
88 //=======================================================================
89 //function : FixResult
90 //purpose  : auxiliary
91 //=======================================================================
92 static void FixResult(const TopoDS_Shape& result,
93                       Handle(ShapeBuild_ReShape)& Context,
94                       const Standard_Real Tol)
95 {
96   for (TopExp_Explorer ex_f(result,TopAbs_FACE); ex_f.More(); ex_f.Next()) {
97     TopoDS_Shape aShape = Context->Apply(ex_f.Current().Oriented(TopAbs_FORWARD));
98     // face could not be dropped or split on this step
99     TopoDS_Face aFace = TopoDS::Face(aShape);
100     TopLoc_Location L;
101     Handle(Geom_Surface) Surf = BRep_Tool::Surface(aFace,L);
102
103     if( Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
104         Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ) {
105
106       Standard_Integer nbWires = 0;
107       for (TopExp_Explorer ex_w(aFace,TopAbs_WIRE); ex_w.More(); ex_w.Next()) {
108         nbWires++;
109         Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(TopoDS::Wire(ex_w.Current()),
110                                                       aFace,
111                                                       Precision::Confusion());
112         sfw->FixReorder();
113         if(sfw->StatusReorder ( ShapeExtend_FAIL ))
114           continue;
115
116         sfw->SetPrecision(2.*Tol);
117         sfw->FixShifted();
118
119         Standard_Boolean isDone = sfw->LastFixStatus ( ShapeExtend_DONE );
120         isDone |= sfw->FixDegenerated();
121
122         // remove degenerated edges from not degenerated points
123         ShapeAnalysis_Edge sae;
124         Handle(ShapeExtend_WireData) sewd = sfw->WireData();
125         Standard_Integer i;
126         for( i = 1; i<=sewd->NbEdges();i++) {
127           TopoDS_Edge E = sewd->Edge(i);
128           if(BRep_Tool::Degenerated(E)&&!sae.HasPCurve(E,aFace)) {
129             sewd->Remove(i);
130             isDone = Standard_True;
131             i--;
132           }
133         }
134
135         //isDone |= sfw->FixLacking(); // commented by skl 22.03.2005 (PAL8395)
136
137         // remove neighbour seam edges
138         if(isDone) {
139           for( i = 1; i<sewd->NbEdges();i++) {
140             if(sewd->IsSeam(i) && sewd->IsSeam(i+1)) {
141               isDone = Standard_True;
142               sewd->Remove(i);
143               sewd->Remove(i);
144               i--;
145             }
146           }
147           if(sewd->IsSeam(1) && sewd->IsSeam(sewd->NbEdges())) {
148             sewd->Remove(1);
149             sewd->Remove(sewd->NbEdges());
150           }
151         }
152
153         if(isDone) {
154           TopoDS_Wire ResWire = sfw->Wire();
155           Context->Replace(ex_w.Current(), ResWire);
156         };
157       }
158       // Implement fix orientation in case of several wires
159       if(nbWires > 1) {
160         TopoDS_Face aFixedFace = TopoDS::Face(Context->Apply(aFace));
161         Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFixedFace);
162         if(sff->FixOrientation())
163           Context->Replace(aFixedFace,sff->Face());
164       }
165     }
166   }
167 }
168
169 //=======================================================================
170 //function : RotateSphereSpace
171 //purpose  :
172 //=======================================================================
173 TopoDS_Shape BlockFix::RotateSphereSpace (const TopoDS_Shape& S,
174                                           const Standard_Real Tol)
175 {
176   // Create a modification description
177   Handle(BlockFix_SphereSpaceModifier) SR = new BlockFix_SphereSpaceModifier;
178   SR->SetTolerance(Tol);
179
180   TopTools_DataMapOfShapeShape context;
181   BRepTools_Modifier MD;
182   TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );
183
184   Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
185   FixResult(result,RS,Tol);
186   result = RS->Apply(result);
187
188   ShapeFix_Edge sfe;
189   for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
190     TopoDS_Edge E = TopoDS::Edge(exp.Current());
191     sfe.FixVertexTolerance (E);
192   }
193
194   ShapeFix::SameParameter(result,Standard_False);
195   return result;
196 }
197
198 //=======================================================================
199 //function : RefillProblemFaces
200 //purpose  :
201 //=======================================================================
202 TopoDS_Shape BlockFix::RefillProblemFaces (const TopoDS_Shape& aShape)
203 {
204   Standard_Integer NbSamples = 10;
205
206   TopTools_ListOfShape theFaces;
207
208   TopExp_Explorer Explo(aShape, TopAbs_FACE);
209   for (; Explo.More(); Explo.Next())
210   {
211     TopoDS_Face aFace = TopoDS::Face(Explo.Current());
212     BRepAdaptor_Surface BAsurf(aFace);
213     GeomAbs_SurfaceType SurfType = BAsurf.GetType();
214     if (SurfType >= GeomAbs_BezierSurface)
215     {
216       TopExp_Explorer fexp(aFace, TopAbs_EDGE);
217       for (; fexp.More(); fexp.Next())
218       {
219         const TopoDS_Edge& anEdge = TopoDS::Edge(fexp.Current());
220         if (BRep_Tool::Degenerated(anEdge))
221         {
222           TopoDS_Vertex V1, V2;
223           TopExp::Vertices(anEdge, V1, V2);
224           if (V1.IsSame(V2))
225           {
226             gp_Pnt aPnt = BRep_Tool::Pnt(V1);
227             Standard_Real TolV = BRep_Tool::Tolerance(V1);
228             Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
229             Handle(ShapeAnalysis_Surface) Analyser = new ShapeAnalysis_Surface(aSurf);
230             if (Analyser->IsDegenerated(aPnt, TolV))
231             {
232               theFaces.Append(aFace);
233               break;
234             }
235           }
236         }
237       }
238     }
239   }
240
241   //Now all problem faces are collected in the list "theFaces"
242   BRepTools_Substitution aSubst;
243   TopTools_ListIteratorOfListOfShape itl(theFaces);
244   for (; itl.More(); itl.Next())
245   {
246     const TopoDS_Face& aFace = TopoDS::Face(itl.Value());
247     BRepOffsetAPI_MakeFilling Filler;
248     for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
249     {
250       const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
251       if (!BRep_Tool::Degenerated(anEdge))
252         Filler.Add(anEdge, GeomAbs_C0);
253     }
254     Standard_Real Umin, Umax, Vmin, Vmax;
255     BRepTools::UVBounds(aFace, Umin, Umax, Vmin, Vmax);
256     //Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
257     Standard_Integer i, j;
258     for (i = 1; i < NbSamples; i++)
259       for (j = 1; j < NbSamples; j++) {
260         /*
261         gp_Pnt aPoint = aSurf->Value(Umin + i*(Umax-Umin)/NbSamples,
262                                      Vmin + j*(Vmax-Vmin)/NbSamples);
263         Filler.Add(aPoint);
264         */
265         Filler.Add(Umin + i*(Umax-Umin)/NbSamples,
266                    Vmin + j*(Vmax-Vmin)/NbSamples,
267                    aFace, GeomAbs_G1);
268       }
269
270     Filler.Build();
271     if (Filler.IsDone())
272     {
273       for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
274       {
275         const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
276         TopTools_ListOfShape Ledge;
277         if (!BRep_Tool::Degenerated(anEdge))
278         {
279           const TopTools_ListOfShape& Ledges = Filler.Generated(anEdge);
280           if (!Ledges.IsEmpty()) {
281             TopoDS_Shape NewEdge = Ledges.First();
282             Ledge.Append(NewEdge.Oriented(TopAbs_FORWARD));
283           }
284         }
285         aSubst.Substitute(anEdge, Ledge);
286       }
287       TopTools_ListOfShape Lface;
288       TopoDS_Face NewFace = TopoDS::Face(Filler.Shape());
289       NewFace.Orientation(TopAbs_FORWARD);
290       BRepAdaptor_Surface NewBAsurf(NewFace);
291       gp_Pnt MidPnt;
292       gp_Vec D1U, D1V, Normal, NewNormal;
293       Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
294       aSurf->D1((Umin+Umax)*0.5, (Vmin+Vmax)*0.5, MidPnt, D1U, D1V);
295       Normal = D1U ^ D1V;
296       NewBAsurf.D1((NewBAsurf.FirstUParameter() + NewBAsurf.LastUParameter())*0.5,
297                    (NewBAsurf.FirstVParameter() + NewBAsurf.LastVParameter())*0.5,
298                    MidPnt, D1U, D1V);
299       NewNormal = D1U ^ D1V;
300       if (Normal * NewNormal < 0.)
301         NewFace.Reverse();
302       Lface.Append(NewFace);
303       aSubst.Substitute(aFace, Lface);
304     }
305   }
306   aSubst.Build(aShape);
307
308   TopoDS_Shape Result = aShape;
309   if (aSubst.IsCopied(aShape))
310     Result = aSubst.Copy(aShape).First();
311
312   BRepTools::RemoveUnusedPCurves(Result);
313
314   return Result;
315 }
316
317 //=======================================================================
318 //function : FixRanges
319 //purpose  :
320 //=======================================================================
321 TopoDS_Shape BlockFix::FixRanges (const TopoDS_Shape& S,
322                                   const Standard_Real Tol)
323 {
324   // Create a modification description
325   Handle(BlockFix_PeriodicSurfaceModifier) SR = new BlockFix_PeriodicSurfaceModifier;
326   SR->SetTolerance(Tol);
327
328   TopTools_DataMapOfShapeShape context;
329   BRepTools_Modifier MD;
330   TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );
331
332   Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
333   FixResult(result,RS,Tol);
334   result = RS->Apply(result);
335
336   ShapeFix_Edge sfe;
337   for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
338     TopoDS_Edge E = TopoDS::Edge(exp.Current());
339     sfe.FixVertexTolerance (E);
340   }
341
342   ShapeFix::SameParameter(result,Standard_False);
343
344   return result;
345 }