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