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