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