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