0022627: Change OCCT memory management defaults
[occt.git] / src / LocOpe / LocOpe_WiresOnShape.cxx
CommitLineData
7fd59977 1// File: LocOpe_WiresOnShape.cxx
2// Created: Thu Jan 11 13:48:03 1996
3// Author: Jacques GOUSSARD
4// <jag@bravox>
5
6
7#include <LocOpe_WiresOnShape.ixx>
8
9#include <TopExp_Explorer.hxx>
10#include <BRep_Builder.hxx>
11#include <BRep_Tool.hxx>
12#include <TopTools_MapOfShape.hxx>
13#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
14#include <TopTools_ListOfShape.hxx>
15#include <TopTools_ListIteratorOfListOfShape.hxx>
16
17#include <GeomAPI_ProjectPointOnCurve.hxx>
18#include <GeomAdaptor_Surface.hxx>
19#include <Geom_Curve.hxx>
20#include <Geom_TrimmedCurve.hxx>
21#include <Geom_Surface.hxx>
22#include <Geom_RectangularTrimmedSurface.hxx>
23#include <Geom2d_Curve.hxx>
24
25#include <gp_Pnt2d.hxx>
26#include <gp_Vec2d.hxx>
27#include <gp_Vec.hxx>
28
29#include <TopoDS.hxx>
30#include <TopExp.hxx>
31#include <BRepTools.hxx>
32#include <GeomProjLib.hxx>
33#include <LocOpe.hxx>
34#include <Precision.hxx>
35
36#include <Standard_ConstructionError.hxx>
37#include <TopoDS_Compound.hxx>
38#include <BRepLib.hxx>
39
40static Standard_Boolean Project(const TopoDS_Vertex&,
41 const TopoDS_Face&,
42 TopoDS_Edge&,
43 Standard_Real&);
44
45static Standard_Real Project(const TopoDS_Vertex&,
46 const TopoDS_Edge&);
47
48
49static void PutPCurve(const TopoDS_Edge&,
50 const TopoDS_Face&);
51
52
53static void PutPCurves(const TopoDS_Edge&,
54 const TopoDS_Edge&,
55 const TopoDS_Shape&);
56
57
58//=======================================================================
59//function : LocOpe_WiresOnShape
60//purpose :
61//=======================================================================
62
63LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
64 myShape(S),myDone(Standard_False)
65{}
66
67
68
69//=======================================================================
70//function : Init
71//purpose :
72//=======================================================================
73
74void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
75{
76 myShape = S;
77 myDone = Standard_False;
78 myMap.Clear();
79 myMapEF.Clear();
80}
81
82
83
84//=======================================================================
85//function : Bind
86//purpose :
87//=======================================================================
88
89void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
90 const TopoDS_Face& F)
91{
92 for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next()) {
93 Bind(TopoDS::Edge(exp.Current()),F);
94 }
95}
96
97
98//=======================================================================
99//function : Bind
100//purpose :
101//=======================================================================
102
103void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E,
104 const TopoDS_Face& F)
105{
106// if (!myMapEF.IsBound(E)) {
107 if (!myMapEF.Contains(E)) {
108// for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) {
109 TopExp_Explorer exp(F,TopAbs_EDGE) ;
110 for ( ;exp.More();exp.Next()) {
111 if (exp.Current().IsSame(E)) {
112 break;
113 }
114 }
115 if (!exp.More()) {
116// myMapEF.Bind(E,F);
117 myMapEF.Add(E,F);
118 }
119 }
120 else {
121 Standard_ConstructionError::Raise();
122 }
123}
124
125
126//=======================================================================
127//function : Bind
128//purpose :
129//=======================================================================
130
131void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir,
132 const TopoDS_Edge& Efac)
133{
134 if (Ewir.IsSame(Efac)) {
135 return;
136 }
137 myMap.Bind(Ewir,Efac);
138}
139
140
141//=======================================================================
142//function : BindAll
143//purpose :
144//=======================================================================
145
146void LocOpe_WiresOnShape::BindAll()
147{
148 if (myDone) {
149 return;
150 }
151 TopTools_MapOfShape theMap;
152
153 // Detection des vertex a projeter ou a "binder" avec des vertex existants
154 TopTools_DataMapOfShapeShape mapV;
155 TopTools_DataMapIteratorOfDataMapOfShapeShape ite(myMap);
156 TopExp_Explorer exp,exp2;
157 for (; ite.More(); ite.Next()) {
158 const TopoDS_Edge& eref = TopoDS::Edge(ite.Key());
159 const TopoDS_Edge& eimg = TopoDS::Edge(ite.Value());
160
161 PutPCurves(eref,eimg,myShape);
162
163 for (exp.Init(eref,TopAbs_VERTEX); exp.More(); exp.Next()) {
164 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
165 if (!theMap.Contains(vtx)) { // pas deja traite
166 for (exp2.Init(eimg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
167 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
168 if (vtx2.IsSame(vtx)) {
169 break;
170 }
171 else if (BRepTools::Compare(vtx,vtx2)) {
172 mapV.Bind(vtx,vtx2);
173 break;
174 }
175 }
176 if (!exp2.More()) {
177 mapV.Bind(vtx,eimg);
178 }
179 theMap.Add(vtx);
180 }
181 }
182 }
183
184 for (ite.Initialize(mapV); ite.More(); ite.Next()) {
185 myMap.Bind(ite.Key(),ite.Value());
186 }
187
188 // Il faut s`occuper maintenant des vertex "de changement de face",
189 // et des vertex "libres"
190// TopTools_DataMapIteratorOfDataMapOfShapeShape ite2;
191
192// for (ite.Initialize(myMapEF); ite.More(); ite.Next()) {
193// const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
194// const TopoDS_Face& fac = TopoDS::Face(ite.Value());
195 for (Standard_Integer Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
196 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
197 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
198 // JAG 02.02.96 : On verifie les pcurves...
199
200 PutPCurve(edg,fac);
201
202 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
203 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
204 if (theMap.Contains(vtx)) {
205 continue;
206 }
207 TopoDS_Edge Epro;
208 Standard_Real prm;
209 Standard_Boolean ok = Project(vtx,fac,Epro,prm);
210 if (ok) {
211 for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
212 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
213 if (vtx2.IsSame(vtx)) {
214 break;
215 }
216 else if (BRepTools::Compare(vtx,vtx2)) {
217 myMap.Bind(vtx,vtx2);
218 break;
219 }
220 }
221 if (!exp2.More()) {
222 myMap.Bind(vtx,Epro);
223 }
224 theMap.Add(vtx);
225 }
226 }
227 }
228
229// Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin
230 for (ite.Initialize(myMap); ite.More(); ite.Next())
231 if ((ite.Key()).ShapeType() == TopAbs_EDGE)
232 myMapEF.Add(ite.Key(),ite.Value());
233// Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End
234
235
236 myDone = Standard_True;
237
238}
239
240
241//=======================================================================
242//function : InitEdgeIterator
243//purpose :
244//=======================================================================
245
246void LocOpe_WiresOnShape::InitEdgeIterator()
247{
248 BindAll();
249// myIt.Initialize(myMapEF);
250 myIndex = 1;
251}
252
253
254//=======================================================================
255//function : MoreEdge
256//purpose :
257//=======================================================================
258
259Standard_Boolean LocOpe_WiresOnShape::MoreEdge()
260{
261// return myIt.More();
262 return (myIndex <= myMapEF.Extent());
263}
264
265
266//=======================================================================
267//function : Edge
268//purpose :
269//=======================================================================
270
271TopoDS_Edge LocOpe_WiresOnShape::Edge()
272{
273// return TopoDS::Edge(myIt.Key());
274 return TopoDS::Edge(myMapEF.FindKey(myIndex));
275}
276
277
278//=======================================================================
279//function : Face
280//purpose :
281//=======================================================================
282
283TopoDS_Face LocOpe_WiresOnShape::OnFace()
284{
285// return TopoDS::Face(myIt.Value());
286 return TopoDS::Face(myMapEF(myIndex));
287}
288
289
290//=======================================================================
291//function : OnEdge
292//purpose :
293//=======================================================================
294
295Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E)
296{
297// if (myMap.IsBound(myIt.Key())) {
298 if (myMap.IsBound(myMapEF.FindKey(myIndex))) {
299// E = TopoDS::Edge(myMap(myIt.Key()));
300 E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex)));
301 return Standard_True;
302 }
303 return Standard_False;
304}
305
306
307
308
309//=======================================================================
310//function : NextEdge
311//purpose :
312//=======================================================================
313
314void LocOpe_WiresOnShape::NextEdge()
315{
316// myIt.Next();
317 myIndex++;
318}
319
320
321
322//=======================================================================
323//function : OnVertex
324//purpose :
325//=======================================================================
326
327Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
328 TopoDS_Vertex& Vs)
329{
330 if (myMap.IsBound(Vw)) {
331 if (myMap(Vw).ShapeType() == TopAbs_VERTEX) {
332 Vs = TopoDS::Vertex(myMap(Vw));
333 return Standard_True;
334 }
335 return Standard_False;
336 }
337 return Standard_False;
338}
339
340
341
342
343//=======================================================================
344//function : OnEdge
345//purpose :
346//=======================================================================
347
348Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
349 TopoDS_Edge& Ed,
350 Standard_Real& prm)
351{
352 if (!myMap.IsBound(V) ||
353 myMap(V).ShapeType() == TopAbs_VERTEX) {
354 return Standard_False;
355 }
356
357 Ed = TopoDS::Edge(myMap(V));
358 prm = Project(V,Ed);
359 return Standard_True;
360}
361
362
363//=======================================================================
364//function : Project
365//purpose :
366//=======================================================================
367
368Standard_Boolean Project(const TopoDS_Vertex& V,
369 const TopoDS_Face& F,
370 TopoDS_Edge& theEdge,
371 Standard_Real& param)
372{
373 Handle(Geom_Curve) C;
374 TopLoc_Location Loc;
375 Standard_Real f,l;
376
377 Standard_Real dmin = RealLast();
378 gp_Pnt toproj(BRep_Tool::Pnt(V));
379 Standard_Boolean valret = Standard_False;
380 GeomAPI_ProjectPointOnCurve proj;
381
382 for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
383 exp.More(); exp.Next()) {
384 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
385 if (!BRep_Tool::Degenerated(edg)) {
386 C = BRep_Tool::Curve(edg,Loc,f,l);
387 if (!Loc.IsIdentity()) {
388 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
389 C = *((Handle(Geom_Curve)*)&GG);
390 }
391 proj.Init(toproj,C,f,l);
392 if (proj.NbPoints() > 0) {
393 if (proj.LowerDistance() < dmin) {
394 theEdge = edg;
395 theEdge.Orientation(edg.Orientation());
396 dmin = proj.LowerDistance();
397 param = proj.LowerDistanceParameter();
398 }
399 }
400 }
401 }
402
403 if(theEdge.IsNull())
404 return Standard_False;
405
406 Standard_Real ttol = BRep_Tool::Tolerance(V) + BRep_Tool::Tolerance(theEdge);
407 if (dmin <= ttol) {
408 valret = Standard_True;
409 BRep_Builder B;
410 B.UpdateVertex(V, Max(dmin, BRep_Tool::Tolerance(V)));
411 }
412#ifdef DEB_MESH
413 else {
414 cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une ";
415 cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
416 }
417#endif
418 return valret;
419}
420
421//=======================================================================
422//function : Project
423//purpose :
424//=======================================================================
425
426Standard_Real Project(const TopoDS_Vertex& V,
427 const TopoDS_Edge& theEdge)
428{
429 Handle(Geom_Curve) C;
430 TopLoc_Location Loc;
431 Standard_Real f,l;
432
433 gp_Pnt toproj(BRep_Tool::Pnt(V));
434 GeomAPI_ProjectPointOnCurve proj;
435
436 C = BRep_Tool::Curve(theEdge,Loc,f,l);
437 if (!Loc.IsIdentity()) {
438 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
439 C = *((Handle(Geom_Curve)*)&GG);
440 }
441 proj.Init(toproj,C,f,l);
442
443
444 return proj.LowerDistanceParameter();
445}
446
447
448//=======================================================================
449//function : PutPCurve
450//purpose :
451//=======================================================================
452
453void PutPCurve(const TopoDS_Edge& Edg,
454 const TopoDS_Face& Fac)
455{
456 BRep_Builder B;
457 TopLoc_Location LocFac;
458
459 Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
460 Handle(Standard_Type) styp = S->DynamicType();
461
462 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
463 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
464 styp = S->DynamicType();
465 }
466
467 if (styp == STANDARD_TYPE(Geom_Plane)) {
468 return;
469 }
470
471 Standard_Real Umin,Umax,Vmin,Vmax;
472 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
473
474 Standard_Real f,l;
475
476 //if (!BRep_Tool::CurveOnSurface(Edg,Fac,f,l).IsNull()) {
477 // return;
478 //}
479 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
480 if ( !aC2d.IsNull() ) {
481 gp_Pnt2d p2d;
482 aC2d->D0(f,p2d);
483 Standard_Boolean IsIn = Standard_True;
484 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
485 ( p2d.X() > Umax+Precision::PConfusion() ) )
486 IsIn = Standard_False;
487 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
488 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
489 IsIn = Standard_False;
490 aC2d->D0(l,p2d);
491 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
492 ( p2d.X() > Umax+Precision::PConfusion() ) )
493 IsIn = Standard_False;
494 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
495 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
496 IsIn = Standard_False;
497 if (IsIn)
498 return;
499 }
500
501 TopLoc_Location Loc;
502 Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
503 if (!Loc.IsIdentity()) {
504 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
505 C = *((Handle(Geom_Curve)*)&GG);
506 }
507
508 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
509 C = new Geom_TrimmedCurve(C,f,l);
510 }
511
512 S = BRep_Tool::Surface(Fac);
513
514 // Compute the tol2d
515 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Edg),
516 BRep_Tool::Tolerance(Fac));
517 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
518 Standard_Real TolU = Gas.UResolution(tol3d);
519 Standard_Real TolV = Gas.VResolution(tol3d);
520 Standard_Real tol2d = Max(TolU,TolV);
521
522 Handle(Geom2d_Curve) C2d =
523 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
524 if(C2d.IsNull())
525 return;
526 gp_Pnt2d pf(C2d->Value(f));
527 gp_Pnt2d pl(C2d->Value(l));
528 gp_Pnt PF,PL;
529 S->D0(pf.X(),pf.Y(),PF);
530 S->D0(pl.X(),pl.Y(),PL);
531 TopoDS_Vertex V1,V2;
532 if (Edg.Orientation() == TopAbs_REVERSED) {
533 V1 = TopExp::LastVertex(Edg);
534 V1.Reverse();
535 }
536 else {
537 V1 = TopExp::FirstVertex (Edg);
538 }
539 if (Edg.Orientation() == TopAbs_REVERSED) {
540 V2 = TopExp::FirstVertex(Edg);
541 V2.Reverse();
542 }
543 else {
544 V2 = TopExp::LastVertex (Edg);
545 }
546
547 if(!V1.IsNull() && V2.IsNull()) {
548 //Handling of internal vertices
549 Standard_Real old1 = BRep_Tool::Tolerance (V1);
550 Standard_Real old2 = BRep_Tool::Tolerance (V2);
551 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
552 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
553 Standard_Real tol1 = pnt1.Distance(PF);
554 Standard_Real tol2 = pnt2.Distance(PL);
555 B.UpdateVertex(V1,Max(old1,tol1));
556 B.UpdateVertex(V2,Max(old2,tol2));
557 }
558
559 if (S->IsUPeriodic()) {
560 Standard_Real up = S->UPeriod();
561 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
562 Standard_Integer nbtra = 0;
563 Standard_Real theUmin = Min(pf.X(),pl.X());
564 Standard_Real theUmax = Max(pf.X(),pl.X());
565
566 if (theUmin < Umin-tolu) {
567 while (theUmin < Umin-tolu) {
568 theUmin += up;
569 nbtra++;
570 }
571 }
572 else if (theUmax > Umax+tolu) {
573 while (theUmax > Umax+tolu) {
574 theUmax -= up;
575 nbtra--;
576 }
577 }
578
579/*
580 if (theUmin > Umax-tolu) {
581 while (theUmin > Umax-tolu) {
582 theUmin -= up;
583 nbtra--;
584 }
585 }
586 else if (theUmax < Umin+tolu) {
587 while (theUmax < Umin+tolu) {
588 theUmax += up;
589 nbtra++;
590 }
591 }
592*/
593 if (nbtra !=0) {
594 C2d->Translate(gp_Vec2d(nbtra*up,0.));
595 }
596 }
597
598 if (S->IsVPeriodic()) {
599 Standard_Real vp = S->VPeriod();
600 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
601 Standard_Integer nbtra = 0;
602 Standard_Real theVmin = Min(pf.Y(),pl.Y());
603 Standard_Real theVmax = Max(pf.Y(),pl.Y());
604
605 if (theVmin < Vmin-tolv) {
606 while (theVmin < Vmin-tolv) {
607 theVmin += vp; theVmax += vp;
608 nbtra++;
609 }
610 }
611 else if (theVmax > Vmax+tolv) {
612 while (theVmax > Vmax+tolv) {
613 theVmax -= vp; theVmin -= vp;
614 nbtra--;
615 }
616 }
617/*
618 if (theVmin > Vmax-tolv) {
619 while (theVmin > Vmax-tolv) {
620 theVmin -= vp;
621 nbtra--;
622 }
623 }
624 else if (theVmax < Vmin+tolv) {
625 while (theVmax < Vmin+tolv) {
626 theVmax += vp;
627 nbtra++;
628 }
629 }
630*/
631 if (nbtra !=0) {
632 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
633 }
634 }
635 B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
636
637 B.SameParameter(Edg,Standard_False);
638 BRepLib::SameParameter(Edg,tol2d);
639}
640
641
642//=======================================================================
643//function : PutPCurves
644//purpose :
645//=======================================================================
646
647void PutPCurves(const TopoDS_Edge& Efrom,
648 const TopoDS_Edge& Eto,
649 const TopoDS_Shape& myShape)
650{
651
652 TopTools_ListOfShape Lfaces;
653 TopExp_Explorer exp,exp2;
654
655 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
656 for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
657 if (exp2.Current().IsSame(Eto)) {
658 Lfaces.Append(exp.Current());
659 }
660 }
661 }
662
663 if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
664 Standard_ConstructionError::Raise();
665 }
666
667 // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
668
669 if (Lfaces.Extent() ==1) {
670 return; // sera fait par PutPCurve.... on l`espere
671 }
672
673 BRep_Builder B;
674 Handle(Geom_Surface) S;
675 Handle(Standard_Type) styp;
676 Handle(Geom_Curve) C;
677 Standard_Real Umin,Umax,Vmin,Vmax;
678 Standard_Real f,l;
679 TopLoc_Location Loc, LocFac;
680
681 if (!Lfaces.First().IsSame(Lfaces.Last())) {
682 TopTools_ListIteratorOfListOfShape itl(Lfaces);
683 for (; itl.More(); itl.Next()) {
684 const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
685
686 if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
687 continue;
688 }
689 S = BRep_Tool::Surface(Fac, LocFac);
690 styp = S->DynamicType();
691 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
692 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
693 styp = S->DynamicType();
694 }
695 if (styp == STANDARD_TYPE(Geom_Plane)) {
696 continue;
697 }
698
699
700 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
701 C = BRep_Tool::Curve(Efrom,Loc,f,l);
702 if (!Loc.IsIdentity()) {
703 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
704 C = *((Handle(Geom_Curve)*)&GG);
705 }
706
707 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
708 C = new Geom_TrimmedCurve(C,f,l);
709 }
710
711 S = BRep_Tool::Surface(Fac);
712
713 // Compute the tol2d
714 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
715 BRep_Tool::Tolerance(Fac));
716 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
717 Standard_Real TolU = Gas.UResolution(tol3d);
718 Standard_Real TolV = Gas.VResolution(tol3d);
719 Standard_Real tol2d = Max(TolU,TolV);
720
721 Handle(Geom2d_Curve) C2d =
722 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
723 if(C2d.IsNull())
724 return;
725
726 gp_Pnt2d pf(C2d->Value(f));
727 gp_Pnt2d pl(C2d->Value(l));
728
729 if (S->IsUPeriodic()) {
730 Standard_Real up = S->UPeriod();
731 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
732 Standard_Integer nbtra = 0;
733 Standard_Real theUmin = Min(pf.X(),pl.X());
734 Standard_Real theUmax = Max(pf.X(),pl.X());
735
736 if (theUmin < Umin-tolu) {
737 while (theUmin < Umin-tolu) {
738 theUmin += up; theUmax += up;
739 nbtra++;
740 }
741 }
742 else if (theUmax > Umax+tolu) {
743 while (theUmax > Umax+tolu) {
744 theUmax -= up; theUmin -= up;
745 nbtra--;
746 }
747 }
748/*
749 if (theUmin > Umax+tolu) {
750 while (theUmin > Umax+tolu) {
751 theUmin -= up;
752 nbtra--;
753 }
754 }
755 else if (theUmax < Umin-tolu) {
756 while (theUmax < Umin-tolu) {
757 theUmax += up;
758 nbtra++;
759 }
760 }
761*/
762 if (nbtra !=0) {
763 C2d->Translate(gp_Vec2d(nbtra*up,0.));
764 }
765 }
766
767 if (S->IsVPeriodic()) {
768 Standard_Real vp = S->VPeriod();
769 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
770 Standard_Integer nbtra = 0;
771 Standard_Real theVmin = Min(pf.Y(),pl.Y());
772 Standard_Real theVmax = Max(pf.Y(),pl.Y());
773
774 if (theVmin < Vmin-tolv) {
775 while (theVmin < Vmin-tolv) {
776 theVmin += vp; theVmax += vp;
777 nbtra++;
778 }
779 }
780 else if (theVmax > Vmax+tolv) {
781 while (theVmax > Vmax+tolv) {
782 theVmax -= vp; theVmin -= vp;
783 nbtra--;
784 }
785 }
786/*
787 if (theVmin > Vmax+tolv) {
788 while (theVmin > Vmax+tolv) {
789 theVmin -= vp;
790 nbtra--;
791 }
792 }
793 else if (theVmax < Vmin-tolv) {
794 while (theVmax < Vmin-tolv) {
795 theVmax += vp;
796 nbtra++;
797 }
798 }
799*/
800 if (nbtra !=0) {
801 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
802 }
803 }
804 B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
805 }
806 }
807
808 else {
809 const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
810 if (!BRep_Tool::IsClosed(Eto,Fac)) {
811 Standard_ConstructionError::Raise();
812 }
813
814 TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
815 TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
816 Handle(Geom2d_Curve) c2dff =
817 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
818 TopoDS::Face(aLocalF),
819 f,l);
820
821// Handle(Geom2d_Curve) c2dff =
822// BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
823// TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
824// f,l);
825
826 aLocalE = Efrom.Oriented(TopAbs_REVERSED);
827 aLocalF = Fac.Oriented(TopAbs_FORWARD);
828 Handle(Geom2d_Curve) c2dfr =
829 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
830 TopoDS::Face(aLocalF),
831 f,l);
832// Handle(Geom2d_Curve) c2dfr =
833// BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
834// TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
835// f,l);
836
837 aLocalE = Eto.Oriented(TopAbs_FORWARD);
838 aLocalF = Fac.Oriented(TopAbs_FORWARD);
839 Handle(Geom2d_Curve) c2dtf =
840 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
841 TopoDS::Face(aLocalF),
842 f,l);
843
844// Handle(Geom2d_Curve) c2dtf =
845// BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
846// TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
847// f,l);
848 aLocalE = Eto.Oriented(TopAbs_REVERSED);
849 aLocalF = Fac.Oriented(TopAbs_FORWARD);
850 Handle(Geom2d_Curve) c2dtr =
851 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
852 TopoDS::Face(aLocalF),
853 f,l);
854// Handle(Geom2d_Curve) c2dtr =
855// BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
856// TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
857// f,l);
858
859 gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
860 gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
861
862 Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
863
864 // Efrom et Eto dans le meme sens???
865
866 C = BRep_Tool::Curve(Efrom,Loc,f,l);
867 if (!Loc.IsIdentity()) {
868 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
869 C = *((Handle(Geom_Curve)*)&GG);
870 }
871
872 gp_Pnt pt;
873 gp_Vec d1f,d1t;
874
875 C->D1(f,pt,d1f);
876
877 Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),Eto);
878
879 C = BRep_Tool::Curve(Eto,Loc,f,l);
880 if (!Loc.IsIdentity()) {
881 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
882 C = *((Handle(Geom_Curve)*)&GG);
883 }
884
885 C->D1(prmproj,pt,d1t);
886
887 Standard_Real SameOri = (d1t.Dot(d1f)>0.);
888
889
890 if (c2dff.IsNull() && c2dfr.IsNull()) {
891 S = BRep_Tool::Surface(Fac);
892 styp = S->DynamicType();
893 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
894 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
895 styp = S->DynamicType();
896 }
897
898 C = BRep_Tool::Curve(Efrom,Loc,f,l);
899 if (!Loc.IsIdentity()) {
900 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
901 C = *((Handle(Geom_Curve)*)&GG);
902 }
903
904 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
905 C = new Geom_TrimmedCurve(C,f,l);
906 }
907
908 // Compute the tol2d
909 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
910
911 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
912 BRep_Tool::Tolerance(Fac));
913 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
914 Standard_Real TolU = Gas.UResolution(tol3d);
915 Standard_Real TolV = Gas.VResolution(tol3d);
916 Standard_Real tol2d = Max(TolU,TolV);
917
918 Handle(Geom2d_Curve) C2d =
919 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
920 c2dff = C2d;
921 c2dfr = C2d;
922 }
923 else if (c2dfr.IsNull()) {
924 c2dfr = c2dff;
925
926 }
927 else if (c2dff.IsNull()) {
928 c2dff = c2dfr;
929 }
930
931 BRep_Tool::Range(Efrom,f,l);
932
933 gp_Pnt2d p2f = c2dff->Value(f);
934 gp_Pnt2d p2r = c2dfr->Value(f);
935
936 if (isoU) {
937 if (SameOri) {
938 if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
939 c2dff = Handle(Geom2d_Curve)::DownCast
940 (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
941 }
942 if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
943 c2dfr = Handle(Geom2d_Curve)::DownCast
944 (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
945 }
946 }
947 else {
948 if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
949 c2dff = Handle(Geom2d_Curve)::DownCast
950 (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
951 }
952
953 if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
954 c2dfr = Handle(Geom2d_Curve)::DownCast
955 (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
956 }
957 }
958
959 // on est bien en U, recalage si periodique en V a faire
960
961
962
963 }
964
965 else { // !isoU soit isoV
966 if (SameOri) {
967 if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
968 c2dff = Handle(Geom2d_Curve)::DownCast
969 (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
970 }
971 if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
972 c2dfr = Handle(Geom2d_Curve)::DownCast
973 (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
974 }
975 }
976 else {
977 if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
978 c2dff = Handle(Geom2d_Curve)::DownCast
979 (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
980 }
981 if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
982 c2dfr = Handle(Geom2d_Curve)::DownCast
983 (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
984 }
985 }
986 // on est bien en V, recalage si periodique en U a faire
987
988 }
989 B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
990 }
991}
992