1 // Created on: 1996-01-09
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 #include <LocOpe_Generator.hxx>
18 
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAlgo_Loop.hxx>
22 #include <BRepTools.hxx>
23 #include <ElCLib.hxx>
24 #include <Geom2d_Curve.hxx>
25 #include <Geom_Circle.hxx>
26 #include <Geom_Curve.hxx>
27 #include <Geom_CylindricalSurface.hxx>
28 #include <Geom_Line.hxx>
29 #include <Geom_Plane.hxx>
30 #include <Geom_RectangularTrimmedSurface.hxx>
31 #include <Geom_Surface.hxx>
32 #include <Geom_TrimmedCurve.hxx>
33 #include <GeomProjLib.hxx>
34 #include <gp_Cylinder.hxx>
35 #include <gp_Pln.hxx>
36 #include <LocOpe_BuildShape.hxx>
37 #include <LocOpe_GeneratedShape.hxx>
38 #include <Precision.hxx>
39 #include <Standard_NoSuchObject.hxx>
40 #include <Standard_NullObject.hxx>
41 #include <StdFail_NotDone.hxx>
42 #include <TopExp.hxx>
43 #include <TopExp_Explorer.hxx>
44 #include <TopoDS.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Face.hxx>
47 #include <TopoDS_Iterator.hxx>
48 #include <TopoDS_Shape.hxx>
49 #include <TopoDS_Solid.hxx>
50 #include <TopoDS_Vertex.hxx>
51 #include <TopoDS_Wire.hxx>
52 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
53 #include <TopTools_DataMapOfShapeListOfShape.hxx>
54 #include <TopTools_DataMapOfShapeShape.hxx>
55 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
57 #include <TopTools_MapIteratorOfMapOfShape.hxx>
58 #include <TopTools_MapOfShape.hxx>
59 
60 static Standard_Boolean ToFuse(const TopoDS_Face& ,
61 			       const TopoDS_Face&);
62 
63 
64 static Standard_Boolean ToFuse(const TopoDS_Edge& ,
65 			       const TopoDS_Edge&);
66 
67 
68 static Standard_Boolean ToFuse(const TopoDS_Edge&,
69 			       const TopoDS_Face&,
70 			       const TopoDS_Vertex&,
71 			       const TopTools_MapOfShape&);
72 
73 static Standard_Real NewParameter(const TopoDS_Edge&,
74 				  const TopoDS_Vertex&,
75 				  const TopoDS_Edge&,
76 				  const TopoDS_Vertex&);
77 
78 
79 //=======================================================================
80 //function : Perform
81 //purpose  :
82 //=======================================================================
83 
Perform(const Handle (LocOpe_GeneratedShape)& G)84 void LocOpe_Generator::Perform(const Handle(LocOpe_GeneratedShape)& G)
85 {
86   if (myShape.IsNull()) {
87     throw Standard_NullObject();
88   }
89   myDone = Standard_False;
90   myRes.Nullify();
91 //  myDescFaces.Clear();
92   myModShapes.Clear();
93 //  myFFromE.Clear();
94 
95   const TopTools_ListOfShape& ledges = G->GeneratingEdges();
96 
97   // On genere une liste des faces a gauche du wire. Equivalent du LeftOf.
98   // Attention : il faudra bien propager pour ne pas oublier des faces
99   // a l`interieur
100 
101   TopExp_Explorer exp, exp2, exp3;
102   TopTools_MapOfShape theLeft; // Faces a gauche
103 
104   TopTools_MapOfShape GEdg,GVtx; // Edges et vertex generateurs
105 
106   TopTools_ListIteratorOfListOfShape itl,itl2;
107 
108 
109   for (itl.Initialize(ledges); itl.More(); itl.Next()) {
110     const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
111 
112     GEdg.Add(edg);
113     for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
114       const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
115       if (!GVtx.Contains(vtx)) {
116 	GVtx.Add(vtx);
117       }
118     }
119     for (exp2.Init(myShape, TopAbs_FACE); exp2.More(); exp2.Next()) {
120       const TopoDS_Face& fac = TopoDS::Face(exp2.Current());
121       for (exp3.Init(fac,TopAbs_EDGE); exp3.More(); exp3.Next()) {
122 	if (exp3.Current().IsSame(edg) &&
123 	    exp3.Current().Orientation() == edg.Orientation()) {
124 	  theLeft.Add(fac);
125 	  TopTools_ListOfShape emptylist;
126 	  if(!myModShapes.IsBound(fac)) {
127 	    myModShapes.Bind(fac,emptylist);
128 	  }
129 	  break;
130 	}
131       }
132       if (exp3.More()) {
133 	break;
134       }
135     }
136   }
137 
138   TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
139   TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,theEFMap);
140 
141   TopTools_DataMapOfShapeListOfShape theEEMap;
142   TopTools_DataMapOfShapeListOfShape theFFMap;
143   TopTools_MapOfShape toRemove;
144   TopTools_MapIteratorOfMapOfShape itm;
145   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itf;
146 
147   // recherche des fusions de faces
148   for (itm.Initialize(GEdg); itm.More(); itm.Next()) {
149     const TopoDS_Edge& edg = TopoDS::Edge(itm.Key());
150     if (!theEFMap.Contains(edg)) {
151       continue;
152     }
153     for (itl2.Initialize(theEFMap.FindFromKey(edg));itl2.More();itl2.Next()){
154       if (!theLeft.Contains(itl2.Value())) {
155 	break;
156       }
157     }
158     if (!itl2.More()) { // edge "interne" au shell, ou bord libre
159     }
160     else {
161       const TopoDS_Face& fac = TopoDS::Face(itl2.Value());
162       TopoDS_Face facbis = G->Generated(edg);
163       if (ToFuse(fac,facbis)) {
164 	// On recherche si une face a deja fusionne avec facbis
165 	Standard_Boolean facbisfound = Standard_False;
166 	for (itf.Initialize(theFFMap); itf.More(); itf.Next()) {
167 	  if (itf.Key().IsSame(fac)) {
168 	    continue;
169 	  }
170 	  for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
171 	    if (itl.Value().IsSame(facbis)) {
172 	      facbisfound = Standard_True;
173 	      break;
174 	    }
175 	  }
176 	  if (facbisfound) {
177 	    theFFMap(itf.Key()).Append(fac);
178 	    toRemove.Add(fac);
179 	    toRemove.Add(edg);
180 	    break;
181 	  }
182 	}
183 
184 	if (!facbisfound) {
185 	  if (!theFFMap.IsBound(fac)) {
186             TopTools_ListOfShape thelist;
187  	    theFFMap.Bind(fac, thelist);
188 	  }
189 	  for (itl.Initialize(theFFMap(fac)); itl.More(); itl.Next()) {
190 	    if (itl.Value().IsSame(facbis)) {
191 	      break;
192 	    }
193 	  }
194 	  if (!itl.More()) {
195 	    theFFMap(fac).Append(facbis);
196 	  }
197 	  toRemove.Add(edg);
198 	  toRemove.Add(facbis);
199 	}
200       }
201       else { // face generee par edg : on la marque.
202 //	myFFromE.Bind(edg,facbis);
203       }
204     }
205   }
206 
207 
208   // Il faut ici ajouter dans toRemove les edges de connexites entre faces
209   // a fusionner avec une meme face de base
210 
211 //  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itf(theFFMap);
212   itf.Initialize(theFFMap);
213   for (; itf.More(); itf.Next()) {
214     for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
215       for (exp.Init(itl.Value(),TopAbs_EDGE); exp.More(); exp.Next()) {
216 	const TopoDS_Edge& ed = TopoDS::Edge(exp.Current());
217 	if (toRemove.Contains(ed)) {
218 	  continue;
219 	}
220 	for (itl2.Initialize(itf.Value()); itl2.More(); itl2.Next()) {
221 	  if (!itl2.Value().IsSame(itl.Value())) {
222 	    for (exp2.Init(itl2.Value(),TopAbs_EDGE);exp2.More();exp2.Next()) {
223 	      if (ed.IsSame(exp2.Current())) {
224 		toRemove.Add(ed);
225 		break;
226 	      }
227 	    }
228 	    if (exp2.More()) {
229 	      break;
230 	    }
231 	  }
232 	}
233       }
234     }
235   }
236 
237   TopTools_ListOfShape RebuildFace;
238   TopTools_MapOfShape mapTreated;
239   TopTools_DataMapOfShapeShape DontFuse;
240   TopAbs_Orientation orient,orface;
241 
242   for (itf.Reset(); itf.More(); itf.Next()) {
243     const TopoDS_Face& fac = TopoDS::Face(itf.Key());
244     for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
245       const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
246       if (mapTreated.Contains(edg)) {
247 	continue; // on saute l`edge
248       }
249 
250       mapTreated.Add(edg);
251       for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
252 	const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
253 	if (GVtx.Contains(vtx)) {
254 	  TopoDS_Edge edgbis = G->Generated(vtx);
255 
256 	  if ((edgbis.IsNull() || BRep_Tool::Degenerated(edgbis)) ||
257 //	      toRemove.Contains(edgbis) ||
258 	      !ToFuse(edg,edgbis)) {
259 	    continue;
260 	  }
261 // a voir
262 	  if (BRepTools::IsReallyClosed(edg,fac)) {
263 	    if (!theEEMap.IsBound(edg)) {
264               TopTools_ListOfShape thelist1;
265 	      theEEMap.Bind(edg, thelist1);
266 	      theEEMap(edg).Append(edgbis);
267 	      toRemove.Add(edgbis); // toujours vrai pour edge double
268 	      Standard_Boolean FuseEdge = Standard_True;
269 	      TopoDS_Vertex Vf,Vl;
270 	      TopExp::Vertices(edg,Vf,Vl);
271 	      Standard_Boolean ConnectLast = (Vl.IsSame(vtx));
272 	      for (exp3.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
273 		   exp3.More(); exp3.Next()) {
274 		const TopoDS_Edge& eee = TopoDS::Edge(exp3.Current());
275 		orient = eee.Orientation();
276 		if (!eee.IsSame(edg)) {
277 		  TopExp::Vertices(eee,Vf,Vl);
278 		  if ((Vf.IsSame(vtx) || Vl.IsSame(vtx)) &&
279 		      !toRemove.Contains(eee)) {
280 		    FuseEdge = Standard_False;
281 		    // On recherche celui qu`il ne faut pas fusionner
282 
283 		    if ((Vf.IsSame(vtx) && orient == TopAbs_FORWARD) ||
284 			(Vl.IsSame(vtx) && orient == TopAbs_REVERSED)) {
285 		      if (ConnectLast) {
286 			DontFuse.Bind(edg,fac.Oriented(TopAbs_FORWARD));
287 		      }
288 		      else {
289 			DontFuse.Bind(edg,fac.Oriented(TopAbs_REVERSED));
290 		      }
291 		    }
292 		    else {
293 		      if (ConnectLast) {
294 			DontFuse.Bind(edg,fac.Oriented(TopAbs_REVERSED));
295 		      }
296 		      else {
297 			DontFuse.Bind(edg,fac.Oriented(TopAbs_FORWARD));
298 		      }
299 		    }
300 		    break;
301 		  }
302 		}
303 	      }
304 	      if (FuseEdge) {
305 		toRemove.Add(vtx);
306 	      }
307 	    }
308 	  }
309 
310 
311 	  else {
312 /*  A VOIR
313 	  if (!BRep_Tool::IsClosed(edg,fac)) {
314 */
315 	    if (!theEEMap.IsBound(edg)) {
316               TopTools_ListOfShape thelist2;
317 	      theEEMap.Bind(edg, thelist2);
318 	    }
319 	    theEEMap(edg).Append(edgbis);
320 	    const TopTools_ListOfShape& L = theEEMap(edg);
321 	    TopTools_ListIteratorOfListOfShape Lit(L);
322 	    Standard_Boolean OK = Standard_True;
323 	    for (; Lit.More(); Lit.Next()) {
324 	      if (Lit.Value().IsSame(edgbis)) {
325 		OK = Standard_False;
326 		break;
327 	      }
328 	    }
329 	    if (OK) theEEMap(edg).Append(edgbis);
330 
331 	    itl.Initialize(theEFMap.FindFromKey(edg));
332 	    Standard_Boolean FuseEdge = ToFuse(edg,fac,vtx,toRemove);
333 	    if (!FuseEdge) {
334 	      DontFuse.Bind(edg,fac);
335 	    }
336 	    else {
337 	      for (; itl.More(); itl.Next()) {
338 		if (!itl.Value().IsSame(fac)) {
339 		  if (theFFMap.IsBound(itl.Value())) {
340 		    FuseEdge = ToFuse(edg,TopoDS::Face(itl.Value()),
341 				      vtx,toRemove);
342 		    // edge a fusionner
343 		    if (FuseEdge) {
344 		      toRemove.Add(vtx);
345 		    }
346 		    else {
347 		      if (toRemove.Contains(vtx)) {
348 			toRemove.Remove(vtx);
349 		      }
350 		      DontFuse.Bind(edg,itl.Value());
351 		    }
352 		  }
353 		  else { // on marque comme face a reconstruire
354 		    RebuildFace.Append(itl.Value());
355 		    if (toRemove.Contains(vtx)) {
356 		      toRemove.Remove(vtx);
357 		    }
358 		    DontFuse.Bind(edg,itl.Value());
359 		  }
360 
361 		  break;
362 		}
363 	      }
364 	    }
365 	  }
366 	}
367       }
368     }
369   }
370 
371 
372 
373   for (itl.Initialize(RebuildFace); itl.More(); itl.Next()) {
374     TopTools_ListOfShape thelist3;
375     theFFMap.Bind(itl.Value(), thelist3);
376   }
377 
378   BRep_Builder B;
379   TopoDS_Face newface;
380   TopoDS_Wire outw,newwire;
381   TopoDS_Edge newedg;
382   TopoDS_Vertex newvtx;
383   TopLoc_Location loc;
384   Standard_Real tol,prm,f,l, Uminc = 0.,Umaxc = 0.;
385   gp_Pnt2d pf,pl;
386 
387   Handle(Geom_Surface) S;
388   Handle(Geom_Plane) P;
389   Handle(Geom_Curve) C;
390 
391   // Fusion des edges
392   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape ite(theEEMap);
393   for (; ite.More(); ite.Next()) {
394     Standard_Boolean KeepNewEdge = Standard_False;
395     const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
396     BRep_Tool::Range(edg,f,l);
397     TopoDS_Shape aLocalEdge = edg.EmptyCopied();
398     newedg = TopoDS::Edge(aLocalEdge);
399 //    newedg = TopoDS::Edge(edg.EmptyCopied());
400     newedg.Orientation(TopAbs_FORWARD);
401     for (exp.Init(edg.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
402 	 exp.More(); exp.Next()) {
403       const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
404       prm = BRep_Tool::Parameter(vtx,edg);
405 
406       newvtx.Nullify();
407       for (itl.Initialize(theEEMap(edg)); itl.More(); itl.Next()) {
408 	const TopoDS_Edge& edgbis = TopoDS::Edge(itl.Value());
409 	for (exp2.Init(edgbis,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
410 	  if (exp2.Current().IsSame(vtx)) {
411 	    break;
412 	  }
413 	}
414 	if (exp2.More()) {
415 	  for (exp2.ReInit(); exp2.More(); exp2.Next()) {
416 	    if (!exp2.Current().IsSame(vtx)) {
417 	      newvtx = TopoDS::Vertex(exp2.Current());
418 	      prm = NewParameter(edg,vtx,newedg,newvtx);
419 	      break;
420 	    }
421 	  }
422 	  break;
423 	}
424       }
425 
426       if (toRemove.Contains(vtx) ||
427 	  (prm <l && prm > f)) {
428 	B.Add(newedg,newvtx.Oriented(vtx.Orientation()));
429 	tol = BRep_Tool::Tolerance(newvtx);
430 	B.UpdateVertex(newvtx,prm,newedg,tol);
431 	toRemove.Add(itl.Value()); // i-e edgbis
432 	KeepNewEdge = Standard_True;
433       }
434       else {
435 	B.Add(newedg,vtx.Oriented(vtx.Orientation()));
436 	tol = BRep_Tool::Tolerance(vtx);
437 	B.UpdateVertex(vtx,prm,newedg,tol);
438       }
439     }
440     if (KeepNewEdge) {
441       TopTools_ListOfShape emptylist;
442       if(!myModShapes.IsBound(edg)) {
443 	myModShapes.Bind(edg,emptylist);
444       }
445       myModShapes(edg).Append(newedg);
446       toRemove.Add(edg);
447     }
448   }
449 
450   TopTools_MapOfShape EdgAdded;
451 
452   // Fusion des faces, ou reconstruction
453   for (itf.Reset();itf.More(); itf.Next()) {
454     const TopoDS_Face& fac = TopoDS::Face(itf.Key());
455     Standard_Boolean ModFace = Standard_False;
456     TopTools_ListOfShape listofedg;
457 
458     EdgAdded.Clear();
459 
460     for(exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
461       if (exp.Current().IsSame(fac)) {
462 	break;
463       }
464     }
465     orface = exp.Current().Orientation();
466     TopoDS_Shape aLocalFaceEmptyCopied = fac.EmptyCopied();
467     newface = TopoDS::Face(aLocalFaceEmptyCopied);
468 //    newface = TopoDS::Face(fac.EmptyCopied());
469     newface.Orientation(TopAbs_FORWARD);
470     S = BRep_Tool::Surface(fac);
471     if (S->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
472       S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
473     }
474     P = Handle(Geom_Plane)::DownCast(S);
475     TopoDS_Wire wir;
476     for (exp.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
477 	 exp.More(); exp.Next()) {
478       wir = TopoDS::Wire(exp.Current());
479       for (exp2.Init(wir,TopAbs_EDGE); exp2.More(); exp2.Next()) {
480 	const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
481 	if (toRemove.Contains(edg) || myModShapes.IsBound(edg) ) {
482 	  break;
483 	}
484       }
485       if (!exp2.More()) { // wire non modifie
486 //	B.Add(newface,wir.Oriented(wir.Orientation()));
487 	for (exp2.Init(wir,TopAbs_EDGE); exp2.More(); exp2.Next()) {
488 	  listofedg.Append(exp2.Current());
489 	}
490       }
491       else {
492 	if (!ModFace) {
493 
494 	  // Petit truc crad pour les p-curves sur les cylindres...
495 	  if (P.IsNull()) {
496 	    Standard_Real Vminc,Vmaxc;
497 	    BRepTools::UVBounds(fac,Uminc,Umaxc,Vminc,Vmaxc);
498 	  }
499 
500 
501 	  // premier passage : on met les wires non touches des faces
502 	  // en vis a vis
503 
504 	  for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
505 	    TopoDS_Face facbis = TopoDS::Face(itl.Value());
506 	    for (itl2.Initialize(G->OrientedFaces());itl2.More();itl2.Next()) {
507 	      if (itl2.Value().IsSame(facbis)) {
508 		break;
509 	      }
510 	    }
511 	    if (itl2.More()) {
512 	      orient = itl2.Value().Orientation();
513 	      facbis.Orientation(orient);
514 	    }
515 	    else { // on fusionne avec une autre face du shape...
516 	      for (exp2.Init(myShape, TopAbs_FACE); exp2.More(); exp2.Next()) {
517 		if (exp2.Current().IsSame(facbis)) {
518 		  facbis.Orientation(exp2.Current().Orientation());
519 		  break;
520 		}
521 	      }
522 	    }
523 
524 	    for (exp3.Init(facbis,TopAbs_WIRE); exp3.More(); exp3.Next()) {
525 	      for (exp2.Init(exp3.Current(),TopAbs_EDGE);
526 		   exp2.More(); exp2.Next()) {
527 		if (toRemove.Contains(exp2.Current())) {
528 		  break;
529 		}
530 	      }
531 	      if (!exp2.More()) {
532 		TopoDS_Wire theNew;
533 		B.MakeWire(theNew); // FORWARD
534 		for (exp2.ReInit(); exp2.More(); exp2.Next()) {
535 		  const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
536 
537 		  orient = TopAbs::Compose(orface,edg.Orientation());
538 //		  B.Add(theNew,edg.Oriented(or));
539 		  listofedg.Append(edg.Oriented(orient));
540 		  EdgAdded.Add(edg);
541 		  if (P.IsNull()) {
542 		    // on met les courbes 2d si on n`est pas sur un plan
543 		    // on ne devrait pas avoir de pb d`edge de couture.
544 		    tol = BRep_Tool::Tolerance(edg);
545 		    C = BRep_Tool::Curve(edg,loc,f,l);
546 		    if (!loc.IsIdentity()) {
547 		      Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
548 		      C = Handle(Geom_Curve)::DownCast (GG);
549 		    }
550 		    if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
551 		      C = Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve();
552 		    }
553 
554 		    Handle(Geom2d_Curve) C2d = GeomProjLib::Curve2d(C,f,l,S,tol);
555 
556 		    // Tentative de recalage dans la facette
557 		    pf = C2d->Value(f);
558 		    pl = C2d->Value(l);
559 		    Standard_Real tttol = Precision::Angular();
560 		    while (Min(pf.X(),pl.X()) >= Umaxc-tttol) {
561 		      C2d->Translate(gp_Vec2d(-2.*M_PI,0));
562 		      pf = C2d->Value(f);
563 		      pl = C2d->Value(l);
564 		    }
565 
566 		    while (Max(pf.X(),pl.X()) <= Uminc+tttol) {
567 		      C2d->Translate(gp_Vec2d(2.*M_PI,0));
568 		      pf = C2d->Value(f);
569 		      pl = C2d->Value(l);
570 		    }
571 
572 		    if (!BRepTools::IsReallyClosed(edg,facbis)) {
573 		      B.UpdateEdge(edg,C2d,newface,tol);
574 		    }
575 		    //		else {
576 		    //		  std::cout << "Edge double bizarre... " << std::endl;
577 		    //		}
578 		  }
579 		}
580 //		B.Add(newface,theNew);
581 	      }
582 	    }
583 	  }
584 	  ModFace = Standard_True;
585 	}
586 
587 	// reconstruction du wire
588 	//B.MakeWire(newwire);
589 
590 	Handle(Geom2d_Curve) C2d,C2d1;
591 
592 //	for (exp2.Init(wir.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
593 	for (exp2.Init(wir,TopAbs_EDGE); exp2.More(); exp2.Next()) {
594 	  const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
595 	  orient = edg.Orientation();
596 	  if (!toRemove.Contains(edg) && !theEEMap.IsBound(edg)) {
597 //	    B.Add(newwire,edg.Oriented(or));
598 //            listofedg.Append(edg.Oriented(or));
599             listofedg.Append(edg);
600 	  }
601 	  else if (myModShapes.IsBound(edg) || theEEMap.IsBound(edg)) {
602 	    if (myModShapes.IsBound(edg)) {
603 	      newedg = TopoDS::Edge(myModShapes(edg).First());
604 	    }
605 	    else {
606 	      newedg = edg;
607 	    }
608 //	    B.Add(newwire,newedg.Oriented(or));
609 	    listofedg.Append(newedg.Oriented(orient));
610 	    C = BRep_Tool::Curve(newedg,loc,f,l);
611 	    if (!loc.IsIdentity()) {
612 	      Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
613 	      C = Handle(Geom_Curve)::DownCast (GG);
614 	    }
615 	    if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
616 	      C = Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve();
617 	    }
618 	    if (P.IsNull()) { // on met les courbes 2d si on n`est pas
619 	                      // sur un plan
620 //	      TopAbs_Orientation oredonfafw = TopAbs::Compose(or,orsav);
621 	      TopAbs_Orientation oredonfafw = orient;
622 	      tol = BRep_Tool::Tolerance(newedg);
623 	      TopoDS_Shape aLocalEdge = edg.Oriented(oredonfafw);
624 	      TopoDS_Shape aLocalFace = fac.Oriented(TopAbs_FORWARD);
625 	      C2d = BRep_Tool::CurveOnSurface
626 		(TopoDS::Edge(aLocalEdge),TopoDS::Face(aLocalFace),f,l);
627 //	      C2d = BRep_Tool::CurveOnSurface
628 //		(TopoDS::Edge(edg.Oriented(oredonfafw)),
629 //		 TopoDS::Face(fac.Oriented(TopAbs_FORWARD)),
630 //		 f,l);
631 
632 	      if (!BRepTools::IsReallyClosed(edg,fac)) {
633 		B.UpdateEdge(newedg,C2d,newface,tol);
634 	      }
635 	      else if (C2d1.IsNull()){
636 		C2d1 = C2d;
637 	      }
638 	      else {
639 //		if (TopAbs::Compose(orsav,or) == TopAbs_FORWARD) {
640 		if (orient == TopAbs_FORWARD) {
641 		  B.UpdateEdge(newedg,C2d,C2d1,newface,tol);
642 		}
643 		else {
644 		  B.UpdateEdge(newedg,C2d1,C2d,newface,tol);
645 		}
646 	      }
647 	    }
648 	    Standard_Boolean AddPart = Standard_False;
649 	    if (DontFuse.IsBound(edg)) {
650 	      if (!BRepTools::IsReallyClosed(edg,fac)) {
651 		if (DontFuse(edg).IsSame(fac)) {
652 		  if (myModShapes.IsBound(edg)) {
653 		    AddPart = Standard_True;
654 		  }
655 		}
656 		else if (!toRemove.Contains(edg)) {
657 		  AddPart = Standard_True;
658 		}
659 
660 	      }
661 	      else {
662 		if (myModShapes.IsBound(edg)) { // edg raccourci
663 //		  if (TopAbs::Compose(orsav,or)==DontFuse(edg).Orientation()){
664 		  if (orient == DontFuse(edg).Orientation()){
665 		    AddPart = Standard_True;
666 		  }
667 		}
668 		else {
669 //		  if (TopAbs::Compose(orsav,or) ==
670 		  if (orient ==
671 		      TopAbs::Reverse(DontFuse(edg).Orientation())) {
672 		    AddPart = Standard_True;
673 		  }
674 		}
675 	      }
676 	    }
677 	    if (AddPart) {
678 	      itl2.Initialize(theEEMap(edg));
679 	      gp_Vec dir1,dir2;
680 	      for (; itl2.More(); itl2.Next()) {
681 		if (EdgAdded.Contains(itl2.Value())) {
682 		  continue;
683 		}
684 		const TopoDS_Edge& edgbis = TopoDS::Edge(itl2.Value());
685 		TopoDS_Iterator it1(newedg),it2;
686 		for (; it1.More(); it1.Next()) {
687 		  for (it2.Initialize(edgbis); it2.More(); it2.Next()) {
688 		    if (it1.Value().IsSame(it2.Value())) {
689 		      break;
690 		    }
691 		  }
692 		  if (it2.More()) {
693 		    break;
694 		  }
695 		}
696 
697 		if (it1.More()) {
698 		  gp_Pnt ptbid;
699 		  Standard_Real prmvt =
700 		    BRep_Tool::Parameter(TopoDS::Vertex(it1.Value()),newedg);
701 		  C->D1(prmvt,ptbid,dir1);
702 
703 
704 		  C = BRep_Tool::Curve(edgbis,loc,f,l);
705 		  if (!loc.IsIdentity()) {
706 		    Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
707 		    C = Handle(Geom_Curve)::DownCast (GG);
708 		  }
709 		  if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
710 		    C = Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve();
711 		  }
712 		  prmvt =
713 		    BRep_Tool::Parameter(TopoDS::Vertex(it1.Value()),edgbis);
714 		  C->D1(prmvt,ptbid,dir2);
715 		}
716 		else {
717 		  dir1 = dir2 = gp_Vec(1,0,0);
718 		}
719 		EdgAdded.Add(edgbis);
720 		if (dir1.Dot(dir2) <0.) {
721 //		  B.Add(newwire,edgbis.Oriented(TopAbs::Reverse(or)));
722 		  listofedg.Append(edgbis.Oriented(TopAbs::Reverse(orient)));
723 		}
724 		else {
725 //		  B.Add(newwire,edgbis.Oriented(or));
726 		  listofedg.Append(edgbis.Oriented(orient));
727 		}
728 
729 
730 		if (P.IsNull()) {
731 		  // on met les courbes 2d si on n`est pas sur un plan
732 		  // C est la courbe de edgbis, f et l s`y rapportent
733 		  Handle(Geom2d_Curve) PTC = GeomProjLib::Curve2d(C,f,l,S,tol);
734 		  if (S->IsUPeriodic()) {
735 		    Standard_Real Uref;
736 		    if (DontFuse.IsBound(edg)) {
737 		      TopAbs_Orientation oredge = DontFuse(edg).Orientation();
738 		      if (myModShapes.IsBound(edg)) { // edge raccourci...
739 			TopoDS_Shape aLocalShape = edg.Oriented(oredge);
740 			TopoDS_Shape aLocalFace  = fac.Oriented(TopAbs_FORWARD);
741 			BRep_Tool::
742 			UVPoints(TopoDS::Edge(aLocalShape),TopoDS::Face(aLocalFace),pf,pl);
743 //			BRep_Tool::
744 //			UVPoints(TopoDS::Edge(edg.Oriented(oredge)),
745 //				 TopoDS::Face(fac.Oriented(TopAbs_FORWARD)),
746 //				 pf,pl);
747 		      }
748 		      else {
749 			TopoDS_Shape aLocalShape = edg.Oriented(TopAbs::Reverse(oredge));
750 			TopoDS_Shape aLocalFace  = fac.Oriented(TopAbs_FORWARD);
751 			BRep_Tool::
752 			UVPoints(TopoDS::Edge(aLocalShape),TopoDS::Face(aLocalFace),pf,pl);
753 //			BRep_Tool::
754 //			UVPoints(TopoDS::Edge(edg.Oriented(TopAbs::Reverse(oredge))),
755 //				 TopoDS::Face(fac.Oriented(TopAbs_FORWARD)),
756 //				 pf,pl);
757 		      }
758 		      Uref = pf.X();
759 		    }
760 		    else {
761 		      BRep_Tool::UVPoints(edg,fac,pf,pl);
762 		      Uref = pf.X();
763 		    }
764 
765 		    Standard_Real NewU = (PTC->Value(f)).X();
766 
767 //		    if(abs(NewU - Uref) > Epsilon(S->UPeriod()))   {
768 		    if(fabs(NewU - Uref) > Epsilon(S->UPeriod()))   {
769 		      PTC -> Translate(gp_Vec2d((Uref - NewU), 0.));
770 		    }
771 		  }
772 
773 		  B.UpdateEdge(edgbis,PTC,newface,tol);
774 		}
775 	      }
776 	    }
777 	  }
778 	}
779 
780 	// Recuperation des edges sur les faces a fusionner.
781 
782 // ICICICICI
783 
784 //	orface = TopAbs::Compose(orsav,orface);
785 
786 	Standard_Boolean includeinw = Standard_False;
787 	for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
788 	  TopoDS_Face facbis = TopoDS::Face(itl.Value());
789 	  Standard_Boolean genface = Standard_True;
790 	  for (itl2.Initialize(G->OrientedFaces()); itl2.More(); itl2.Next()) {
791 	    if (itl2.Value().IsSame(facbis)) {
792 	      break;
793 	    }
794 	  }
795 	  if (itl2.More()) {
796 	    orient = itl2.Value().Orientation();
797 	    facbis.Orientation(orient);
798 	  }
799 	  else { // on fusionne avec une autre face du shape...
800 	    genface = Standard_False;
801 	    for (exp2.Init(myShape, TopAbs_FACE); exp2.More(); exp2.Next()) {
802 	      if (exp2.Current().IsSame(facbis)) {
803 		facbis.Orientation(exp2.Current().Orientation());
804 		break;
805 	      }
806 	    }
807 	  }
808 
809 	  for (exp3.Init(facbis,TopAbs_WIRE); exp3.More(); exp3.Next()) {
810 	    for (exp2.Init(exp3.Current(),TopAbs_EDGE);
811 		 exp2.More(); exp2.Next()) {
812 	      if (toRemove.Contains(exp2.Current())) {
813 		break;
814 	      }
815 	    }
816 	    if (genface) {
817 	      includeinw = Standard_True;
818 	    }
819 	    else {
820 	      Standard_Boolean isIncludedInW = Standard_False;
821 	      if (exp2.More()) {
822 		for (exp2.ReInit(); exp2.More(); exp2.Next()) {
823 		  if (!toRemove.Contains(exp2.Current())) {
824 		    continue;
825 		  }
826 		  TopoDS_Vertex VF,VL;
827 		  TopExp::Vertices(TopoDS::Edge(exp2.Current()),VF,VL);
828 		  TopExp_Explorer exp4;
829 		  for (exp4.Init(wir,TopAbs_VERTEX);
830 //		  for (TopExp_Explorer exp4(wir,TopAbs_VERTEX);
831 		       exp4.More(); exp4.Next()) {
832 		    if (exp4.Current().IsSame(VF) ||
833 			exp4.Current().IsSame(VL)) {
834                       isIncludedInW = Standard_True;
835 		      break;
836 		    }
837 		  }
838 		  if (isIncludedInW) {
839 		    break;
840 		  }
841 		}
842 	      }
843 	    }
844 
845 	    if (!includeinw) {
846 	      continue;
847 	    }
848 
849 	    for (exp2.ReInit(); exp2.More(); exp2.Next()) {
850 	      const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
851 	      if (!toRemove.Contains(edg) && !EdgAdded.Contains(edg)) {
852 
853 		orient = TopAbs::Compose(orface,edg.Orientation());
854 		//		B.Add(newwire,edg.Oriented(or));
855 		listofedg.Append(edg.Oriented(orient));
856 		EdgAdded.Add(edg);
857 		if (P.IsNull()) {
858 		  // on met les courbes 2d si on n`est pas sur un plan
859 		  // on ne devrait pas avoir de pb d`edge de couture.
860 		  tol = BRep_Tool::Tolerance(edg);
861 		  C = BRep_Tool::Curve(edg,loc,f,l);
862 		  if (!loc.IsIdentity()) {
863 		    Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
864 		    C = Handle(Geom_Curve)::DownCast (GG);
865 		  }
866 		  if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
867 		    C =  Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve();
868 		  }
869 
870 		  C2d = GeomProjLib::Curve2d(C,f,l,S,tol);
871 
872 		  // Tentative de recalage dans la facette
873 		  pf = C2d->Value(f);
874 		  pl = C2d->Value(l);
875 		  Standard_Real tttol = Precision::Angular();
876 		  while (Min(pf.X(),pl.X()) >= Umaxc - tttol) {
877 		    C2d->Translate(gp_Vec2d(-2.*M_PI,0));
878 		    pf = C2d->Value(f);
879 		    pl = C2d->Value(l);
880 		  }
881 
882 		  while (Max(pf.X(),pl.X()) <= Uminc + tttol) {
883 		    C2d->Translate(gp_Vec2d(2.*M_PI,0));
884 		    pf = C2d->Value(f);
885 		    pl = C2d->Value(l);
886 		  }
887 
888 		  if (!BRepTools::IsReallyClosed(edg,facbis)) {
889 		    B.UpdateEdge(edg,C2d,newface,tol);
890 		  }
891 		  //		else {
892 		  //		  std::cout << "Edge double bizarre... " << std::endl;
893 		  //		}
894 		}
895 	      }
896 	    }
897 	  }
898 	}
899       }
900     }
901     if (!listofedg.IsEmpty()) {
902       BRepAlgo_Loop L;
903       L.Init(newface);
904       L.AddConstEdges(listofedg);
905       L.Perform();
906       L.WiresToFaces();
907       const TopTools_ListOfShape& listoffaces = L.NewFaces();
908       toRemove.Add(fac);
909       //      if (!HasWire) {
910       //	newface.Nullify();
911       //      }
912       myModShapes.Bind(fac,listoffaces);
913       for (itl.Initialize(itf.Value()); itl.More(); itl.Next()) {
914 	myModShapes.Bind(itl.Value(),listoffaces);
915       }
916     }
917   }
918 
919 /* JAG 16.09.96 : on utilise LocOpe_BuildShape
920   TopoDS_Shell theShell;
921   B.MakeShell(theShell);
922   for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
923     const TopoDS_Face& fac = TopoDS::Face(exp.Current());
924     if (!theLeft.Contains(fac)) {
925       if (!toRemove.Contains(exp.Current())) {
926 	B.Add(theShell,fac);
927 	myModShapes.Bind(fac,fac);
928       }
929       else if (!myModShapes(fac).IsNull())  {
930 	B.Add(theShell, myModShapes(fac).Oriented(fac.Orientation()));
931       }
932     }
933   }
934 
935 
936   TopAbs_Orientation orsolid = myShape.Orientation();
937   for (itl.Initialize(G->OrientedFaces()); itl.More(); itl.Next()) {
938     const TopoDS_Face& fac = TopoDS::Face(itl.Value());
939     if (toRemove.Contains(fac)) {
940       continue;
941     }
942 
943     if (orsolid == TopAbs_FORWARD) {
944       B.Add(theShell,fac);
945     }
946     else {
947       B.Add(theShell,fac.Reversed());
948     }
949     myModShapes.Bind(fac,fac);
950 
951   }
952 
953   B.MakeSolid(TopoDS::Solid(myRes));
954   B.Add(myRes,theShell);
955   myRes.Orientation(orsolid);
956 
957 */
958 
959   // 06.11.96
960   // Debug temporaire. Il faudra prevoir un syntaxe de BuildShape
961   // qui impose une ori de certaines faces.
962 
963   TopoDS_Face FaceRefOri;
964 
965   TopTools_ListOfShape lfres;
966   for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
967     const TopoDS_Face& fac = TopoDS::Face(exp.Current());
968     if (!theLeft.Contains(fac)) {
969       if (!toRemove.Contains(exp.Current())) {
970 	lfres.Append(fac);
971 	if(!myModShapes.IsBound(fac)) {
972 	  TopTools_ListOfShape emptylist;
973 	  myModShapes.Bind(fac, emptylist);
974 	}
975 	myModShapes(fac).Append(fac);
976 	if (FaceRefOri.IsNull()) {
977 	  FaceRefOri = fac;
978 	}
979       }
980       else if (myModShapes.IsBound(fac))  {
981 	lfres.Append(myModShapes(fac).First().Oriented(fac.Orientation()));
982       }
983     }
984   }
985 
986 
987   TopAbs_Orientation orsolid = myShape.Orientation();
988   for (itl.Initialize(G->OrientedFaces()); itl.More(); itl.Next()) {
989     const TopoDS_Face& fac = TopoDS::Face(itl.Value());
990     if (toRemove.Contains(fac)) {
991       continue;
992     }
993 
994     if (orsolid == TopAbs_FORWARD) {
995       lfres.Append(fac);
996     }
997     else {
998       lfres.Append(fac.Reversed());
999     }
1000     if(!myModShapes.IsBound(fac)) {
1001       TopTools_ListOfShape emptylist;
1002       myModShapes.Bind(fac, emptylist);
1003     }
1004     myModShapes(fac).Append(fac);
1005   }
1006 
1007   LocOpe_BuildShape BS(lfres);
1008   myRes = BS.Shape();
1009   // Suite debug du 06.11.96
1010   if (myRes.ShapeType() == TopAbs_SOLID) {
1011     for (exp.Init(myRes,TopAbs_FACE); exp.More(); exp.Next()) {
1012       if (exp.Current().IsSame(FaceRefOri)) {
1013 	break;
1014       }
1015     }
1016     if (exp.More() &&
1017 	exp.Current().Orientation() != FaceRefOri.Orientation()) {
1018       // 	---C++: return const&	---C++: return const&	---C++: return const&Si un seul Shell , on change son orientation
1019       TopoDS_Solid NewSol;
1020       B.MakeSolid(NewSol);
1021       exp.Init(myRes,TopAbs_SHELL);
1022       B.Add(NewSol,exp.Current().Reversed());
1023       myRes.Nullify();
1024       myRes = NewSol;
1025     }
1026   }
1027 
1028 
1029   // recodage des regularites qui existaient sur le shape colle
1030 
1031 
1032 
1033   myDone = Standard_True;
1034 }
1035 
1036 //=======================================================================
1037 //function : DescendantFace
1038 //purpose  :
1039 //=======================================================================
1040 
DescendantFace(const TopoDS_Face & F)1041  const TopTools_ListOfShape& LocOpe_Generator::DescendantFace(const TopoDS_Face& F)
1042 {
1043  // TopTools_ListOfShape list;
1044 
1045   if (!myDone) {throw StdFail_NotDone();}
1046   return myModShapes(F);
1047 }
1048 
1049 //=======================================================================
1050 //function : ToFuse
1051 //purpose  :
1052 //=======================================================================
1053 
ToFuse(const TopoDS_Face & F1,const TopoDS_Face & F2)1054 Standard_Boolean ToFuse(const TopoDS_Face& F1,
1055 			const TopoDS_Face& F2)
1056 {
1057   if (F1.IsNull() || F2.IsNull()) {
1058     return Standard_False;
1059   }
1060 
1061   Handle(Geom_Surface) S1,S2;
1062   TopLoc_Location loc1, loc2;
1063   Handle(Standard_Type) typS1,typS2;
1064   const Standard_Real tollin = Precision::Confusion();
1065   const Standard_Real tolang = Precision::Angular();
1066 
1067   S1 = BRep_Tool::Surface(F1,loc1);
1068   S2 = BRep_Tool::Surface(F2,loc2);
1069 
1070   typS1 = S1->DynamicType();
1071   typS2 = S2->DynamicType();
1072 
1073   if (typS1 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1074     S1 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S1)->BasisSurface();
1075     typS1 = S1->DynamicType();
1076   }
1077 
1078   if (typS2 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1079     S2 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S2)->BasisSurface();
1080     typS2 = S2->DynamicType();
1081   }
1082 
1083   if (typS1 != typS2) {
1084     return Standard_False;
1085   }
1086 
1087 
1088   Standard_Boolean ValRet = Standard_False;
1089   if (typS1 == STANDARD_TYPE(Geom_Plane)) {
1090 
1091     gp_Pln pl1( Handle(Geom_Plane)::DownCast (S1)->Pln());
1092     gp_Pln pl2( Handle(Geom_Plane)::DownCast (S2)->Pln());
1093 
1094     pl1.Transform(loc1.Transformation());
1095     pl2.Transform(loc2.Transformation());
1096 
1097     if (pl1.Position().IsCoplanar(pl2.Position(),tollin,tolang)) {
1098       ValRet = Standard_True;
1099     }
1100   }
1101 
1102   return ValRet;
1103 }
1104 
1105 
1106 //=======================================================================
1107 //function : ToFuse
1108 //purpose  :
1109 //=======================================================================
1110 
ToFuse(const TopoDS_Edge & E1,const TopoDS_Edge & E2)1111 Standard_Boolean ToFuse(const TopoDS_Edge& E1,
1112 			const TopoDS_Edge& E2)
1113 {
1114 
1115   if (E1.IsNull() || E2.IsNull()) {
1116     return Standard_False;
1117   }
1118 
1119   Handle(Geom_Curve) C1,C2;
1120   TopLoc_Location loc1, loc2;
1121   Handle(Standard_Type) typC1,typC2;
1122   const Standard_Real tollin = Precision::Confusion();
1123   const Standard_Real tolang = Precision::Angular();
1124   Standard_Real f,l;
1125 
1126   C1 = BRep_Tool::Curve(E1,loc1,f,l);
1127   if (!loc1.IsIdentity()) {
1128     Handle(Geom_Geometry) CC1 = C1->Transformed(loc1.Transformation());
1129     C1 = Handle(Geom_Curve)::DownCast (CC1);
1130   }
1131 
1132   C2 = BRep_Tool::Curve(E2,loc2,f,l);
1133   if (!loc2.IsIdentity()) {
1134     Handle(Geom_Geometry) CC2 = C2->Transformed(loc2.Transformation());
1135     C2 = Handle(Geom_Curve)::DownCast (CC2);
1136   }
1137 
1138   typC1 = C1->DynamicType();
1139   typC2 = C2->DynamicType();
1140 
1141   if (typC1 == STANDARD_TYPE(Geom_TrimmedCurve)) {
1142     C1 =  Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
1143     typC1 = C1->DynamicType();
1144   }
1145   if (typC2 == STANDARD_TYPE(Geom_TrimmedCurve)) {
1146     C2 =  Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
1147     typC2 = C2->DynamicType();
1148   }
1149 
1150   if (typC1 != typC2) {
1151     return Standard_False;
1152   }
1153 
1154   Standard_Boolean ValRet = Standard_False;
1155   if (typC1 == STANDARD_TYPE(Geom_Line)) {
1156     gp_Lin li1( Handle(Geom_Line)::DownCast (C1)->Lin());
1157     gp_Lin li2( Handle(Geom_Line)::DownCast (C2)->Lin());
1158 
1159     if (li1.Position().IsCoaxial(li2.Position(),tolang,tollin)) {
1160       ValRet = Standard_True;
1161     }
1162   }
1163 
1164   return ValRet;
1165 }
1166 
1167 
1168 //=======================================================================
1169 //function : ToFuse
1170 //purpose  :
1171 //=======================================================================
1172 
ToFuse(const TopoDS_Edge & E,const TopoDS_Face & F,const TopoDS_Vertex & V,const TopTools_MapOfShape & toRemove)1173 Standard_Boolean ToFuse(const TopoDS_Edge& E,
1174 			const TopoDS_Face& F,
1175 			const TopoDS_Vertex& V,
1176 			const TopTools_MapOfShape& toRemove)
1177 {
1178   TopoDS_Vertex Vf,Vl;
1179   TopExp_Explorer exp;
1180   for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
1181 //  for (TopExp_Explorer exp(F,TopAbs_EDGE); exp.More(); exp.Next()) {
1182     const TopoDS_Edge& eee = TopoDS::Edge(exp.Current());
1183     if (!eee.IsSame(E)) {
1184       TopExp::Vertices(eee,Vf,Vl);
1185       if ((Vf.IsSame(V) || Vl.IsSame(V)) &&
1186 	  !toRemove.Contains(eee)) {
1187 	return Standard_False;
1188       }
1189     }
1190   }
1191   return Standard_True;
1192 }
1193 
1194 
1195 //=======================================================================
1196 //function : NewParameter
1197 //purpose  :
1198 //=======================================================================
1199 
NewParameter(const TopoDS_Edge & Edg,const TopoDS_Vertex & Vtx,const TopoDS_Edge & NewEdg,const TopoDS_Vertex & NewVtx)1200 Standard_Real NewParameter(const TopoDS_Edge& Edg,
1201 			   const TopoDS_Vertex& Vtx,
1202 			   const TopoDS_Edge& NewEdg,
1203 			   const TopoDS_Vertex& NewVtx)
1204 {
1205 
1206   Handle(Geom_Curve) C;
1207   TopLoc_Location loc;
1208   Handle(Standard_Type) typC;
1209   Standard_Real f,l;
1210 
1211   gp_Pnt P = BRep_Tool::Pnt(NewVtx);
1212 
1213   C = BRep_Tool::Curve(Edg,loc,f,l);
1214   if (!loc.IsIdentity()) {
1215     Handle(Geom_Geometry) GG = C->Transformed(loc.Transformation());
1216     C = Handle(Geom_Curve)::DownCast (GG);
1217   }
1218   typC = C->DynamicType();
1219   if (typC == STANDARD_TYPE(Geom_TrimmedCurve)) {
1220     C =  Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve();
1221     typC = C->DynamicType();
1222   }
1223 
1224   if (typC == STANDARD_TYPE(Geom_Line)) {
1225     return ElCLib::Parameter( Handle(Geom_Line)::DownCast (C)->Lin(),P);
1226   }
1227   else if (typC == STANDARD_TYPE(Geom_Circle)) {
1228     Standard_Real prm = ElCLib::Parameter
1229       ( Handle(Geom_Circle)::DownCast (C)->Circ(),P);
1230     // Vtx vient d`une exploration de Edg orientee FORWARD
1231 
1232     TopAbs_Orientation orient = TopAbs::Reverse(Vtx.Orientation());
1233     if (orient == TopAbs_FORWARD || orient == TopAbs_REVERSED) {
1234 //      for (TopExp_Explorer exp(NewEdg.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
1235       TopExp_Explorer exp(NewEdg.Oriented(TopAbs_FORWARD),TopAbs_VERTEX) ;
1236       for ( ; exp.More(); exp.Next()) {
1237 	if (exp.Current().Orientation() == orient) {
1238 	  break;
1239 	}
1240       }
1241       if (exp.More()) {
1242 	Standard_Real prmmax = BRep_Tool::Parameter
1243 	  (TopoDS::Vertex(exp.Current()),NewEdg);
1244 	if (Abs(prmmax - prm) <= Epsilon(2.*M_PI)) {
1245 	  if (orient == TopAbs_REVERSED) {
1246 	    prm -= 2.*M_PI;
1247 	  }
1248 	  else {
1249 	    prm += 2.*M_PI;
1250 	  }
1251 	}
1252       }
1253     }
1254     return prm;
1255   }
1256   return 0;
1257 }
1258