0025161: Exception in draw trying pload ALL (espesially TOPTEST)
[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
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <LocOpe_WiresOnShape.ixx>
18
19#include <TopExp_Explorer.hxx>
20#include <BRep_Builder.hxx>
21#include <BRep_Tool.hxx>
22#include <TopTools_MapOfShape.hxx>
23#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
24#include <TopTools_ListOfShape.hxx>
25#include <TopTools_ListIteratorOfListOfShape.hxx>
26
27#include <GeomAPI_ProjectPointOnCurve.hxx>
28#include <GeomAdaptor_Surface.hxx>
29#include <Geom_Curve.hxx>
30#include <Geom_TrimmedCurve.hxx>
31#include <Geom_Surface.hxx>
32#include <Geom_RectangularTrimmedSurface.hxx>
33#include <Geom2d_Curve.hxx>
34
35#include <gp_Pnt2d.hxx>
36#include <gp_Vec2d.hxx>
37#include <gp_Vec.hxx>
38
39#include <TopoDS.hxx>
40#include <TopExp.hxx>
41#include <BRepTools.hxx>
42#include <GeomProjLib.hxx>
43#include <LocOpe.hxx>
44#include <Precision.hxx>
45
46#include <Standard_ConstructionError.hxx>
47#include <TopoDS_Compound.hxx>
48#include <BRepLib.hxx>
49
ed60a55e 50#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
51#include <BRepAdaptor_Curve2d.hxx>
52#include <Bnd_Box2d.hxx>
53#include <BndLib_Add2dCurve.hxx>
54#include <Extrema_ExtCC.hxx>
55#include <BRepLib_MakeVertex.hxx>
56
57
7fd59977 58static Standard_Boolean Project(const TopoDS_Vertex&,
59 const TopoDS_Face&,
60 TopoDS_Edge&,
61 Standard_Real&);
62
63static Standard_Real Project(const TopoDS_Vertex&,
64 const TopoDS_Edge&);
65
66
67static void PutPCurve(const TopoDS_Edge&,
68 const TopoDS_Face&);
69
70
71static void PutPCurves(const TopoDS_Edge&,
72 const TopoDS_Edge&,
73 const TopoDS_Shape&);
74
ed60a55e 75static void FindInternalIntersections(const TopoDS_Edge&,
76 const TopoDS_Face&,
77 TopTools_IndexedDataMapOfShapeListOfShape&,
78 TopTools_DataMapOfShapeShape&,
79 TopTools_MapOfShape&);
7fd59977 80
81//=======================================================================
82//function : LocOpe_WiresOnShape
83//purpose :
84//=======================================================================
85
86LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S):
7c104885 87 myShape(S),myCheckInterior(Standard_True),myDone(Standard_False)
7fd59977 88{}
89
90
91
92//=======================================================================
93//function : Init
94//purpose :
95//=======================================================================
96
97void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
98{
99 myShape = S;
7c104885 100 myCheckInterior = Standard_True;
7fd59977 101 myDone = Standard_False;
102 myMap.Clear();
103 myMapEF.Clear();
104}
105
106
107
108//=======================================================================
109//function : Bind
110//purpose :
111//=======================================================================
112
113void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
114 const TopoDS_Face& F)
115{
ed60a55e 116 for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) {
7fd59977 117 Bind(TopoDS::Edge(exp.Current()),F);
118 }
119}
120
ed60a55e 121//=======================================================================
122//function : Bind
123//purpose :
124//=======================================================================
125
126void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp,
127 const TopoDS_Face& F)
128{
129 for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) {
130 Bind(TopoDS::Edge(exp.Current()),F);
131 }
132 myFacesWithSection.Add(F);
133}
7fd59977 134
135//=======================================================================
136//function : Bind
137//purpose :
138//=======================================================================
139
140void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E,
141 const TopoDS_Face& F)
142{
143// if (!myMapEF.IsBound(E)) {
144 if (!myMapEF.Contains(E)) {
145// for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) {
146 TopExp_Explorer exp(F,TopAbs_EDGE) ;
147 for ( ;exp.More();exp.Next()) {
148 if (exp.Current().IsSame(E)) {
149 break;
150 }
151 }
152 if (!exp.More()) {
153// myMapEF.Bind(E,F);
154 myMapEF.Add(E,F);
155 }
156 }
157 else {
158 Standard_ConstructionError::Raise();
159 }
160}
161
162
163//=======================================================================
164//function : Bind
165//purpose :
166//=======================================================================
167
168void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir,
169 const TopoDS_Edge& Efac)
170{
171 if (Ewir.IsSame(Efac)) {
172 return;
173 }
174 myMap.Bind(Ewir,Efac);
175}
176
177
178//=======================================================================
179//function : BindAll
180//purpose :
181//=======================================================================
182
183void LocOpe_WiresOnShape::BindAll()
184{
185 if (myDone) {
186 return;
187 }
188 TopTools_MapOfShape theMap;
189
190 // Detection des vertex a projeter ou a "binder" avec des vertex existants
191 TopTools_DataMapOfShapeShape mapV;
192 TopTools_DataMapIteratorOfDataMapOfShapeShape ite(myMap);
193 TopExp_Explorer exp,exp2;
194 for (; ite.More(); ite.Next()) {
195 const TopoDS_Edge& eref = TopoDS::Edge(ite.Key());
196 const TopoDS_Edge& eimg = TopoDS::Edge(ite.Value());
197
198 PutPCurves(eref,eimg,myShape);
199
200 for (exp.Init(eref,TopAbs_VERTEX); exp.More(); exp.Next()) {
201 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
202 if (!theMap.Contains(vtx)) { // pas deja traite
203 for (exp2.Init(eimg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
204 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
205 if (vtx2.IsSame(vtx)) {
206 break;
207 }
208 else if (BRepTools::Compare(vtx,vtx2)) {
209 mapV.Bind(vtx,vtx2);
210 break;
211 }
212 }
213 if (!exp2.More()) {
214 mapV.Bind(vtx,eimg);
215 }
216 theMap.Add(vtx);
217 }
218 }
219 }
220
221 for (ite.Initialize(mapV); ite.More(); ite.Next()) {
222 myMap.Bind(ite.Key(),ite.Value());
223 }
224
ed60a55e 225 TopTools_IndexedDataMapOfShapeListOfShape Splits;
226 Standard_Integer Ind;
227 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++)
228 {
229 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
230 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
231
232 PutPCurve(edg,fac);
233 Standard_Real pf, pl;
234 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(edg, fac, pf, pl);
235 if (aPCurve.IsNull())
236 continue;
237
7c104885 238 if (myCheckInterior)
239 FindInternalIntersections(edg, fac, Splits, myMap, theMap);
ed60a55e 240 }
241
242 for (Ind = 1; Ind <= Splits.Extent(); Ind++)
243 {
244 TopoDS_Shape anEdge = Splits.FindKey(Ind);
245 TopoDS_Shape aFace = myMapEF.FindFromKey(anEdge);
246 //Remove "anEdge" from "myMapEF"
247 TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent());
248 TopoDS_Shape LastFace = myMapEF(myMapEF.Extent());
249 myMapEF.RemoveLast();
250 if (myMapEF.FindIndex(anEdge) != 0)
251 myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace);
252 ////////////////////////////////
253 TopTools_ListIteratorOfListOfShape itl(Splits(Ind));
254 for (; itl.More(); itl.Next())
255 myMapEF.Add(itl.Value(), aFace);
256 }
257
7fd59977 258 // Il faut s`occuper maintenant des vertex "de changement de face",
259 // et des vertex "libres"
260// TopTools_DataMapIteratorOfDataMapOfShapeShape ite2;
261
262// for (ite.Initialize(myMapEF); ite.More(); ite.Next()) {
263// const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
264// const TopoDS_Face& fac = TopoDS::Face(ite.Value());
ed60a55e 265 for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
7fd59977 266 const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
267 const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
268 // JAG 02.02.96 : On verifie les pcurves...
269
ed60a55e 270 //PutPCurve(edg,fac);
7fd59977 271
272 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
273 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
274 if (theMap.Contains(vtx)) {
275 continue;
276 }
277 TopoDS_Edge Epro;
278 Standard_Real prm;
279 Standard_Boolean ok = Project(vtx,fac,Epro,prm);
280 if (ok) {
281 for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
282 const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current());
283 if (vtx2.IsSame(vtx)) {
284 break;
285 }
286 else if (BRepTools::Compare(vtx,vtx2)) {
287 myMap.Bind(vtx,vtx2);
288 break;
289 }
290 }
291 if (!exp2.More()) {
292 myMap.Bind(vtx,Epro);
293 }
294 theMap.Add(vtx);
295 }
296 }
297 }
298
299// Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin
300 for (ite.Initialize(myMap); ite.More(); ite.Next())
301 if ((ite.Key()).ShapeType() == TopAbs_EDGE)
302 myMapEF.Add(ite.Key(),ite.Value());
303// Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End
304
305
306 myDone = Standard_True;
307
308}
309
310
311//=======================================================================
312//function : InitEdgeIterator
313//purpose :
314//=======================================================================
315
316void LocOpe_WiresOnShape::InitEdgeIterator()
317{
318 BindAll();
319// myIt.Initialize(myMapEF);
320 myIndex = 1;
321}
322
323
324//=======================================================================
325//function : MoreEdge
326//purpose :
327//=======================================================================
328
329Standard_Boolean LocOpe_WiresOnShape::MoreEdge()
330{
331// return myIt.More();
332 return (myIndex <= myMapEF.Extent());
333}
334
335
336//=======================================================================
337//function : Edge
338//purpose :
339//=======================================================================
340
341TopoDS_Edge LocOpe_WiresOnShape::Edge()
342{
343// return TopoDS::Edge(myIt.Key());
344 return TopoDS::Edge(myMapEF.FindKey(myIndex));
345}
346
347
348//=======================================================================
349//function : Face
350//purpose :
351//=======================================================================
352
353TopoDS_Face LocOpe_WiresOnShape::OnFace()
354{
355// return TopoDS::Face(myIt.Value());
356 return TopoDS::Face(myMapEF(myIndex));
357}
358
359
360//=======================================================================
361//function : OnEdge
362//purpose :
363//=======================================================================
364
365Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E)
366{
367// if (myMap.IsBound(myIt.Key())) {
368 if (myMap.IsBound(myMapEF.FindKey(myIndex))) {
369// E = TopoDS::Edge(myMap(myIt.Key()));
370 E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex)));
371 return Standard_True;
372 }
373 return Standard_False;
374}
375
376
377
378
379//=======================================================================
380//function : NextEdge
381//purpose :
382//=======================================================================
383
384void LocOpe_WiresOnShape::NextEdge()
385{
386// myIt.Next();
387 myIndex++;
388}
389
390
391
392//=======================================================================
393//function : OnVertex
394//purpose :
395//=======================================================================
396
397Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw,
398 TopoDS_Vertex& Vs)
399{
400 if (myMap.IsBound(Vw)) {
401 if (myMap(Vw).ShapeType() == TopAbs_VERTEX) {
402 Vs = TopoDS::Vertex(myMap(Vw));
403 return Standard_True;
404 }
405 return Standard_False;
406 }
407 return Standard_False;
408}
409
410
411
412
413//=======================================================================
414//function : OnEdge
415//purpose :
416//=======================================================================
417
418Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V,
419 TopoDS_Edge& Ed,
420 Standard_Real& prm)
421{
422 if (!myMap.IsBound(V) ||
423 myMap(V).ShapeType() == TopAbs_VERTEX) {
424 return Standard_False;
425 }
426
427 Ed = TopoDS::Edge(myMap(V));
428 prm = Project(V,Ed);
429 return Standard_True;
430}
431
432
433//=======================================================================
434//function : Project
435//purpose :
436//=======================================================================
437
438Standard_Boolean Project(const TopoDS_Vertex& V,
439 const TopoDS_Face& F,
440 TopoDS_Edge& theEdge,
441 Standard_Real& param)
442{
443 Handle(Geom_Curve) C;
444 TopLoc_Location Loc;
445 Standard_Real f,l;
446
447 Standard_Real dmin = RealLast();
448 gp_Pnt toproj(BRep_Tool::Pnt(V));
449 Standard_Boolean valret = Standard_False;
450 GeomAPI_ProjectPointOnCurve proj;
451
452 for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
453 exp.More(); exp.Next()) {
454 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
455 if (!BRep_Tool::Degenerated(edg)) {
456 C = BRep_Tool::Curve(edg,Loc,f,l);
457 if (!Loc.IsIdentity()) {
458 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
459 C = *((Handle(Geom_Curve)*)&GG);
460 }
461 proj.Init(toproj,C,f,l);
462 if (proj.NbPoints() > 0) {
463 if (proj.LowerDistance() < dmin) {
464 theEdge = edg;
465 theEdge.Orientation(edg.Orientation());
466 dmin = proj.LowerDistance();
467 param = proj.LowerDistanceParameter();
468 }
469 }
470 }
471 }
472
473 if(theEdge.IsNull())
474 return Standard_False;
475
476 Standard_Real ttol = BRep_Tool::Tolerance(V) + BRep_Tool::Tolerance(theEdge);
477 if (dmin <= ttol) {
478 valret = Standard_True;
479 BRep_Builder B;
480 B.UpdateVertex(V, Max(dmin, BRep_Tool::Tolerance(V)));
481 }
482#ifdef DEB_MESH
483 else {
484 cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une ";
485 cout <<"distance / la face = "<<dmin <<" superieure a la tolerance = "<<ttol<<endl;
486 }
487#endif
488 return valret;
489}
490
491//=======================================================================
492//function : Project
493//purpose :
494//=======================================================================
495
496Standard_Real Project(const TopoDS_Vertex& V,
497 const TopoDS_Edge& theEdge)
498{
499 Handle(Geom_Curve) C;
500 TopLoc_Location Loc;
501 Standard_Real f,l;
502
503 gp_Pnt toproj(BRep_Tool::Pnt(V));
504 GeomAPI_ProjectPointOnCurve proj;
505
506 C = BRep_Tool::Curve(theEdge,Loc,f,l);
507 if (!Loc.IsIdentity()) {
508 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
509 C = *((Handle(Geom_Curve)*)&GG);
510 }
511 proj.Init(toproj,C,f,l);
512
513
514 return proj.LowerDistanceParameter();
515}
516
517
518//=======================================================================
519//function : PutPCurve
520//purpose :
521//=======================================================================
522
523void PutPCurve(const TopoDS_Edge& Edg,
524 const TopoDS_Face& Fac)
525{
526 BRep_Builder B;
527 TopLoc_Location LocFac;
528
529 Handle(Geom_Surface) S = BRep_Tool::Surface(Fac, LocFac);
530 Handle(Standard_Type) styp = S->DynamicType();
531
532 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
533 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
534 styp = S->DynamicType();
535 }
536
537 if (styp == STANDARD_TYPE(Geom_Plane)) {
538 return;
539 }
540
541 Standard_Real Umin,Umax,Vmin,Vmax;
542 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
543
544 Standard_Real f,l;
545
546 //if (!BRep_Tool::CurveOnSurface(Edg,Fac,f,l).IsNull()) {
547 // return;
548 //}
549 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(Edg,Fac,f,l);
550 if ( !aC2d.IsNull() ) {
551 gp_Pnt2d p2d;
552 aC2d->D0(f,p2d);
553 Standard_Boolean IsIn = Standard_True;
554 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
555 ( p2d.X() > Umax+Precision::PConfusion() ) )
556 IsIn = Standard_False;
557 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
558 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
559 IsIn = Standard_False;
560 aC2d->D0(l,p2d);
561 if ( ( p2d.X() < Umin-Precision::PConfusion() ) ||
562 ( p2d.X() > Umax+Precision::PConfusion() ) )
563 IsIn = Standard_False;
564 if ( ( p2d.Y() < Vmin-Precision::PConfusion() ) ||
565 ( p2d.Y() > Vmax+Precision::PConfusion() ) )
566 IsIn = Standard_False;
567 if (IsIn)
568 return;
569 }
570
571 TopLoc_Location Loc;
572 Handle(Geom_Curve) C = BRep_Tool::Curve(Edg,Loc,f,l);
573 if (!Loc.IsIdentity()) {
574 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
575 C = *((Handle(Geom_Curve)*)&GG);
576 }
577
578 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
579 C = new Geom_TrimmedCurve(C,f,l);
580 }
581
582 S = BRep_Tool::Surface(Fac);
583
584 // Compute the tol2d
585 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Edg),
586 BRep_Tool::Tolerance(Fac));
587 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
588 Standard_Real TolU = Gas.UResolution(tol3d);
589 Standard_Real TolV = Gas.VResolution(tol3d);
590 Standard_Real tol2d = Max(TolU,TolV);
591
592 Handle(Geom2d_Curve) C2d =
593 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
594 if(C2d.IsNull())
595 return;
596 gp_Pnt2d pf(C2d->Value(f));
597 gp_Pnt2d pl(C2d->Value(l));
598 gp_Pnt PF,PL;
599 S->D0(pf.X(),pf.Y(),PF);
600 S->D0(pl.X(),pl.Y(),PL);
601 TopoDS_Vertex V1,V2;
602 if (Edg.Orientation() == TopAbs_REVERSED) {
603 V1 = TopExp::LastVertex(Edg);
604 V1.Reverse();
605 }
606 else {
607 V1 = TopExp::FirstVertex (Edg);
608 }
609 if (Edg.Orientation() == TopAbs_REVERSED) {
610 V2 = TopExp::FirstVertex(Edg);
611 V2.Reverse();
612 }
613 else {
614 V2 = TopExp::LastVertex (Edg);
615 }
616
617 if(!V1.IsNull() && V2.IsNull()) {
618 //Handling of internal vertices
619 Standard_Real old1 = BRep_Tool::Tolerance (V1);
620 Standard_Real old2 = BRep_Tool::Tolerance (V2);
621 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
622 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
623 Standard_Real tol1 = pnt1.Distance(PF);
624 Standard_Real tol2 = pnt2.Distance(PL);
625 B.UpdateVertex(V1,Max(old1,tol1));
626 B.UpdateVertex(V2,Max(old2,tol2));
627 }
628
629 if (S->IsUPeriodic()) {
630 Standard_Real up = S->UPeriod();
631 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
632 Standard_Integer nbtra = 0;
633 Standard_Real theUmin = Min(pf.X(),pl.X());
634 Standard_Real theUmax = Max(pf.X(),pl.X());
635
636 if (theUmin < Umin-tolu) {
637 while (theUmin < Umin-tolu) {
638 theUmin += up;
639 nbtra++;
640 }
641 }
642 else if (theUmax > Umax+tolu) {
643 while (theUmax > Umax+tolu) {
644 theUmax -= up;
645 nbtra--;
646 }
647 }
648
649/*
650 if (theUmin > Umax-tolu) {
651 while (theUmin > Umax-tolu) {
652 theUmin -= up;
653 nbtra--;
654 }
655 }
656 else if (theUmax < Umin+tolu) {
657 while (theUmax < Umin+tolu) {
658 theUmax += up;
659 nbtra++;
660 }
661 }
662*/
663 if (nbtra !=0) {
664 C2d->Translate(gp_Vec2d(nbtra*up,0.));
665 }
666 }
667
668 if (S->IsVPeriodic()) {
669 Standard_Real vp = S->VPeriod();
670 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
671 Standard_Integer nbtra = 0;
672 Standard_Real theVmin = Min(pf.Y(),pl.Y());
673 Standard_Real theVmax = Max(pf.Y(),pl.Y());
674
675 if (theVmin < Vmin-tolv) {
676 while (theVmin < Vmin-tolv) {
677 theVmin += vp; theVmax += vp;
678 nbtra++;
679 }
680 }
681 else if (theVmax > Vmax+tolv) {
682 while (theVmax > Vmax+tolv) {
683 theVmax -= vp; theVmin -= vp;
684 nbtra--;
685 }
686 }
687/*
688 if (theVmin > Vmax-tolv) {
689 while (theVmin > Vmax-tolv) {
690 theVmin -= vp;
691 nbtra--;
692 }
693 }
694 else if (theVmax < Vmin+tolv) {
695 while (theVmax < Vmin+tolv) {
696 theVmax += vp;
697 nbtra++;
698 }
699 }
700*/
701 if (nbtra !=0) {
702 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
703 }
704 }
705 B.UpdateEdge(Edg,C2d,Fac,BRep_Tool::Tolerance(Edg));
706
707 B.SameParameter(Edg,Standard_False);
708 BRepLib::SameParameter(Edg,tol2d);
709}
710
711
712//=======================================================================
713//function : PutPCurves
714//purpose :
715//=======================================================================
716
717void PutPCurves(const TopoDS_Edge& Efrom,
718 const TopoDS_Edge& Eto,
719 const TopoDS_Shape& myShape)
720{
721
722 TopTools_ListOfShape Lfaces;
723 TopExp_Explorer exp,exp2;
724
725 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
726 for (exp2.Init(exp.Current(), TopAbs_EDGE); exp2.More();exp2.Next()) {
727 if (exp2.Current().IsSame(Eto)) {
728 Lfaces.Append(exp.Current());
729 }
730 }
731 }
732
733 if (Lfaces.Extent() != 1 && Lfaces.Extent() !=2) {
734 Standard_ConstructionError::Raise();
735 }
736
737 // soit bord libre, soit connexite entre 2 faces, eventuellement edge closed
738
739 if (Lfaces.Extent() ==1) {
740 return; // sera fait par PutPCurve.... on l`espere
741 }
742
743 BRep_Builder B;
744 Handle(Geom_Surface) S;
745 Handle(Standard_Type) styp;
746 Handle(Geom_Curve) C;
747 Standard_Real Umin,Umax,Vmin,Vmax;
748 Standard_Real f,l;
749 TopLoc_Location Loc, LocFac;
750
751 if (!Lfaces.First().IsSame(Lfaces.Last())) {
752 TopTools_ListIteratorOfListOfShape itl(Lfaces);
753 for (; itl.More(); itl.Next()) {
754 const TopoDS_Face& Fac = TopoDS::Face(itl.Value());
755
756 if (!BRep_Tool::CurveOnSurface(Efrom,Fac,f,l).IsNull()) {
757 continue;
758 }
759 S = BRep_Tool::Surface(Fac, LocFac);
760 styp = S->DynamicType();
761 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
762 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
763 styp = S->DynamicType();
764 }
765 if (styp == STANDARD_TYPE(Geom_Plane)) {
766 continue;
767 }
768
769
770 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
771 C = BRep_Tool::Curve(Efrom,Loc,f,l);
772 if (!Loc.IsIdentity()) {
773 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
774 C = *((Handle(Geom_Curve)*)&GG);
775 }
776
777 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
778 C = new Geom_TrimmedCurve(C,f,l);
779 }
780
781 S = BRep_Tool::Surface(Fac);
782
783 // Compute the tol2d
784 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
785 BRep_Tool::Tolerance(Fac));
786 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
787 Standard_Real TolU = Gas.UResolution(tol3d);
788 Standard_Real TolV = Gas.VResolution(tol3d);
789 Standard_Real tol2d = Max(TolU,TolV);
790
791 Handle(Geom2d_Curve) C2d =
792 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
793 if(C2d.IsNull())
794 return;
795
796 gp_Pnt2d pf(C2d->Value(f));
797 gp_Pnt2d pl(C2d->Value(l));
798
799 if (S->IsUPeriodic()) {
800 Standard_Real up = S->UPeriod();
801 Standard_Real tolu = Precision::PConfusion();// Epsilon(up);
802 Standard_Integer nbtra = 0;
803 Standard_Real theUmin = Min(pf.X(),pl.X());
804 Standard_Real theUmax = Max(pf.X(),pl.X());
805
806 if (theUmin < Umin-tolu) {
807 while (theUmin < Umin-tolu) {
808 theUmin += up; theUmax += up;
809 nbtra++;
810 }
811 }
812 else if (theUmax > Umax+tolu) {
813 while (theUmax > Umax+tolu) {
814 theUmax -= up; theUmin -= up;
815 nbtra--;
816 }
817 }
818/*
819 if (theUmin > Umax+tolu) {
820 while (theUmin > Umax+tolu) {
821 theUmin -= up;
822 nbtra--;
823 }
824 }
825 else if (theUmax < Umin-tolu) {
826 while (theUmax < Umin-tolu) {
827 theUmax += up;
828 nbtra++;
829 }
830 }
831*/
832 if (nbtra !=0) {
833 C2d->Translate(gp_Vec2d(nbtra*up,0.));
834 }
835 }
836
837 if (S->IsVPeriodic()) {
838 Standard_Real vp = S->VPeriod();
839 Standard_Real tolv = Precision::PConfusion();// Epsilon(vp);
840 Standard_Integer nbtra = 0;
841 Standard_Real theVmin = Min(pf.Y(),pl.Y());
842 Standard_Real theVmax = Max(pf.Y(),pl.Y());
843
844 if (theVmin < Vmin-tolv) {
845 while (theVmin < Vmin-tolv) {
846 theVmin += vp; theVmax += vp;
847 nbtra++;
848 }
849 }
850 else if (theVmax > Vmax+tolv) {
851 while (theVmax > Vmax+tolv) {
852 theVmax -= vp; theVmin -= vp;
853 nbtra--;
854 }
855 }
856/*
857 if (theVmin > Vmax+tolv) {
858 while (theVmin > Vmax+tolv) {
859 theVmin -= vp;
860 nbtra--;
861 }
862 }
863 else if (theVmax < Vmin-tolv) {
864 while (theVmax < Vmin-tolv) {
865 theVmax += vp;
866 nbtra++;
867 }
868 }
869*/
870 if (nbtra !=0) {
871 C2d->Translate(gp_Vec2d(0.,nbtra*vp));
872 }
873 }
874 B.UpdateEdge(Efrom,C2d,Fac,BRep_Tool::Tolerance(Efrom));
875 }
876 }
877
878 else {
879 const TopoDS_Face& Fac = TopoDS::Face(Lfaces.First());
880 if (!BRep_Tool::IsClosed(Eto,Fac)) {
881 Standard_ConstructionError::Raise();
882 }
883
884 TopoDS_Shape aLocalE = Efrom.Oriented(TopAbs_FORWARD);
885 TopoDS_Shape aLocalF = Fac.Oriented(TopAbs_FORWARD);
886 Handle(Geom2d_Curve) c2dff =
887 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
888 TopoDS::Face(aLocalF),
889 f,l);
890
891// Handle(Geom2d_Curve) c2dff =
892// BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_FORWARD)),
893// TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
894// f,l);
895
896 aLocalE = Efrom.Oriented(TopAbs_REVERSED);
897 aLocalF = Fac.Oriented(TopAbs_FORWARD);
898 Handle(Geom2d_Curve) c2dfr =
899 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
900 TopoDS::Face(aLocalF),
901 f,l);
902// Handle(Geom2d_Curve) c2dfr =
903// BRep_Tool::CurveOnSurface(TopoDS::Edge(Efrom.Oriented(TopAbs_REVERSED)),
904// TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
905// f,l);
906
907 aLocalE = Eto.Oriented(TopAbs_FORWARD);
908 aLocalF = Fac.Oriented(TopAbs_FORWARD);
909 Handle(Geom2d_Curve) c2dtf =
910 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
911 TopoDS::Face(aLocalF),
912 f,l);
913
914// Handle(Geom2d_Curve) c2dtf =
915// BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_FORWARD)),
916// TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
917// f,l);
918 aLocalE = Eto.Oriented(TopAbs_REVERSED);
919 aLocalF = Fac.Oriented(TopAbs_FORWARD);
920 Handle(Geom2d_Curve) c2dtr =
921 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalE),
922 TopoDS::Face(aLocalF),
923 f,l);
924// Handle(Geom2d_Curve) c2dtr =
925// BRep_Tool::CurveOnSurface(TopoDS::Edge(Eto.Oriented(TopAbs_REVERSED)),
926// TopoDS::Face(Fac.Oriented(TopAbs_FORWARD)),
927// f,l);
928
929 gp_Pnt2d ptf(c2dtf->Value(f)); // sur courbe frw
930 gp_Pnt2d ptr(c2dtr->Value(f)); // sur courbe rev
931
932 Standard_Boolean isoU = (Abs(ptf.Y()-ptr.Y())<Epsilon(ptf.X())); // meme V
933
934 // Efrom et Eto dans le meme sens???
935
936 C = BRep_Tool::Curve(Efrom,Loc,f,l);
937 if (!Loc.IsIdentity()) {
938 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
939 C = *((Handle(Geom_Curve)*)&GG);
940 }
941
942 gp_Pnt pt;
943 gp_Vec d1f,d1t;
944
945 C->D1(f,pt,d1f);
946
947 Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),Eto);
948
949 C = BRep_Tool::Curve(Eto,Loc,f,l);
950 if (!Loc.IsIdentity()) {
951 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
952 C = *((Handle(Geom_Curve)*)&GG);
953 }
954
955 C->D1(prmproj,pt,d1t);
956
957 Standard_Real SameOri = (d1t.Dot(d1f)>0.);
958
959
960 if (c2dff.IsNull() && c2dfr.IsNull()) {
961 S = BRep_Tool::Surface(Fac);
962 styp = S->DynamicType();
963 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
964 S = (*((Handle(Geom_RectangularTrimmedSurface)*)&(S)))->BasisSurface();
965 styp = S->DynamicType();
966 }
967
968 C = BRep_Tool::Curve(Efrom,Loc,f,l);
969 if (!Loc.IsIdentity()) {
970 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
971 C = *((Handle(Geom_Curve)*)&GG);
972 }
973
974 if (C->DynamicType() != STANDARD_TYPE(Geom_TrimmedCurve)) {
975 C = new Geom_TrimmedCurve(C,f,l);
976 }
977
978 // Compute the tol2d
979 BRepTools::UVBounds(Fac,Umin,Umax,Vmin,Vmax);
980
981 Standard_Real tol3d = Max(BRep_Tool::Tolerance(Efrom),
982 BRep_Tool::Tolerance(Fac));
983 GeomAdaptor_Surface Gas(S,Umin,Umax,Vmin,Vmax);
984 Standard_Real TolU = Gas.UResolution(tol3d);
985 Standard_Real TolV = Gas.VResolution(tol3d);
986 Standard_Real tol2d = Max(TolU,TolV);
987
988 Handle(Geom2d_Curve) C2d =
989 GeomProjLib::Curve2d(C,S,Umin,Umax,Vmin,Vmax,tol2d);
990 c2dff = C2d;
991 c2dfr = C2d;
992 }
993 else if (c2dfr.IsNull()) {
994 c2dfr = c2dff;
995
996 }
997 else if (c2dff.IsNull()) {
998 c2dff = c2dfr;
999 }
1000
1001 BRep_Tool::Range(Efrom,f,l);
1002
1003 gp_Pnt2d p2f = c2dff->Value(f);
1004 gp_Pnt2d p2r = c2dfr->Value(f);
1005
1006 if (isoU) {
1007 if (SameOri) {
1008 if (Abs(ptf.X()-p2f.X()) > Epsilon(ptf.X())) {
1009 c2dff = Handle(Geom2d_Curve)::DownCast
1010 (c2dff->Translated(gp_Vec2d(ptf.X()-p2f.X(),0.)));
1011 }
1012 if (Abs(ptr.X()-p2r.X()) > Epsilon(ptr.X())) {
1013 c2dfr = Handle(Geom2d_Curve)::DownCast
1014 (c2dfr->Translated(gp_Vec2d(ptr.X()-p2r.X(),0.)));
1015 }
1016 }
1017 else {
1018 if (Abs(ptr.X()-p2f.X()) > Epsilon(ptr.X())) {
1019 c2dff = Handle(Geom2d_Curve)::DownCast
1020 (c2dff->Translated(gp_Vec2d(ptr.X()-p2f.X(),0.)));
1021 }
1022
1023 if (Abs(ptf.X()-p2r.X()) > Epsilon(ptf.X())) {
1024 c2dfr = Handle(Geom2d_Curve)::DownCast
1025 (c2dfr->Translated(gp_Vec2d(ptf.X()-p2r.X(),0.)));
1026 }
1027 }
1028
1029 // on est bien en U, recalage si periodique en V a faire
1030
1031
1032
1033 }
1034
1035 else { // !isoU soit isoV
1036 if (SameOri) {
1037 if (Abs(ptf.Y()-p2f.Y()) > Epsilon(ptf.Y())) {
1038 c2dff = Handle(Geom2d_Curve)::DownCast
1039 (c2dff->Translated(gp_Vec2d(0.,ptf.Y()-p2f.Y())));
1040 }
1041 if (Abs(ptr.Y()-p2r.Y()) > Epsilon(ptr.Y())) {
1042 c2dfr = Handle(Geom2d_Curve)::DownCast
1043 (c2dfr->Translated(gp_Vec2d(0.,ptr.Y()-p2r.Y())));
1044 }
1045 }
1046 else {
1047 if (Abs(ptr.Y()-p2f.Y()) > Epsilon(ptr.Y())) {
1048 c2dff = Handle(Geom2d_Curve)::DownCast
1049 (c2dff->Translated(gp_Vec2d(0.,ptr.Y()-p2f.Y())));
1050 }
1051 if (Abs(ptf.Y()-p2r.Y()) > Epsilon(ptf.Y())) {
1052 c2dfr = Handle(Geom2d_Curve)::DownCast
1053 (c2dfr->Translated(gp_Vec2d(0.,ptf.Y()-p2r.Y())));
1054 }
1055 }
1056 // on est bien en V, recalage si periodique en U a faire
1057
1058 }
1059 B.UpdateEdge(Efrom,c2dff,c2dfr,Fac,BRep_Tool::Tolerance(Efrom));
1060 }
1061}
1062
ed60a55e 1063//=======================================================================
1064//function : FindInternalIntersections
1065//purpose :
1066//=======================================================================
1067
1068void FindInternalIntersections(const TopoDS_Edge& theEdge,
1069 const TopoDS_Face& theFace,
1070 TopTools_IndexedDataMapOfShapeListOfShape& Splits,
1071 TopTools_DataMapOfShapeShape& GlobalMap,
1072 TopTools_MapOfShape& theMap)
1073{
1074 Standard_Real TolExt = Precision::PConfusion();
1075 Standard_Integer i, j, aNbExt;
1076
1077 TColStd_SequenceOfReal SplitPars;
1078
1079 TopoDS_Vertex theVertices [2];
1080 TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
1081 if (theEdge.Orientation() == TopAbs_REVERSED)
1082 {
1083 theVertices[0].Reverse();
1084 theVertices[1].Reverse();
1085 }
1086 gp_Pnt thePnt [2];
1087 thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
1088 thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
1089
1090 BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
1091 Bnd_Box2d theBox;
1092 BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
1093
1094 Standard_Real thePar [2];
1095 Standard_Real /*theFpar, theLpar,*/ aFpar, aLpar;
1096 const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
1097 GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
1098
1099 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1100 for (; Explo.More(); Explo.Next())
1101 {
1102 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1103 BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
1104 Bnd_Box2d aBox;
1105 BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
1106 if (theBox.IsOut(aBox))
1107 continue;
1108
1109 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(anEdge, aFpar, aLpar);
1110 GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
1111 Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
1112
1113 if (!anExtrema.IsDone())
1114 continue;
1115 if (anExtrema.IsParallel())
1116 continue;
1117
1118 aNbExt = anExtrema.NbExt();
1119 Standard_Real MaxTol = Max(BRep_Tool::Tolerance(theEdge), BRep_Tool::Tolerance(anEdge));
1120 for (i = 1; i <= aNbExt; i++)
1121 {
1122 Standard_Real aDist = Sqrt(anExtrema.SquareDistance(i));
1123 if (aDist > MaxTol)
1124 continue;
1125
1126 Extrema_POnCurv aPOnC1, aPOnC2;
1127 anExtrema.Points(i, aPOnC1, aPOnC2);
1128 Standard_Real theIntPar = aPOnC1.Parameter();
1129 Standard_Real anIntPar = aPOnC2.Parameter();
1130 Standard_Boolean IntersFound = Standard_False;
1131 for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
1132 {
1133 if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion() &&
1134 aDist <= Precision::Confusion())
1135 {
1136 theMap.Add(theVertices[j]);
1137 TopExp_Explorer exp2(anEdge, TopAbs_VERTEX);
1138 for (; exp2.More(); exp2.Next())
1139 {
1140 const TopoDS_Vertex& aVertex = TopoDS::Vertex(exp2.Current());
1141 if (aVertex.IsSame(theVertices[j]))
1142 {
1143 IntersFound = Standard_True;
1144 break;
1145 }
1146 if (BRepTools::Compare(theVertices[j], aVertex))
1147 {
1148 GlobalMap.Bind(theVertices[j], aVertex);
1149 IntersFound = Standard_True;
1150 break;
1151 }
1152 }
1153 if (!IntersFound)
1154 {
1155 GlobalMap.Bind(theVertices[j], anEdge);
1156 IntersFound = Standard_True;
1157 break;
1158 }
1159 }
1160 }
4bbaf12b 1161 if (!IntersFound && aDist <= Precision::Confusion()) //intersection is inside "theEdge" => split
ed60a55e 1162 {
1163 gp_Pnt aPoint = aCurve->Value(anIntPar);
1164 if (aPoint.Distance(thePnt[0]) > BRep_Tool::Tolerance(theVertices[0]) &&
1165 aPoint.Distance(thePnt[1]) > BRep_Tool::Tolerance(theVertices[1]))
1166 SplitPars.Append(theIntPar);
1167 }
1168 }
1169 }
1170
1171 if (SplitPars.IsEmpty())
1172 return;
1173
1174 //Sort
1175 for (i = 1; i < SplitPars.Length(); i++)
1176 for (j = i+1; j <= SplitPars.Length(); j++)
1177 if (SplitPars(i) > SplitPars(j))
1178 {
1179 Standard_Real Tmp = SplitPars(i);
1180 SplitPars(i) = SplitPars(j);
1181 SplitPars(j) = Tmp;
1182 }
1183
1184 //Remove repeating points
1185 i = 1;
1186 while (i < SplitPars.Length())
1187 {
1188 gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
1189 gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
1190 if (Pnt1.Distance(Pnt2) <= Precision::Confusion())
1191 SplitPars.Remove(i+1);
1192 else
1193 i++;
1194 }
1195
1196 //Split
1197 TopTools_ListOfShape NewEdges;
1198 BRep_Builder BB;
1199 //theVertices[0].Orientation(TopAbs_FORWARD);
1200 //theVertices[1].Orientation(TopAbs_REVERSED);
1201 TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
1202 Standard_Real FirstPar = thePar[0], LastPar;
1203 for (i = 1; i <= SplitPars.Length()+1; i++)
1204 {
1205 FirstVertex.Orientation(TopAbs_FORWARD);
1206 if (i <= SplitPars.Length())
1207 {
1208 LastPar = SplitPars(i);
1209 gp_Pnt LastPoint = theCurve->Value(LastPar);
1210 LastVertex = BRepLib_MakeVertex(LastPoint);
1211 }
1212 else
1213 {
1214 LastPar = thePar[1];
1215 LastVertex = theVertices[1];
1216 }
1217 LastVertex.Orientation(TopAbs_REVERSED);
1218
1219 TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
1220 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
1221 BB.Range(NewEdge, FirstPar, LastPar);
1222 BB.Add(NewEdge, FirstVertex);
1223 BB.Add(NewEdge, LastVertex);
1224
1225 NewEdges.Append(NewEdge);
1226 FirstVertex = LastVertex;
1227 FirstPar = LastPar;
1228 }
1229
1230 if (!NewEdges.IsEmpty())
1231 Splits.Add(theEdge, NewEdges);
1232}