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