0023267: cppcheck warning: Using 'memcpy' on class that contains a virtual method
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_PURGE.cxx
CommitLineData
b311480e 1// Created on: 1997-11-13
2// Created by: Xuan PHAM PHU
3// Copyright (c) 1997-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#include <TopOpeBRepTool.hxx>
23#include <TopOpeBRepTool_TOOL.hxx>
24#include <TopOpeBRepTool_CORRISO.hxx>
25#include <TopOpeBRepTool_C2DF.hxx>
26#include <gp_Pnt2d.hxx>
27#include <gp_Vec2d.hxx>
28#include <GeomAdaptor_Surface.hxx>
29#include <Geom2d_Curve.hxx>
30#include <Geom2d_TrimmedCurve.hxx>
31#include <Geom2d_Line.hxx>
32#include <Geom_Surface.hxx>
33#include <TopoDS.hxx>
34#include <TopoDS_Wire.hxx>
35#include <TopTools_Array1OfShape.hxx>
36
37#include <BRep_Tool.hxx>
38#include <Precision.hxx>
39#include <TopExp.hxx>
40#include <TopExp_Explorer.hxx>
41#include <BRep_Builder.hxx>
42#include <BRepAdaptor_Surface.hxx>
43#include <TopOpeBRepTool_define.hxx>
44#include <TopOpeBRepTool_EXPORT.hxx>
45#include <TopOpeBRepTool_2d.hxx>
46#include <Standard_Failure.hxx>
47#include <TopOpeBRepTool_PURGE.hxx>
48
49#ifdef DEB
50//Standard_EXPORT Standard_Integer STATIC_PURGE_iwi = 0;
51//Standard_EXPORT TopTools_IndexedMapOfShape STATIC_PURGE_mapw, STATIC_PURGE_mapv;
52//Standard_EXPORT TopTools_IndexedMapOfOrientedShape STATIC_PURGE_mapeds, STATIC_CORR_mapeds;
53
54Standard_EXPORT void debcorrUV(){};
55Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettracePURGE();
56Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceCORRISO();
57#endif
58// DEB
59
60// Unused :
61#ifdef DEB
62static void FUN_RaiseError()
63{
64#ifdef DEB
65 Standard_Boolean trc = TopOpeBRepTool_GettracePURGE();
66 // Standard_Failure::Raise("TopOpeBRepTool::PurgeClosingEdges");
67 FUN_REINIT();
68 if (trc) cout <<"*********failure in TopOpeBRepTool::PurgeClosingEdges***********\n";
69#endif
70}
71static void FUN_Raise()
72{
73#ifdef DEB
74 // cout <<"*********failure in TopOpeBRepTool::CorrectONUVISO***********\n";
75 // Standard_Failure::Raise("TopOpeBRepTool::CorrectONUVISO");
76#endif
77}
78#endif
79
80#define SPLITEDGE (0)
81#define INCREASE (1)
82#define DECREASE (-1)
83
84#define M_FORWARD(sta) (sta == TopAbs_FORWARD)
85#define M_REVERSED(sta) (sta == TopAbs_REVERSED)
86#define M_INTERNAL(sta) (sta == TopAbs_INTERNAL)
87#define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL)
88
89static void FUN_addtomap(TopTools_DataMapOfShapeListOfShape& map, const TopoDS_Shape& key, const TopoDS_Shape& item)
90{
91 if (map.IsBound(key)) map.ChangeFind(key).Append(item);
92 else {TopTools_ListOfShape los; los.Append(item); map.Bind(key,los);}
93}
94
95static Standard_Boolean FUN_getv(const TopAbs_Orientation& orivine, const TopoDS_Shape& e, TopoDS_Shape& v)
96{
97 v.Nullify();
98 // gets <v> oriented <orivine> in <e>
99 TopAbs_Orientation oe = e.Orientation();
100 Standard_Boolean isnonO = M_INTERNAL(oe) || M_EXTERNAL(oe);
101 TopoDS_Shape eO;
102 if (isnonO) {
103 eO = e.Oriented(TopAbs_FORWARD);
104 }
105 else {
106 eO = e;
107 }
108 TopExp_Explorer exv(eO, TopAbs_VERTEX);
109 for (; exv.More(); exv.Next()) {
110 const TopoDS_Shape& vcur = exv.Current();
111 if (vcur.Orientation() == orivine) {v = vcur; return Standard_True;}
112 } // exv
113 return Standard_False;
114}
115
116Standard_EXPORT Standard_Boolean FUN_tool_ClosedW(const TopoDS_Wire& W)
117{
118 // !! an edge oriented INTERNAL/EXTERNAL has all its vertices
119 // oriented INTERNAL/EXTERNAL.
120
121 // <mapvedsO> = {(v,loe)} / e is oriented :
122 // <mapvedsO> = {(v,loe)} / e is not oriented (INTERNAL/EXTERNAL) :
123 TopTools_DataMapOfShapeListOfShape mapvFine,mapvRine, mapvIine;
124
125 TopExp_Explorer exe(W, TopAbs_EDGE);
126 for (; exe.More(); exe.Next()){
127 const TopoDS_Shape& e = exe.Current();
128 TopAbs_Orientation oe = e.Orientation();
129 Standard_Boolean isnonO = M_INTERNAL(oe) || M_EXTERNAL(oe);
130 TopoDS_Shape eO;
131 if (isnonO) {
132 eO = e.Oriented(TopAbs_FORWARD);
133 }
134 else {
135 eO = e;
136 }
137
138 TopExp_Explorer exv(eO, TopAbs_VERTEX);
139 for (; exv.More(); exv.Next()) {
140 const TopoDS_Shape& v = exv.Current();
141 TopAbs_Orientation oriv = v.Orientation();
142 if (M_FORWARD(oriv)) FUN_addtomap(mapvFine,v,e);
143 if (M_REVERSED(oriv)) FUN_addtomap(mapvRine,v,e);
144 if (M_INTERNAL(oriv)) FUN_addtomap(mapvIine,v,e);
145 }
146 }
147
148 if (mapvFine.Extent() == 0) return Standard_False; // empty wire
149
150 TopTools_MapOfShape mapvok;
151 // a vertex is found valid if is - an internal vertex
152 // - found FORWARD and REVERSED.
153 TopTools_MapOfShape mapvonlyFine; // {(v,e)} v F in e, v belongs to only one e
154 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itvFine(mapvFine);
155 for (; itvFine.More(); itvFine.Next()){
156 const TopoDS_Shape& vFine = itvFine.Key();
7fd59977 157 Standard_Boolean vIine = mapvIine.IsBound(vFine);
158 if (vIine) {mapvok.Add(vFine); continue;}
159 Standard_Boolean vRine = mapvRine.IsBound(vFine);
160 if (vRine) {mapvok.Add(vFine); continue;}
161 mapvonlyFine.Add(vFine);
162 }
163 // <mapvRinonee> = {(v,e)} v R in e, v belongs to only one e
164 TopTools_MapOfShape mapvonlyRine;
165 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itvRine(mapvRine);
166 for (; itvRine.More(); itvRine.Next()){
167 const TopoDS_Shape& vRine = itvRine.Key();
7fd59977 168 Standard_Boolean vok = mapvok.Contains(vRine);
169 if (vok) continue;
170 Standard_Boolean vIine = mapvIine.IsBound(vRine);
171 if (vIine) {mapvok.Add(vRine); continue;}
172 mapvonlyRine.Add(vRine);
173 }
174
175 // checking vertices <mapvonlyFine> and <mapvonlyRine>
176 TopTools_MapIteratorOfMapOfShape itvonlyFRine;
177 Standard_Integer nmap = 0;
178 while (nmap <= 2) {
179 nmap++;
180 Standard_Boolean vFine = (nmap == 1);
181 if (vFine) itvonlyFRine.Initialize(mapvonlyFine);
182 else itvonlyFRine.Initialize(mapvonlyRine);
183
184 for (; itvonlyFRine.More(); itvonlyFRine.Next()){
185 const TopoDS_Shape& vtocheck = itvonlyFRine.Key();
186 TopTools_ListOfShape edsvFRine;
187 if (vFine) edsvFRine = mapvFine.Find(vtocheck);
188 else edsvFRine = mapvRine.Find(vtocheck);
189
190 if (edsvFRine.Extent() > 1) return Standard_False; // faulty wire
191 const TopoDS_Shape& e = edsvFRine.First();
192
193 TopAbs_Orientation ovori = vFine? TopAbs_REVERSED: TopAbs_FORWARD;
194 TopoDS_Shape ov; Standard_Boolean ovfound = FUN_getv(ovori,e,ov);
195 if (!ovfound) return Standard_False; // faulty edge
196
197 // <vtocheck> is on only one edge <e>,
198 // <vtocheck> is FORWARD/REVERSED in <e>,
199 // <ovfound> is REVERSED/FORWARD in <e>.
200 // <vtocheck> is ok if : - <ovfound> is INTERNAL in another edge
201 // - <ovfound> is FORWARD and REVERSED in
202 // one or two other edges.
203 // and e is not oriented
204 TopAbs_Orientation oe = e.Orientation();
205 if (M_FORWARD(oe) || M_REVERSED(oe)) return Standard_False;
206 if (!mapvok.Contains(ov)) return Standard_False;
207
208 Standard_Boolean ovIine = mapvIine.IsBound(ov); if (ovIine) continue;
209 Standard_Boolean ovFine = mapvRine.IsBound(ov); if (!ovFine) return Standard_False;
210 Standard_Boolean ovRine = mapvRine.IsBound(ov); if (!ovRine) return Standard_False;
211
212 const TopTools_ListOfShape& edsovFine = mapvFine.Find(ov);
213 const TopTools_ListOfShape& edsovRine = mapvRine.Find(ov);
214 if (edsovFine.Extent() > 1) continue;
215 if (edsovRine.Extent() > 1) continue;
216 if (edsovFine.First().IsEqual(e)) return Standard_False;
217 if (edsovRine.First().IsEqual(e)) return Standard_False;
218 }
219 } // nmap
220 return Standard_True;
221}
222
223//=======================================================================
224//function : PurgeClosingEdges
225//purpose :
226//=======================================================================
227
228Standard_Boolean TopOpeBRepTool::PurgeClosingEdges(const TopoDS_Face& Fin, const TopoDS_Face& FF,
229// const TopTools_DataMapOfShapeInteger& MWisOld,
230 const TopTools_DataMapOfShapeInteger& ,
231 TopTools_IndexedMapOfOrientedShape& MshNOK)
232{
233 // Fin is the original face
234 // FF is the splitted face
235
236 // prequesitory : splitted edges, of edge ancestor a closing edge
237 // keep in memory the geometry of the ancestor edge,
238 // they answer True to BRep_Tool::IsClosed.
239 // elsewhere : we have to get this information using geometric
240 // criteriums (TopOpeBRepTool_TOOL::IsonCLO)
241
242#ifdef DEB
243 Standard_Boolean trc = TopOpeBRepTool_GettracePURGE();
244 if (trc) cout<<"\n* PurgeClosingEdges:\n\n";
245#endif
246 TopOpeBRepTool_CORRISO CORRISO(Fin);
247 Standard_Real tolF = BRep_Tool::Tolerance(Fin);
248 Standard_Real uperiod; Standard_Boolean uclosed = CORRISO.Refclosed(1,uperiod);
249 Standard_Real vperiod; Standard_Boolean vclosed = CORRISO.Refclosed(2,vperiod);
250 if (!uclosed && !vclosed) return Standard_False;
251 Standard_Boolean inU = uclosed ? Standard_True : Standard_False;
252 Standard_Real xmin = inU ? (CORRISO.GASref().FirstUParameter()) :
253 (CORRISO.GASref().FirstVParameter());
254 Standard_Real xper = inU ? uperiod : vperiod;
255 Standard_Real tolx = inU ? (CORRISO.Tol(1,tolF)) : (CORRISO.Tol(2,tolF));
256
257 TopExp_Explorer exw(FF, TopAbs_WIRE);
258 for (; exw.More(); exw.Next()){
259 const TopoDS_Shape& W = exw.Current();
260
261 CORRISO.Init(W);
262 Standard_Boolean ok = CORRISO.UVClosed();
263 if (ok) continue;
264
265 TopTools_ListOfShape cEds;
266 TopTools_ListIteratorOfListOfShape ite(CORRISO.Eds());
267 for (; ite.More(); ite.Next()){
268 const TopoDS_Edge& E = TopoDS::Edge(ite.Value());
269 Standard_Boolean closing = BRep_Tool::IsClosed(E,Fin);
270 if (!closing) {// xpu231198 : pcurve modified, the information is lost
271 TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = CORRISO.UVRep(E,C2DF);
272 if (!isb) return Standard_False;//NYIRAISE
273 Standard_Boolean onclo = TopOpeBRepTool_TOOL::IsonCLO(C2DF,inU,xmin,xper,tolx);
274 if (onclo) closing=Standard_True;
275 }
276 if (closing) cEds.Append(E);
277 }
278 Standard_Integer ncE = cEds.Extent();
279 Standard_Boolean nopurge = (ncE <= 1);
280 if (nopurge) return Standard_True;
281
282 // Checking <W>
283 TopTools_ListOfShape fyEds; Standard_Boolean topurge = CORRISO.PurgeFyClosingE(cEds,fyEds);
284 if (topurge) {
285 TopTools_ListIteratorOfListOfShape it(fyEds);
286 for (; it.More(); it.Next()) MshNOK.Add(it.Value());
287 MshNOK.Add(W);
288 MshNOK.Add(FF);
289 }
290
291#ifdef DEB
292 if (trc && topurge) cout<<"found FAULTY edge = ed"<<endl;
293#endif
294 } // exw
295 return Standard_True;
296}
297
298//=======================================================================
299//function : PurgeClosingEdges
300//purpose :
301//=======================================================================
302
303Standard_Boolean TopOpeBRepTool::PurgeClosingEdges(const TopoDS_Face& Fin, const TopTools_ListOfShape& LOF,
304 const TopTools_DataMapOfShapeInteger& MWisOld,
305 TopTools_IndexedMapOfOrientedShape& MshNOK)
306{
307 Standard_Boolean uvclosed = FUN_tool_closedS(Fin);
308 if (!uvclosed) return Standard_True;
309
310 TopTools_ListIteratorOfListOfShape it(LOF);
311 for (; it.More(); it.Next()){
312 const TopoDS_Face& FF = TopoDS::Face(it.Value());
313 Standard_Boolean ok = TopOpeBRepTool::PurgeClosingEdges(Fin,FF,MWisOld,MshNOK);
314 if (!ok) return Standard_False;
315 }
316 return Standard_True;
317}
318
319/*static Standard_Boolean FUN_correctClosingE(TopoDS_Edge& newfE, TopoDS_Face& Fsp)
320{
321 Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FUNTOOLC2D_CurveOnSurface(newfE,Fsp,f,l,tol);
322 gp_Dir2d d2d; gp_Pnt2d O2d; Standard_Boolean isuiso,isviso;
323 Standard_Boolean uviso = FUN_tool_IsUViso(PC,isuiso,isviso,d2d,O2d);
324 if (!uviso) return Standard_False;
325
c6541a0c 326 Standard_Real period = 2*M_PI;
7fd59977 327 Standard_Real piso = isuiso? O2d.X(): O2d.Y();
328 Standard_Real tol2d = 1.e-6;
329 Standard_Boolean is0 = Abs(piso) < tol2d;
330 Standard_Boolean is2PI = Abs(period-piso) < tol2d;
331 // --------------------------------------------------
332 // prequesitory : Closed Surfaces have period 2PI
333 if (!is0 && !is2PI) return Standard_False;
334 // --------------------------------------------------
335 Standard_Real factor = is0? period: -period;
336 gp_Vec2d transl(1.,0.); if (isviso) transl = gp_Vec2d(0.,1.);
337 transl.Multiply(factor);
338
339 Standard_Integer ok = FUN_tool_translate(transl,Fsp,newfE);
340 return Standard_True;
341}
342
343static Standard_Boolean FUN_correctDegeneratedE
344(const TopTools_IndexedDataMapOfShapeListOfShape& mve,TopoDS_Edge& Ein,TopoDS_Face& Fsp)
345{
346 TopoDS_Vertex v1,v2; TopExp::Vertices(Ein,v1,v2);
347 TopAbs_Orientation ov1 = v1.Orientation();
348 TopAbs_Orientation ov2 = v2.Orientation();
349 Standard_Boolean ok1 = mve.Contains(v1); if (!ok1) return Standard_False;
350 Standard_Boolean ok2 = mve.Contains(v2); if (!ok2) return Standard_False;
351
352 const TopTools_ListOfShape& le= mve.FindFromKey(v1);
353
354 TopoDS_Edge e1,e2; Standard_Boolean fe1 = Standard_False; Standard_Boolean fe2 = Standard_False;
355 TopoDS_Vertex vfe1,vfe2;
356 Standard_Boolean fEin = Standard_False;
357 for(TopTools_ListIteratorOfListOfShape itle(le);itle.More();itle.Next()) {
358 const TopoDS_Shape& ecx = TopoDS::Edge(itle.Value());
359 if (ecx.IsEqual(Ein)) {
360 fEin = Standard_True;
361 }
362 else {
363 TopExp_Explorer exv;
364 for (exv.Init(ecx,TopAbs_VERTEX);exv.More();exv.Next()) {
365// for (TopExp_Explorer exv(ecx,TopAbs_VERTEX);exv.More();exv.Next()) {
366 const TopoDS_Vertex& vecx = TopoDS::Vertex(exv.Current());
367 Standard_Boolean issam = vecx.IsSame(v1);
368 if (issam) {
369 Standard_Boolean iseq1 = vecx.IsEqual(v1);
370 Standard_Boolean iseq2 = vecx.IsEqual(v2);
371 if (!iseq1) {
372 e1 = TopoDS::Edge(ecx);
373 vfe1 = TopoDS::Vertex(vecx);
374 fe1 = Standard_True;
375 }
376 if (!iseq2) {
377 e2 = TopoDS::Edge(ecx);
378 vfe2 = TopoDS::Vertex(vecx);
379 fe2 = Standard_True;
380 }
381 }
382 if (fe1 && fe2) break;
383 }
384 if (fe1 && fe2) break;
385 }
386 if (fEin && fe1 && fe2) break;
387 } // itle.More()
388
389 Standard_Boolean ok = (fEin && fe1 && fe2);
390 if (!ok) return Standard_False;
391
392#ifdef DEB
393 debcorrUV(); // call Draw_Call("av2d;dy fyf;fit;ppcu fyf")
394#endif
395
396 Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FUNTOOLC2D_CurveOnSurface(Ein,Fsp,f,l,tol);
397 gp_Dir2d d2d; gp_Pnt2d O2d; Standard_Boolean isuiso = 0,isviso = 0;
398 Standard_Boolean uviso = FUN_tool_IsUViso(PC,isuiso,isviso,d2d,O2d);
399 if (!uviso) return Standard_False;
400
401 Standard_Real pfEin,plEin,tolEin; Handle(Geom2d_Curve) PCEin = FUNTOOLC2D_CurveOnSurface(Ein,Fsp,pfEin,plEin,tolEin);
402 if (PCEin.IsNull()) Standard_Failure::Raise(" FUN_correctDegeneratedE : no 2d curve Ein");
403 Standard_Real pf1,pl1,tol1; Handle(Geom2d_Curve) PC1 = FUNTOOLC2D_CurveOnSurface(e1,Fsp,pf1,pl1,tol1);
404 if (PC1.IsNull()) Standard_Failure::Raise(" FUN_correctDegeneratedE : no 2d curve e1");
405 Standard_Real pf2,pl2,tol2; Handle(Geom2d_Curve) PC2 = FUNTOOLC2D_CurveOnSurface(e2,Fsp,pf2,pl2,tol2);
406 if (PC2.IsNull()) Standard_Failure::Raise(" FUN_correctDegeneratedE : no 2d curve e2");
407
408 Standard_Real parv1 = BRep_Tool::Parameter(v1,Ein,Fsp);
409 Standard_Real parv2 = BRep_Tool::Parameter(v2,Ein,Fsp);
410 gp_Pnt2d pv1; PCEin->D0(parv1,pv1);
411 gp_Pnt2d pv2; PCEin->D0(parv2,pv2);
412
413 Standard_Real par1 = BRep_Tool::Parameter(vfe1,e1,Fsp);
414 Standard_Real par2 = BRep_Tool::Parameter(vfe2,e2,Fsp);
415 gp_Pnt2d p1; PC1->D0(par1,p1);
416 gp_Pnt2d p2; PC2->D0(par2,p2);
417
418 Standard_Real cv1 = (isuiso) ? pv1.Y() : pv1.X();
419 Standard_Real cv2 = (isuiso) ? pv2.Y() : pv2.X();
420 Standard_Real c1 = (isuiso) ? p1.Y() : p1.X();
421 Standard_Real c2 = (isuiso) ? p2.Y() : p2.X();
422
423 Standard_Real d1 = (c1 - cv1);
424 Standard_Real d2 = (c2 - cv2);
425 Standard_Real adc = Abs(c1 - c2);
426 Standard_Real adcv = Abs(cv1 - cv2);
427
428 Standard_Real tol2d = 1.e-6;
429 Standard_Boolean mmd = (Abs(adc-adcv) < tol2d);
430 if (mmd) { // correction de CTS20973
431 gp_Vec2d transl(0.,1.); if (isviso) transl = gp_Vec2d(1.,0.);
432 transl.Multiply(d1); // ou d2
433 ok = FUN_tool_translate(transl,Fsp,Ein);
434 }
435 else {
436 // redefinition des parametres de v1,v2 de Ein tels que des parametres de
437#ifdef DEB
438 if (TopOpeBRepTool_GettraceCORRISO()) {
439 cout<<"FUN_correctDegeneratedE : !mmd NYI"<<endl;
440 }
441#endif
442 ok = Standard_False;
443 }
444
445 return ok;
446} //FUN_correctDegeneratedE*/
447
448/*static Standard_Boolean FUN_tool_reguUV(const TopoDS_Face& FF, TopoDS_Face& fF)
449{
450
451 const TopoDS_Face& F = TopoDS::Face(FF);
452 Standard_Boolean uclosed,vclosed; Standard_Real uperiod,vperiod;
453 Standard_Boolean closed = FUN_tool_closedS(F,uclosed,uperiod,vclosed,vperiod);
454 if (!closed) return Standard_False;
455 Standard_Real tolu,tolv; FUN_tool_tolUV(TopoDS::Face(fF),tolu,tolv);
456
457 TopTools_ListOfShape leko;
458 // --------
459 TopTools_IndexedMapOfOrientedShape mape;
460 TopExp_Explorer ex(fF, TopAbs_EDGE);
461 for (; ex.More(); ex.Next()){
462 const TopoDS_Edge& ee = TopoDS::Edge(ex.Current());
463 TopAbs_Orientation oee = ee.Orientation();
464 TopAbs_Orientation oe = TopAbs::Complement(oee);
465 TopoDS_Edge e = TopoDS::Edge(ee.Oriented(oe));
466 Standard_Boolean hasoppo = mape.Contains(e); // e with complement ori was added to mape
467 if (hasoppo) {
468 // ee :
469 Standard_Real ff,ll; Handle(Geom2d_Curve) PCee = BRep_Tool::CurveOnSurface(ee,F,ff,ll);
470 Standard_Boolean uisoee,visoee; gp_Dir2d d2dee; gp_Pnt2d O2dee;
471 Standard_Boolean uvisoee = FUN_tool_IsUViso(PCee,uisoee,visoee,d2dee,O2dee);
472 // e :
473 Standard_Real f,l; Handle(Geom2d_Curve) PCe = BRep_Tool::CurveOnSurface(e,F,f,l);
474 Standard_Boolean uisoe,visoe; gp_Dir2d d2de; gp_Pnt2d O2de;
475 Standard_Boolean uvisoe = FUN_tool_IsUViso(PCe,uisoe,visoe,d2de,O2de);
476
477 // isfaulty :
478 Standard_Boolean isfaulty = Standard_False;
479 Standard_Real dd = O2dee.Distance(O2de);
480 if (uisoee && uisoe) isfaulty = (dd < tolu);
481 if (visoee && visoe) isfaulty = (dd < tolv);
482
483 if (isfaulty) leko.Append(ee);
484 }
485 else mape.Add(ee);
486 }
487
488 Standard_Integer nko = leko.Extent();
489 if (nko != 1) return Standard_False;
490
491 // eko = edge with faulty pcurve :
492 const TopoDS_Shape& eko = leko.First();
493 TopAbs_Orientation oeko = eko.Orientation();
494 TopTools_ListOfShape edges; ex.Init(fF, TopAbs_EDGE);
495 for (; ex.More(); ex.Next()){
496 const TopoDS_Shape& ee = ex.Current();
497 if (!ee.IsSame(eko)) edges.Append(ee);
498 }
499 // fe = edge with vfe = vertex(ivfe) not uv-connexed :
500 TopoDS_Shape fe; Standard_Integer ivfe=0;
501 Standard_Boolean det = ::FUN_DetectEdgewithfaultyUV(FF,fF,edges,Standard_False,fe,ivfe);
502 if (!det) return Standard_False;
503
504 TopTools_Array1OfShape Vfe(1,2); FUN_Vertices(TopoDS::Edge(fe),Vfe);
505 TopAbs_Orientation ofe = fe.Orientation();
506 const TopoDS_Vertex& vfe = TopoDS::Vertex(Vfe(ivfe));
507 Standard_Real parfe = BRep_Tool::Parameter(vfe,TopoDS::Edge(fe));
508 gp_Pnt2d uvfe; Standard_Boolean ok = FUN_tool_paronEF(TopoDS::Edge(fe),parfe,F,uvfe);
509 if (!ok) return Standard_False;
510 // ivconnex :
511 Standard_Integer ivconnex = (ivfe == 1) ? 2 : 1;
512// if (ofe == TopAbs_REVERSED) ivconnex = (ivconnex == 1) ? 2 : 1;
513
514 // vertex(ivconnex) of eko FORWARD
515 TopoDS_Edge ekoFOR = TopoDS::Edge(eko.Oriented(TopAbs_FORWARD));
516 TopTools_Array1OfShape Veko(1,2); FUN_Vertices(TopoDS::Edge(ekoFOR),Veko);
517 const TopoDS_Vertex& veko1 = TopoDS::Vertex(Veko(1));
518 const TopoDS_Vertex& veko2 = TopoDS::Vertex(Veko(2));
519 Standard_Integer iveko = 0;
520 if (veko1.IsSame(vfe)) iveko = 1;
521 if (veko2.IsSame(vfe)) iveko = 2;
522 if (iveko == 0) return Standard_False;
523
524 // ett : edge same eko with pcurve to translate
525 // isekoFOR=true : vfe should be connexed to vertex(ivconnex) of ekoFOR
526 Standard_Boolean isekoFOR = (iveko == ivconnex);
527 TopAbs_Orientation oett = isekoFOR ? TopAbs_FORWARD : TopAbs_REVERSED;
528 TopoDS_Edge ett = TopoDS::Edge(eko.Oriented(oett));
529 const TopoDS_Vertex& vtt = TopoDS::Vertex(Veko(iveko));
530
531 Standard_Real parett = BRep_Tool::Parameter(vtt,ett);
532 gp_Pnt2d uvtt; ok = FUN_tool_paronEF(ett,parett,F,uvtt);
533 if (!ok) return Standard_False;
534
535 Standard_Real du = uvfe.X()-uvtt.X();
536 Standard_Real dv = uvfe.Y()-uvtt.Y();
537 Standard_Boolean tru=Standard_False, trv=Standard_False;
538 if (uclosed) tru = (Abs(Abs(du)-uperiod) < tolu);
539 if (vclosed) trv = (Abs(Abs(dv)-vperiod) < tolv);
540 if (!tru && !trv) return Standard_False;
541
542 gp_Vec2d tt;
543 if (tru) tt = gp_Vec2d(du,0.);
544 if (trv) tt = gp_Vec2d(0.,dv);
545 Standard_Real f,l; Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface(ett,F,f,l);
546 Standard_Boolean uisoett,visoett; gp_Dir2d d2dett; gp_Pnt2d o2dett;
547 Standard_Boolean uvisoett = FUN_tool_IsUViso(PC1,uisoett,visoett,d2dett,o2dett);o2dett.Translate(tt);
548 Handle(Geom2d_Line) L2d = new Geom2d_Line(o2dett,d2dett);
549 Handle(Geom2d_TrimmedCurve) PC2 = new Geom2d_TrimmedCurve(L2d,f,l);
550
551 BRep_Builder BB;
552 Standard_Real toltt = BRep_Tool::Tolerance(ett);
553// BB.UpdateEdge(TopoDS::Edge(ett),PC2,PC1,fF,toltt);
554 // xpu220998 : cto cylcong A1
555 Handle(Geom2d_Curve) nullc2d;
556 BB.UpdateEdge(TopoDS::Edge(ekoFOR),nullc2d,nullc2d,fF,toltt); // clear
557 if (isekoFOR) BB.UpdateEdge(TopoDS::Edge(ekoFOR),PC2,PC1,fF,toltt);
558 else BB.UpdateEdge(TopoDS::Edge(ekoFOR),PC1,PC2,fF,toltt);
559
560 return Standard_True;
561}*/
562
563static Standard_Boolean FUN_connexX(const Standard_Boolean onU, TopOpeBRepTool_CORRISO& CORRISO,
564 const TopTools_ListOfShape& EdstoCheck, TopTools_DataMapOfOrientedShapeInteger& fyEds)
565// purpose : Fref is x-periodic,
566// <fyEds>={(fye,recadre)}, recadre = INCREASE,DECREASE
567// fye has its 2 bounds faulty
568{
569 fyEds.Clear();
570 Standard_Real tolF = BRep_Tool::Tolerance(CORRISO.Fref());
571 Standard_Integer Index = onU ? 1 : 2;
572 Standard_Real xperiod; Standard_Boolean xclosed = CORRISO.Refclosed(Index,xperiod);
573 if (!xclosed) return Standard_False;
574 Standard_Real xtol = CORRISO.Tol(Index,tolF);
575
576 // fy has its 2 uvbounds non-connexed
577 //nyixpu300998 : iterative (while ko) + map of "static" edges
578 TopoDS_Shape fy; Standard_Integer Ify=0; Standard_Boolean hasfy = CORRISO.EdgeWithFaultyUV(EdstoCheck,2,fy,Ify);
579 if (!hasfy) return Standard_False;
580 TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = CORRISO.UVRep(TopoDS::Edge(fy),C2DF);
581 if (!isb) return Standard_False; // NYIRAISE
582
583 TopTools_Array1OfShape vfy(1,2); TopOpeBRepTool_TOOL::Vertices(TopoDS::Edge(fy),vfy);
584 for (Standard_Integer ii = 1; ii <=2; ii++) {
585 // vff = vertex[ii] of fy
586 const TopoDS_Vertex& vff = TopoDS::Vertex(vfy(ii));
587 Standard_Real parvff = TopOpeBRepTool_TOOL::ParE(ii,TopoDS::Edge(fy));gp_Pnt2d uvff = TopOpeBRepTool_TOOL::UVF(parvff,C2DF);
588 // loe list of edges connexed to faultE
589 TopTools_ListOfShape loe; isb = CORRISO.Connexity(vff,loe);
590 if (!isb) return Standard_False; // FUNRAISE
591
592 TopTools_ListIteratorOfListOfShape ite(loe); // iteration on connex edges of vff
593 for (; ite.More(); ite.Next()){
594 const TopoDS_Edge& ee = TopoDS::Edge(ite.Value());
595 TopTools_Array1OfShape vee(1,2); TopOpeBRepTool_TOOL::Vertices(ee,vee);
596 for (Standard_Integer ive = 1; ive <=2; ive++) {
597 // ve = vertex[ive] of ee
598 const TopoDS_Vertex& ve = TopoDS::Vertex(vee(ive));
599 Standard_Boolean samev = ve.IsSame(vff);
600 if (!samev) continue;
601 if (ive == ii) continue;
602 TopOpeBRepTool_C2DF C2DFe; isb = CORRISO.UVRep(ee,C2DFe);
603 if (!isb) return Standard_False; // FUNRAISE
604 Standard_Real paree = TopOpeBRepTool_TOOL::ParE(ive,ee); gp_Pnt2d uve = TopOpeBRepTool_TOOL::UVF(paree,C2DFe);
605
606 // xxtrsl :
607 Standard_Real dxx = onU ? uve.X()-uvff.X() : uve.Y()-uvff.Y();
608 Standard_Boolean isper =( Abs(xperiod-Abs(dxx)) < xtol);
609 if (!isper) continue;
610
611 Standard_Integer recadre = (dxx > 0) ? INCREASE : DECREASE;
612 fyEds.Bind(fy,recadre);
613 } //ive=1..2
614 }//ite(loe)
615 }//ii=1..2
616 return !fyEds.IsEmpty();
617} // FUN_connexX
618
619//=======================================================================
620//function : CorrectONUVISO
621//purpose :
622//=======================================================================
623
624Standard_Boolean TopOpeBRepTool::CorrectONUVISO(const TopoDS_Face& Fin, TopoDS_Face& Fsp)
625// <Fref> is x-periodic
626{
627#ifdef DEB
628 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
629 if (trc) cout<<"\n#### CorrectONUVISO ####\n\n";
630 debcorrUV();
631#endif
632
633 Standard_Real tolF = BRep_Tool::Tolerance(Fin);
634
635 TopOpeBRepTool_CORRISO CORRISO(Fin);
636 Standard_Real uperiod,vperiod;
637 Standard_Boolean uclosed = CORRISO.Refclosed(1,uperiod);
638 Standard_Boolean vclosed = CORRISO.Refclosed(2,vperiod);
639 if (!uclosed && !vclosed) return Standard_False;
640
641 CORRISO.Init(Fsp);
642 Standard_Boolean ok = CORRISO.UVClosed();
643 if (ok) return Standard_True; // Fsp is valid
644
645 // 1. We check connexity among all edges of <Fsp>
646 // if we find on edge with 2 faulty UVbounds, we try to UVconnect it.
647// for (Standard_Integer i=1; i<=2; i++) {
648 Standard_Integer i ;
649 for ( i=1; i<=2; i++) {
650 Standard_Boolean onU = (i==1) ? Standard_True : Standard_False;
651 const TopTools_ListOfShape& Tocheck = CORRISO.Eds();
652 TopTools_DataMapOfOrientedShapeInteger fyEds; ok =::FUN_connexX(onU,CORRISO,Tocheck,fyEds);
653 if (!ok) continue;
654 ok = CORRISO.TrslUV(onU,fyEds);
655 if (!ok) continue;
656 ok = CORRISO.UVClosed();
657 if (!ok) continue;
658 ok = CORRISO.GetnewS(Fsp);
659 if (!ok) return Standard_False; //NYIRAISE
660 return Standard_True;
661 }
662
663 // 2. x-2drep(edges) are in [xfirst,xfirst+xperiod]
664 for (i = 1; i <=2; i++) {
665 Standard_Boolean onU = (i==1);
666 Standard_Real xper=0.; Standard_Boolean xclosed = CORRISO.Refclosed(i,xper);
667 if (!xclosed) continue;
668 Standard_Real tolx = CORRISO.Tol(i,tolF);
669 tolx *= 1.e2; // BUC60380
670 TopTools_DataMapOfOrientedShapeInteger FyEds; Standard_Boolean hasfy = CORRISO.EdgesOUTofBoundsUV(CORRISO.Eds(),onU,tolx,FyEds);
671 if (!hasfy) continue;
672 ok = CORRISO.TrslUV(onU,FyEds);
673 if (!ok) return Standard_False;
674 ok = CORRISO.UVClosed();
675 if (!ok) continue;
676 ok = CORRISO.GetnewS(Fsp);
677 if (!ok) return Standard_False; //NYIRAISE
678 return Standard_True;
679 }
680 return Standard_False;
681
682 /*// xpu310898 : eC closing ff, ff sdm F(reference face), proj(eC,F) gives ee with
683 // !closing(ee,Fsp) -> 2drep(Fsp) is not closed.
684 // purpose : translate pceCFOR or pceCREV
685 // cto902B7 (ff=f7,eC=e9,F=f14)
686 ok = ::FUN_tool_reguUV(Fin,Fsp);*/
687
688 /*// JYL 980909 : reecriture complete
689 // 1/ traitement de TOUTES les aretes
690 // isou et isov fautives (et non la premiere trouvee);
691 // 2/ traitement des aretes degenerees fautives : CTS20973
692
693 TopTools_ListOfShape lisoe,ldege;
694 TopExp_Explorer exe(Fsp, TopAbs_EDGE);
695 for (; exe.More(); exe.Next()){
696 const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
697 Standard_Boolean degen = BRep_Tool::Degenerated(E);
698 if ( degen ) {
699 ldege.Append(E);
700 }
701 else {
702 Standard_Real f,l; Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,Fin,f,l);
703 Standard_Boolean uiso,viso; gp_Dir2d d2d; gp_Pnt2d O2d;
704 Standard_Boolean uviso = FUN_tool_IsUViso(PC,uiso,viso,d2d,O2d);
705 Standard_Boolean onclosing = (uiso && uclosed) || (viso && vclosed);
706 if ( onclosing) {
707 lisoe.Append(E);
708 }
709 }
710 }
711
712 Standard_Integer nisoe = lisoe.Extent();
713 Standard_Integer ndege = ldege.Extent();
714 if (nisoe ==0 && ndege == 0) return Standard_False;
715
716 Standard_Integer tmpisoe;
717 Standard_Integer tmpdege;
718
719 TopTools_ListOfShape lfyisoe; Standard_Boolean tocorrectisoe = Standard_False;
720 tocorrectisoe = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,lisoe,Standard_True,lfyisoe,tmpisoe);
721
722 TopTools_ListOfShape lfydege; Standard_Boolean tocorrectdege = Standard_False;
723 tocorrectdege = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,ldege,Standard_True,lfydege,tmpdege);
724
725 tocorrect = (tocorrectisoe || tocorrectdege);
726 if (!tocorrect) {
727 return Standard_True;
728 }
729
730#ifdef DEB
731 if (trc) {
732 cout<<"CorrectONUVISO ";
733 cout<<"iso faulty "<<tocorrectisoe<<" deg faulty "<<tocorrectdege<<endl;;
734 }
735 debcorrUV();
736#endif
737
738 if (tocorrectisoe) {
739 for (TopTools_ListIteratorOfListOfShape itiso(lfyisoe);itiso.More();itiso.Next()) {
740 TopoDS_Edge& fyisoe = TopoDS::Edge(itiso.Value());
741
742 // !! if the faulty edge ON closing appears twice in <Eds>, NOTHING is done!
743 // -> see processing ::PurgeClosingEdges later called in WESMakeFaces
744 Standard_Integer nfoundisoe = 0;
745 for (exe.Init(Fsp, TopAbs_EDGE); exe.More(); exe.Next()) {
746 if (exe.Current().IsSame(fyisoe)) {
747 nfoundisoe++;
748 }
749 }
750 if (nfoundisoe > 1) {
751 continue;
752 }
753
754#ifdef DRAW
755 if (trc) {
756 cout<<"TopOpeBRepTool correctONUVISO : faulty iso edge"<<endl;
757 FUN_tool_draw("fyf",Fsp);FUN_tool_draw("fyisoe",fyisoe);
758 }
759#endif
760
761 Standard_Boolean ok = ::FUN_correctClosingE(fyisoe,Fsp);
762 if (!ok) {
763 FUN_Raise();
764 continue;
765 }
766 }
767
768 Standard_Integer tmpisoe;
769 TopTools_ListOfShape lffyisoe; tocorrectisoe = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,lfyisoe,Standard_False,lffyisoe,tmpisoe);
770 } // end lffyisoe process
771
772 if (tocorrectdege) {
773 TopTools_IndexedDataMapOfShapeListOfShape mve;
774 TopExp::MapShapesAndAncestors(Fsp,TopAbs_VERTEX,TopAbs_EDGE,mve);
775
776 for (TopTools_ListIteratorOfListOfShape itdeg(lfydege);itdeg.More();itdeg.Next()) {
777 TopoDS_Edge& fydege = TopoDS::Edge(itdeg.Value());
778
779#ifdef DRAW
780 if (trc) {
781 cout<<"TopOpeBRepTool correctONUVISO : faulty deg edge"<<endl;
782 FUN_tool_draw("fyf",Fsp);FUN_tool_draw("fydege",fydege);
783 }
784#endif
785
786 Standard_Boolean ok = ::FUN_correctDegeneratedE(mve,fydege,Fsp);
787 if (!ok) {
788 FUN_Raise();
789 continue;
790 }
791 } // itdeg
792
793 TopTools_ListOfShape lffydege; tocorrectdege = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,lfydege,Standard_False,lffydege,tmpdege);
794 } // end lfydege process
795
796 TopTools_ListOfShape eFsp; FUN_tool_shapes(Fsp,TopAbs_EDGE,eFsp);
797 TopTools_ListOfShape lffydege; tocorrect = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,eFsp,Standard_False,lffydege,tmpdege);
798 Standard_Boolean done = !tocorrect;
799 return done;*/
800
801} // correctONUVISO
802
803//=======================================================================
804//function : MakeFaces
805//purpose :
806//=======================================================================
807
808Standard_Boolean TopOpeBRepTool::MakeFaces(const TopoDS_Face& Fin, const TopTools_ListOfShape& LOF,
809 const TopTools_IndexedMapOfOrientedShape& MshNOK,
810 TopTools_ListOfShape& LOFF)
811{
812// TopOpeBRepDS_BuildTool BT;
813 BRep_Builder BB;
814 LOFF.Clear();
815 TopTools_ListIteratorOfListOfShape it(LOF);
816 for (; it.More(); it.Next()){
817 const TopoDS_Face& FF = TopoDS::Face(it.Value());
818 Standard_Boolean valid = !MshNOK.Contains(FF);
819 if (valid) {LOFF.Append(FF); continue;}
820
821 TopoDS_Shape aLocalShape = Fin.EmptyCopied();
822 TopoDS_Face newFace = TopoDS::Face(aLocalShape);// BT.CopyFace(Fin,newFace);
823// TopoDS_Face newFace = TopoDS::Face(Fin.EmptyCopied());// BT.CopyFace(Fin,newFace);
824 TopExp_Explorer exw(FF, TopAbs_WIRE);
825
826 for (; exw.More(); exw.Next()){
827 const TopoDS_Wire& W = TopoDS::Wire(exw.Current());
828 valid = !MshNOK.Contains(W);
829 // if (valid) {BT.AddFaceWire(newFace,W); continue;}
830 if (valid) {BB.Add(newFace,W); continue;}
831
832 TopoDS_Wire newWire; //BT.MakeWire(newWire);
833 BB.MakeWire(newWire);
834 TopExp_Explorer exe(W, TopAbs_EDGE);
835 Standard_Integer ne = 0;
836 for (; exe.More(); exe.Next()){
837 const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
838 valid = !MshNOK.Contains(E);
839 if (!valid) continue;
840 // BT.AddWireEdge(newWire,E);
841 BB.Add(newWire,E);
842 ne++;
843 } // exe
844 if (ne == 0) continue;
845 Standard_Boolean closed = FUN_tool_ClosedW(newWire);
846 // BT.Closed(newWire,closed);
847 // BT.AddFaceWire(newFace,newWire);
848 newWire.Closed(closed);
849 BB.Add(newFace,newWire);
850 } // exw
851 LOFF.Append(newFace);
852 }
853 return Standard_True;
854}
855
856/*static Handle(Geom2d_TrimmedCurve) FUN_translate(const gp_Vec2d& tvector, const TopoDS_Face& fF, TopoDS_Edge& fyE)
857{
858 Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FUNTOOLC2D_CurveOnSurface(fyE,fF,f,l,tol);
859 Standard_Boolean isou,isov; gp_Pnt2d o2d; gp_Dir2d d2d;
860 Standard_Boolean isouv = FUN_tool_IsUViso(PC,isou,isov,d2d,o2d); o2d.Translate(tvector);
861 Handle(Geom2d_Line) L2d = new Geom2d_Line(o2d,d2d);
862 Handle(Geom2d_TrimmedCurve) C2d = new Geom2d_TrimmedCurve(L2d,f,l);
863 return C2d;
864}
865Standard_EXPORT void FUN_tool_ttranslate(const gp_Vec2d& tvector, const TopoDS_Face& fF, TopoDS_Edge& fyE)
866{
867 Handle(Geom2d_TrimmedCurve) C2d = ::FUN_translate(tvector,fF,fyE);
868 Standard_Real tole = BRep_Tool::Tolerance(fyE);
869 BRep_Builder BB;
870// Handle(Geom2d_Curve) toclear; BB.UpdateEdge(fyE,toclear,fF,tole);
871 BB.UpdateEdge(fyE,C2d,fF,tole);
872}
873
874static Standard_Boolean FUN_tool_translate(const gp_Vec2d& tvector, TopoDS_Face& fF, TopoDS_Edge& fyE)
875 // prequesitory : <fF> is on periodic surface, translates edge
876 // <fyE>'s uorviso to have its uorvpar bounded in [0.,2PI].
877{
878 Handle(Geom2d_TrimmedCurve) C2d = ::FUN_translate(tvector,fF,fyE);
879 Standard_Real tole = BRep_Tool::Tolerance(fyE);
880
881 //xpu040598 : CTS20280 f37 modified when its split is modified!
882 TopoDS_Face newf; Standard_Boolean ok = FUN_tool_pcurveonF(fF,fyE,C2d,newf);
883 if (ok) fF = newf;
884 return ok;
885 //xpu040598
886}
887*/