Salome HOME
a8c47b09d3a386de8c568ffa037b15383425bfc4
[modules/geom.git] / src / GEOMAlgo / BlockFix.cxx
1 //  Copyright (C) 2007-2008  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.
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 // File:        BlockFix.cxx
23 // Created:     Tue Dec  7 11:59:05 2004
24 // Author:      Pavel DURANDIN
25 //
26 #include <BlockFix.hxx>
27 #include <TopoDS_Shape.hxx>
28 #include <TopTools_DataMapOfShapeShape.hxx>
29 #include <ShapeCustom.hxx>
30 #include <BRepTools.hxx>
31 #include <ShapeBuild_ReShape.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <TopoDS.hxx>
35 #include <TopLoc_Location.hxx>
36 #include <Geom_Surface.hxx>
37 #include <Geom_CylindricalSurface.hxx>
38 #include <Geom_ConicalSurface.hxx>
39 #include <ShapeFix_Wire.hxx>
40 #include <TopoDS_Wire.hxx>
41 #include <BRepTools_Modifier.hxx>
42 #include <Geom_SphericalSurface.hxx>
43 #include <Geom_ToroidalSurface.hxx>
44 #include <BRep_Tool.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <Geom2d_Curve.hxx>
47 #include <BRep_Builder.hxx>
48 #include <ShapeAnalysis_Edge.hxx>
49 #include <ShapeFix_Edge.hxx>
50 #include <ShapeFix.hxx>
51 #include <ShapeFix_Face.hxx>
52 #include <ShapeAnalysis.hxx>
53
54 #include <TColgp_SequenceOfPnt2d.hxx>
55 #include <ShapeAnalysis_Curve.hxx>
56 #include <TopoDS_Vertex.hxx>
57 #include <ShapeBuild_Edge.hxx>
58
59 #include <BlockFix_SphereSpaceModifier.hxx>
60 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
61 #include <TopTools_MapOfShape.hxx>
62 #include <BlockFix_PeriodicSurfaceModifier.hxx>
63
64 #include <TopoDS_Solid.hxx>
65
66
67 //=======================================================================
68 //function : FixResult
69 //purpose  : auxilary
70 //=======================================================================
71 static void FixResult(const TopoDS_Shape& result,
72                       Handle(ShapeBuild_ReShape)& Context,
73                       const Standard_Real Tol)
74 {
75   for (TopExp_Explorer ex_f(result,TopAbs_FACE); ex_f.More(); ex_f.Next()) {
76     TopoDS_Shape aShape = Context->Apply(ex_f.Current().Oriented(TopAbs_FORWARD));
77     // face coud not be dropped or splitted on this step
78     TopoDS_Face aFace = TopoDS::Face(aShape);
79     TopLoc_Location L;
80     Handle(Geom_Surface) Surf = BRep_Tool::Surface(aFace,L);
81     
82     if( Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
83         Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ) {
84     
85       Standard_Integer nbWires = 0;
86       for (TopExp_Explorer ex_w(aFace,TopAbs_WIRE); ex_w.More(); ex_w.Next()) {
87         nbWires++;
88         Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(TopoDS::Wire(ex_w.Current()), 
89                                                       aFace, 
90                                                       Precision::Confusion());
91         sfw->FixReorder();
92         if(sfw->StatusReorder ( ShapeExtend_FAIL ))
93           continue;
94         
95         sfw->SetPrecision(2.*Tol);
96         sfw->FixShifted();
97         
98         Standard_Boolean isDone = sfw->LastFixStatus ( ShapeExtend_DONE );
99         isDone |= sfw->FixDegenerated();
100         
101         // remove degenerated edges from not degenerated points
102         ShapeAnalysis_Edge sae;
103         Handle(ShapeExtend_WireData) sewd = sfw->WireData();
104         Standard_Integer i;
105         for( i = 1; i<=sewd->NbEdges();i++) {
106           TopoDS_Edge E = sewd->Edge(i);
107           if(BRep_Tool::Degenerated(E)&&!sae.HasPCurve(E,aFace)) {
108             sewd->Remove(i);
109             isDone = Standard_True;
110             i--;
111           }
112         }
113         
114         //isDone |= sfw->FixLacking(); // commented by skl 22.03.2005 (PAL8395)
115         
116         // remove neighbour seam edges 
117         if(isDone) {
118           for( i = 1; i<sewd->NbEdges();i++) {
119             if(sewd->IsSeam(i) && sewd->IsSeam(i+1)) {
120               isDone = Standard_True;
121               sewd->Remove(i);
122               sewd->Remove(i);
123               i--;
124             }
125           }
126           if(sewd->IsSeam(1) && sewd->IsSeam(sewd->NbEdges())) {
127             sewd->Remove(1);
128             sewd->Remove(sewd->NbEdges());
129           }
130         }
131         
132                
133         if(isDone) {
134           TopoDS_Wire ResWire = sfw->Wire();
135           Context->Replace(ex_w.Current(), ResWire);
136         };
137       }
138       // Implement fix orientation in case of several wires
139       if(nbWires > 1) {
140         TopoDS_Face aFixedFace = TopoDS::Face(Context->Apply(aFace));
141         Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFixedFace);
142         if(sff->FixOrientation())
143           Context->Replace(aFixedFace,sff->Face());
144       }
145       
146     }
147   }
148 }
149
150
151
152
153
154 //=======================================================================
155 //function : ConvertToAnalytical
156 //purpose  : 
157 //=======================================================================
158
159 TopoDS_Shape BlockFix::RotateSphereSpace (const TopoDS_Shape& S,
160                                           const Standard_Real Tol) 
161 {
162
163   // Create a modification description
164   Handle(BlockFix_SphereSpaceModifier) SR = new BlockFix_SphereSpaceModifier;
165   SR->SetTolerance(Tol);
166
167   TopTools_DataMapOfShapeShape context;
168   BRepTools_Modifier MD;
169   TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );
170   
171   Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
172   FixResult(result,RS,Tol);
173   result = RS->Apply(result);
174   
175   ShapeFix_Edge sfe;
176   for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
177     TopoDS_Edge E = TopoDS::Edge(exp.Current());
178     sfe.FixVertexTolerance (E);
179   }
180   
181   ShapeFix::SameParameter(result,Standard_False);
182   return result;
183 }
184
185
186 //=======================================================================
187 //function : FixRanges
188 //purpose  : 
189 //=======================================================================
190
191 TopoDS_Shape BlockFix::FixRanges (const TopoDS_Shape& S,
192                                   const Standard_Real Tol) 
193 {
194   // Create a modification description
195   Handle(BlockFix_PeriodicSurfaceModifier) SR = new BlockFix_PeriodicSurfaceModifier;
196   SR->SetTolerance(Tol);
197
198   TopTools_DataMapOfShapeShape context;
199   BRepTools_Modifier MD;
200   TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );
201   
202   Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
203   FixResult(result,RS,Tol);
204   result = RS->Apply(result);
205   
206   ShapeFix_Edge sfe;
207   for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
208     TopoDS_Edge E = TopoDS::Edge(exp.Current());
209     sfe.FixVertexTolerance (E);
210   }
211   
212   ShapeFix::SameParameter(result,Standard_False);
213
214   return result;
215 }