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