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