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