0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[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
75 IMPLEMENT_STANDARD_RTTIEXT(LocOpe_WiresOnShape,MMgt_TShared)
76
77 static Standard_Boolean Project(const TopoDS_Vertex&,
78                                 const gp_Pnt2d&,
79                                 const TopoDS_Face&,
80                                 TopoDS_Edge&,
81                                 Standard_Real&);
82
83 static Standard_Real Project(const TopoDS_Vertex&,
84                              const TopoDS_Edge&);
85
86 static Standard_Real Project(const TopoDS_Vertex&,
87                              const gp_Pnt2d&,
88                              const TopoDS_Edge&,
89                              const TopoDS_Face&);
90
91
92 static void PutPCurve(const TopoDS_Edge&,
93                       const TopoDS_Face&);
94
95
96 static void PutPCurves(const TopoDS_Edge&,
97                        const TopoDS_Edge&,
98                        const TopoDS_Shape&);
99
100 static void FindInternalIntersections(const TopoDS_Edge&,
101                                       const TopoDS_Face&,
102                                       TopTools_IndexedDataMapOfShapeListOfShape&,
103                                       Standard_Boolean&);
104
105 //=======================================================================
106 //function : LocOpe_WiresOnShape
107 //purpose  : 
108 //=======================================================================
109
110 LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
111   myShape(S),myCheckInterior(Standard_True),myDone(Standard_False)
112 {}
113
114 //=======================================================================
115 //function : Init
116 //purpose  : 
117 //=======================================================================
118
119 void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
120 {
121    myShape = S;
122    myCheckInterior = Standard_True;
123    myDone = Standard_False;
124    myMap.Clear();
125    myMapEF.Clear();
126 }
127
128 //=======================================================================
129 //function : Bind
130 //purpose  : 
131 //=======================================================================
132
133 void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
134                                const TopoDS_Face& F)
135 {
136   for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) {
137     Bind(TopoDS::Edge(exp.Current()),F);
138   }
139 }
140
141 //=======================================================================
142 //function : Bind
143 //purpose  : 
144 //=======================================================================
145
146 void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp,
147                                const TopoDS_Face& F)
148 {
149   for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) {
150     Bind(TopoDS::Edge(exp.Current()),F);
151   }
152   myFacesWithSection.Add(F);
153 }
154
155 //=======================================================================
156 //function : Bind
157 //purpose  : 
158 //=======================================================================
159
160 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E,
161                                const TopoDS_Face& F)
162 {
163 //  if (!myMapEF.IsBound(E)) {
164   if (!myMapEF.Contains(E)) {
165 //    for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) {
166     TopExp_Explorer exp(F,TopAbs_EDGE) ;
167     for ( ;exp.More();exp.Next()) {
168       if (exp.Current().IsSame(E)) {
169         break;
170       }
171     }
172     if (!exp.More()) {
173 //      myMapEF.Bind(E,F);
174       myMapEF.Add(E,F);
175     }
176   }
177   else {
178     Standard_ConstructionError::Raise();
179   }
180 }
181
182
183 //=======================================================================
184 //function : Bind
185 //purpose  : 
186 //=======================================================================
187
188 void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir,
189                                const TopoDS_Edge& Efac)
190 {
191   myMap.Bind(Ewir,Efac);
192 }
193
194
195 //=======================================================================
196 //function : BindAll
197 //purpose  : 
198 //=======================================================================
199
200 void LocOpe_WiresOnShape::BindAll()
201 {
202   if (myDone) {
203     return;
204   }
205   TopTools_MapOfShape theMap;
206
207   // Detection des vertex a projeter ou a "binder" avec des vertex existants
208   TopTools_DataMapOfShapeShape mapV;
209   TopTools_DataMapIteratorOfDataMapOfShapeShape ite(myMap);
210   TopExp_Explorer exp,exp2;
211   for (; ite.More(); ite.Next()) {
212     const TopoDS_Edge& eref = TopoDS::Edge(ite.Key());
213     const TopoDS_Edge& eimg = TopoDS::Edge(ite.Value());
214
215     PutPCurves(eref,eimg,myShape);
216
217     for (exp.Init(eref,TopAbs_VERTEX); exp.More(); exp.Next()) {
218       const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
219       if (!theMap.Contains(vtx)) { // pas deja traite
220         for (exp2.Init(eimg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
221           const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
222           if (vtx2.IsSame(vtx)) {
223             break;
224           }
225           else if (BRepTools::Compare(vtx,vtx2)) {
226             mapV.Bind(vtx,vtx2);
227             break;
228           }
229         }
230         if (!exp2.More()) {
231           mapV.Bind(vtx,eimg);
232         }
233         theMap.Add(vtx);
234       }
235     }
236   }
237   
238   for (ite.Initialize(mapV); ite.More(); ite.Next()) {
239     myMap.Bind(ite.Key(),ite.Value());
240   }
241
242   TopTools_IndexedDataMapOfShapeListOfShape Splits;
243   Standard_Integer Ind;
244   TopTools_MapOfShape anOverlappedEdges;
245   for (Ind = 1; Ind <= myMapEF.Extent(); Ind++)
246   {
247     const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
248     const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
249     
250     PutPCurve(edg,fac);
251     Standard_Real pf, pl;
252     Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(edg, fac, pf, pl);
253     if (aPCurve.IsNull())
254       continue;
255
256     if (myCheckInterior)
257     {
258       Standard_Boolean isOverlapped = Standard_False;
259       FindInternalIntersections(edg, fac, Splits, isOverlapped);
260       if(isOverlapped)
261         anOverlappedEdges.Add(edg);
262     }
263   }
264
265   for (Ind = 1; Ind <= Splits.Extent(); Ind++)
266   {
267     TopoDS_Shape anEdge = Splits.FindKey(Ind);
268     if(anOverlappedEdges.Contains(anEdge))
269       continue;
270     TopoDS_Shape aFace  = myMapEF.FindFromKey(anEdge);
271     //Remove "anEdge" from "myMapEF"
272     TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent());
273     TopoDS_Shape LastFace = myMapEF(myMapEF.Extent());
274     myMapEF.RemoveLast();
275     if (myMapEF.FindIndex(anEdge) != 0)
276       myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace);
277     ////////////////////////////////
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 aDist3d = p2d.Distance(aPBound2d) / Min(anUResolution, aVResolution);
617
618       gp_Pnt aPBound;
619       aSurf->D0(aPBound2d.X(), aPBound2d.Y(), aPBound);
620       gp_Pnt aPV2d;
621       aSurf->D0(p2d.X(), p2d.Y(), aPV2d);
622       Standard_Real aDistPoints_3D = aPV2d.SquareDistance(aPBound);
623       Standard_Real aDist2d = Max(aDistPoints_3D, aDist3d * aDist3d);
624
625       BRep_Builder B;
626       if (aTolV * aTolV < aDist2d)
627       {
628         Standard_Real aNewTol = sqrt(aDist2d) + Precision::Confusion();
629         B.UpdateVertex(V, aNewTol);
630       }
631     }
632   }
633 #ifdef OCCT_DEBUG_MESH
634   else {
635     cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une "; 
636     cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
637   }
638 #endif
639   return valret;
640 }
641
642 //=======================================================================
643 //function : Project
644 //purpose  : 
645 //=======================================================================
646
647 Standard_Real Project(const TopoDS_Vertex& V,
648                       const TopoDS_Edge& theEdge)
649 {
650   Handle(Geom_Curve) C;
651   TopLoc_Location Loc;
652   Standard_Real f,l;
653
654   gp_Pnt toproj(BRep_Tool::Pnt(V));
655   GeomAPI_ProjectPointOnCurve proj;
656
657   C = BRep_Tool::Curve(theEdge,Loc,f,l);
658   if (!Loc.IsIdentity()) {
659     Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
660     C = Handle(Geom_Curve)::DownCast (GG);
661   }
662   proj.Init(toproj,C,f,l);
663   
664
665
666   return (proj.NbPoints() > 0 ? proj.LowerDistanceParameter() : Precision::Infinite());
667 }
668
669 //=======================================================================
670 //function : Project
671 //purpose  : 
672 //=======================================================================
673
674 Standard_Real Project(const TopoDS_Vertex&,
675                       const gp_Pnt2d&      p2d,
676                       const TopoDS_Edge& theEdge,
677                       const TopoDS_Face& theFace)
678 {
679
680   
681   Handle(Geom2d_Curve) PC;
682  
683   Standard_Real f, l;
684
685   Geom2dAPI_ProjectPointOnCurve proj;
686
687   PC = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
688   
689   proj.Init(p2d, PC, f, l);
690
691   return proj.NbPoints() > 0 ? proj.LowerDistanceParameter() : Precision::Infinite();
692 }
693
694
695 //=======================================================================
696 //function : PutPCurve
697 //purpose  : 
698 //=======================================================================
699
700 void PutPCurve(const TopoDS_Edge& Edg,
701                const TopoDS_Face& Fac)
702 {
703   BRep_Builder B;
704   TopLoc_Location LocFac;
705
706   Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
707   Handle(Standard_Type) styp = S->DynamicType();
708
709   if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
710     S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
711     styp = S->DynamicType();
712   }
713
714   if (styp == STANDARD_TYPE(Geom_Plane)) {
715     return;
716   }
717
718   Standard_Real Umin,Umax,Vmin,Vmax;
719   BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
720
721   Standard_Real f,l;
722
723   Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
724   if ( !aC2d.IsNull() ) {
725     gp_Pnt2d p2d;
726     aC2d->D0((f + l) *0.5, p2d);
727     Standard_Boolean IsIn = Standard_True;
728     if ( ( p2d.X() < Umin-Precision::PConfusion() ) || 
729          ( p2d.X() > Umax+Precision::PConfusion() ) )
730       IsIn = Standard_False;
731     if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) || 
732          ( p2d.Y() > Vmax+Precision::PConfusion() ) )
733       IsIn = Standard_False;
734  
735     if (IsIn)
736       return;
737   }
738
739   TopLoc_Location Loc;
740   Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
741   if (!Loc.IsIdentity()) {
742     Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
743     C = Handle(Geom_Curve)::DownCast (GG);
744   }
745
746   if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
747     C = new Geom_TrimmedCurve(C,f,l);
748   }
749
750   S = BRep_Tool::Surface(Fac);
751
752   Standard_Real tol2d = Precision::Confusion();
753   Handle(Geom2d_Curve) C2d;
754   ShapeConstruct_ProjectCurveOnSurface aToolProj;
755   aToolProj.Init(S, tol2d);
756
757   aToolProj.Perform(C,f,l, C2d);
758   if (C2d.IsNull())
759   {
760     return;
761   }
762  
763   gp_Pnt2d pf(C2d->Value(f));
764   gp_Pnt2d pl(C2d->Value(l));
765   gp_Pnt PF,PL;
766   S->D0(pf.X(),pf.Y(),PF);
767   S->D0(pl.X(),pl.Y(),PL);
768   TopoDS_Vertex V1,V2;
769   if (Edg.Orientation() == TopAbs_REVERSED) {
770     V1 = TopExp::LastVertex(Edg);
771     V1.Reverse();
772   }
773   else {
774     V1 = TopExp::FirstVertex (Edg);
775   }
776   if (Edg.Orientation() == TopAbs_REVERSED) {
777     V2 = TopExp::FirstVertex(Edg);
778     V2.Reverse();
779   }
780   else {
781     V2 = TopExp::LastVertex (Edg);
782   }
783
784   if(!V1.IsNull() && V2.IsNull()) {
785     //Handling of internal vertices
786     Standard_Real old1 = BRep_Tool::Tolerance (V1);
787     Standard_Real old2 = BRep_Tool::Tolerance (V2);
788     gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
789     gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
790     Standard_Real tol1 = pnt1.Distance(PF);
791     Standard_Real tol2 = pnt2.Distance(PL);
792     B.UpdateVertex(V1,Max(old1,tol1));
793     B.UpdateVertex(V2,Max(old2,tol2));
794   }
795
796   if (S->IsUPeriodic()) {
797     Standard_Real up   = S->UPeriod();
798     Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
799     Standard_Integer nbtra = 0;
800     Standard_Real theUmin = Min(pf.X(),pl.X());
801     Standard_Real theUmax = Max(pf.X(),pl.X());
802
803     if (theUmin < Umin-tolu) {
804       while (theUmin < Umin-tolu) {
805         theUmin += up;
806         nbtra++;
807       }
808     }
809     else if (theUmax > Umax+tolu) {
810       while (theUmax > Umax+tolu) {
811         theUmax -= up;
812         nbtra--;
813       }
814     }
815
816     if (nbtra !=0) {
817       C2d->Translate(gp_Vec2d(nbtra*up,0.));
818     }
819   }    
820
821   if (S->IsVPeriodic()) {
822     Standard_Real vp   = S->VPeriod();
823     Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
824     Standard_Integer nbtra = 0;
825     Standard_Real theVmin = Min(pf.Y(),pl.Y());
826     Standard_Real theVmax = Max(pf.Y(),pl.Y());
827
828     if (theVmin < Vmin-tolv) {
829       while (theVmin < Vmin-tolv) {
830         theVmin += vp; theVmax += vp;
831         nbtra++;
832       }
833     }
834     else if (theVmax > Vmax+tolv) {
835       while (theVmax > Vmax+tolv) {
836         theVmax -= vp; theVmin -= vp;
837         nbtra--;
838       }
839     }
840
841     if (nbtra !=0) {
842       C2d->Translate(gp_Vec2d(0.,nbtra*vp));
843     }
844   }
845   B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
846   
847   B.SameParameter(Edg,Standard_False);
848   BRepLib::SameParameter(Edg,tol2d); 
849 }
850
851
852 //=======================================================================
853 //function : PutPCurves
854 //purpose  : 
855 //=======================================================================
856
857 void PutPCurves(const TopoDS_Edge& Efrom,
858                 const TopoDS_Edge& Eto,
859                 const TopoDS_Shape& myShape)
860 {
861
862   TopTools_ListOfShape Lfaces;
863   TopExp_Explorer exp,exp2;
864
865   for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
866     for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
867       if (exp2.Current().IsSame(Eto)) {
868         Lfaces.Append(exp.Current());
869       }
870     }
871   }
872
873   if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
874     Standard_ConstructionError::Raise();
875   }
876
877   // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
878
879   if (Lfaces.Extent() ==1) {
880     return; // sera fait par PutPCurve.... on l`espere
881   }
882
883   BRep_Builder B;
884   Handle(Geom_Surface) S;
885   Handle(Standard_Type) styp;
886   Handle(Geom_Curve) C;
887   Standard_Real Umin,Umax,Vmin,Vmax;
888   Standard_Real f,l;
889   TopLoc_Location Loc, LocFac;
890
891   if (!Lfaces.First().IsSame(Lfaces.Last())) {
892     TopTools_ListIteratorOfListOfShape itl(Lfaces);
893     for (; itl.More(); itl.Next()) {
894       const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
895
896       if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
897         continue;
898       }
899       S = BRep_Tool::Surface(Fac, LocFac);
900       styp = S->DynamicType();
901       if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
902         S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
903         styp = S->DynamicType();
904       }
905       if (styp == STANDARD_TYPE(Geom_Plane)) {
906         continue;
907       }
908
909             
910       BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
911       C = BRep_Tool::Curve(Efrom,Loc,f,l);
912       if (!Loc.IsIdentity()) {
913         Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
914         C = Handle(Geom_Curve)::DownCast (GG);
915       }
916       
917       if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
918         C = new Geom_TrimmedCurve(C,f,l);
919       }
920     
921       S = BRep_Tool::Surface(Fac);
922
923       // Compute the tol2d
924       Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
925                                 BRep_Tool::Tolerance(Fac));
926       GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
927       Standard_Real TolU  = Gas.UResolution(tol3d);
928       Standard_Real TolV  = Gas.VResolution(tol3d);
929       Standard_Real tol2d = Max(TolU,TolV);
930
931       Handle(Geom2d_Curve) C2d = 
932         GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
933      if(C2d.IsNull())
934        return;
935
936       gp_Pnt2d pf(C2d->Value(f));
937       gp_Pnt2d pl(C2d->Value(l));
938       
939       if (S->IsUPeriodic()) {
940         Standard_Real up   = S->UPeriod();
941         Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
942         Standard_Integer nbtra = 0;
943         Standard_Real theUmin = Min(pf.X(),pl.X());
944         Standard_Real theUmax = Max(pf.X(),pl.X());
945
946         if (theUmin < Umin-tolu) {
947           while (theUmin < Umin-tolu) {
948             theUmin += up; theUmax += up;
949             nbtra++;
950           }
951         }
952         else if (theUmax > Umax+tolu) {
953           while (theUmax > Umax+tolu) {
954             theUmax -= up; theUmin -= up;
955             nbtra--;
956           }
957         }
958 /*
959         if (theUmin > Umax+tolu) {
960           while (theUmin > Umax+tolu) {
961             theUmin -= up;
962             nbtra--;
963           }
964         }
965         else if (theUmax < Umin-tolu) {
966           while (theUmax < Umin-tolu) {
967             theUmax += up;
968             nbtra++;
969           }
970         }
971 */
972         if (nbtra !=0) {
973           C2d->Translate(gp_Vec2d(nbtra*up,0.));
974         }
975       }    
976       
977       if (S->IsVPeriodic()) {
978         Standard_Real vp   = S->VPeriod();
979         Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
980         Standard_Integer nbtra = 0;
981         Standard_Real theVmin = Min(pf.Y(),pl.Y());
982         Standard_Real theVmax = Max(pf.Y(),pl.Y());
983
984         if (theVmin < Vmin-tolv) {
985           while (theVmin < Vmin-tolv) {
986             theVmin += vp; theVmax += vp;
987             nbtra++;
988           }
989         }
990         else if (theVmax > Vmax+tolv) {
991           while (theVmax > Vmax+tolv) {
992             theVmax -= vp; theVmin -= vp;
993             nbtra--;
994           }
995         }
996 /*
997         if (theVmin > Vmax+tolv) {
998           while (theVmin > Vmax+tolv) {
999             theVmin -= vp;
1000             nbtra--;
1001           }
1002         }
1003         else if (theVmax < Vmin-tolv) {
1004           while (theVmax < Vmin-tolv) {
1005             theVmax += vp;
1006             nbtra++;
1007           }
1008         }
1009 */
1010         if (nbtra !=0) {
1011           C2d->Translate(gp_Vec2d(0.,nbtra*vp));
1012         }
1013       }
1014       B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
1015     }
1016   }
1017
1018   else {
1019     const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
1020     if (!BRep_Tool::IsClosed(Eto,Fac)) {
1021       Standard_ConstructionError::Raise();
1022     }
1023
1024     TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
1025     TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
1026     Handle(Geom2d_Curve) c2dff = 
1027       BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1028                                 TopoDS::Face(aLocalF),
1029                                 f,l);
1030
1031 //    Handle(Geom2d_Curve) c2dff = 
1032 //      BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
1033 //                              TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1034 //                              f,l);
1035     
1036     aLocalE = Efrom.Oriented(TopAbs_REVERSED);
1037     aLocalF = Fac.Oriented(TopAbs_FORWARD);
1038     Handle(Geom2d_Curve) c2dfr = 
1039       BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1040                                 TopoDS::Face(aLocalF),
1041                                 f,l);
1042 //    Handle(Geom2d_Curve) c2dfr = 
1043 //      BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
1044 //                              TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1045 //                              f,l);
1046     
1047     aLocalE = Eto.Oriented(TopAbs_FORWARD);
1048     aLocalF = Fac.Oriented(TopAbs_FORWARD);
1049     Handle(Geom2d_Curve) c2dtf = 
1050       BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1051                                 TopoDS::Face(aLocalF),
1052                                 f,l);
1053
1054 //    Handle(Geom2d_Curve) c2dtf = 
1055 //      BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
1056 //                              TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1057 //                              f,l);
1058     aLocalE = Eto.Oriented(TopAbs_REVERSED);
1059     aLocalF = Fac.Oriented(TopAbs_FORWARD);
1060     Handle(Geom2d_Curve) c2dtr = 
1061       BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
1062                                 TopoDS::Face(aLocalF),
1063                                 f,l);
1064 //    Handle(Geom2d_Curve) c2dtr = 
1065 //      BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
1066 //                              TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
1067 //                              f,l);
1068
1069     gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
1070     gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
1071
1072     Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
1073
1074     // Efrom et Eto dans le meme sens???
1075
1076     C = BRep_Tool::Curve(Efrom,Loc,f,l);
1077     if (!Loc.IsIdentity()) {
1078       Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1079       C = Handle(Geom_Curve)::DownCast (GG);
1080     }
1081
1082     gp_Pnt pt;
1083     gp_Vec d1f,d1t;
1084
1085     C->D1(f,pt,d1f);
1086
1087
1088     TopoDS_Vertex FirstVertex = TopExp::FirstVertex(Efrom);
1089     Standard_Real vtx_param = BRep_Tool::Parameter(FirstVertex, Efrom);
1090     BRepAdaptor_Curve2d BAcurve2d(Efrom, Fac);
1091     gp_Pnt2d p2d = BAcurve2d.Value(vtx_param);
1092
1093     Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),p2d,Eto,Fac);
1094     
1095     C = BRep_Tool::Curve(Eto,Loc,f,l);
1096     if (!Loc.IsIdentity()) {
1097       Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1098       C = Handle(Geom_Curve)::DownCast (GG);
1099     }
1100     
1101     C->D1(prmproj,pt,d1t);
1102
1103     Standard_Real SameOri = (d1t.Dot(d1f)>0.); 
1104
1105
1106     if (c2dff.IsNull() && c2dfr.IsNull()) {
1107       S = BRep_Tool::Surface(Fac);
1108       styp = S->DynamicType();
1109       if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1110         S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
1111         styp = S->DynamicType();
1112       }
1113       
1114       C = BRep_Tool::Curve(Efrom,Loc,f,l);
1115       if (!Loc.IsIdentity()) {
1116         Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
1117         C = Handle(Geom_Curve)::DownCast (GG);
1118       }
1119       
1120       if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
1121         C = new Geom_TrimmedCurve(C,f,l);
1122       }
1123
1124       // Compute the tol2d
1125       BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
1126
1127       Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
1128                                 BRep_Tool::Tolerance(Fac));
1129       GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
1130       Standard_Real TolU  = Gas.UResolution(tol3d);
1131       Standard_Real TolV  = Gas.VResolution(tol3d);
1132       Standard_Real tol2d = Max(TolU,TolV);
1133     
1134       Handle(Geom2d_Curve) C2d = 
1135         GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
1136       c2dff = C2d;
1137       c2dfr = C2d;
1138     }
1139     else if (c2dfr.IsNull()) {
1140       c2dfr = c2dff;
1141
1142     }
1143     else if (c2dff.IsNull()) {
1144       c2dff = c2dfr;
1145     }
1146
1147     BRep_Tool::Range(Efrom,f,l);
1148
1149     gp_Pnt2d p2f = c2dff->Value(f);
1150     gp_Pnt2d p2r = c2dfr->Value(f);
1151
1152     if (isoU) {
1153       if (SameOri) {
1154         if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
1155           c2dff = Handle(Geom2d_Curve)::DownCast
1156             (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
1157         }
1158         if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
1159           c2dfr = Handle(Geom2d_Curve)::DownCast
1160             (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
1161         }
1162       }
1163       else {
1164         if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
1165           c2dff = Handle(Geom2d_Curve)::DownCast
1166             (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
1167         }
1168         
1169         if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
1170           c2dfr = Handle(Geom2d_Curve)::DownCast
1171             (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
1172         }
1173       }
1174
1175       // on est bien en U, recalage si periodique en V a faire
1176
1177
1178
1179     }
1180     
1181     else { // !isoU soit isoV
1182       if (SameOri) {
1183         if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
1184           c2dff = Handle(Geom2d_Curve)::DownCast
1185             (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
1186         }
1187         if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
1188           c2dfr = Handle(Geom2d_Curve)::DownCast
1189             (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
1190         }
1191       }
1192       else {
1193         if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
1194           c2dff = Handle(Geom2d_Curve)::DownCast
1195             (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
1196         }
1197         if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
1198           c2dfr = Handle(Geom2d_Curve)::DownCast
1199             (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
1200         }
1201       }
1202       // on est bien en V, recalage si periodique en U a faire
1203
1204     }
1205     B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
1206   }
1207 }
1208
1209 //=======================================================================
1210 //function : FindInternalIntersections
1211 //purpose  : 
1212 //=======================================================================
1213
1214 void FindInternalIntersections(const TopoDS_Edge& theEdge,
1215                                const TopoDS_Face& theFace,
1216                                TopTools_IndexedDataMapOfShapeListOfShape& Splits,
1217                                Standard_Boolean& isOverlapped)
1218 {
1219   Standard_Real TolExt = Precision::PConfusion();
1220   Standard_Integer i, j;
1221
1222   BRepAdaptor_Surface anAdSurf(theFace, Standard_False);
1223   TColStd_SequenceOfReal SplitPars;
1224   
1225   TopoDS_Vertex theVertices [2];
1226   TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
1227   gp_Pnt thePnt [2];
1228   thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
1229   thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
1230   Standard_Real aTolV[2];
1231   aTolV[0] =BRep_Tool::Tolerance(theVertices[0]);
1232   aTolV[1] =BRep_Tool::Tolerance(theVertices[1]);
1233
1234   BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
1235   Bnd_Box2d theBox;
1236   BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
1237
1238   Standard_Real thePar [2];
1239   Standard_Real  aFpar, aLpar;
1240   const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
1241   GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
1242   Standard_Real aDistMax = Precision::Confusion() * Precision::Confusion();
1243   TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1244   for (; Explo.More(); Explo.Next())
1245   {
1246     const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1247     BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
1248     Bnd_Box2d aBox;
1249     BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
1250     if (theBox.IsOut(aBox))
1251       continue;
1252
1253     const Handle(Geom_Curve)& aCurve   = BRep_Tool::Curve(anEdge, aFpar, aLpar);
1254     GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
1255     Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
1256
1257     if (!anExtrema.IsDone() || !anExtrema.NbExt())
1258       continue;
1259    
1260     Standard_Integer aNbExt = anExtrema.NbExt();
1261     Standard_Real MaxTol = BRep_Tool::Tolerance(anEdge);
1262     Standard_Real aMaxTol2 =  MaxTol *  MaxTol;
1263     if (anExtrema.IsParallel() && anExtrema.SquareDistance(1) <= aMaxTol2)
1264     {
1265       isOverlapped = Standard_True;
1266       return;
1267     }
1268     for (i = 1; i <= aNbExt; i++)
1269     {
1270       Standard_Real aDist = anExtrema.SquareDistance(i);
1271       if (aDist > aMaxTol2)
1272         continue;
1273
1274       Extrema_POnCurv aPOnC1, aPOnC2;
1275       anExtrema.Points(i, aPOnC1, aPOnC2);
1276       Standard_Real theIntPar = aPOnC1.Parameter();
1277       Standard_Real anIntPar = aPOnC2.Parameter();
1278       for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
1279       {
1280         if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion())
1281           break;
1282       }
1283       //intersection found in the middle of the edge
1284       if (j >= 2) //intersection is inside "theEdge" => split
1285       {
1286         gp_Pnt aPoint = aCurve->Value(anIntPar);
1287         gp_Pnt aPointInt = theCurve->Value(theIntPar);
1288     
1289         if (aPointInt.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] &&
1290           aPointInt.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1] &&
1291           aPoint.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] &&
1292           aPoint.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1])
1293         {
1294           SplitPars.Append(theIntPar);
1295           if( aDist > aDistMax)
1296             aDistMax = aDist;
1297         }
1298       }
1299     }
1300   }
1301
1302   if (SplitPars.IsEmpty())
1303     return;
1304   
1305   //Sort
1306   for (i = 1; i < SplitPars.Length(); i++)
1307     for (j = i+1; j <= SplitPars.Length(); j++)
1308       if (SplitPars(i) > SplitPars(j))
1309       {
1310         Standard_Real Tmp = SplitPars(i);
1311         SplitPars(i) = SplitPars(j);
1312         SplitPars(j) = Tmp;
1313       }
1314   //Remove repeating points
1315   i = 1;
1316   while (i < SplitPars.Length())
1317   {
1318     gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
1319     gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
1320     if (Pnt1.SquareDistance(Pnt2) <= Precision::Confusion()* Precision::Confusion())
1321       SplitPars.Remove(i+1);
1322     else
1323       i++;
1324   }
1325
1326   //Split
1327   TopTools_ListOfShape NewEdges;
1328   BRep_Builder BB;
1329   
1330   TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
1331   Standard_Real FirstPar = thePar[0], LastPar;
1332   for (i = 1; i <= SplitPars.Length()+1; i++)
1333   {
1334     FirstVertex.Orientation(TopAbs_FORWARD);
1335     if (i <= SplitPars.Length())
1336     {
1337       LastPar = SplitPars(i);
1338       gp_Pnt LastPoint = theCurve->Value(LastPar);
1339       LastVertex = BRepLib_MakeVertex(LastPoint);
1340       BRep_Builder aB;
1341       aB.UpdateVertex(LastVertex, sqrt(aDistMax));
1342     }
1343     else
1344     {
1345       LastPar = thePar[1];
1346       LastVertex = theVertices[1];
1347     }
1348     LastVertex.Orientation(TopAbs_REVERSED);
1349     
1350     TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
1351     TopAbs_Orientation anOrient = aLocalShape.Orientation();
1352     aLocalShape.Orientation(TopAbs_FORWARD);
1353     TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
1354     BB.Range(NewEdge, FirstPar, LastPar);
1355     BB.Add(NewEdge, FirstVertex);
1356     BB.Add(NewEdge, LastVertex);
1357     NewEdge.Orientation(anOrient);
1358     ShapeAnalysis_Edge aSae;
1359     Standard_Real amaxdev =0.;
1360     if (aSae.CheckSameParameter(NewEdge, theFace, amaxdev))
1361     {
1362       BRep_Builder aB;
1363       aB.UpdateEdge(NewEdge, amaxdev);
1364     }
1365
1366     if (anOrient == TopAbs_FORWARD)
1367       NewEdges.Append(NewEdge);
1368     else
1369       NewEdges.Prepend(NewEdge);
1370     FirstVertex = LastVertex;
1371     FirstPar = LastPar;
1372   }
1373
1374   if (!NewEdges.IsEmpty())
1375     Splits.Add(theEdge, NewEdges);
1376 }
1377
1378 //=======================================================================
1379 //function : AddSplittingEdges
1380 //purpose  : 
1381 //=======================================================================
1382
1383 Standard_Boolean LocOpe_WiresOnShape::Add(const TopTools_SequenceOfShape& theEdges)
1384 {
1385   TopTools_SequenceOfShape anEdges;
1386   Bnd_SeqOfBox anEdgeBoxes;
1387   Standard_Integer i = 1, nb = theEdges.Length();
1388   for (; i <= nb; i++)
1389   {
1390     const TopoDS_Shape& aCurSplit = theEdges(i);
1391     TopExp_Explorer anExpE(aCurSplit, TopAbs_EDGE);
1392     for (; anExpE.More(); anExpE.Next())
1393     {
1394       const TopoDS_Shape& aCurE = anExpE.Current();
1395
1396       Bnd_Box aBoxE;
1397       BRepBndLib::AddClose(aCurE, aBoxE);
1398       if (aBoxE.IsVoid())
1399         continue;
1400       Standard_Real aTolE = BRep_Tool::Tolerance(TopoDS::Edge(aCurE));
1401       aBoxE.SetGap(aTolE);
1402       anEdgeBoxes.Append(aBoxE);
1403       anEdges.Append(aCurE);
1404
1405     }
1406   }
1407   TopExp_Explorer anExpFaces(myShape, TopAbs_FACE);
1408   Standard_Integer numF = 1;
1409   TColStd_PackedMapOfInteger anUsedEdges;
1410   for (; anExpFaces.More(); anExpFaces.Next(), numF++)
1411   {
1412     const TopoDS_Face& aCurF = TopoDS::Face(anExpFaces.Current());
1413     Bnd_Box aBoxF;
1414     BRepBndLib::Add(aCurF, aBoxF);
1415     if (aBoxF.IsVoid())
1416       continue;
1417     BRepAdaptor_Surface anAdF(aCurF, Standard_False);
1418     NCollection_Handle<BRepTopAdaptor_FClass2d> aCheckStateTool;
1419
1420     i = 1;
1421     nb = anEdgeBoxes.Length();
1422     for (; i <= nb; i++)
1423     {
1424       if (anUsedEdges.Contains(i))
1425         continue;
1426
1427       if (aBoxF.IsOut(anEdgeBoxes(i)))
1428         continue;
1429
1430       const TopoDS_Edge& aCurE = TopoDS::Edge(anEdges(i));
1431
1432       Standard_Real aF, aL;
1433       Handle(Geom_Curve) aC = BRep_Tool::Curve(aCurE, aF, aL);
1434       if (aC.IsNull())
1435       {
1436         anUsedEdges.Add(i);
1437         continue;
1438       }
1439       gp_Pnt aP = aC->Value((aF + aL)* 0.5);
1440       Extrema_ExtPS anExtr(aP, anAdF, Precision::Confusion(), Precision::Confusion());
1441      
1442       if (!anExtr.IsDone() || !anExtr.NbExt())
1443         continue;
1444       Standard_Real aTolE = BRep_Tool::Tolerance(TopoDS::Edge(aCurE));
1445       Standard_Real aTol2 = (aTolE + Precision::Confusion()) * (aTolE + Precision::Confusion());
1446       Standard_Integer n = 1;
1447       for (; n <= anExtr.NbExt(); n++)
1448       {
1449         Standard_Real aDist2 = anExtr.SquareDistance(n);
1450         if (aDist2 > aTol2)
1451           continue;
1452         const Extrema_POnSurf& aPS = anExtr.Point(n);
1453         Standard_Real aU, aV;
1454         aPS.Parameter(aU, aV);
1455
1456         if (aCheckStateTool.IsNull())
1457         {
1458           aCheckStateTool = new BRepTopAdaptor_FClass2d(aCurF, Precision::PConfusion());
1459         }
1460         if (aCheckStateTool->Perform(gp_Pnt2d(aU, aV)) == TopAbs_IN)
1461         {
1462           Bind(aCurE, aCurF);
1463           anUsedEdges.Add(i);
1464         }
1465         
1466       }
1467     }
1468
1469   }
1470   return !anUsedEdges.IsEmpty();
1471 }