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