1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
16 #include <BRep_Builder.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>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Wire.hxx>
28 #include <TopTools_HArray1OfShape.hxx>
30 //ied_modif_for_compil_Nov-19-1998
31 //=======================================================================
32 //function : ShapeFix_WireVertex
34 //=======================================================================
35 ShapeFix_WireVertex::ShapeFix_WireVertex()
39 //=======================================================================
42 //=======================================================================
44 void ShapeFix_WireVertex::Init (const TopoDS_Wire& wire,
45 const Standard_Real preci)
47 Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData ( wire );
51 //=======================================================================
54 //=======================================================================
56 void ShapeFix_WireVertex::Init (const Handle(ShapeExtend_WireData)& sbwd,
57 const Standard_Real preci)
59 myAnalyzer.Load ( sbwd );
60 myAnalyzer.SetPrecision ( preci );
64 //=======================================================================
67 //=======================================================================
69 void ShapeFix_WireVertex::Init (const ShapeAnalysis_WireVertex& sawv)
74 //=======================================================================
77 //=======================================================================
79 const ShapeAnalysis_WireVertex& ShapeFix_WireVertex::Analyzer() const
84 //=======================================================================
87 //=======================================================================
89 const Handle(ShapeExtend_WireData)& ShapeFix_WireVertex::WireData() const
91 return myAnalyzer.WireData();
94 //=======================================================================
97 //=======================================================================
99 TopoDS_Wire ShapeFix_WireVertex::Wire() const
101 return myAnalyzer.WireData()->Wire();
104 //=======================================================================
107 //=======================================================================
109 Standard_Integer ShapeFix_WireVertex::FixSame()
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;
115 Standard_Integer nbfix = 0;
118 Handle(ShapeExtend_WireData) sbwd = myAnalyzer.WireData();
119 Standard_Integer i, nb = sbwd->NbEdges();
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);
129 ShapeAnalysis_Edge sae;
130 TopoDS_Vertex V1 = sae.LastVertex ( E1 );
131 TopoDS_Vertex V2 = sae.FirstVertex ( E2 );
133 myAnalyzer.SetSameVertex(i);
137 // OK mais en reprenant les tolerances
138 Handle(Geom_Curve) crv;
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());
145 // Et remettre ce vtx en commun
146 V1.Orientation (E2.Orientation());
148 V1.Orientation (E1.Orientation()); V1.Reverse();
150 myAnalyzer.SetSameVertex(i); // conclusion
156 //=======================================================================
159 //=======================================================================
161 Standard_Integer ShapeFix_WireVertex::Fix()
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 ...
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;
173 Handle(ShapeExtend_WireData) sbwd = myAnalyzer.WireData();
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 ++;
182 if (nbfix == 0) return 0;
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);
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);
197 ShapeAnalysis_Edge sae;
198 TopoDS_Vertex V1 = sae.LastVertex ( sbwd->Edge(i) );
199 TopoDS_Vertex V2 = sae.FirstVertex ( sbwd->Edge(j) );
203 TopoDS_Edge E = sbwd->Edge(i);
204 // E.EmptyCopy(); trop d ennuis
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);
213 Handle(Geom_Curve) crv;
215 //szv#4:S4163:12Mar99 optimized
217 sae.Curve3d ( sbwd->Edge(i), crv, cf, cl );
220 if (stat < 3 || stat == 4) {
221 sae.Curve3d ( sbwd->Edge(j), crv, cf, cl );
225 UI->SetValue (i,upre);
226 UJ->SetValue (j,ufol);
230 if (nbfix == 0) return nbfix;
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 !
237 for (i = 1; i <= nb; i ++) {
238 TopoDS_Edge E1 = TopoDS::Edge (EF->Value (i));
240 E1.Orientation (TopAbs_FORWARD);
241 TopExp::Vertices (E1,VA,VB);
242 E1.Free(Standard_True);
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;
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);
263 B.UpdateVertex (V1, gp_Pnt(myAnalyzer.Position(i)), Prec);
265 // ce qui suit : seulement si vertex a reprendre
267 B.UpdateVertex (V1,upre,E1,Prec);
268 B.UpdateVertex (V1,ufol,E2,Prec);
269 V1.Orientation (TopAbs_FORWARD);
270 // V1.Orientation (E2.Orientation());
273 // Comme on a deshabille les edges, il faut tout remettre
274 E2.Free (Standard_True); // sur place
276 V1.Orientation (TopAbs_REVERSED);
277 // V1.Orientation (E1.Orientation()); V1.Reverse();
278 E1.Free (Standard_True); // sur place
281 myAnalyzer.SetSameVertex (i); // conclusion
285 // pour finir, MAJ du STW
286 for (i = 1; i <= nb; i ++) sbwd->Set (TopoDS::Edge(EF->Value(i)),i);