0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / LocOpe / LocOpe_WiresOnShape.cxx
1 // Created on: 1996-01-11
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Bnd_Box2d.hxx>
19 #include <BndLib_Add2dCurve.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepAdaptor_Curve2d.hxx>
23 #include <BRepLib.hxx>
24 #include <BRepLib_MakeVertex.hxx>
25 #include <BRepTools.hxx>
26 #include <Extrema_ExtCC.hxx>
27 #include <Geom2d_Curve.hxx>
28 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom_Plane.hxx>
31 #include <Geom_RectangularTrimmedSurface.hxx>
32 #include <Geom_Surface.hxx>
33 #include <Geom_TrimmedCurve.hxx>
34 #include <GeomAdaptor_Surface.hxx>
35 #include <GeomAPI_ProjectPointOnCurve.hxx>
36 #include <GeomProjLib.hxx>
37 #include <gp_Pnt2d.hxx>
38 #include <gp_Vec.hxx>
39 #include <gp_Vec2d.hxx>
40 #include <LocOpe.hxx>
41 #include <LocOpe_WiresOnShape.hxx>
42 #include <Precision.hxx>
43 #include <Standard_ConstructionError.hxx>
44 #include <Standard_Type.hxx>
45 #include <TopExp.hxx>
46 #include <TopExp_Explorer.hxx>
47 #include <TopoDS.hxx>
48 #include <TopoDS_Compound.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Face.hxx>
51 #include <TopoDS_Shape.hxx>
52 #include <TopoDS_Vertex.hxx>
53 #include <TopoDS_Wire.hxx>
54 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
55 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
57 #include <TopTools_ListOfShape.hxx>
58 #include <TopTools_MapOfShape.hxx>
59 #include <TopTools_DataMapOfShapeReal.hxx>
60 #include <Extrema_ExtCC2d.hxx>
61 #include <BRepAdaptor_Surface.hxx>
62 #include <ShapeAnalysis_Edge.hxx>
63
64 #include <TopTools_SequenceOfShape.hxx>
65 #include <BRepBndLib.hxx>
66 #include <Bnd_Box.hxx>
67 #include <Bnd_SeqOfBox.hxx>
68 #include <NCollection_Handle.hxx>
69 #include <TColStd_PackedMapOfInteger.hxx>
70 #include <Extrema_ExtPS.hxx>
71
72 #include <BRepTopAdaptor_FClass2d.hxx>
73 #include <ShapeConstruct_ProjectCurveOnSurface.hxx>
74 #include <ShapeAnalysis.hxx>
75
76 IMPLEMENT_STANDARD_RTTIEXT(LocOpe_WiresOnShape,MMgt_TShared)
77
78 static Standard_Boolean Project(const TopoDS_Vertex&,
79                                 const gp_Pnt2d&,
80                                 const TopoDS_Face&,
81                                 TopoDS_Edge&,
82                                 Standard_Real&);
83
84 static Standard_Real Project(const TopoDS_Vertex&,
85                              const TopoDS_Edge&);
86
87 static Standard_Real Project(const TopoDS_Vertex&,
88                              const gp_Pnt2d&,
89                              const TopoDS_Edge&,
90                              const TopoDS_Face&);
91
92
93 static void PutPCurve(const TopoDS_Edge&,
94                       const TopoDS_Face&);
95
96
97 static void PutPCurves(const TopoDS_Edge&,
98                        const TopoDS_Edge&,
99                        const TopoDS_Shape&);
100
101 static void FindInternalIntersections(const TopoDS_Edge&,
102                                       const TopoDS_Face&,
103                                       TopTools_IndexedDataMapOfShapeListOfShape&,
104                                       Standard_Boolean&);
105
106 //=======================================================================
107 //function : LocOpe_WiresOnShape
108 //purpose  : 
109 //=======================================================================
110
111 LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
112   myShape(S),myCheckInterior(Standard_True),myDone(Standard_False)
113 {}
114
115 //=======================================================================
116 //function : Init
117 //purpose  : 
118 //=======================================================================
119
120 void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
121 {
122    myShape = S;
123    myCheckInterior = Standard_True;
124    myDone = Standard_False;
125    myMap.Clear();
126    myMapEF.Clear();
127 }
128
129 //=======================================================================
130 //function : Bind
131 //purpose  : 
132 //=======================================================================
133
134 void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
135                                const TopoDS_Face& F)
136 {
137   for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) {
138     Bind(TopoDS::Edge(exp.Current()),F);
139   }
140 }
141
142 //=======================================================================
143 //function : Bind
144 //purpose  : 
145 //=======================================================================
146
147 void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp,
148                                const TopoDS_Face& F)
149 {
150   for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) {
151     Bind(TopoDS::Edge(exp.Current()),F);
152   }
153   myFacesWithSection.Add(F);
154 }
155
156 //=======================================================================
157 //function : Bind
158 //purpose  : 
159 //=======================================================================
160
161 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E,
162                                const TopoDS_Face& F)
163 {
164 //  if (!myMapEF.IsBound(E)) {
165   if (!myMapEF.Contains(E)) {
166 //    for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) {
167     TopExp_Explorer exp(F,TopAbs_EDGE) ;
168     for ( ;exp.More();exp.Next()) {
169       if (exp.Current().IsSame(E)) {
170         break;
171       }
172     }
173     if (!exp.More()) {
174 //      myMapEF.Bind(E,F);
175       myMapEF.Add(E,F);
176     }
177   }
178   else {
179     throw Standard_ConstructionError();
180   }
181 }
182
183
184 //=======================================================================
185 //function : Bind
186 //purpose  : 
187 //=======================================================================
188
189 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir,
190                                const TopoDS_Edge& Efac)
191 {
192   myMap.Bind(Ewir,Efac);
193 }
194
195
196 //=======================================================================
197 //function : BindAll
198 //purpose  : 
199 //=======================================================================
200
201 void LocOpe_WiresOnShape::BindAll()
202 {
203   if (myDone) {
204     return;
205   }
206   TopTools_MapOfShape theMap;
207
208   // Detection des vertex a projeter ou a "binder" avec des vertex existants
209   TopTools_DataMapOfShapeShape mapV;
210   TopTools_DataMapIteratorOfDataMapOfShapeShape ite(myMap);
211   TopExp_Explorer exp,exp2;
212   for (; ite.More(); ite.Next()) {
213     const TopoDS_Edge& eref = TopoDS::Edge(ite.Key());
214     const TopoDS_Edge& eimg = TopoDS::Edge(ite.Value());
215
216     PutPCurves(eref,eimg,myShape);
217
218     for (exp.Init(eref,TopAbs_VERTEX); exp.More(); exp.Next()) {
219       const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
220       if (!theMap.Contains(vtx)) { // pas deja traite
221         for (exp2.Init(eimg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
222           const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
223           if (vtx2.IsSame(vtx)) {
224             break;
225           }
226           else if (BRepTools::Compare(vtx,vtx2)) {
227             mapV.Bind(vtx,vtx2);
228             break;
229           }
230         }
231         if (!exp2.More()) {
232           mapV.Bind(vtx,eimg);
233         }
234         theMap.Add(vtx);
235       }
236     }
237   }
238   
239   for (ite.Initialize(mapV); ite.More(); ite.Next()) {
240     myMap.Bind(ite.Key(),ite.Value());
241   }
242
243   TopTools_IndexedDataMapOfShapeListOfShape Splits;
244   Standard_Integer Ind;
245   TopTools_MapOfShape anOverlappedEdges;
246   for (Ind = 1; Ind <= myMapEF.Extent(); Ind++)
247   {
248     const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
249     const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
250     
251     PutPCurve(edg,fac);
252     Standard_Real pf, pl;
253     Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(edg, fac, pf, pl);
254     if (aPCurve.IsNull())
255       continue;
256
257     if (myCheckInterior)
258     {
259       Standard_Boolean isOverlapped = Standard_False;
260       FindInternalIntersections(edg, fac, Splits, isOverlapped);
261       if(isOverlapped)
262         anOverlappedEdges.Add(edg);
263     }
264   }
265
266   for (Ind = 1; Ind <= Splits.Extent(); Ind++)
267   {
268     TopoDS_Shape anEdge = Splits.FindKey(Ind);
269     if(anOverlappedEdges.Contains(anEdge))
270       continue;
271     TopoDS_Shape aFace  = myMapEF.FindFromKey(anEdge);
272     //Remove "anEdge" from "myMapEF"
273     TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent());
274     TopoDS_Shape LastFace = myMapEF(myMapEF.Extent());
275     myMapEF.RemoveLast();
276     if (myMapEF.FindIndex(anEdge) != 0)
277       myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace);
278     ////////////////////////////////
279     TopTools_ListIteratorOfListOfShape itl(Splits(Ind));
280     for (; itl.More(); itl.Next())
281       myMapEF.Add(itl.Value(), aFace);
282   }
283
284   TopTools_DataMapOfShapeReal  aVertParam;
285
286   for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
287     const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
288     const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
289     // JAG 02.02.96 : On verifie les pcurves...
290
291     //PutPCurve(edg,fac);
292
293     for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
294       const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
295       if (theMap.Contains(vtx)) {
296         continue;
297       }
298       
299       Standard_Real vtx_param = BRep_Tool::Parameter(vtx, edg);
300       BRepAdaptor_Curve2d BAcurve2d(edg, fac);
301             
302       gp_Pnt2d p2d = (!BAcurve2d.Curve().IsNull() ? 
303         BAcurve2d.Value(vtx_param) : gp_Pnt2d(Precision::Infinite(), Precision::Infinite()));
304
305       TopoDS_Edge Epro;
306       Standard_Real prm = Precision::Infinite();
307       Standard_Boolean isProjected = myMap.IsBound(vtx);
308
309       //if vertex was already projected on the current edge on the previous face
310       //it is necessary to check tolerance of the vertex in the 2D space on the current
311       //face without projection and update tolerance of vertex if it is necessary
312       if (isProjected)
313       {
314         TopoDS_Shape aSh = myMap.Find(vtx);
315         if (aSh.ShapeType() != TopAbs_EDGE)
316           continue;
317         Epro = TopoDS::Edge(myMap.Find(vtx));
318         if (aVertParam.IsBound(vtx))
319           prm = aVertParam.Find(vtx);
320       }
321       Standard_Boolean ok = Project(vtx, p2d, fac, Epro, prm);
322       if (ok && !isProjected) {
323
324         for (exp2.Init(Epro, TopAbs_VERTEX); exp2.More(); exp2.Next()) {
325           const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
326           if (vtx2.IsSame(vtx)) {
327             myMap.Bind(vtx, vtx2);
328             theMap.Add(vtx);
329             break;
330           }
331           else if (BRepTools::Compare(vtx, vtx2)) {
332             Standard_Real aF1, aL1;
333             BRep_Tool::Range(Epro, fac, aF1, aL1);
334             if (!BRep_Tool::Degenerated(Epro) && (
335               Abs(prm - aF1) <= Precision::PConfusion() ||
336               Abs(prm - aL1) <= Precision::PConfusion()))
337             {
338               myMap.Bind(vtx, vtx2);
339               theMap.Add(vtx);
340               break;
341             }
342           }
343         }
344         if (!exp2.More()) {
345           myMap.Bind(vtx,Epro);
346           aVertParam.Bind(vtx, prm);
347         }
348       }
349     }
350   }
351
352 //  Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin
353   for (ite.Initialize(myMap); ite.More(); ite.Next())
354     if ((ite.Key()).ShapeType() == TopAbs_EDGE)
355       myMapEF.Add(ite.Key(),ite.Value());
356 //  Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End
357
358
359   myDone = Standard_True;
360
361 }
362
363
364 //=======================================================================
365 //function : InitEdgeIterator
366 //purpose  : 
367 //=======================================================================
368
369 void LocOpe_WiresOnShape::InitEdgeIterator()
370 {
371   BindAll();
372 //  myIt.Initialize(myMapEF);
373   myIndex = 1;
374 }
375
376
377 //=======================================================================
378 //function : MoreEdge
379 //purpose  : 
380 //=======================================================================
381
382 Standard_Boolean LocOpe_WiresOnShape::MoreEdge()
383 {
384 //  return myIt.More();
385   return (myIndex <= myMapEF.Extent());
386 }
387
388
389 //=======================================================================
390 //function : Edge
391 //purpose  : 
392 //=======================================================================
393
394 TopoDS_Edge LocOpe_WiresOnShape::Edge()
395 {
396 //  return TopoDS::Edge(myIt.Key());
397   return TopoDS::Edge(myMapEF.FindKey(myIndex));
398 }
399
400
401 //=======================================================================
402 //function : Face
403 //purpose  : 
404 //=======================================================================
405
406 TopoDS_Face LocOpe_WiresOnShape::OnFace()
407 {
408 //  return TopoDS::Face(myIt.Value());
409   return TopoDS::Face(myMapEF(myIndex));
410 }
411
412
413 //=======================================================================
414 //function : OnEdge
415 //purpose  : 
416 //=======================================================================
417
418 Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E)
419 {
420 //  if (myMap.IsBound(myIt.Key())) {
421   if (myMap.IsBound(myMapEF.FindKey(myIndex))) {
422 //    E = TopoDS::Edge(myMap(myIt.Key()));
423     E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex)));
424     return Standard_True;
425   }
426   return Standard_False;
427 }
428
429
430
431
432 //=======================================================================
433 //function : NextEdge
434 //purpose  : 
435 //=======================================================================
436
437 void LocOpe_WiresOnShape::NextEdge()
438 {
439 //  myIt.Next();
440   myIndex++;
441 }
442
443
444
445 //=======================================================================
446 //function : OnVertex
447 //purpose  : 
448 //=======================================================================
449
450 Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
451                                                TopoDS_Vertex& Vs)
452 {
453   if (myMap.IsBound(Vw)) {
454     if (myMap(Vw).ShapeType() == TopAbs_VERTEX) {
455       Vs = TopoDS::Vertex(myMap(Vw));
456       return Standard_True;
457     }
458     return Standard_False;
459   }
460   return Standard_False;
461 }
462
463
464 //=======================================================================
465 //function : OnEdge
466 //purpose  : 
467 //=======================================================================
468
469 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
470                                           TopoDS_Edge& Ed,
471                                           Standard_Real& prm)
472 {
473   if (!myMap.IsBound(V) ||
474       myMap(V).ShapeType() == TopAbs_VERTEX) {
475     return Standard_False;
476   }
477   
478   Ed = TopoDS::Edge(myMap(V));
479   prm = Project(V,Ed);
480   return Standard_True;
481 }
482
483 //=======================================================================
484 //function : OnEdge
485 //purpose  : 
486 //=======================================================================
487
488 Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
489                                              const TopoDS_Edge& EdgeFrom,
490                                              TopoDS_Edge& Ed,
491                                              Standard_Real& prm)
492 {
493   if (!myMap.IsBound(V) ||
494       myMap(V).ShapeType() == TopAbs_VERTEX) {
495     return Standard_False;
496   }
497   
498   Ed = TopoDS::Edge(myMap(V));
499   if(!myMapEF.Contains(EdgeFrom))
500     return Standard_False;
501
502   TopoDS_Shape aShape = myMapEF.FindFromKey(EdgeFrom);
503   Standard_Real aF, aL;
504   Handle(Geom_Curve) aC = BRep_Tool::Curve(Ed, aF, aL);
505   if (aC.IsNull() && aShape.ShapeType() == TopAbs_FACE)
506   {
507
508     TopoDS_Face aFace = TopoDS::Face(aShape);
509     Standard_Real vtx_param = BRep_Tool::Parameter(V, EdgeFrom);
510     BRepAdaptor_Curve2d BAcurve2d(EdgeFrom, aFace);
511     gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
512
513
514     prm = Project(V, p2d, Ed, aFace);
515   }
516   else
517     prm = Project( V, TopoDS::Edge(Ed));
518         
519   return Standard_True;
520 }
521
522
523 //=======================================================================
524 //function : Project
525 //purpose  : 
526 //=======================================================================
527
528 Standard_Boolean Project(const TopoDS_Vertex& V,
529                          const gp_Pnt2d& p2d,
530                          const TopoDS_Face& F,
531                          TopoDS_Edge& theEdge,
532                          Standard_Real& param)
533 {
534   Standard_Real aTolV = BRep_Tool::Tolerance(V);
535   Standard_Real dmin = (theEdge.IsNull() ? RealLast() : aTolV * aTolV);
536  
537   Standard_Boolean valret = Standard_False;
538   
539   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
540  
541   if (theEdge.IsNull())
542   {
543     gp_Pnt toproj(BRep_Tool::Pnt(V));
544     for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
545       exp.More(); exp.Next()) {
546       const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
547       Standard_Real f, l;
548       Handle(Geom_Curve) C = BRep_Tool::Curve(edg, f, l);
549       Standard_Real aCurDist = Precision::Infinite();
550       Standard_Real aCurPar = Precision::Infinite();
551       if (!C.IsNull())
552       {
553         aCurPar = Project(V, edg);
554         if (Precision::IsInfinite(aCurPar))
555           continue;
556         gp_Pnt aCurPBound;
557         C->D0(aCurPar, aCurPBound);
558         aCurDist = aCurPBound.SquareDistance(toproj);
559       }
560
561       else if(!Precision::IsInfinite(p2d.X()))
562       {
563         //Geom2dAPI_ProjectPointOnCurve proj;
564         Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(edg,F , f, l);
565         if(aC2d.IsNull())
566           continue;
567
568         aCurPar = Project(V, p2d, edg, F);
569         if (Precision::IsInfinite(aCurPar))
570           continue;
571         Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(edg, F, f, l);
572         gp_Pnt2d aPProj;
573         PC->D0(aCurPar, aPProj);
574         gp_Pnt aCurPBound;
575         aSurf->D0(aPProj.X(), aPProj.Y(), aCurPBound);
576         aCurDist = aCurPBound.SquareDistance(toproj);
577
578       }
579
580       if (aCurDist < dmin) {
581         theEdge = edg;
582         theEdge.Orientation(edg.Orientation());
583         dmin = aCurDist;
584         param = aCurPar;
585
586       }
587
588     }
589     if (theEdge.IsNull())
590       return Standard_False;
591   }
592   else if (Precision::IsInfinite(param))
593   {
594     Standard_Real f, l;
595     Handle(Geom_Curve) C = BRep_Tool::Curve(theEdge, f, l);
596     param = (!C.IsNull() ? Project(V, theEdge) : Project(V, p2d, theEdge, F));
597
598   }
599
600   Standard_Real ttol = aTolV + BRep_Tool::Tolerance(theEdge);
601   if (dmin <= ttol* ttol) {
602     valret = Standard_True;
603     GeomAdaptor_Surface adSurf(aSurf);
604
605     Standard_Real anUResolution = adSurf.UResolution(1.);
606     Standard_Real aVResolution = adSurf.UResolution(1.);
607
608     Standard_Real f, l;
609     Handle(Geom2d_Curve) aCrvBound = BRep_Tool::CurveOnSurface(theEdge, F, f, l);
610     if (!aCrvBound.IsNull())
611     {
612       gp_Pnt2d aPBound2d;
613       aCrvBound->D0(param, aPBound2d);
614
615       //distance in 2D space recomputed in the 3D space in order to tolerance of vertex
616       //cover gap in 2D space. For consistency with check of the validity in the  BRepCheck_Wire
617       Standard_Real dumax = 0.01 * (adSurf.LastUParameter() - adSurf.FirstUParameter());
618       Standard_Real dvmax = 0.01 * (adSurf.LastVParameter() - adSurf.FirstVParameter());
619       
620       gp_Pnt2d aPcur = p2d;
621       Standard_Real dumin = Abs(aPcur.X() - aPBound2d.X());
622       Standard_Real dvmin = Abs(aPcur.Y() - aPBound2d.Y());
623       if (dumin > dumax && adSurf.IsUPeriodic())
624       {
625         Standard_Real aX1 = aPBound2d.X();
626         Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aX1, adSurf.FirstUParameter(), adSurf.LastUParameter());
627         aX1 += aShift;
628         aPBound2d.SetX(aX1);
629         Standard_Real aX2 = p2d.X();
630         aShift = ShapeAnalysis::AdjustToPeriod(aX2, adSurf.FirstUParameter(), adSurf.LastUParameter());
631         aX2 += aShift;
632         dumin = Abs(aX2 - aX1);
633         if (dumin > dumax &&  (Abs(dumin - adSurf.UPeriod()) < Precision::PConfusion()) )
634         {
635           aX2 = aX1;
636           dumin = 0.;
637         }
638         aPcur.SetX(aX2);
639
640       }
641
642       if (dvmin > dvmax && adSurf.IsVPeriodic())
643       {
644         Standard_Real aY1 = aPBound2d.Y();
645         Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aY1, adSurf.FirstVParameter(), adSurf.LastVParameter());
646         aY1 += aShift;
647         aPBound2d.SetY(aY1);
648         Standard_Real aY2 = p2d.Y();
649         aShift = ShapeAnalysis::AdjustToPeriod(aY2, adSurf.FirstVParameter(), adSurf.LastVParameter());
650         aY2 += aShift;
651         dvmin = Abs(aY1 - aY2);
652         if (dvmin > dvmax && ( Abs(dvmin - adSurf.VPeriod()) < Precision::Confusion()) )
653         {
654           aY2 = aY1;
655           dvmin = 0.;
656         }
657         aPcur.SetY(aY2);
658       }
659       Standard_Real aDist3d = aTolV;
660       if ((dumin > dumax) || (dvmin > dvmax))
661       {
662
663         dumax = adSurf.UResolution(aTolV);
664         dvmax = adSurf.VResolution(aTolV);
665         Standard_Real aTol2d = 2. * Max(dumax, dvmax);
666         Standard_Real aDist2d =  Max(dumin, dvmin);
667
668         if (aDist2d > aTol2d)
669         {
670           Standard_Real aDist3d1 = aDist2d / Max(anUResolution, aVResolution);
671           if( aDist3d1 > aDist3d)
672             aDist3d =  aDist3d1;
673         }
674       }
675
676       //added check by 3D the same as in the BRepCheck_Wire::SelfIntersect
677       gp_Pnt aPBound;
678       aSurf->D0(aPBound2d.X(), aPBound2d.Y(), aPBound);
679       gp_Pnt aPV2d;
680       aSurf->D0(p2d.X(), p2d.Y(), aPV2d);
681       Standard_Real aDistPoints_3D = aPV2d.SquareDistance(aPBound);
682             Standard_Real aMaxDist = Max(aDistPoints_3D, aDist3d * aDist3d);
683  
684       BRep_Builder B;
685       if (aTolV * aTolV < aMaxDist)
686       {
687         Standard_Real aNewTol = sqrt(aMaxDist);
688         B.UpdateVertex(V, aNewTol);
689       }
690     }
691   }
692 #ifdef OCCT_DEBUG_MESH
693   else {
694     cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une "; 
695     cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
696   }
697 #endif
698   return valret;
699 }
700
701 //=======================================================================
702 //function : Project
703 //purpose  : 
704 //=======================================================================
705
706 Standard_Real Project(const TopoDS_Vertex& V,
707                       const TopoDS_Edge& theEdge)
708 {
709   Handle(Geom_Curve) C;
710   TopLoc_Location Loc;
711   Standard_Real f,l;
712
713   gp_Pnt toproj(BRep_Tool::Pnt(V));
714   GeomAPI_ProjectPointOnCurve proj;
715
716   C = BRep_Tool::Curve(theEdge,Loc,f,l);
717   if (!Loc.IsIdentity()) {
718     Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
719     C = Handle(Geom_Curve)::DownCast (GG);
720   }
721   proj.Init(toproj,C,f,l);
722   
723
724
725   return (proj.NbPoints() > 0 ? proj.LowerDistanceParameter() : Precision::Infinite());
726 }
727
728 //=======================================================================
729 //function : Project
730 //purpose  : 
731 //=======================================================================
732
733 Standard_Real Project(const TopoDS_Vertex&,
734                       const gp_Pnt2d&      p2d,
735                       const TopoDS_Edge& theEdge,
736                       const TopoDS_Face& theFace)
737 {
738
739   
740   Handle(Geom2d_Curve) PC;
741  
742   Standard_Real f, l;
743
744   Geom2dAPI_ProjectPointOnCurve proj;
745
746   PC = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
747   
748   proj.Init(p2d, PC, f, l);
749
750   return proj.NbPoints() > 0 ? proj.LowerDistanceParameter() : Precision::Infinite();
751 }
752
753
754 //=======================================================================
755 //function : PutPCurve
756 //purpose  : 
757 //=======================================================================
758
759 void PutPCurve(const TopoDS_Edge& Edg,
760                const TopoDS_Face& Fac)
761 {
762   BRep_Builder B;
763   TopLoc_Location LocFac;
764
765   Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
766   Handle(Standard_Type) styp = S->DynamicType();
767
768   if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
769     S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
770     styp = S->DynamicType();
771   }
772
773   if (styp == STANDARD_TYPE(Geom_Plane)) {
774     return;
775   }
776
777   Standard_Real Umin,Umax,Vmin,Vmax;
778   BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
779
780   Standard_Real f,l;
781
782   Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
783   if ( !aC2d.IsNull() ) {
784     gp_Pnt2d p2d;
785     aC2d->D0((f + l) *0.5, p2d);
786     Standard_Boolean IsIn = Standard_True;
787     if ( ( p2d.X() < Umin-Precision::PConfusion() ) || 
788          ( p2d.X() > Umax+Precision::PConfusion() ) )
789       IsIn = Standard_False;
790     if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) || 
791          ( p2d.Y() > Vmax+Precision::PConfusion() ) )
792       IsIn = Standard_False;
793  
794     if (IsIn)
795       return;
796   }
797
798   TopLoc_Location Loc;
799   Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
800   if (!Loc.IsIdentity()) {
801     Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
802     C = Handle(Geom_Curve)::DownCast (GG);
803   }
804
805   if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
806     C = new Geom_TrimmedCurve(C,f,l);
807   }
808
809   S = BRep_Tool::Surface(Fac);
810
811   Standard_Real tol2d = Precision::Confusion();
812   Handle(Geom2d_Curve) C2d;
813   ShapeConstruct_ProjectCurveOnSurface aToolProj;
814   aToolProj.Init(S, tol2d);
815
816   aToolProj.Perform(C,f,l, C2d);
817   if (C2d.IsNull())
818   {
819     return;
820   }
821  
822   gp_Pnt2d pf(C2d->Value(f));
823   gp_Pnt2d pl(C2d->Value(l));
824   gp_Pnt PF,PL;
825   S->D0(pf.X(),pf.Y(),PF);
826   S->D0(pl.X(),pl.Y(),PL);
827   TopoDS_Vertex V1,V2;
828   if (Edg.Orientation() == TopAbs_REVERSED) {
829     V1 = TopExp::LastVertex(Edg);
830     V1.Reverse();
831   }
832   else {
833     V1 = TopExp::FirstVertex (Edg);
834   }
835   if (Edg.Orientation() == TopAbs_REVERSED) {
836     V2 = TopExp::FirstVertex(Edg);
837     V2.Reverse();
838   }
839   else {
840     V2 = TopExp::LastVertex (Edg);
841   }
842
843   if(!V1.IsNull() && V2.IsNull()) {
844     //Handling of internal vertices
845     Standard_Real old1 = BRep_Tool::Tolerance (V1);
846     Standard_Real old2 = BRep_Tool::Tolerance (V2);
847     gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
848     gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
849     Standard_Real tol1 = pnt1.Distance(PF);
850     Standard_Real tol2 = pnt2.Distance(PL);
851     B.UpdateVertex(V1,Max(old1,tol1));
852     B.UpdateVertex(V2,Max(old2,tol2));
853   }
854
855   if (S->IsUPeriodic()) {
856     Standard_Real up   = S->UPeriod();
857     Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
858     Standard_Integer nbtra = 0;
859     Standard_Real theUmin = Min(pf.X(),pl.X());
860     Standard_Real theUmax = Max(pf.X(),pl.X());
861
862     if (theUmin < Umin-tolu) {
863       while (theUmin < Umin-tolu) {
864         theUmin += up;
865         nbtra++;
866       }
867     }
868     else if (theUmax > Umax+tolu) {
869       while (theUmax > Umax+tolu) {
870         theUmax -= up;
871         nbtra--;
872       }
873     }
874
875     if (nbtra !=0) {
876       C2d->Translate(gp_Vec2d(nbtra*up,0.));
877     }
878   }    
879
880   if (S->IsVPeriodic()) {
881     Standard_Real vp   = S->VPeriod();
882     Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
883     Standard_Integer nbtra = 0;
884     Standard_Real theVmin = Min(pf.Y(),pl.Y());
885     Standard_Real theVmax = Max(pf.Y(),pl.Y());
886
887     if (theVmin < Vmin-tolv) {
888       while (theVmin < Vmin-tolv) {
889         theVmin += vp; theVmax += vp;
890         nbtra++;
891       }
892     }
893     else if (theVmax > Vmax+tolv) {
894       while (theVmax > Vmax+tolv) {
895         theVmax -= vp; theVmin -= vp;
896         nbtra--;
897       }
898     }
899
900     if (nbtra !=0) {
901       C2d->Translate(gp_Vec2d(0.,nbtra*vp));
902     }
903   }
904   B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
905   
906   B.SameParameter(Edg,Standard_False);
907   BRepLib::SameParameter(Edg,tol2d); 
908 }
909
910
911 //=======================================================================
912 //function : PutPCurves
913 //purpose  : 
914 //=======================================================================
915
916 void PutPCurves(const TopoDS_Edge& Efrom,
917                 const TopoDS_Edge& Eto,
918                 const TopoDS_Shape& myShape)
919 {
920
921   TopTools_ListOfShape Lfaces;
922   TopExp_Explorer exp,exp2;
923
924   for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
925     for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
926       if (exp2.Current().IsSame(Eto)) {
927         Lfaces.Append(exp.Current());
928       }
929     }
930   }
931
932   if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
933     throw Standard_ConstructionError();
934   }
935
936   // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
937
938   if (Lfaces.Extent() ==1) {
939     return; // sera fait par PutPCurve.... on l`espere
940   }
941
942   BRep_Builder B;
943   Handle(Geom_Surface) S;
944   Handle(Standard_Type) styp;
945   Handle(Geom_Curve) C;
946   Standard_Real Umin,Umax,Vmin,Vmax;
947   Standard_Real f,l;
948   TopLoc_Location Loc, LocFac;
949
950   if (!Lfaces.First().IsSame(Lfaces.Last())) {
951     TopTools_ListIteratorOfListOfShape itl(Lfaces);
952     for (; itl.More(); itl.Next()) {
953       const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
954
955       if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
956         continue;
957       }
958       S = BRep_Tool::Surface(Fac, LocFac);
959       styp = S->DynamicType();
960       if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
961         S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
962         styp = S->DynamicType();
963       }
964       if (styp == STANDARD_TYPE(Geom_Plane)) {
965         continue;
966       }
967
968             
969       BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
970       C = BRep_Tool::Curve(Efrom,Loc,f,l);
971       if (!Loc.IsIdentity()) {
972         Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
973         C = Handle(Geom_Curve)::DownCast (GG);
974       }
975       
976       if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
977         C = new Geom_TrimmedCurve(C,f,l);
978       }
979     
980       S = BRep_Tool::Surface(Fac);
981
982       // Compute the tol2d
983       Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
984                                 BRep_Tool::Tolerance(Fac));
985       GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
986       Standard_Real TolU  = Gas.UResolution(tol3d);
987       Standard_Real TolV  = Gas.VResolution(tol3d);
988       Standard_Real tol2d = Max(TolU,TolV);
989
990       Handle(Geom2d_Curve) C2d = 
991         GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
992      if(C2d.IsNull())
993        return;
994
995       gp_Pnt2d pf(C2d->Value(f));
996       gp_Pnt2d pl(C2d->Value(l));
997       
998       if (S->IsUPeriodic()) {
999         Standard_Real up   = S->UPeriod();
1000         Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
1001         Standard_Integer nbtra = 0;
1002         Standard_Real theUmin = Min(pf.X(),pl.X());
1003         Standard_Real theUmax = Max(pf.X(),pl.X());
1004
1005         if (theUmin < Umin-tolu) {
1006           while (theUmin < Umin-tolu) {
1007             theUmin += up; theUmax += up;
1008             nbtra++;
1009           }
1010         }
1011         else if (theUmax > Umax+tolu) {
1012           while (theUmax > Umax+tolu) {
1013             theUmax -= up; theUmin -= up;
1014             nbtra--;
1015           }
1016         }
1017 /*
1018         if (theUmin > Umax+tolu) {
1019           while (theUmin > Umax+tolu) {
1020             theUmin -= up;
1021             nbtra--;
1022           }
1023         }
1024         else if (theUmax < Umin-tolu) {
1025           while (theUmax < Umin-tolu) {
1026             theUmax += up;
1027             nbtra++;
1028           }
1029         }
1030 */
1031         if (nbtra !=0) {
1032           C2d->Translate(gp_Vec2d(nbtra*up,0.));
1033         }
1034       }    
1035       
1036       if (S->IsVPeriodic()) {
1037         Standard_Real vp   = S->VPeriod();
1038         Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
1039         Standard_Integer nbtra = 0;
1040         Standard_Real theVmin = Min(pf.Y(),pl.Y());
1041         Standard_Real theVmax = Max(pf.Y(),pl.Y());
1042
1043         if (theVmin < Vmin-tolv) {
1044           while (theVmin < Vmin-tolv) {
1045             theVmin += vp; theVmax += vp;
1046             nbtra++;
1047           }
1048         }
1049         else if (theVmax > Vmax+tolv) {
1050           while (theVmax > Vmax+tolv) {
1051             theVmax -= vp; theVmin -= vp;
1052             nbtra--;
1053           }
1054         }
1055 /*
1056         if (theVmin > Vmax+tolv) {
1057           while (theVmin > Vmax+tolv) {
1058             theVmin -= vp;
1059             nbtra--;
1060           }
1061         }
1062         else if (theVmax < Vmin-tolv) {
1063           while (theVmax < Vmin-tolv) {
1064             theVmax += vp;
1065             nbtra++;
1066           }
1067         }
1068 */
1069         if (nbtra !=0) {
1070           C2d->Translate(gp_Vec2d(0.,nbtra*vp));
1071         }
1072       }
1073       B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
1074     }
1075   }
1076
1077   else {
1078     const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
1079     if (!BRep_Tool::IsClosed(Eto,Fac)) {
1080       throw Standard_ConstructionError();
1081     }
1082
1083     TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
1084     TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
1085     Handle(Geom2d_Curve) c2dff = 
1086       BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1087                                 TopoDS::Face(aLocalF),
1088                                 f,l);
1089
1090 //    Handle(Geom2d_Curve) c2dff = 
1091 //      BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
1092 //                              TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1093 //                              f,l);
1094     
1095     aLocalE = Efrom.Oriented(TopAbs_REVERSED);
1096     aLocalF = Fac.Oriented(TopAbs_FORWARD);
1097     Handle(Geom2d_Curve) c2dfr = 
1098       BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1099                                 TopoDS::Face(aLocalF),
1100                                 f,l);
1101 //    Handle(Geom2d_Curve) c2dfr = 
1102 //      BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
1103 //                              TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1104 //                              f,l);
1105     
1106     aLocalE = Eto.Oriented(TopAbs_FORWARD);
1107     aLocalF = Fac.Oriented(TopAbs_FORWARD);
1108     Handle(Geom2d_Curve) c2dtf = 
1109       BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1110                                 TopoDS::Face(aLocalF),
1111                                 f,l);
1112
1113 //    Handle(Geom2d_Curve) c2dtf = 
1114 //      BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
1115 //                              TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1116 //                              f,l);
1117     aLocalE = Eto.Oriented(TopAbs_REVERSED);
1118     aLocalF = Fac.Oriented(TopAbs_FORWARD);
1119     Handle(Geom2d_Curve) c2dtr = 
1120       BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1121                                 TopoDS::Face(aLocalF),
1122                                 f,l);
1123 //    Handle(Geom2d_Curve) c2dtr = 
1124 //      BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
1125 //                              TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1126 //                              f,l);
1127
1128     gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
1129     gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
1130
1131     Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
1132
1133     // Efrom et Eto dans le meme sens???
1134
1135     C = BRep_Tool::Curve(Efrom,Loc,f,l);
1136     if (!Loc.IsIdentity()) {
1137       Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1138       C = Handle(Geom_Curve)::DownCast (GG);
1139     }
1140
1141     gp_Pnt pt;
1142     gp_Vec d1f,d1t;
1143
1144     C->D1(f,pt,d1f);
1145
1146
1147     TopoDS_Vertex FirstVertex = TopExp::FirstVertex(Efrom);
1148     Standard_Real vtx_param = BRep_Tool::Parameter(FirstVertex, Efrom);
1149     BRepAdaptor_Curve2d BAcurve2d(Efrom, Fac);
1150     gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
1151
1152     Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),p2d,Eto,Fac);
1153     
1154     C = BRep_Tool::Curve(Eto,Loc,f,l);
1155     if (!Loc.IsIdentity()) {
1156       Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1157       C = Handle(Geom_Curve)::DownCast (GG);
1158     }
1159     
1160     C->D1(prmproj,pt,d1t);
1161
1162     Standard_Real SameOri = (d1t.Dot(d1f)>0.); 
1163
1164
1165     if (c2dff.IsNull() && c2dfr.IsNull()) {
1166       S = BRep_Tool::Surface(Fac);
1167       styp = S->DynamicType();
1168       if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1169         S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
1170         styp = S->DynamicType();
1171       }
1172       
1173       C = BRep_Tool::Curve(Efrom,Loc,f,l);
1174       if (!Loc.IsIdentity()) {
1175         Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1176         C = Handle(Geom_Curve)::DownCast (GG);
1177       }
1178       
1179       if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
1180         C = new Geom_TrimmedCurve(C,f,l);
1181       }
1182
1183       // Compute the tol2d
1184       BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
1185
1186       Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
1187                                 BRep_Tool::Tolerance(Fac));
1188       GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
1189       Standard_Real TolU  = Gas.UResolution(tol3d);
1190       Standard_Real TolV  = Gas.VResolution(tol3d);
1191       Standard_Real tol2d = Max(TolU,TolV);
1192     
1193       Handle(Geom2d_Curve) C2d = 
1194         GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
1195       c2dff = C2d;
1196       c2dfr = C2d;
1197     }
1198     else if (c2dfr.IsNull()) {
1199       c2dfr = c2dff;
1200
1201     }
1202     else if (c2dff.IsNull()) {
1203       c2dff = c2dfr;
1204     }
1205
1206     BRep_Tool::Range(Efrom,f,l);
1207
1208     gp_Pnt2d p2f = c2dff->Value(f);
1209     gp_Pnt2d p2r = c2dfr->Value(f);
1210
1211     if (isoU) {
1212       if (SameOri) {
1213         if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
1214           c2dff = Handle(Geom2d_Curve)::DownCast
1215             (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
1216         }
1217         if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
1218           c2dfr = Handle(Geom2d_Curve)::DownCast
1219             (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
1220         }
1221       }
1222       else {
1223         if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
1224           c2dff = Handle(Geom2d_Curve)::DownCast
1225             (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
1226         }
1227         
1228         if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
1229           c2dfr = Handle(Geom2d_Curve)::DownCast
1230             (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
1231         }
1232       }
1233
1234       // on est bien en U, recalage si periodique en V a faire
1235
1236
1237
1238     }
1239     
1240     else { // !isoU soit isoV
1241       if (SameOri) {
1242         if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
1243           c2dff = Handle(Geom2d_Curve)::DownCast
1244             (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
1245         }
1246         if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
1247           c2dfr = Handle(Geom2d_Curve)::DownCast
1248             (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
1249         }
1250       }
1251       else {
1252         if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
1253           c2dff = Handle(Geom2d_Curve)::DownCast
1254             (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
1255         }
1256         if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
1257           c2dfr = Handle(Geom2d_Curve)::DownCast
1258             (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
1259         }
1260       }
1261       // on est bien en V, recalage si periodique en U a faire
1262
1263     }
1264     B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
1265   }
1266 }
1267
1268 //=======================================================================
1269 //function : FindInternalIntersections
1270 //purpose  : 
1271 //=======================================================================
1272
1273 void FindInternalIntersections(const TopoDS_Edge& theEdge,
1274                                const TopoDS_Face& theFace,
1275                                TopTools_IndexedDataMapOfShapeListOfShape& Splits,
1276                                Standard_Boolean& isOverlapped)
1277 {
1278   Standard_Real TolExt = Precision::PConfusion();
1279   Standard_Integer i, j;
1280
1281   BRepAdaptor_Surface anAdSurf(theFace, Standard_False);
1282   TColStd_SequenceOfReal SplitPars;
1283   
1284   TopoDS_Vertex theVertices [2];
1285   TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
1286   gp_Pnt thePnt [2];
1287   thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
1288   thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
1289   Standard_Real aTolV[2];
1290   aTolV[0] =BRep_Tool::Tolerance(theVertices[0]);
1291   aTolV[1] =BRep_Tool::Tolerance(theVertices[1]);
1292
1293   BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
1294   Bnd_Box2d theBox;
1295   BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
1296
1297   Standard_Real thePar [2];
1298   Standard_Real  aFpar, aLpar;
1299   const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
1300   GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
1301   Standard_Real aDistMax = Precision::Confusion() * Precision::Confusion();
1302   TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1303   for (; Explo.More(); Explo.Next())
1304   {
1305     const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1306     BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
1307     Bnd_Box2d aBox;
1308     BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
1309     if (theBox.IsOut(aBox))
1310       continue;
1311
1312     const Handle(Geom_Curve)& aCurve   = BRep_Tool::Curve(anEdge, aFpar, aLpar);
1313     GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
1314     Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
1315
1316     if (!anExtrema.IsDone() || !anExtrema.NbExt())
1317       continue;
1318    
1319     Standard_Integer aNbExt = anExtrema.NbExt();
1320     Standard_Real MaxTol = BRep_Tool::Tolerance(anEdge);
1321     Standard_Real aMaxTol2 =  MaxTol *  MaxTol;
1322     if (anExtrema.IsParallel() && anExtrema.SquareDistance(1) <= aMaxTol2)
1323     {
1324       isOverlapped = Standard_True;
1325       return;
1326     }
1327     for (i = 1; i <= aNbExt; i++)
1328     {
1329       Standard_Real aDist = anExtrema.SquareDistance(i);
1330       if (aDist > aMaxTol2)
1331         continue;
1332
1333       Extrema_POnCurv aPOnC1, aPOnC2;
1334       anExtrema.Points(i, aPOnC1, aPOnC2);
1335       Standard_Real theIntPar = aPOnC1.Parameter();
1336       Standard_Real anIntPar = aPOnC2.Parameter();
1337       for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
1338       {
1339         if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion())
1340           break;
1341       }
1342       //intersection found in the middle of the edge
1343       if (j >= 2) //intersection is inside "theEdge" => split
1344       {
1345         gp_Pnt aPoint = aCurve->Value(anIntPar);
1346         gp_Pnt aPointInt = theCurve->Value(theIntPar);
1347     
1348         if (aPointInt.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] &&
1349           aPointInt.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1] &&
1350           aPoint.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] &&
1351           aPoint.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1])
1352         {
1353           SplitPars.Append(theIntPar);
1354           if( aDist > aDistMax)
1355             aDistMax = aDist;
1356         }
1357       }
1358     }
1359   }
1360
1361   if (SplitPars.IsEmpty())
1362     return;
1363   
1364   //Sort
1365   for (i = 1; i < SplitPars.Length(); i++)
1366     for (j = i+1; j <= SplitPars.Length(); j++)
1367       if (SplitPars(i) > SplitPars(j))
1368       {
1369         Standard_Real Tmp = SplitPars(i);
1370         SplitPars(i) = SplitPars(j);
1371         SplitPars(j) = Tmp;
1372       }
1373   //Remove repeating points
1374   i = 1;
1375   while (i < SplitPars.Length())
1376   {
1377     gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
1378     gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
1379     if (Pnt1.SquareDistance(Pnt2) <= Precision::Confusion()* Precision::Confusion())
1380       SplitPars.Remove(i+1);
1381     else
1382       i++;
1383   }
1384
1385   //Split
1386   TopTools_ListOfShape NewEdges;
1387   BRep_Builder BB;
1388   
1389   TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
1390   Standard_Real FirstPar = thePar[0], LastPar;
1391   for (i = 1; i <= SplitPars.Length()+1; i++)
1392   {
1393     FirstVertex.Orientation(TopAbs_FORWARD);
1394     if (i <= SplitPars.Length())
1395     {
1396       LastPar = SplitPars(i);
1397       gp_Pnt LastPoint = theCurve->Value(LastPar);
1398       LastVertex = BRepLib_MakeVertex(LastPoint);
1399       BRep_Builder aB;
1400       aB.UpdateVertex(LastVertex, sqrt(aDistMax));
1401     }
1402     else
1403     {
1404       LastPar = thePar[1];
1405       LastVertex = theVertices[1];
1406     }
1407     LastVertex.Orientation(TopAbs_REVERSED);
1408     
1409     TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
1410     TopAbs_Orientation anOrient = aLocalShape.Orientation();
1411     aLocalShape.Orientation(TopAbs_FORWARD);
1412     TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
1413     BB.Range(NewEdge, FirstPar, LastPar);
1414     BB.Add(NewEdge, FirstVertex);
1415     BB.Add(NewEdge, LastVertex);
1416     NewEdge.Orientation(anOrient);
1417     ShapeAnalysis_Edge aSae;
1418     Standard_Real amaxdev =0.;
1419     if (aSae.CheckSameParameter(NewEdge, theFace, amaxdev))
1420     {
1421       BRep_Builder aB;
1422       aB.UpdateEdge(NewEdge, amaxdev);
1423     }
1424
1425     if (anOrient == TopAbs_FORWARD)
1426       NewEdges.Append(NewEdge);
1427     else
1428       NewEdges.Prepend(NewEdge);
1429     FirstVertex = LastVertex;
1430     FirstPar = LastPar;
1431   }
1432
1433   if (!NewEdges.IsEmpty())
1434     Splits.Add(theEdge, NewEdges);
1435 }
1436
1437 //=======================================================================
1438 //function : AddSplittingEdges
1439 //purpose  : 
1440 //=======================================================================
1441
1442 Standard_Boolean LocOpe_WiresOnShape::Add(const TopTools_SequenceOfShape& theEdges)
1443 {
1444   TopTools_SequenceOfShape anEdges;
1445   Bnd_SeqOfBox anEdgeBoxes;
1446   Standard_Integer i = 1, nb = theEdges.Length();
1447   for (; i <= nb; i++)
1448   {
1449     const TopoDS_Shape& aCurSplit = theEdges(i);
1450     TopExp_Explorer anExpE(aCurSplit, TopAbs_EDGE);
1451     for (; anExpE.More(); anExpE.Next())
1452     {
1453       const TopoDS_Shape& aCurE = anExpE.Current();
1454
1455       Bnd_Box aBoxE;
1456       BRepBndLib::AddClose(aCurE, aBoxE);
1457       if (aBoxE.IsVoid())
1458         continue;
1459       Standard_Real aTolE = BRep_Tool::Tolerance(TopoDS::Edge(aCurE));
1460       aBoxE.SetGap(aTolE);
1461       anEdgeBoxes.Append(aBoxE);
1462       anEdges.Append(aCurE);
1463
1464     }
1465   }
1466   TopExp_Explorer anExpFaces(myShape, TopAbs_FACE);
1467   Standard_Integer numF = 1;
1468   TColStd_PackedMapOfInteger anUsedEdges;
1469   for (; anExpFaces.More(); anExpFaces.Next(), numF++)
1470   {
1471     const TopoDS_Face& aCurF = TopoDS::Face(anExpFaces.Current());
1472     Bnd_Box aBoxF;
1473     BRepBndLib::Add(aCurF, aBoxF);
1474     if (aBoxF.IsVoid())
1475       continue;
1476     BRepAdaptor_Surface anAdF(aCurF, Standard_False);
1477     NCollection_Handle<BRepTopAdaptor_FClass2d> aCheckStateTool;
1478
1479     i = 1;
1480     nb = anEdgeBoxes.Length();
1481     for (; i <= nb; i++)
1482     {
1483       if (anUsedEdges.Contains(i))
1484         continue;
1485
1486       if (aBoxF.IsOut(anEdgeBoxes(i)))
1487         continue;
1488
1489       const TopoDS_Edge& aCurE = TopoDS::Edge(anEdges(i));
1490
1491       Standard_Real aF, aL;
1492       Handle(Geom_Curve) aC = BRep_Tool::Curve(aCurE, aF, aL);
1493       if (aC.IsNull())
1494       {
1495         anUsedEdges.Add(i);
1496         continue;
1497       }
1498       gp_Pnt aP = aC->Value((aF + aL)* 0.5);
1499       Extrema_ExtPS anExtr(aP, anAdF, Precision::Confusion(), Precision::Confusion());
1500      
1501       if (!anExtr.IsDone() || !anExtr.NbExt())
1502         continue;
1503       Standard_Real aTolE = BRep_Tool::Tolerance(TopoDS::Edge(aCurE));
1504       Standard_Real aTol2 = (aTolE + Precision::Confusion()) * (aTolE + Precision::Confusion());
1505       Standard_Integer n = 1;
1506       for (; n <= anExtr.NbExt(); n++)
1507       {
1508         Standard_Real aDist2 = anExtr.SquareDistance(n);
1509         if (aDist2 > aTol2)
1510           continue;
1511         const Extrema_POnSurf& aPS = anExtr.Point(n);
1512         Standard_Real aU, aV;
1513         aPS.Parameter(aU, aV);
1514
1515         if (aCheckStateTool.IsNull())
1516         {
1517           aCheckStateTool = new BRepTopAdaptor_FClass2d(aCurF, Precision::PConfusion());
1518         }
1519         if (aCheckStateTool->Perform(gp_Pnt2d(aU, aV)) == TopAbs_IN)
1520         {
1521           Bind(aCurE, aCurF);
1522           anUsedEdges.Add(i);
1523         }
1524         
1525       }
1526     }
1527
1528   }
1529   return !anUsedEdges.IsEmpty();
1530 }