0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / ShapeFix / ShapeFix_WireVertex.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //szv#4 S4163
15
16 #include <BRep_Builder.hxx>
17 #include <gp_Pnt.hxx>
18 #include <ShapeAnalysis_Edge.hxx>
19 #include <ShapeAnalysis_WireVertex.hxx>
20 #include <ShapeExtend_WireData.hxx>
21 #include <ShapeFix_WireVertex.hxx>
22 #include <TColStd_HArray1OfReal.hxx>
23 #include <TopExp.hxx>
24 #include <TopoDS.hxx>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Wire.hxx>
28 #include <TopTools_HArray1OfShape.hxx>
29
30 //ied_modif_for_compil_Nov-19-1998
31 //=======================================================================
32 //function : ShapeFix_WireVertex
33 //purpose  : 
34 //=======================================================================
35 ShapeFix_WireVertex::ShapeFix_WireVertex()
36 {
37 }
38
39 //=======================================================================
40 //function : Init
41 //purpose  : 
42 //=======================================================================
43
44 void ShapeFix_WireVertex::Init (const TopoDS_Wire& wire, 
45                                 const Standard_Real preci) 
46 {
47   Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData ( wire );
48   Init ( sbwd, preci );
49 }
50
51 //=======================================================================
52 //function : Init
53 //purpose  : 
54 //=======================================================================
55
56 void ShapeFix_WireVertex::Init (const Handle(ShapeExtend_WireData)& sbwd, 
57                                 const Standard_Real preci) 
58 {
59   myAnalyzer.Load ( sbwd );
60   myAnalyzer.SetPrecision ( preci );
61   myAnalyzer.Analyze();
62 }
63
64 //=======================================================================
65 //function : Load
66 //purpose  : 
67 //=======================================================================
68
69 void ShapeFix_WireVertex::Init (const ShapeAnalysis_WireVertex& sawv) 
70 {
71   myAnalyzer = sawv;
72 }
73
74 //=======================================================================
75 //function : Analyzer
76 //purpose  : 
77 //=======================================================================
78
79 const ShapeAnalysis_WireVertex& ShapeFix_WireVertex::Analyzer() const
80 {
81   return myAnalyzer;
82 }
83
84 //=======================================================================
85 //function : WireData
86 //purpose  : 
87 //=======================================================================
88
89 const Handle(ShapeExtend_WireData)& ShapeFix_WireVertex::WireData() const
90 {
91   return myAnalyzer.WireData();
92 }
93
94 //=======================================================================
95 //function : Wire
96 //purpose  : 
97 //=======================================================================
98
99 TopoDS_Wire ShapeFix_WireVertex::Wire() const
100 {
101   return myAnalyzer.WireData()->Wire();
102 }
103
104 //=======================================================================
105 //function : FixSame
106 //purpose  : 
107 //=======================================================================
108
109 Standard_Integer ShapeFix_WireVertex::FixSame() 
110 {
111   //  FixSame : prend les status "SameCoord" et "Close" et les force a "Same"
112   //  reprendre l edge et forcer le vertex. Evt changer sa tolerance. Et voila
113   if ( ! myAnalyzer.IsDone() ) return 0;
114   
115   Standard_Integer nbfix = 0;
116   BRep_Builder B;
117
118   Handle(ShapeExtend_WireData) sbwd = myAnalyzer.WireData();
119   Standard_Integer i, nb = sbwd->NbEdges();
120
121   for (i = 1; i <= nb; i ++) {
122     Standard_Integer j = (i == nb ? 1 : i+1);
123     Standard_Integer stat = myAnalyzer.Status(i);
124     if (stat != 1 && stat != 2) continue;
125     // Ici on prend un vertex et on le generalise aux deux edges
126     TopoDS_Edge   E1 = sbwd->Edge (i);
127     TopoDS_Edge   E2 = sbwd->Edge (j);
128
129     ShapeAnalysis_Edge sae;
130     TopoDS_Vertex V1 = sae.LastVertex  ( E1 );
131     TopoDS_Vertex V2 = sae.FirstVertex ( E2 );
132     if (V1 == V2)  {  
133       myAnalyzer.SetSameVertex(i);  
134       continue;  
135     }    // deja fait ...
136     if (stat == 2) {
137       // OK mais en reprenant les tolerances
138       Handle(Geom_Curve) crv;  
139       Standard_Real cf,cl;
140       sae.Curve3d ( sbwd->Edge(i), crv, cf, cl );
141       B.UpdateVertex (V1,cl,E1,myAnalyzer.Precision());
142       sae.Curve3d ( sbwd->Edge(j), crv, cf, cl );
143       B.UpdateVertex (V1,cf,E2,myAnalyzer.Precision());
144     }
145     // Et remettre ce vtx en commun
146     V1.Orientation (E2.Orientation());
147     B.Add (E2,V1);
148     V1.Orientation (E1.Orientation());  V1.Reverse();
149     B.Add (E1,V1);
150     myAnalyzer.SetSameVertex(i);    // conclusion
151     nbfix ++;
152   }
153   return nbfix;
154 }
155
156 //=======================================================================
157 //function : Fix
158 //purpose  : 
159 //=======================================================================
160
161 Standard_Integer ShapeFix_WireVertex::Fix() 
162 {
163   //  Ici le grand jeu : on repasse partout
164   //  stat = 0 (OK) ou <0 (KO) : on passe
165   //  stat = 1 ou 2 : on reprend le vtx d origine
166   //  sinon on en refait un ...
167
168   //  MAIS ATTENTION : on fait du neuf ... forcement. Donc nouvelles edges
169   //   auxquelles on remet les Vertex (assez facile)
170   //   Donc deux passes : 1 refaire les VTX  et 2 les remettre dans les edges
171   if ( ! myAnalyzer.IsDone() ) return 0;
172
173   Handle(ShapeExtend_WireData) sbwd = myAnalyzer.WireData();
174   
175   Standard_Integer i, nb = sbwd->NbEdges();
176   Standard_Integer nbfix = 0;
177   for (i = 1; i <= nb; i ++) {
178     //    On note les valeurs
179     //szv#4:S4163:12Mar99 optimized
180     if (myAnalyzer.Status(i) > 0) nbfix ++;
181   }
182   if (nbfix == 0) return 0;
183
184   BRep_Builder B;
185
186   Handle(TopTools_HArray1OfShape) VI = new TopTools_HArray1OfShape (1,nb);
187   Handle(TopTools_HArray1OfShape) VJ = new TopTools_HArray1OfShape (1,nb);
188   Handle(TopTools_HArray1OfShape) EF = new TopTools_HArray1OfShape (1,nb);
189   Handle(TColStd_HArray1OfReal)   UI = new TColStd_HArray1OfReal   (1,nb);
190   Handle(TColStd_HArray1OfReal)   UJ = new TColStd_HArray1OfReal   (1,nb);
191
192   for (i = 1; i <= nb; i ++) {
193     //    On note les valeurs
194     Standard_Integer j = (i == nb ? 1 : i+1);
195     Standard_Integer stat = myAnalyzer.Status (i);
196
197     ShapeAnalysis_Edge sae;
198     TopoDS_Vertex V1 = sae.LastVertex ( sbwd->Edge(i) );
199     TopoDS_Vertex V2 = sae.FirstVertex ( sbwd->Edge(j) );
200     VI->SetValue (i,V1);  
201     VJ->SetValue (j,V2);
202
203     TopoDS_Edge E = sbwd->Edge(i);
204 //    E.EmptyCopy();   trop d ennuis
205     EF->SetValue (i,E);
206
207 //    if (stat <= 0) continue;
208 //    TopoDS_Edge   E1 = STW.Edge (i);
209 //    TopoDS_Edge   E2 = STW.Edge (j);
210     Standard_Real upre = myAnalyzer.UPrevious(i);
211     Standard_Real ufol = myAnalyzer.UFollowing(j);
212
213     Handle(Geom_Curve) crv;  
214     Standard_Real cf,cl;
215     //szv#4:S4163:12Mar99 optimized
216     if (stat < 4) {
217       sae.Curve3d ( sbwd->Edge(i), crv, cf, cl );
218       upre = cl;
219     }
220     if (stat < 3 || stat == 4) {
221       sae.Curve3d ( sbwd->Edge(j), crv, cf, cl );
222       ufol = cf;
223     }
224
225     UI->SetValue (i,upre);  
226     UJ->SetValue (j,ufol);
227 //    nbfix ++;
228   }
229
230   if (nbfix == 0) return nbfix;
231
232   // EmptyCopy pas bon : KK sur les Range (dommage, le reste est bon)
233   // Donc on garde l original mais on change les vertex
234   // En effet, avant de "ajouter" des vertex, il faut enlever ceux d avant
235   // Sinon on garde en double !
236
237   for (i = 1; i <= nb; i ++) {
238     TopoDS_Edge E1 = TopoDS::Edge (EF->Value (i));
239     TopoDS_Vertex VA,VB;
240     E1.Orientation (TopAbs_FORWARD);
241     TopExp::Vertices (E1,VA,VB);
242     E1.Free(Standard_True);
243     B.Remove (E1,VA);
244     B.Remove (E1,VB);
245   }
246
247   Standard_Real Prec = myAnalyzer.Precision();
248   for (i = 1; i <= nb; i ++) {
249     //    On y va pour de bon
250     //    Changer les coords ?
251     Standard_Integer j = (i == nb ? 1 : i+1);
252     Standard_Integer stat = myAnalyzer.Status (i);
253 //    if (stat <= 0) continue;
254
255     TopoDS_Vertex V1 = TopoDS::Vertex (VI->Value(i));
256     TopoDS_Vertex V2 = TopoDS::Vertex (VJ->Value(j));
257     TopoDS_Edge   E1 = TopoDS::Edge (EF->Value (i));
258     TopoDS_Edge   E2 = TopoDS::Edge (EF->Value (j));
259     Standard_Real upre = UI->Value(i);
260     Standard_Real ufol = UJ->Value(j);
261
262     if (stat > 2) 
263       B.UpdateVertex (V1, gp_Pnt(myAnalyzer.Position(i)), Prec);
264
265     //    ce qui suit : seulement si vertex a reprendre
266     if (stat > 0) {
267       B.UpdateVertex (V1,upre,E1,Prec);
268       B.UpdateVertex (V1,ufol,E2,Prec);
269       V1.Orientation (TopAbs_FORWARD);
270 //    V1.Orientation (E2.Orientation());
271     }
272
273     //    Comme on a deshabille les edges, il faut tout remettre
274     E2.Free (Standard_True);  // sur place
275     B.Add (E2,V1);
276     V1.Orientation (TopAbs_REVERSED);
277 //    V1.Orientation (E1.Orientation());    V1.Reverse();
278     E1.Free (Standard_True);  // sur place
279     B.Add (E1,V1);
280
281     myAnalyzer.SetSameVertex (i);    // conclusion
282 //    nbfix ++;
283   }
284
285 //  pour finir, MAJ du STW
286   for (i = 1; i <= nb; i ++) sbwd->Set (TopoDS::Edge(EF->Value(i)),i);
287
288   return nbfix;
289 }