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