0024023: Revamp the OCCT Handle -- general
[occt.git] / src / BRepFill / BRepFill_Sweep.cxx
CommitLineData
b311480e 1// Created on: 1998-01-07
2// Created by: Philippe MANGIN
3// Copyright (c) 1998-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 <stdio.h>
18
19#include <BRepFill_Sweep.ixx>
20
21#include <BRepFill_SectionLaw.hxx>
22//#include <BRepFill_TrimCorner.hxx>
23#include <BRepFill_CurveConstraint.hxx>
24
25#include <GeomFill_SectionLaw.hxx>
26#include <GeomFill_LocationLaw.hxx>
27#include <GeomFill_Sweep.hxx>
28
29// modified by NIZHNY-MKK Wed Oct 22 12:25:45 2003
30#include <BRepFill_TrimShellCorner.hxx>
31
32//#include <GeomPlate_BuildPlateSurface.hxx>
33//#include <GeomPlate_Surface.hxx>
34//#include <GeomPlate_PointConstraint.hxx>
35
36#include <gp_Pnt2d.hxx>
37#include <gp_Vec2d.hxx>
38#include <Bnd_Box.hxx>
39
40#include <Geom_Surface.hxx>
41#include <Geom_SurfaceOfRevolution.hxx>
42#include <Geom_RectangularTrimmedSurface.hxx>
43#include <Geom_Plane.hxx>
44#include <Geom_Curve.hxx>
45#include <Geom_BezierCurve.hxx>
46#include <Geom_BSplineCurve.hxx>
47#include <Geom2d_Line.hxx>
c04c30b3 48#include <Geom2d_BSplineCurve.hxx>
7fd59977 49#include <Geom2d_TrimmedCurve.hxx>
50#include <GeomLib.hxx>
51#include <GeomLib_IsPlanarSurface.hxx>
52#include <BRepLib_FindSurface.hxx>
53#include <GeomConvert_ApproxSurface.hxx>
54
55#include <BRepAdaptor_HCurve.hxx>
56#include <BRepAdaptor_HCurve2d.hxx>
57#include <BRepAdaptor_HSurface.hxx>
58#include <Adaptor3d_HCurveOnSurface.hxx>
59#include <GeomAdaptor_HSurface.hxx>
60#include <GeomAdaptor_HCurve.hxx>
61#include <Geom2dAdaptor_HCurve.hxx>
62#include <Approx_CurveOnSurface.hxx>
63#include <Approx_SameParameter.hxx>
64#include <GCPnts_AbscissaPoint.hxx>
65
66#include <BRep_Builder.hxx>
67#include <BRep_Tool.hxx>
68#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
69#include <BRep_TEdge.hxx>
70#include <BRep_TVertex.hxx>
71#include <BRep_CurveRepresentation.hxx>
72#include <BRep_GCurve.hxx>
73
74#include <BRepLib.hxx>
75#include <BRepLib_MakeEdge.hxx>
76#include <BRepLib_MakeFace.hxx>
77#include <BRepLib_FaceError.hxx>
78
79#include <TopoDS.hxx>
80#include <TopoDS_Edge.hxx>
81#include <TopoDS_Face.hxx>
82#include <TopoDS_Compound.hxx>
83#include <TopoDS_Shell.hxx>
84#include <TopExp.hxx>
85#include <TopExp_Explorer.hxx>
86#include <TopAbs_Orientation.hxx>
87
88#include <TColStd_HArray1OfInteger.hxx>
89#include <TColStd_Array2OfInteger.hxx>
90#include <TColStd_Array1OfReal.hxx>
91#include <TColStd_Array2OfReal.hxx>
92#include <TColGeom_Array2OfSurface.hxx>
93#include <TColgp_Array1OfPnt.hxx>
c8ea5b8e 94#include <TColStd_Array1OfBoolean.hxx>
7fd59977 95
96#include <TopTools_Array1OfShape.hxx>
97#include <TopTools_Array2OfShape.hxx>
98#include <TopTools_HArray2OfShape.hxx>
99#include <TopTools_HArray1OfShape.hxx>
100#include <TopTools_ListIteratorOfListOfShape.hxx>
101#include <TopTools_ListOfShape.hxx>
102#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
c8ea5b8e 103#include <TopTools_SequenceOfShape.hxx>
7fd59977 104#include <BRepTools_WireExplorer.hxx>
105
106#include <Standard_ConstructionError.hxx>
107#include <Precision.hxx>
108#include <BRepBuilderAPI_MakeWire.hxx>
109
110#include <BRepTools_Substitution.hxx>
111#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
112#include <TopoDS_Iterator.hxx>
113
114//OCC500(apo)
115#include <BRepCheck_Edge.hxx>
116
117#ifdef DRAW
118#include <Draw.hxx>
119#include <DrawTrSurf.hxx>
120#include <DBRep.hxx>
ec357c5c 121#include <Geom_BoundedSurface.hxx>
7fd59977 122static Standard_Boolean Affich = 0;
123#endif
124
125//=======================================================================
126//function : NumberOfPoles
127//purpose :
128//=======================================================================
129static Standard_Integer NumberOfPoles(const TopoDS_Wire& W)
130{
131 Standard_Integer NbPoints = 0;
132
133 TopoDS_Iterator iter(W);
134 for (; iter.More(); iter.Next())
135 {
136 BRepAdaptor_Curve c(TopoDS::Edge(iter.Value()));
137
138 Standard_Real dfUf = c.FirstParameter();
139 Standard_Real dfUl = c.LastParameter();
140 if (IsEqual(dfUf,dfUl))
141 // Degenerate
142 continue;
143
144 switch (c.GetType())
145 {
146 case GeomAbs_BezierCurve:
147 {
148 // Put all poles for bezier
149 Handle(Geom_BezierCurve) GC = c.Bezier();
150 Standard_Integer iNbPol = GC->NbPoles();
151 if ( iNbPol >= 2)
152 NbPoints += iNbPol;
153 break;
154 }
155 case GeomAbs_BSplineCurve:
156 {
157 // Put all poles for bspline
158 Handle(Geom_BSplineCurve) GC = c.BSpline();
159 Standard_Integer iNbPol = GC->NbPoles();
160 if ( iNbPol >= 2)
161 NbPoints += iNbPol;
162 break;
163 }
164 case GeomAbs_Line:
165 {
166 NbPoints += 2;
167 break;
168 }
169 case GeomAbs_Circle:
170 case GeomAbs_Ellipse:
171 case GeomAbs_Hyperbola:
172 case GeomAbs_Parabola:
173 {
174 NbPoints += 4;
175 break;
176 }
177 default:
178 NbPoints += 15 + c.NbIntervals(GeomAbs_C3);
179 } // switch (c.GetType()) ...
180 } // for (; iter.More(); iter.Next())
181
182 return NbPoints;
183}
184
185//=======================================================================
186//function : HasPCurves
187//purpose :
188//=======================================================================
189static Standard_Boolean HasPCurves(const TopoDS_Edge& E)
190{
191 Standard_Boolean haspcurves = Standard_False;
192
193 BRep_ListIteratorOfListOfCurveRepresentation itcr
194 ((*((Handle(BRep_TEdge)*)&E.TShape()))->Curves());
195 for (; itcr.More(); itcr.Next())
196 {
197 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
198 if (cr->IsCurveOnSurface())
199 {
200 haspcurves = Standard_True;
201 break;
202 }
203 }
204 return haspcurves;
205}
206
207//=======================================================================
208//function : Translate
0d969553 209//purpose : Copy a column from one table to another.
7fd59977 210//=======================================================================
211static void Translate(const Handle(TopTools_HArray2OfShape)& ArrayIn,
212 const Standard_Integer In,
213 Handle(TopTools_HArray2OfShape)& ArrayOut,
214 const Standard_Integer Out)
215{
216 Standard_Integer ii, Nb;
217 Nb = ArrayOut->ColLength();
218 for (ii=1; ii<=Nb; ii++) {
219 ArrayOut->SetValue(ii, Out, ArrayIn->Value(ii, In));
220 }
221}
222
223
224//=======================================================================
225//function : Box
0d969553 226//purpose : Bounding box of a section.
7fd59977 227//=======================================================================
228static void Box(Handle(GeomFill_SectionLaw)& Sec,
229 const Standard_Real U,
230 Bnd_Box& Box)
231
232{
233 Standard_Integer NbPoles, bid;
234 Box.SetVoid();
235 Sec->SectionShape(NbPoles, bid, bid);
236 TColgp_Array1OfPnt Poles(1, NbPoles);
237 TColStd_Array1OfReal W(1, NbPoles);
238 Sec->D0(U, Poles, W);
239 for (Standard_Integer ii=1; ii<=NbPoles; ii++) {
240 Box.Add(Poles(ii));
241 }
242}
243
244//=======================================================================
245//function : Couture
0d969553
Y
246//purpose : Check if E is an edge of sewing on S
247// and make the representation HadHoc
7fd59977 248//=======================================================================
249static Handle(Geom2d_Curve) Couture(const TopoDS_Edge& E,
250 const Handle(Geom_Surface)& S,
251 const TopLoc_Location& L)
252{
253 TopLoc_Location l = L.Predivided(E.Location());
254 Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
255
256 // find the representation
257 BRep_ListIteratorOfListOfCurveRepresentation itcr
258 ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
259
260 while (itcr.More()) {
261 Handle(BRep_CurveRepresentation)& cr = itcr.Value();
262 if (cr->IsCurveOnSurface(S,l)) {
263 Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
264 if (GC->IsCurveOnClosedSurface() && Eisreversed)
265 return GC->PCurve2();
266 else
267 return GC->PCurve();
268 }
269 itcr.Next();
270 }
271 Handle(Geom2d_Curve) pc;
272 pc.Nullify();
273 return pc;
274}
275
276//=======================================================================
277//function : CheckSameParameter
0d969553 278//purpose : Check a posteriori that sameparameter has worked correctly
7fd59977 279//=======================================================================
280
281static Standard_Boolean CheckSameParameter
282(const Handle(Adaptor3d_HCurve)& C3d,
471ce736 283 const Handle(Geom2d_Curve)& Pcurv,
7fd59977 284 const Handle(Adaptor3d_HSurface)& S,
285 const Standard_Real tol3d,
286 Standard_Real& tolreached)
287{
288 tolreached = 0.;
289 Standard_Real f = C3d->FirstParameter();
290 Standard_Real l = C3d->LastParameter();
291 Standard_Integer nbp = 45;
292 Standard_Real step = 1./(nbp -1);
293 for(Standard_Integer i = 0; i < nbp; i++){
294 Standard_Real t,u,v;
295 t = step * i;
296 t = (1-t) * f + t * l;
297 Pcurv->Value(t).Coord(u,v);
298 gp_Pnt pS = S->Value(u,v);
299 gp_Pnt pC = C3d->Value(t);
300 Standard_Real d2 = pS.SquareDistance(pC);
301 tolreached = Max(tolreached,d2);
302 }
303 tolreached = sqrt(tolreached);
304 if(tolreached > tol3d){
305 tolreached *= 2.;
306 return Standard_False;
307 }
308 tolreached *= 2.;
309 tolreached = Max(tolreached,Precision::Confusion());
310 return Standard_True;
311}
312
313//=======================================================================
314//function : SameParameter
0d969553
Y
315//purpose : Encapsulation of Sameparameter
316// Boolean informs if the pcurve was computed or not...
317// The tolerance is always OK.
7fd59977 318//=======================================================================
319
320static Standard_Boolean SameParameter(TopoDS_Edge& E,
321 Handle(Geom2d_Curve)& Pcurv,
322 const Handle(Geom_Surface)& Surf,
323 const Standard_Real tol3d,
324 Standard_Real& tolreached)
325{
326 //Handle(BRepAdaptor_HCurve) C3d = new (BRepAdaptor_HCurve)(E);
327 Standard_Real f, l;
328 Handle(Geom_Curve) C3d = BRep_Tool::Curve( E, f, l );
329 GeomAdaptor_Curve GAC3d( C3d, f, l );
330 Handle(GeomAdaptor_HCurve) HC3d = new GeomAdaptor_HCurve( GAC3d );
331
332 Handle(GeomAdaptor_HSurface) S = new (GeomAdaptor_HSurface)(Surf);
333 Standard_Real ResTol;
334
335 if(CheckSameParameter( HC3d, Pcurv, S, tol3d, tolreached ))
336 return Standard_True;
337
338 if (!HasPCurves(E))
339 {
340 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( Pcurv );
341 Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(),
342 Precision::Confusion(), GeomAbs_C1, 10, 10, Standard_True);
343 if (AppCurve.IsDone() && AppCurve.HasResult())
344 {
345 C3d = AppCurve.Curve3d();
346 tolreached = AppCurve.MaxError3d();
347 BRep_Builder B;
348 B.UpdateEdge( E, C3d, tolreached );
349 return Standard_True;
350 }
351 }
352
353 Approx_SameParameter sp( HC3d, Pcurv, S, tol3d );
354 if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
355 else if(!sp.IsDone() && !sp.IsSameParameter()){
0797d9d3 356#ifdef OCCT_DEBUG
7fd59977 357 cout<<"echec SameParameter"<<endl;
358#endif
359 return Standard_False;
360 }
361
362 ResTol = sp.TolReached();
363 if(ResTol > tolreached ){
0797d9d3 364#ifdef OCCT_DEBUG
0d969553
Y
365 cout<<"SameParameter : Tolerance not reached!"<<endl;
366 cout<<"tol visee : "<<tol3d<<" tol obtained : "<<ResTol<<endl;
7fd59977 367#endif
368 return Standard_False;
369 }
370 else {
371 tolreached = 1.1*ResTol;
372 if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
373 }
374 return Standard_True;
375}
376
377//=======================================================================
0d969553
Y
378//Objet : Orientate an edge of natural restriction
379// : General
7fd59977 380//=======================================================================
381static void Oriente(const Handle(Geom_Surface)& S,
382 TopoDS_Edge& E)
383{
384 gp_Pnt2d P;
385 gp_Vec2d D, URef(1, 0), VRef(0, 1);
386 Standard_Boolean isuiso, isfirst, isopposite;
387 Standard_Real UFirst, ULast, VFirst, VLast, f, l;
388 S->Bounds(UFirst, ULast, VFirst, VLast);
389 Handle(Geom2d_Curve) C;
390 TopLoc_Location bid;
391
392 C = BRep_Tool::CurveOnSurface(E, S, bid, f, l);
393 C->D1((f+l)/2, P, D);
394
395 isuiso = D.IsParallel(VRef, 0.1);
396
397 if ( isuiso ) {
398 isfirst = (Abs (P.X()-UFirst) < Precision::Confusion());
399 isopposite = D.IsOpposite(VRef, 0.1);
400 E.Orientation(TopAbs_REVERSED);
401 }
402 else {
403 isfirst = (Abs (P.Y()-VFirst) < Precision::Confusion());
404 isopposite = D.IsOpposite(URef, 0.1);
405 E.Orientation(TopAbs_FORWARD);
406 }
407
408 if (!isfirst) E.Reverse();
409 if (isopposite) E.Reverse();
410}
411//OCC500(apo)->
412static void UpdateEdgeOnPlane(const TopoDS_Face& F, const TopoDS_Edge& E,
413 const BRep_Builder& BB)
414{
415 Standard_Real f, l;
416 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
417 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
418 TopLoc_Location Loc;
419 Standard_Real Tol = BRep_Tool::Tolerance(E);
420 BB.UpdateEdge(E, C2d, S, Loc, Tol);
421 BRepCheck_Edge Check(E);
422 Tol = Max(Tol,Check.Tolerance());
423 BB.UpdateEdge(E, Tol);
424 TopoDS_Vertex V;
425 Tol *= 1.01;
426 V = TopExp::FirstVertex(E);
427 if(BRep_Tool::Tolerance(V) < Tol) BB.UpdateVertex(V, Tol);
428 V = TopExp::LastVertex(E);
429 if(BRep_Tool::Tolerance(V) < Tol) BB.UpdateVertex(V, Tol);
430}
431//<-OCC500(apo)
432//=======================================================================
433//Function : BuildFace
0d969553
Y
434//Objet : Construct a Face via a surface and 4 Edges (natural borders)
435// : Only one Hypothesis : isos u and v are switched :
436// Edge1/3 are iso u (recp v)
437// Edge2/4 are iso v (recp u)
7fd59977 438//=======================================================================
439static void BuildFace(const Handle(Geom_Surface)& S,
440 const TopoDS_Edge& E1,
441 const TopoDS_Edge& E2,
442 const TopoDS_Edge& E3,
443 const TopoDS_Edge& E4,
444 TopTools_DataMapOfShapeShape& EEmap,
445 const Standard_Boolean ExchUV,
446 const Standard_Boolean UReverse,
447 TopoDS_Face& F)
448{
449 Standard_Real Tol;
450// Class BRep_Tool without fields and without Constructor :
451// BRep_Tool BT;
452 TopoDS_Edge e1, e2, E;
453 TopoDS_Wire WW;
454 BRep_Builder BB;
455 BRepBuilderAPI_MakeWire B;
456 TopoDS_Iterator Iter;
457 //gp_Pnt2d P;
458
0d969553 459 //Is the surface planar ?
7fd59977 460 Standard_Real Tol1, Tol2, Tol3, Tol4;
461 Tol1 = BRep_Tool::Tolerance( E1 );
462 Tol2 = BRep_Tool::Tolerance( E2 );
463 Tol3 = BRep_Tool::Tolerance( E3 );
464 Tol4 = BRep_Tool::Tolerance( E4 );
465// Tol = Min( BT.Tolerance(E1), BT.Tolerance(E2));
466 Tol = Min( Tol1, Tol2 );
467// Tol = Min(Tol, Min(BT.Tolerance(E3),BT.Tolerance(E4)));
468 Tol = Min( Tol, Min( Tol3, Tol4 ) );
469 Standard_Boolean IsPlan = Standard_False;
470 Handle(Geom_Plane) thePlane;
471
472 if (!E1.IsSame(E3) && !E2.IsSame(E4)) //exclude cases with seam edges: they are not planar
473 {
474 GeomLib_IsPlanarSurface IsP(S, Tol);
475 if (IsP.IsPlanar())
476 {
477 IsPlan = Standard_True;
478 thePlane = new Geom_Plane( IsP.Plan() );
479 }
480 else
481 {
482 Handle(BRep_TEdge)& TE1 = *((Handle(BRep_TEdge)*)&E1.TShape());
483 Handle(BRep_TEdge)& TE2 = *((Handle(BRep_TEdge)*)&E2.TShape());
484 Handle(BRep_TEdge)& TE3 = *((Handle(BRep_TEdge)*)&E3.TShape());
485 Handle(BRep_TEdge)& TE4 = *((Handle(BRep_TEdge)*)&E4.TShape());
486 TE1->Tolerance( Precision::Confusion() );
487 TE2->Tolerance( Precision::Confusion() );
488 TE3->Tolerance( Precision::Confusion() );
489 TE4->Tolerance( Precision::Confusion() );
490
491 TopoDS_Wire theWire = BRepLib_MakeWire( E1, E2, E3, E4 );
492 Standard_Integer NbPoints = NumberOfPoles( theWire );
493 if (NbPoints <= 100) //limitation for CPU
494 {
495 BRepLib_FindSurface FS( theWire, -1, Standard_True );
496 if (FS.Found())
497 {
498 IsPlan = Standard_True;
499 thePlane = Handle(Geom_Plane)::DownCast(FS.Surface());
500 }
501 }
502 BB.UpdateEdge( E1, Tol1 );
503 BB.UpdateEdge( E2, Tol2 );
504 BB.UpdateEdge( E3, Tol3 );
505 BB.UpdateEdge( E4, Tol4 );
506 }
507 }
508
0d969553 509 // Construction of the wire
7fd59977 510// B.MakeWire(WW);
511 e1 = E1;
512 Oriente(S, e1);
513// if (!IsPlan || !BT.Degenerated(e1))
514 if (!IsPlan || !BRep_Tool::Degenerated(e1))
515 B.Add(e1);
516
517 e2 = E2;
518 Oriente(S, e2);
519// if (!IsPlan || !BT.Degenerated(e2))
520 if (!IsPlan || !BRep_Tool::Degenerated(e2))
521 {
522 B.Add(e2);
523 if (!BRep_Tool::Degenerated(e2))
524 {
525 WW = B.Wire();
526 TopoDS_Shape NewEdge;
527 //take the last edge added to WW
528 for (Iter.Initialize( WW ); Iter.More(); Iter.Next())
529 NewEdge = Iter.Value();
530 if (! e2.IsSame(NewEdge))
531 EEmap.Bind( e2, NewEdge );
532 }
533 }
534
535 if (E3.IsSame(E1)) {
536 E = e1;
537 E.Reverse();
538 }
539 else {
540 E = E3;
541 Oriente(S, E);
542 }
543// if (!IsPlan || !BT.Degenerated(E))
544 if (!IsPlan || !BRep_Tool::Degenerated(E))
545 {
546 B.Add(E);
547 if (!BRep_Tool::Degenerated(E))
548 {
549 WW = B.Wire();
550 TopoDS_Shape NewEdge;
551 //take the last edge added to WW
552 for (Iter.Initialize( WW ); Iter.More(); Iter.Next())
553 NewEdge = Iter.Value();
554 if (! E.IsSame(NewEdge))
555 EEmap.Bind( E, NewEdge );
556 }
557 }
558
559 if (E4.IsSame(E2)) {
560 E = e2;
561 E.Reverse();
562 }
563 else {
564 E = E4;
565 Oriente(S, E);
566 }
567// if (!IsPlan || !BT.Degenerated(E))
568 if (!IsPlan || !BRep_Tool::Degenerated(E))
569 {
570 B.Add(E);
571 if (!BRep_Tool::Degenerated(E))
572 {
573 WW = B.Wire();
574 TopoDS_Shape NewEdge;
575 //take the last edge added to WW
576 for (Iter.Initialize( WW ); Iter.More(); Iter.Next())
577 NewEdge = Iter.Value();
578 if (! E.IsSame(NewEdge))
579 EEmap.Bind( E, NewEdge );
580 }
581 }
582
583 WW = B.Wire();
584#if DRAW
c0695321
A
585 if (Affich)
586 DBRep::Set("wire-on-face", WW);
7fd59977 587#endif
588
0d969553
Y
589// Construction of the face.
590 if (IsPlan) { // Suspend representation 2d
591 // and construct face Plane
7fd59977 592
593 //BRepLib_MakeFace MkF(IsP.Plan(), WW);
594 gp_Pnt aPnt;
595 gp_Vec DU, DV, NS, NP;
596 Standard_Real Ufirst, Ulast, Vfirst, Vlast;
597 S->Bounds( Ufirst, Ulast, Vfirst, Vlast );
598 S->D1( (Ufirst+Ulast)/2., (Vfirst+Vlast)/2., aPnt, DU, DV );
599 NS = DU ^ DV;
600 NP = thePlane->Pln().Axis().Direction();
601 if (NS.Dot(NP) < 0.)
602 thePlane->UReverse();
603 BRepLib_MakeFace MkF( thePlane, WW );
604 if (MkF.Error() != BRepLib_FaceDone) {
0797d9d3 605#ifdef OCCT_DEBUG
7fd59977 606 BRepLib_FaceError Err = MkF.Error();
607 cout << "Planar Face Error :" << Err << endl;
608#endif
609 }
610 else {
611 Handle(Geom2d_Curve) NullC2d;
612 TopLoc_Location Loc;
613 BB.UpdateEdge( E1, NullC2d, S, Loc, Tol1 );
614 BB.UpdateEdge( E2, NullC2d, S, Loc, Tol2 );
615 BB.UpdateEdge( E3, NullC2d, S, Loc, Tol3 );
616 BB.UpdateEdge( E4, NullC2d, S, Loc, Tol4 );
617
618 F = MkF.Face();
619 UpdateEdgeOnPlane(F,E1,BB);
620 UpdateEdgeOnPlane(F,E2,BB);
621 UpdateEdgeOnPlane(F,E3,BB);
622 UpdateEdgeOnPlane(F,E4,BB);
623/*OCC500(apo)->
624 TopLoc_Location Loc;
625 Handle(Geom2d_Curve) NC;
626 NC.Nullify();
627// B.UpdateEdge(E1, NC, S, Loc, BT.Tolerance(E1));
628 BB.UpdateEdge(E1, NC, S, Loc, BRep_Tool::Tolerance(E1));
629// B.UpdateEdge(E2, NC, S, Loc, BT.Tolerance(E2));
630 BB.UpdateEdge(E2, NC, S, Loc, BRep_Tool::Tolerance(E2));
631// B.UpdateEdge(E3, NC, S, Loc, BT.Tolerance(E3));
632 BB.UpdateEdge(E3, NC, S, Loc, BRep_Tool::Tolerance(E3));
633// B.UpdateEdge(E4, NC, S, Loc, BT.Tolerance(E4));
634 BB.UpdateEdge(E4, NC, S, Loc, BRep_Tool::Tolerance(E4));
635<-OCC500(apo)*/
636 }
637 }
638
639 if (!IsPlan) {// Cas Standard : Ajout
640 BB.MakeFace(F, S, Precision::Confusion());
641 BB.Add(F, WW);
642 }
643
644 // Reorientation
645 if (ExchUV) F.Reverse();
646 if (UReverse) F.Reverse();
647}
648
649
650//=======================================================================
651//Fonction : BuildEdge
0d969553 652//Objet : Construct non-closed Edge
7fd59977 653//=======================================================================
654static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d,
655 Handle(Geom2d_Curve)& C2d,
656 Handle(Geom_Surface)& S,
657 const TopoDS_Vertex& VF,
658 const TopoDS_Vertex& VL,
659 const Standard_Real f,
660 const Standard_Real l,
661 const Standard_Real Tol3d)
662{
663 gp_Pnt P1, P2, P;
664 Standard_Real Tol1, Tol2, Tol, d;
665// Class BRep_Tool without fields and without Constructor :
666// BRep_Tool BT;
667 BRep_Builder B;
668 TopoDS_Edge E;
669
670// P1 = BT.Pnt(VF);
671 P1 = BRep_Tool::Pnt(VF);
672// Tol1 = BT.Tolerance(VF);
673 Tol1 = BRep_Tool::Tolerance(VF);
674// P2 = BT.Pnt(VL);
675 P2 = BRep_Tool::Pnt(VL);
676// Tol2 = BT.Tolerance(VF);
677 Tol2 = BRep_Tool::Tolerance(VF);
678 Tol = Max(Tol1, Tol2);
679
680 if (VF.IsSame(VL) ||
681 (P1.Distance(P2) < Tol ) ) {
0d969553 682 // Degenerated case
7fd59977 683 gp_Pnt2d P2d;
684 C2d->D0(f, P2d);
685 S->D0(P2d.X(), P2d.Y(), P);
686 d = P1.Distance(P);
687 if (d > Tol) Tol = d;
688 C2d->D0(l, P2d);
689 S->D0(P2d.X(), P2d.Y(), P);
690 d = P2.Distance(P);
691 if (d > Tol) Tol = d;
692
693 B.UpdateVertex(VF, Tol);
694 B.UpdateVertex(VL, Tol);
695
696 B.MakeEdge(E);
697 B.UpdateEdge(E,C2d,S,TopLoc_Location(), Tol);
698 B.Add(E,VF);
699 B.Add(E,VL);
700 B.Range(E,f,l);
701 B.Degenerated(E, Standard_True);
702
703 return E;
704 }
705
706 C3d->D0(f, P);
707 d = P1.Distance(P);
708 if (d > Tol1)
709 B.UpdateVertex(VF, d);
710
711// P1 = BT.Pnt(VL);
712 P1 = BRep_Tool::Pnt(VL);
713 C3d->D0(l, P);
714 d = P2.Distance(P);
715 if (d > Tol2)
716 B.UpdateVertex(VL, d);
717
718 BRepLib_MakeEdge MkE (C3d, VF, VL, f, l);
0d969553 719 if (!MkE.IsDone()) { // Error of construction !!
7fd59977 720#ifdef DRAW
721 char name[100];
722 sprintf(name,"firstvertex_error");
723 DBRep::Set(name, VF);
724 sprintf(name,"lastvertex_error");
725 DBRep::Set(name, VL);
726 sprintf(name,"curve3d_error");
727 char* Temp = name ;
728 DrawTrSurf::Set(Temp, C3d);
729// DrawTrSurf::Set(name, C3d);
730 Standard_ConstructionError::Raise("BRepFill_Sweep::BuildEdge");
731#endif
732 }
733
734 E = MkE.Edge();
735 TopLoc_Location Loc;
736 B.UpdateEdge(E, C2d, S, Loc, Tol3d);
737
738 return E;
739}
740
741
742//=======================================================================
743//Fonction : Filling
0d969553 744//Objet : Construct the faces of filling
7fd59977 745//=======================================================================
746static Standard_Boolean Filling(const TopoDS_Shape& EF,
747 const TopoDS_Shape& F1,
748 const TopoDS_Shape& EL,
749 const TopoDS_Shape& F2,
750 TopTools_DataMapOfShapeShape& EEmap,
751 const Standard_Real Tol,
752 const gp_Ax2& Axe,
753 const gp_Vec& TangentOnPart1,
754 TopoDS_Edge& Aux1,
755 TopoDS_Edge& Aux2,
756 TopoDS_Face& Result)
757{
758 BRep_Builder B;
759// Class BRep_Tool without fields and without Constructor :
760// BRep_Tool BT;
761// Standard_Integer NbInt =0;
762// Standard_Real Tol3d = Tol;
763 Standard_Boolean WithE3, WithE4;
764
0d969553 765// Return constraints
7fd59977 766 TopoDS_Vertex V1, V2, Vf, Vl;
767 TopoDS_Edge E1, E2, E3, E4;
768 E1 = TopoDS::Edge(EF);
769 E2 = TopoDS::Edge(EL);
770
771 TopExp::Vertices(E1, Vf, Vl);
772 Vf.Orientation(TopAbs_FORWARD);
773 Vl.Orientation(TopAbs_FORWARD);
774
775 TopExp::Vertices(E2, V1, V2);
776 V1.Orientation(TopAbs_REVERSED);
777 V2.Orientation(TopAbs_REVERSED);
778
779 B.MakeEdge(E3);
780 B.MakeEdge(E4);
781
782 WithE3 = WithE4 = Standard_False;
783
784 if ((!Aux1.IsNull()) && (!Vf.IsSame(V1))) {
785 E3 = Aux1;
786// E3 = TopoDS::Edge(Aux1);
787 WithE3 = Standard_True;
788 }
789
790 if (Vf.IsSame(Vl)) {
791 E4 = E3;
792 E4.Reverse();
793 WithE4 = WithE3;
794 }
795 else if (!Aux2.IsNull() && (!Vl.IsSame(V2))) {
796 E4 = Aux2;
797// E4 = TopoDS::Edge(Aux2);
798 WithE4 = Standard_True;
799 }
800
801#if DRAW
802 if (Affich) {
803 DBRep::Set("Fill_Edge1", E1);
804 DBRep::Set("Fill_Edge2", E2);
805 if (!E3.IsNull())
806 DBRep::Set("Fill_Edge3", E3);
807 if (!E4.IsNull())
808 DBRep::Set("Fill_Edge4", E4);
809 }
810#endif
811
0d969553 812// Construction of a surface of revolution
7fd59977 813 Handle(Geom_Curve) Prof1, Prof2;
814 //Standard_Integer ii, jj;//, Nb;
815 Standard_Real f1, f2, l1, l2,/*d1, d2,*/ Angle;//, Eps = 1.e-9;
816// Prof1 = BT.Curve(E1, f1, l1);
817 Prof1 = BRep_Tool::Curve(E1, f1, l1);
818// Prof2 = BT.Curve(E2, f2, l2);
819 Prof2 = BRep_Tool::Curve(E2, f2, l2);
820 gp_Pnt P1, P2, P;
821 gp_Pnt2d p1, p2;
822 gp_Trsf Tf;
823 Tf.SetTransformation(Axe);
824
0d969553 825// Choose the angle of opening
7fd59977 826 P1 = Prof1->Value((f1+l1)/2);
827 P2 = Prof2->Value((f2+l2)/2);
828 P1.Transform(Tf);
829 P2.Transform(Tf);
830 p1.SetCoord(P1.Z(), P1.X());
831 p2.SetCoord(P2.Z(), P2.X());
832 gp_Vec2d v1(gp::Origin2d(), p1);
833 gp_Vec2d v2(gp::Origin2d(), p2);
834 if (v1.Magnitude() <= gp::Resolution() ||
835 v2.Magnitude() <= gp::Resolution())
836 return Standard_False;
837 Angle = v1.Angle(v2);
838
839 gp_Ax1 axe(Axe.Location(), Axe.YDirection());
840
841 if (Angle < 0) {
842 Angle = -Angle;
843 axe.Reverse();
844 }
845
846 Handle(Geom_SurfaceOfRevolution) Rev =
847 new (Geom_SurfaceOfRevolution) (Prof1, axe);
848
849 Handle(Geom_Surface) Surf =
850 new (Geom_RectangularTrimmedSurface) (Rev, 0, Angle, f1, l1);
851
0d969553 852 // Control the direction of the rotation
7fd59977 853 Standard_Boolean ToReverseResult = Standard_False;
854 gp_Vec d1u;
855 d1u = Surf->DN(0, (f1+l1)/2, 1, 0);
c6541a0c 856 if (d1u.Angle(TangentOnPart1) > M_PI/2) { //Invert everything
7fd59977 857 ToReverseResult = Standard_True;
858 /*
859 axe.Reverse();
c6541a0c 860 Angle = 2*M_PI - Angle;
7fd59977 861 Rev = new (Geom_SurfaceOfRevolution) (Prof1, axe);
862 Surf = new (Geom_RectangularTrimmedSurface)
863 (Rev, 0, Angle, f1, l1);
864 */
865 }
866
867#if DRAW
868 if (Affich) {
869 char* Temp = "Surf_Init" ;
870 DrawTrSurf::Set(Temp, Surf);
871 }
872#endif
873
874 Handle(Geom2d_Curve) C1, C2, C3, C4;
875/*
0d969553 876// Deform the surface of revolution.
7fd59977 877 GeomPlate_BuildPlateSurface BPS;
878
879 Handle(BRepAdaptor_HSurface) AS;
880 Handle(BRepAdaptor_HCurve2d) AC2d;
881 Handle(Adaptor3d_HCurveOnSurface) HConS;
882*/
883 Handle(Geom2d_Line) L;
884 gp_Pnt2d P2d(0.,0.);
885
886 L = new (Geom2d_Line) (P2d, gp::DY2d());
887 C1 = new (Geom2d_TrimmedCurve) (L, f1, l1);
888
889 P2d.SetCoord(Angle,0.);
890 L = new (Geom2d_Line) (P2d, gp::DY2d());
891 C2 = new (Geom2d_TrimmedCurve) (L, f1, l1);
892
0d969553 893 // It is required to control the direction and the range.
7fd59977 894 C2->D0(f1, P2d);
895 Surf->D0(P2d.X(), P2d.Y(), P1);
896 C2->D0(l1, P2d);
897 Surf->D0(P2d.X(), P2d.Y(), P2);
898// P = BT.Pnt(V1);
899 P = BRep_Tool::Pnt(V1);
900 if (P.Distance(P2)+Tol < P.Distance(P1)) {
0d969553 901 // E2 is parsed in the direction opposite to E1
7fd59977 902 C2->Reverse();
903 TopoDS_Vertex aux;
904 aux = V2;
905 V2 = V1;
906 V1 = aux;
907 }
908 GeomLib::SameRange(Precision::PConfusion(), C2,
909 C2->FirstParameter(),
910 C2->LastParameter(),
911 f2, l2, C3);
912 C2 = C3;
913
7fd59977 914// P1 = BT.Pnt(Vf);
915 P1 = BRep_Tool::Pnt(Vf);
916// P2 = BT.Pnt(V1);
917 P2 = BRep_Tool::Pnt(V1);
918// pointu_f = Vf.IsSame(V1) || (P1.Distance(P2) < BT.Tolerance(Vf));
7fd59977 919// P1 = BT.Pnt(Vl);
920 P1 = BRep_Tool::Pnt(Vl);
921// P2 = BT.Pnt(V2);
922 P2 = BRep_Tool::Pnt(V2);
923// pointu_l = Vl.IsSame(V2) || (P1.Distance(P2) < BT.Tolerance(Vl));
7fd59977 924
925 P2d.SetCoord(0.,f1);
926 L = new (Geom2d_Line) (P2d, gp::DX2d());
927 C3 = new (Geom2d_TrimmedCurve) (L, 0, Angle);
928
929
930 P2d.SetCoord(0.,l1);
931 L = new (Geom2d_Line) (P2d, gp::DX2d());
932 C4 = new (Geom2d_TrimmedCurve) (L, 0, Angle);
933/*
0d969553
Y
934 // Determine the constraints and
935 // their parametric localisation.
7fd59977 936 if (!E1.IsNull()) {
937 AS = new BRepAdaptor_HSurface(TopoDS::Face(F1));
938 AC2d = new BRepAdaptor_HCurve2d();
939 AC2d->ChangeCurve2d().Initialize(E1,TopoDS::Face(F1));
940 HConS = new (Adaptor3d_HCurveOnSurface)();
941 HConS->ChangeCurve().Load(AC2d);
942 HConS->ChangeCurve().Load(AS);
943
944 Handle(BRepFill_CurveConstraint) Cont
945 = new BRepFill_CurveConstraint(HConS, 1, 15);
946 Cont->SetCurve2dOnSurf(C1);
947
948 BPS.Add(Cont);
949 NbInt = HConS->NbIntervals(GeomAbs_CN);
950 }
951
952 if (!E2.IsNull()) {
953 AS = new BRepAdaptor_HSurface(TopoDS::Face(F2));
954 AC2d = new BRepAdaptor_HCurve2d();
955 AC2d->ChangeCurve2d().Initialize(E2,TopoDS::Face(F2));
956 HConS = new (Adaptor3d_HCurveOnSurface);
957
958 HConS->ChangeCurve().Load(AC2d);
959 HConS->ChangeCurve().Load(AS);
960
961 Handle(BRepFill_CurveConstraint) Cont
962 = new BRepFill_CurveConstraint(HConS, 1, 15);
963 Cont->SetCurve2dOnSurf(C2);
964 BPS.Add(Cont);
965 }
966
967 if (WithE3) {
968 Handle(BRepAdaptor_HCurve) AC = new (BRepAdaptor_HCurve) (E3);
969 Handle(BRepFill_CurveConstraint) Cont
970 = new BRepFill_CurveConstraint(AC, 0);
971 Cont->SetCurve2dOnSurf(C3);
972 BPS.Add(Cont);
973 }
974 else if (pointu_f) {
975 Standard_Real delta = Angle / 11;
976// P = BT.Pnt(Vf);
977 P = BRep_Tool::Pnt(Vf);
978 Handle(GeomPlate_PointConstraint) PC;
979 for (ii=1; ii<=10; ii++) {
980 C3->D0(ii*delta, P2d);
981 PC = new (GeomPlate_PointConstraint) (P, 0);
982 PC->SetPnt2dOnSurf(P2d);
983 BPS.Add(PC);
984 }
985 }
986
987
988 if (WithE4) {
989 Handle(BRepAdaptor_HCurve) AC = new (BRepAdaptor_HCurve) (E4);
990 Handle(BRepFill_CurveConstraint) Cont
991 = new BRepFill_CurveConstraint(AC, 0);
992 Cont->SetCurve2dOnSurf(C4);
993 BPS.Add(Cont);
994 }
995 else if (pointu_l) {
996 Standard_Real delta = Angle / 11;
997// P = BT.Pnt(Vl);
998 P = BRep_Tool::Pnt(Vl);
999 Handle(GeomPlate_PointConstraint) PC;
1000 for (ii=1; ii<=10; ii++) {
1001 C4->D0(ii*delta, P2d);
1002 PC = new (GeomPlate_PointConstraint) (P, 0);
1003 PC->SetPnt2dOnSurf(P2d);
1004 BPS.Add(PC);
1005 }
1006 }
1007
1008 BPS.LoadInitSurface(Surf);
1009 BPS.Perform();
1010
1011 // Controle s'il y a une deformation effective
1012 Handle(GeomPlate_Surface) plate;
1013 plate = BPS.Surface();
1014 plate->SetBounds(0, Angle, f1, l1);
1015 Standard_Boolean Ok=Standard_True;
1016 Standard_Real u, v;
1017 d1 = (l1-f1)/5;
1018 d2 = Angle/5;
1019 for (ii=0; ii<=5 && Ok; ii++) {
1020 u = f1 + ii*d1;
1021 for (jj=0; jj<=5 && Ok; jj++) {
1022 v = jj*d2;
1023 plate->D0(u, v, P1);
1024 Surf->D0(u, v, P2);
1025 Ok = (P2.IsEqual(P1, Tol));
1026 }
1027 }
1028
1029
1030 if (!Ok) {
1031 // Approx de la plate surface
1032 // Bords naturelles => pas besoin de criteres.
1033 GeomConvert_ApproxSurface App(BPS.Surface(),
1034 Tol3d,
1035 GeomAbs_C1, GeomAbs_C1,
1036 8, 8, 2*NbInt, 0);
1037 if (!App.HasResult()) {
0797d9d3 1038#ifdef OCCT_DEBUG
7fd59977 1039 cout << "Filling_Approx : Pas de resultat" << endl;
1040#endif
1041 return Standard_False;
1042 }
0797d9d3 1043#ifdef OCCT_DEBUG
7fd59977 1044 cout << "Filling_Approx Error 3d = " <<
1045 App.MaxError() << endl;
1046#endif
1047 Surf = App.Surface();
1048 Tol3d = App.MaxError();
1049 }
1050*/
1051
1052// Update des Edges
1053 TopLoc_Location Loc;
1054 Handle(Geom_Curve) C3d;
1055 B.UpdateEdge(E1, C1, Surf, Loc, /*Tol3d*/Precision::Confusion());
1056 B.UpdateEdge(E2, C2, Surf, Loc, /*Tol3d*/Precision::Confusion());
1057
1058 if (E3.IsSame(E4)) {
1059 if (!WithE3)
1060 {
1061 C3d = Surf->VIso(f1);
1062 E3 = BuildEdge(C3d, C3, Surf, Vf, V1, 0, Angle, /*Tol3d*/Precision::Confusion());
1063 }
1064 else
1065 {
1066 BRepAdaptor_Curve aCurve(E3);
1067 Standard_Real AngleOld = aCurve.LastParameter();
1068 if (Angle > AngleOld)
1069 {
1070 B.Range( E3, 0, Angle );
1071 TopoDS_Vertex V (TopExp::LastVertex(E3));
1072 Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*) &V.TShape());
1073 TVlast->Tolerance( Precision::Confusion() );
1074 }
1075 }
1076
1077 B.UpdateEdge(E3, C3, C4, Surf, Loc, /*Tol3d*/Precision::Confusion());
1078 E4 = E3;
1079 E4.Reverse();
1080 }
1081 else {
1082 if (!WithE3)
1083 {
1084 C3d = Surf->VIso(f1);
1085 E3 = BuildEdge(C3d, C3, Surf, Vf, V1, 0, Angle, /*Tol3d*/Precision::Confusion());
1086 }
1087 else
1088 {
1089 BRepAdaptor_Curve aCurve(E3);
1090 Standard_Real AngleOld = aCurve.LastParameter();
1091 if (Angle > AngleOld)
1092 {
1093 B.Range( E3, 0, Angle );
1094 TopoDS_Vertex V(TopExp::LastVertex(E3));
1095 Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*) &V.TShape());
1096 TVlast->Tolerance( Precision::Confusion() );
1097 }
1098
1099 B.UpdateEdge(E3, C3, Surf, Loc, /*Tol3d*/Precision::Confusion());
1100 }
1101
1102 if (!WithE4)
1103 {
1104 C3d = Surf->VIso(l1);
1105 E4 = BuildEdge(C3d, C4, Surf, Vl, V2, 0, Angle, /*Tol3d*/Precision::Confusion());
1106 }
1107 else
1108 {
1109 BRepAdaptor_Curve aCurve(E4);
1110 Standard_Real AngleOld = aCurve.LastParameter();
1111 if (Angle > AngleOld)
1112 {
1113 B.Range( E4, 0, Angle );
1114 TopoDS_Vertex V (TopExp::LastVertex(E4));
1115 Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*)&V.TShape());
1116 TVlast->Tolerance( Precision::Confusion() );
1117 }
1118
1119 B.UpdateEdge(E4, C4, Surf, Loc, /*Tol3d*/Precision::Confusion());
1120 }
1121 }
1122
0d969553 1123//Construct face
7fd59977 1124 BuildFace(Surf,E1, E3, E2, E4, EEmap,
1125 Standard_False, Standard_False,
1126 Result);
1127
0d969553 1128// Set the continuities.
7fd59977 1129 B.Continuity(E1, TopoDS::Face(F1), Result, GeomAbs_G1);
1130 B.Continuity(E2, TopoDS::Face(F2), Result, GeomAbs_G1);
1131
0d969553 1132// Render the calculated borders.
7fd59977 1133// if (!BT.Degenerated(E3))
1134 if (!BRep_Tool::Degenerated(E3))
1135 Aux1 = E3;
1136 else
1137 B.MakeEdge(Aux1); //Nullify
1138
1139// if (!BT.Degenerated(E4))
1140 if (!BRep_Tool::Degenerated(E4))
1141 Aux2 = E4;
1142 else
1143 B.MakeEdge(Aux2);
1144
0d969553 1145 // Set the orientation
7fd59977 1146 gp_Vec D1U, D1V, N1, N2;
1147 C1->D0( (f1+l1)/2, P2d);
1148 Surf->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
1149 N1 = D1U^D1V;
1150
1151// C1 = BT.CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
1152 C1 = BRep_Tool::CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
1153 C1->D0( (f1+l1)/2, P2d);
1154 Handle(BRepAdaptor_HSurface) AS = new BRepAdaptor_HSurface(TopoDS::Face(F1));
1155 AS->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
1156 N2 = D1U^D1V;
1157
c6541a0c 1158 if ( (F1.Orientation() == TopAbs_REVERSED) ^ (N1.Angle(N2)>M_PI/2) )
7fd59977 1159 Result.Orientation(TopAbs_REVERSED);
1160 else Result.Orientation(TopAbs_FORWARD);
1161
1162 if (ToReverseResult)
1163 Result.Reverse();
1164
1165#if DRAW
1166 if (Affich) DBRep::Set("BoucheTrou", Result);
1167#endif
1168
1169 return Standard_True;
1170}
1171
1172//=======================================================================
1173//function : Substitute
1174//purpose :
1175//=======================================================================
1176static void Substitute(BRepTools_Substitution& aSubstitute,
1177 const TopoDS_Edge& Old,
1178 const TopoDS_Edge& New)
1179{
1180 TopTools_ListOfShape listShape;
1181
1182 TopoDS_Vertex OldV1, OldV2, NewV1, NewV2;
1183 TopExp::Vertices( Old, OldV1, OldV2 );
1184 TopExp::Vertices( New, NewV1, NewV2 );
1185
1186 if (!aSubstitute.IsCopied( OldV1 ))
1187 {
1188 listShape.Append( NewV1.Oriented(TopAbs_FORWARD) );
1189 aSubstitute.Substitute( OldV1, listShape );
1190 listShape.Clear();
1191 }
1192 if (!aSubstitute.IsCopied( OldV2 ))
1193 {
1194 listShape.Append( NewV2.Oriented(TopAbs_FORWARD) );
1195 aSubstitute.Substitute( OldV2, listShape );
1196 listShape.Clear();
1197 }
1198 if (!aSubstitute.IsCopied( Old ))
1199 {
1200 listShape.Append( New.Oriented(TopAbs_FORWARD) );
1201 aSubstitute.Substitute( Old, listShape );
1202 }
1203}
1204
1205//=======================================================================
1206//Function : SetCommonEdgeInFace
0d969553 1207//Purpose : Replace an edge of the face by the corresponding edge from
7fd59977 1208// myUEdges
1209//=======================================================================
1210/*
1211static void SetCommonEdgeInFace(BRepTools_Substitution& aSubstitute,
1212 const TopoDS_Shape& Face,
1213 const TopoDS_Shape& Edge)
1214{
1215 if (Edge.IsNull())
1216 return;
1217
1218 Standard_Boolean done = Standard_False;
1219// Class BRep_Tool without fields and without Constructor :
1220// BRep_Tool BT;
1221 Standard_Real f, l;
1222 TopExp_Explorer Exp(Face, TopAbs_EDGE);
1223 Handle(Geom_Curve) Cref, C;
1224 TopLoc_Location Lref, L;
1225// Cref = BT.Curve(TopoDS::Edge(Edge), Lref, f, l);
1226 const TopoDS_Edge& NewEdge = TopoDS::Edge(Edge);
1227 Cref = BRep_Tool::Curve( NewEdge, Lref, f, l );
1228
1229 for ( ; Exp.More() && !done; Exp.Next()) {
1230// C = BT.Curve(TopoDS::Edge(Exp.Current()), L, f, l);
1231 const TopoDS_Edge& OldEdge = TopoDS::Edge(Exp.Current());
1232 C = BRep_Tool::Curve(OldEdge, L, f, l);
1233 if ((Cref==C) && (Lref == L)) {
1234 done = Standard_True;
1235 Substitute( aSubstitute, OldEdge, NewEdge );
1236 }
1237 }
0797d9d3 1238#ifdef OCCT_DEBUG
7fd59977 1239 if (!done) cout << "Substitution of Edge failed" << endl;
1240#endif
1241}
1242*/
1243
1244//=======================================================================
1245//Fonction : KeepEdge
0d969553 1246//Objet : Find edges of the face supported by the same Curve.
7fd59977 1247//=======================================================================
1248static void KeepEdge(const TopoDS_Shape& Face,
1249 const TopoDS_Shape& Edge,
1250 TopTools_ListOfShape& List)
1251{
1252 List.Clear();
1253// Class BRep_Tool without fields and without Constructor :
1254// BRep_Tool BT;
1255 Standard_Real f, l;
1256 TopExp_Explorer Exp(Face, TopAbs_EDGE);
1257 Handle(Geom_Curve) Cref, C;
1258 TopLoc_Location Lref, L;
1259// Cref = BT.Curve(TopoDS::Edge(Edge), Lref, f, l);
1260 Cref = BRep_Tool::Curve(TopoDS::Edge(Edge), Lref, f, l);
1261
1262 for ( ; Exp.More(); Exp.Next()) {
1263// C = BT.Curve(TopoDS::Edge(Exp.Current()), L, f, l);
1264 C = BRep_Tool::Curve(TopoDS::Edge(Exp.Current()), L, f, l);
1265 if ((Cref==C) && (Lref == L)) {
1266 List.Append(Exp.Current());
1267 }
1268 }
1269}
1270
1271//=======================================================================
1272//Function :
0d969553 1273//Objet : Construct a vertex via an iso
7fd59977 1274//=======================================================================
1275static void BuildVertex(const Handle(Geom_Curve)& Iso,
1276 const Standard_Boolean isfirst,
1277 const Standard_Real First,
1278 const Standard_Real Last,
1279 TopoDS_Shape& Vertex)
1280{
1281 BRep_Builder B;
1282 Standard_Real val;
1283
1284 if (isfirst) val = First;
1285 else val = Last;
1286 B.MakeVertex(TopoDS::Vertex(Vertex),
1287 Iso->Value(val),
1288 Precision::Confusion());
1289}
1290
1291//=======================================================================
1292//Function :
0d969553 1293//Objet : Construct an empty edge
7fd59977 1294//=======================================================================
1295static TopoDS_Edge NullEdge(TopoDS_Shape& Vertex)
1296{
1297 TopoDS_Edge E;
1298 BRep_Builder B;
1299 B.MakeEdge(E);
1300 Vertex.Orientation(TopAbs_FORWARD);
1301 B.Add(E, Vertex);
1302 B.Add(E, Vertex.Reversed());
1303 B.Degenerated(E, Standard_True);
1304 return E;
1305
1306}
1307
1308//=======================================================================
1309//Function :
0d969553 1310//Objet : Construct an edge via an iso
7fd59977 1311//=======================================================================
1312static TopoDS_Edge BuildEdge(const Handle(Geom_Surface)& S,
1313 const Standard_Boolean isUiso,
1314 const Standard_Real ValIso,
1315 const TopoDS_Shape& VFirst,
1316 const TopoDS_Shape& VLast,
1317 const Standard_Real Tol)
1318{
1319 TopoDS_Edge E;
1320 BRep_Builder B;
1321 Handle(Geom_Curve) Iso;
1322 Standard_Boolean sing = Standard_False;
1323 if (isUiso) {
1324 Iso = S->UIso(ValIso);
1325 }
1326 else {
1327 Iso = S->VIso(ValIso);
1328 }
1329
0d969553 1330 if (VFirst.IsSame(VLast)) { // Singular case ?
7fd59977 1331 gp_Pnt P;
1332// Class BRep_Tool without fields and without Constructor :
1333// BRep_Tool BT;
1334 const TopoDS_Vertex& V = TopoDS::Vertex(VFirst);
1335// Standard_Real tol = BT.Tolerance(V);
1336 Standard_Real tol = BRep_Tool::Tolerance(V);
1337 if (Tol > tol) tol = Tol;
1338 Iso->D0((Iso->FirstParameter()+Iso->LastParameter())/2, P);
1339// if (P.Distance(BT.Pnt(V)) < tol) {
1340 if (P.Distance(BRep_Tool::Pnt(V)) < tol) {
1341 GeomAdaptor_Curve AC(Iso);
1342 sing = GCPnts_AbscissaPoint::Length(AC, tol/4) < tol;
1343 }
1344 }
1345
1346
0d969553 1347 if (sing) { // Singular case
7fd59977 1348 TopoDS_Shape V;
1349 V = VFirst;
1350 E = NullEdge(V);
1351// Iso.Nullify();
1352// B.UpdateEdge(E, Iso, Precision::Confusion());
1353 B.Degenerated(E, Standard_True);
1354 }
1355
1356 else {
0d969553 1357 // Construction Via 3d
7fd59977 1358// if (isUiso) {
1359// Iso = S->UIso(ValIso);
1360 gp_Pnt P1,P2;
1361 Standard_Real p1, p2, p11, p12, p21, p22;
1362 Standard_Boolean fwd = Standard_False;
1363 p1 = Iso->FirstParameter();
1364 p2 = Iso->LastParameter();
1365 P1 = Iso->Value(p1);
1366 P2 = Iso->Value(p2);
1367
1368 Standard_Real t1 = BRep_Tool::Tolerance(TopoDS::Vertex(VFirst));
1369 Standard_Real t2 = BRep_Tool::Tolerance(TopoDS::Vertex(VLast));
1370
1371 BRep_Builder BB;
1372
1373 p11 = P1.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VFirst)));
1374 p22 = P2.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VLast)));
1375 p12 = P1.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VLast)));
1376 p21 = P2.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VFirst)));
1377
1378 if(p11 < p12 && p22 < p21) fwd = Standard_True;
1379
1380 if(fwd) { //OCC500(apo)
1381 if (p11 >= t1) BB.UpdateVertex(TopoDS::Vertex(VFirst), 1.01*p11);
1382 if (p22 >= t2) BB.UpdateVertex(TopoDS::Vertex(VLast), 1.01*p22);
1383 }
1384 else {
1385// Iso = S->VIso(ValIso);
1386 if (p12 >= t2) BB.UpdateVertex(TopoDS::Vertex(VLast), 1.01*p12);
1387 if (p21 >= t1) BB.UpdateVertex(TopoDS::Vertex(VFirst), 1.01*p21);
1388 }
1389
1390 BRepLib_MakeEdge MkE;
1391
1392// MkE.Init(Iso,
1393// TopoDS::Vertex(VFirst),
1394// TopoDS::Vertex(VLast),
1395// Iso->FirstParameter(),
1396// Iso->LastParameter());
1397 if(fwd)
1398 MkE.Init(Iso,
1399 TopoDS::Vertex(VFirst),
1400 TopoDS::Vertex(VLast),
1401 Iso->FirstParameter(),
1402 Iso->LastParameter());
1403 else
1404 MkE.Init(Iso,
1405 TopoDS::Vertex(VLast),
1406 TopoDS::Vertex(VFirst),
1407 Iso->FirstParameter(),
1408 Iso->LastParameter());
1409
1410// if (!MkE.IsDone()) { // Il faut peut etre permuter les Vertex
1411// MkE.Init(Iso,
1412// TopoDS::Vertex(VLast),
1413// TopoDS::Vertex(VFirst),
1414// Iso->FirstParameter(),
1415// Iso->LastParameter());
1416// }
1417
1418 if (!MkE.IsDone()) { // Erreur de construction !!
1419#ifdef DRAW
1420 char name[100];
1421 sprintf(name,"firstvertex_error");
1422 DBRep::Set(name, VFirst);
1423 sprintf(name,"lastvertex_error");
1424 DBRep::Set(name, VLast);
1425 sprintf(name,"curve3d_error");
1426 char* Temp = name ;
1427 DrawTrSurf::Set(Temp,Iso);
1428// DrawTrSurf::Set(name,Iso);
1429#endif
1430 Standard_ConstructionError::Raise("BRepFill_Sweep::BuildEdge");
1431 }
1432
1433 E = MkE.Edge();
1434 }
1435
0d969553 1436 // Associate 2d
7fd59977 1437 Handle(Geom2d_Line) L;
1438 TopLoc_Location Loc;
9ba2c30f 1439 Standard_Real Umin, Umax, Vmin, Vmax;
1440 S->Bounds(Umin, Umax, Vmin, Vmax);
7fd59977 1441 if (isUiso) {
9ba2c30f 1442 //gp_Pnt2d P(ValIso, 0);
1443 gp_Pnt2d P( ValIso, Vmin - Iso->FirstParameter() );
7fd59977 1444 gp_Vec2d V(0., 1.);
1445 L = new (Geom2d_Line) (P, V);
1446 }
1447 else {
9ba2c30f 1448 //gp_Pnt2d P(0., ValIso);
1449 gp_Pnt2d P( Umin -Iso->FirstParameter() , ValIso );
7fd59977 1450 gp_Vec2d V(1., 0.);
1451 L = new (Geom2d_Line) (P, V);
1452 }
1453
1454 B.UpdateEdge(E, L, S, Loc, Precision::Confusion());
1455 if (sing) B.Range(E, S, Loc,
1456 Iso->FirstParameter(),
1457 Iso->LastParameter());
1458
471ce736 1459 Standard_Real MaxTol = 1.e-4;
1460 Standard_Real theTol;
1461 GeomAdaptor_Curve GAiso(Iso);
1462 Handle(GeomAdaptor_HCurve) GAHiso = new GeomAdaptor_HCurve(GAiso);
1463 GeomAdaptor_Surface GAsurf(S);
1464 Handle(GeomAdaptor_HSurface) GAHsurf = new GeomAdaptor_HSurface(GAsurf);
1465 CheckSameParameter( GAHiso, L, GAHsurf, MaxTol, theTol);
1466 B.UpdateEdge(E, theTol);
1467
7fd59977 1468 return E;
1469}
1470
1471//=======================================================================
1472//Function :
0d969553 1473//Objet : Complete an edge via an iso
7fd59977 1474//=======================================================================
1475static void UpdateEdge(TopoDS_Edge& E,
1476 const Handle(Geom_Surface)& S,
1477 const Standard_Boolean isUiso,
1478 const Standard_Real ValIso)
1479{
1480 BRep_Builder B;
1481 Handle(Geom2d_Line) L;
1482 Handle(Geom2d_Curve) PCurve, CL;
1483 TopLoc_Location Loc;
1484 Standard_Real UFirst, ULast, VFirst, VLast, F2d, L2d;
1485 S->Bounds( UFirst, ULast, VFirst, VLast);
1486
1487 Standard_Boolean sing = Standard_False;
1488 Handle(Geom_Curve) Iso;
1489 if (isUiso) {
1490 Iso = S->UIso(ValIso);
1491 }
1492 else {
1493 Iso = S->VIso(ValIso);
1494 }
1495
1496 TopoDS_Vertex Vf, Vl;
1497 TopExp::Vertices(E, Vf, Vl);
0d969553 1498 if (Vf.IsSame(Vl)) { // Singular case ?
7fd59977 1499 gp_Pnt Pmid;
1500 Standard_Real tol = BRep_Tool::Tolerance(Vf);
1501 Iso->D0((Iso->FirstParameter()+Iso->LastParameter())/2, Pmid);
1502 if (Pmid.Distance(BRep_Tool::Pnt(Vf)) < tol) {
1503 GeomAdaptor_Curve AC(Iso);
1504 sing = GCPnts_AbscissaPoint::Length(AC, tol/4) < tol;
1505 }
1506 }
1507
1508 if (isUiso) {
1509 gp_Pnt2d P(ValIso, 0);
1510 gp_Vec2d V(0., 1.);
1511 L = new (Geom2d_Line) (P, V);
1512 F2d = VFirst;
1513 L2d = VLast;
1514 }
1515 else {
1516 gp_Pnt2d P(0., ValIso);
1517 gp_Vec2d V(1., 0.);
1518 L = new (Geom2d_Line) (P, V);
1519 F2d = UFirst;
1520 L2d = ULast;
1521 }
1522 CL = new (Geom2d_TrimmedCurve) (L, F2d, L2d);
1523
0d969553 1524 // Control direction & Range
7fd59977 1525 Standard_Real R, First, Last, Tol=1.e-4;
1526 Standard_Boolean reverse = Standard_False;;
1527
1528
1529// Class BRep_Tool without fields and without Constructor :
1530// BRep_Tool BT;
1531 gp_Pnt POnS;
1532 gp_Pnt2d P2d;
1533// BT.Range(E, First, Last);
1534 BRep_Tool::Range(E, First, Last);
1535
1536 if (!Vf.IsSame(Vl)) {
0d969553 1537 // Test distances between "FirstPoint" and "Vertex"
7fd59977 1538 P2d = CL->Value(F2d);
1539 POnS = S->Value(P2d.X(), P2d.Y());
1540// reverse = POnS.Distance(BT.Pnt(Vl)) < POnS.Distance(BT.Pnt(Vf));
1541 reverse = POnS.Distance(BRep_Tool::Pnt(Vl)) < POnS.Distance(BRep_Tool::Pnt(Vf));
1542 }
1543 else if (!sing) {
0d969553 1544 // Test angle between "First Tangente"
7fd59977 1545 gp_Vec2d V2d;
1546 gp_Vec V3d, du, dv, dC3d;
1547 BRepAdaptor_Curve C3d(E);
1548
1549 C3d.D1(First, POnS, dC3d);
1550 CL->D1(F2d, P2d, V2d);
1551 S->D1(P2d.X(), P2d.Y(), POnS, du, dv);
1552 V3d.SetLinearForm(V2d.X(), du, V2d.Y(), dv);
1553 reverse = ( dC3d.Angle(V3d) > Tol);
1554 }
0d969553 1555 if (reverse ) { // Return curve 2d
7fd59977 1556 CL = new (Geom2d_TrimmedCurve)(L, F2d, L2d);
1557 CL->Reverse();
1558 F2d = CL->FirstParameter();
1559 L2d = CL->LastParameter();
1560 }
1561
1562 if (sing)
1563 {
1564 Handle(Geom_Curve) NullCurve;
1565 B.UpdateEdge(E, NullCurve, 0.);
1566 B.Degenerated(E, Standard_True);
1567 B.Range(E, F2d, L2d);
1568 First = F2d;
1569 Last = L2d;
1570 }
1571
1572 if (First != F2d || Last != L2d) {
1573 Handle(Geom2d_Curve) C2d;
1574 GeomLib::SameRange(Precision::PConfusion(), CL,
1575 F2d, L2d, First, Last,
1576 C2d);
1577 CL = new (Geom2d_TrimmedCurve)(C2d, First, Last);
1578 }
1579
1580 // Update des Vertex
1581
1582 TopoDS_Vertex V;
1583
1584 P2d = CL->Value(First);
1585 POnS = S->Value(P2d.X(), P2d.Y());
1586 V = TopExp::FirstVertex(E);
1587// R = POnS.Distance(BT.Pnt(V));
1588 R = POnS.Distance(BRep_Tool::Pnt(V));
1589 B.UpdateVertex(V, R);
1590
1591 P2d = CL->Value(Last);
1592 POnS = S->Value(P2d.X(), P2d.Y());
1593 V = TopExp::LastVertex(E);
1594// R = POnS.Distance(BT.Pnt(V));
1595 R = POnS.Distance(BRep_Tool::Pnt(V));
1596 B.UpdateVertex(V, R);
1597
0d969553 1598 // Update Edge
7fd59977 1599 if (!sing && SameParameter(E, CL, S, Tol, R)) {
1600 B.UpdateEdge(E, R);
1601 }
1602
1603 PCurve = Couture(E, S, Loc);
1604 if (PCurve.IsNull())
1605 B.UpdateEdge(E, CL, S, Loc, Precision::Confusion());
0d969553 1606 else { // Sewing edge
7fd59977 1607 TopoDS_Edge e = E;
1608 Oriente(S, e);
1609 if (e.Orientation() == TopAbs_REVERSED)
1610 B.UpdateEdge(E, CL, PCurve, S, Loc, Precision::Confusion());
1611 else
1612 B.UpdateEdge(E, PCurve, CL, S, Loc, Precision::Confusion());
1613 }
1614
0d969553 1615 // Attention to case not SameRange on its shapes (PRO13551)
7fd59977 1616// if (!BT.SameRange(E)) B.Range(E, S, Loc, First, Last);
1617 if (!BRep_Tool::SameRange(E)) B.Range(E, S, Loc, First, Last);
1618}
1619
1620//=======================================================================
0d969553 1621// Object : Check if a surface is degenerated
7fd59977 1622//=======================================================================
1623static Standard_Boolean IsDegen(const Handle(Geom_Surface)& S,
1624 const Standard_Real Tol)
1625{
1626 Standard_Integer Nb = 5;
1627 Standard_Boolean B = Standard_True;
1628 Standard_Real Umax, Umin, Vmax, Vmin, t, dt, l;
1629 Standard_Integer ii;
1630 Handle(Geom_Curve) Iso;
1631 gp_Pnt P1,P2,P3;
1632 GCPnts_AbscissaPoint GC;
1633
1634 S->Bounds(Umin, Umax, Vmin, Vmax);
1635
0d969553 1636 // Check the length of Iso-U
7fd59977 1637 t = (Umin + Umax)/2;
1638 S->D0(t, Vmin, P1);
1639 S->D0(t, (Vmin+Vmax)/2, P2);
1640 S->D0(t, Vmax, P3);
1641 B = ((P1.Distance(P2) + P2.Distance(P3)) < Tol);
1642
1643 for (ii=1, dt = (Umax-Umin)/(Nb+1); B && (ii<=Nb); ii++) {
1644 t = Umin + ii*dt;
1645 Iso = S->UIso(t);
1646 GeomAdaptor_Curve AC(Iso);
1647 l = GC.Length(AC, Tol/4);
1648 B = (l <= Tol);
1649 }
1650
1651 if (B) return Standard_True;
1652
0d969553 1653 // Check the length of Iso-V
7fd59977 1654 t = (Vmin + Vmax)/2;
1655 S->D0(Umin, t, P1);
1656 S->D0((Umin+Umax)/2, t, P2);
1657 S->D0(Umax, t, P3);
1658 B = ((P1.Distance(P2) + P2.Distance(P3)) < Tol);
1659
1660
1661 for (ii=1, dt = (Vmax-Vmin)/(Nb+1); B && (ii<=Nb); ii++) {
1662 t = Vmin + ii*dt;
1663 Iso = S->VIso(t);
1664 GeomAdaptor_Curve AC(Iso);
1665 l = GC.Length(AC, Tol/4);
1666 B = (l <= Tol);
1667 }
1668
1669 return B;
1670}
1671
1672//=======================================================================
1673//function : Constructeur
1674//purpose :
1675//======================================================================
1676BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
1677 const Handle(BRepFill_LocationLaw)& Location,
1678 const Standard_Boolean WithKPart) :
1679 isDone(Standard_False),
1680 KPart(WithKPart)
1681
1682
1683{
1684 mySec = Section;
1685 myLoc = Location;
1686
1687 SetTolerance(1.e-4);
1688 SetAngularControl();
1689 myAuxShape.Clear();
1690
1691 myApproxStyle = GeomFill_Location;
1692 myContinuity = GeomAbs_C2;
1693 myDegmax = 11;
1694 mySegmax = 30;
a31abc03 1695 myForceApproxC1 = Standard_False;
7fd59977 1696}
1697
1698//=======================================================================
1699//function : SetBounds
0d969553 1700//purpose : Define start and end shapes
7fd59977 1701//======================================================================
1702 void BRepFill_Sweep::SetBounds(const TopoDS_Wire& First,
1703 const TopoDS_Wire& Last)
1704{
1705 FirstShape = First;
1706 LastShape = Last;
1707
0d969553 1708 // It is necessary to check the SameRange on its (PRO13551)
0797d9d3 1709#ifdef OCCT_DEBUG
7fd59977 1710 Standard_Boolean issame = Standard_True;
96a95605 1711#endif
7fd59977 1712 BRep_Builder B;
1713 BRepTools_WireExplorer wexp;
1714 if (!FirstShape.IsNull()) {
1715 for (wexp.Init(FirstShape); wexp.More(); wexp.Next()) {
1716 if (!BRepLib::CheckSameRange(wexp.Current())) {
1717 B.SameRange(wexp.Current(), Standard_False);
1718 B.SameParameter(wexp.Current(), Standard_False);
0797d9d3 1719#ifdef OCCT_DEBUG
7fd59977 1720 issame = Standard_False;
96a95605 1721#endif
7fd59977 1722 }
1723 }
1724 }
1725
1726 if (!LastShape.IsNull()) {
1727 for (wexp.Init(LastShape); wexp.More(); wexp.Next()) {
1728 if (!BRepLib::CheckSameRange(wexp.Current())) {
1729 B.SameRange(wexp.Current(), Standard_False);
1730 B.SameParameter(wexp.Current(), Standard_False);
0797d9d3 1731#ifdef OCCT_DEBUG
7fd59977 1732 issame = Standard_False;
96a95605 1733#endif
7fd59977 1734 }
1735 }
1736 }
1737
0797d9d3 1738#ifdef OCCT_DEBUG
7fd59977 1739 if (!issame)
0d969553 1740 cout<<"Sweep Warning : Edge not SameRange in the limits"<<endl;
7fd59977 1741#endif
1742}
1743
1744//=======================================================================
1745//function : SetTolerance
1746//purpose :
1747//======================================================================
1748 void BRepFill_Sweep::SetTolerance(const Standard_Real Tol3d,
1749 const Standard_Real BoundTol,
1750 const Standard_Real Tol2d,
1751 const Standard_Real TolAngular)
1752{
1753 myTol3d = Tol3d;
1754 myBoundTol = BoundTol;
1755 myTol2d =Tol2d;
1756 myTolAngular = TolAngular;
1757}
1758//=======================================================================
1759//function : SetAngularControl
1760//purpose :
1761//======================================================================
1762 void BRepFill_Sweep::SetAngularControl(const Standard_Real MinAngle,
1763 const Standard_Real MaxAngle)
1764{
1765 myAngMin = Max (MinAngle, Precision::Angular());
1766 myAngMax = Min (MaxAngle, 6.28);
1767}
1768
a31abc03 1769//=======================================================================
1770//function : SetForceApproxC1
1771//purpose : Set the flag that indicates attempt to approximate
1772// a C1-continuous surface if a swept surface proved
1773// to be C0.
1774//=======================================================================
1775 void BRepFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
1776{
1777 myForceApproxC1 = ForceApproxC1;
1778}
1779
7fd59977 1780///=======================================================================
1781//function : CorrectApproxParameters
1782//purpose :
1783//=======================================================================
1784 Standard_Boolean BRepFill_Sweep::CorrectApproxParameters()
1785{
1786 TopoDS_Wire thePath = myLoc->Wire();
1787 GeomAbs_Shape NewCont = myContinuity;
1788 Standard_Integer NewSegmax = mySegmax;
1789
1790 TopoDS_Iterator iter(thePath);
1791 for (; iter.More(); iter.Next())
1792 {
1793 TopoDS_Edge anEdge = TopoDS::Edge(iter.Value());
1794 BRepAdaptor_Curve aBAcurve(anEdge);
1795 GeomAbs_Shape aContinuity = aBAcurve.Continuity();
1796 Standard_Integer aNbInterv = aBAcurve.NbIntervals(GeomAbs_CN);
1797 if (aContinuity < NewCont)
1798 NewCont = aContinuity;
1799 if (aNbInterv > NewSegmax)
1800 NewSegmax = aNbInterv;
1801 }
1802
1803 Standard_Boolean Corrected = Standard_False;
1804 if (NewCont != myContinuity || NewSegmax != mySegmax)
1805 Corrected = Standard_True;
1806 myContinuity = NewCont;
1807 mySegmax = NewSegmax;
1808 return Corrected;
1809}
1810
1811//=======================================================================
1812//function : BuildWire
0d969553 1813//purpose : Construit a wire by sweeping
7fd59977 1814//======================================================================
1815 Standard_Boolean BRepFill_Sweep::
1816 BuildWire(const BRepFill_TransitionStyle /*Transition*/)
1817{
1818 Standard_Integer ipath, isec = 1;
1819 gp_Pnt P1;//, P2;
1820
1821 BRep_Builder B;
1822// Class BRep_Tool without fields and without Constructor :
1823// BRep_Tool BT;
1824 Standard_Integer NbPath = myLoc->NbLaw();
1825 Standard_Boolean vclose;
1826 vclose = (myLoc->IsClosed() && (myLoc->IsG1(0, myTol3d)>= 0));
1827 Error = 0.;
1828 Handle(Geom_Surface) S;
1829 Handle(Geom_Curve) Iso;
1830 Standard_Real val, bid, First, Last, Tol;
1831
1832 TopoDS_Wire wire;
1833 TopoDS_Edge E;
1834 B.MakeWire(wire);
1835
0d969553 1836 // (1) Construction of all curves
7fd59977 1837
0d969553 1838 // (1.1) Construction of Tables
7fd59977 1839 myFaces = new (TopTools_HArray2OfShape) (1, 1, 1, NbPath);
1840 myUEdges = new (TopTools_HArray2OfShape) (1, 2, 1, NbPath);
1841 myVEdges = new (TopTools_HArray2OfShape) (1, 1, 1, NbPath+1);
1842
0d969553 1843 // (1.2) Calculate curves / vertex / edge
7fd59977 1844 for (ipath=1; ipath <=NbPath; ipath++) {
0d969553 1845 // Curve by iso value
7fd59977 1846 GeomFill_Sweep Sweep(myLoc->Law(ipath), KPart);
1847 Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
a31abc03 1848 Sweep.SetForceApproxC1(myForceApproxC1);
7fd59977 1849 Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax);
1850 if (!Sweep.IsDone())
1851 return Standard_False;
1852 S = Sweep.Surface();
1853 if (Sweep.ExchangeUV()) {
1854 if (Sweep.UReversed()) S->Bounds(First, Last, bid, val);
1855 else S->Bounds(First, Last, val, bid);
1856 Iso = S->VIso(val);
1857 }
1858 else {
1859 if (Sweep.UReversed()) S->Bounds(bid, val, First, Last);
1860 else S->Bounds(val, bid, First, Last);
1861 Iso = S->UIso(val);
1862 }
0d969553 1863 // Vertex by position
7fd59977 1864 if (ipath < NbPath)
1865 BuildVertex(Iso, Standard_False, First, Last,
1866 myVEdges->ChangeValue(1, ipath+1));
1867 else {
1868 if (vclose) {
1869 TopoDS_Vertex& V = TopoDS::Vertex(myVEdges->ChangeValue(1, 1));
1870 myVEdges->SetValue(1, ipath+1, V);
1871 Iso->D0(Last, P1);
1872// Tol = P1.Distance(BT.Pnt(V));
1873 Tol = P1.Distance(BRep_Tool::Pnt(V));
1874 B.UpdateVertex(V, Tol);
1875 }
1876 else {
1877 if (!LastShape.IsNull()) myVEdges->SetValue(1, NbPath, FirstShape);
1878 else BuildVertex(Iso, Standard_False, First, Last,
1879 myVEdges->ChangeValue(1, NbPath+1));
1880 }
1881 }
1882
1883 if (ipath > 1) {
1884 Iso->D0(First, P1);
1885 TopoDS_Vertex& V = TopoDS::Vertex(myVEdges->ChangeValue(1, ipath));
1886// Tol = P1.Distance(BT.Pnt(V));
1887 Tol = P1.Distance(BRep_Tool::Pnt(V));
1888 B.UpdateVertex(V, Tol);
1889 }
1890 if (ipath == 1) {
1891 if (!FirstShape.IsNull()) myVEdges->SetValue(1,1, FirstShape);
1892 else BuildVertex(Iso, Standard_True, First, Last,
1893 myVEdges->ChangeValue(1, 1));
1894 }
1895
0d969553 1896 // Construction of the edge
7fd59977 1897 BRepLib_MakeEdge MkE;
1898 MkE.Init(Iso,
1899 TopoDS::Vertex(myVEdges->Value(1, ipath)),
1900 TopoDS::Vertex(myVEdges->Value(1, ipath+1)),
1901 Iso->FirstParameter(),
1902 Iso->LastParameter());
0d969553 1903 if (!MkE.IsDone()) { // Error of construction !!
7fd59977 1904#ifdef DRAW
1905 char name[100];
1906 sprintf(name,"firstvertex_error");
1907 DBRep::Set(name, myVEdges->Value(1, ipath));
1908 sprintf(name,"lastvertex_error");
1909 DBRep::Set(name, myVEdges->Value(1, ipath+1));
1910 sprintf(name,"curve3d_error");
1911 char* Temp = name ;
1912 DrawTrSurf::Set(Temp,Iso);
1913// DrawTrSurf::Set(name,Iso);
1914 Standard_ConstructionError::Raise("BRepFill_Sweep::BuildEdge");
1915#endif
1916 return Standard_False;
1917 }
1918 E = MkE.Edge();
1919#if DRAW
1920 if (Affich) {
1921 sprintf(name,"Surf_%d", ipath);
1922 char* Temp = name;
1923 DrawTrSurf::Set(Temp, S);
1924// DrawTrSurf::Set(name, S);
1925 sprintf(name,"Edge_%d", ipath);
1926 DBRep::Set(name, E);
1927 }
1928#endif
1929 B.UpdateEdge(E, Sweep.ErrorOnSurface());
1930 B.Add(wire, E);
1931 myFaces->SetValue(1, ipath, E);
1932 }
1933 myShape = wire;
1934 return Standard_True;
1935}
1936
1937//=======================================================================
1938//function : BuildShell
0d969553 1939//purpose : Construct a Shell by sweeping
7fd59977 1940//======================================================================
1941 Standard_Boolean BRepFill_Sweep::
1942 BuildShell(const BRepFill_TransitionStyle /*Transition*/,
1943 const Standard_Integer IFirst,
1944 const Standard_Integer ILast,
c8ea5b8e 1945 TopTools_MapOfShape& ReversedEdges,
1946 BRepFill_DataMapOfShapeHArray2OfShape& Tapes,
8e817497 1947 BRepFill_DataMapOfShapeHArray2OfShape& Rails,
7fd59977 1948 const Standard_Real ExtendFirst,
1949 const Standard_Real ExtendLast)
1950{
1951 Standard_Integer ipath, isec, IPath;
1952#ifdef DRAW
1953 char name[100];
1954#endif
1955 BRep_Builder B;
1956 Standard_Integer NbPath = ILast - IFirst;
1957 Standard_Integer NbLaw = mySec->NbLaw();
1958 Standard_Boolean uclose, vclose, constSection, hasdegen = Standard_False;
1959 constSection = mySec->IsConstant();
1960 uclose = mySec->IsUClosed();
1961 vclose = (mySec->IsVClosed() && myLoc->IsClosed()) &&
1962 (NbPath == myLoc->NbLaw()) && (myLoc->IsG1(0, myTol3d)>= 0);
1963 Error = 0.;
1964
0d969553 1965 // (1) Construction of all surfaces
7fd59977 1966
0d969553 1967 // (1.1) Construction of Tables
7fd59977 1968
1969 TColStd_Array2OfInteger ExchUV(1, NbLaw, 1, NbPath);
1970 TColStd_Array2OfInteger UReverse(1, NbLaw, 1, NbPath);
1971 TColStd_Array2OfInteger Degenerated(1, NbLaw, 1, NbPath);
1972 Degenerated.Init(0);
0d969553 1973 // No VReverse for the moment...
7fd59977 1974 TColStd_Array2OfReal TabErr(1, NbLaw , 1, NbPath);
1975 TColGeom_Array2OfSurface TabS(1, NbLaw , 1, NbPath);
1976
1977 TopTools_Array2OfShape UEdge(1, NbLaw+1, 1, NbPath);
1978 TopTools_Array2OfShape VEdge(1, NbLaw , 1, NbPath+1);
1979 TopTools_Array2OfShape Vertex(1,NbLaw+1, 1, NbPath+1);
1980
1981 TopoDS_Vertex VNULL;
1982 VNULL.Nullify();
1983 Vertex.Init(VNULL);
1984
1985 TopTools_Array1OfShape SecVertex(1, NbLaw+1);
1986 TColStd_Array1OfReal VError(1, NbLaw+1);
1987 TColStd_Array1OfReal Vi(1, NbPath+1);
1988
0d969553
Y
1989//Initialization of management of parametric intervals
1990//(Case of evolutionary sections)
7fd59977 1991 Standard_Real Length, SecDom, SecDeb;
1992 myLoc->CurvilinearBounds(myLoc->NbLaw(), SecDom, Length);
1993 mySec->Law(1)->GetDomain(SecDeb, SecDom);
1994 SecDom -= SecDeb;
1995 if (IFirst > 1) {
1996 Standard_Real Lf, Ll;
1997 myLoc->CurvilinearBounds(IFirst-1, Lf, Ll);
1998 Vi(1) = SecDeb + (Ll/Length)*SecDom;
1999 }
2000 else
2001 Vi(1) = SecDeb;
2002
0d969553 2003 // Error a priori on vertices
7fd59977 2004 if (constSection) {
2005 for (isec=1; isec<=NbLaw+1; isec++) {
2006 VError(isec) = mySec->VertexTol(isec-1, 0.);
2007 SecVertex(isec) = mySec->Vertex(isec, 0.);
2008 }
2009 }
2010
2011
0d969553 2012 // (1.2) Calculate surfaces
7fd59977 2013 for (ipath=1, IPath=IFirst; ipath <=NbPath; ipath++, IPath++) {
2014
2015 GeomFill_Sweep Sweep(myLoc->Law(IPath), KPart);
2016 Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
a31abc03 2017 Sweep.SetForceApproxC1(myForceApproxC1);
7fd59977 2018
0d969553 2019 // Case of evolutionary section, definition of parametric correspondence
7fd59977 2020 if (!constSection) {
2021 Standard_Real lf, ll, Lf, Ll;
2022 myLoc->Law(IPath)->GetDomain(lf, ll);
2023 myLoc->CurvilinearBounds(IPath, Lf, Ll);
2024 Vi(ipath+1) = SecDeb + (Ll/Length)*SecDom;
2025 Sweep.SetDomain(lf, ll, Vi(ipath), Vi(ipath+1));
2026 }
2027 else //section is constant
2028 {
2029 Standard_Real lf, ll, Lf, Ll;
2030 myLoc->Law(IPath)->GetDomain(lf, ll);
2031 myLoc->CurvilinearBounds(IPath, Lf, Ll);
2032 Vi(ipath+1) = SecDeb + (Ll/Length)*SecDom;
2033 }
2034
2035 for(isec=1; isec<=NbLaw; isec++) {
2036 Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax);
2037 if (!Sweep.IsDone())
2038 return Standard_False;
2039 TabS(isec,ipath) = Sweep.Surface();
2040 TabErr(isec,ipath) = Sweep.ErrorOnSurface();
2041 ExchUV(isec, ipath) = Sweep.ExchangeUV();
2042 UReverse(isec, ipath) = Sweep.UReversed();
2043 if (Sweep.ErrorOnSurface()>Error) Error = Sweep.ErrorOnSurface();
2044
2045 if ((ipath==1)&&(ExtendFirst>0)) {
2046 Handle(Geom_BoundedSurface) BndS;
2047 BndS = Handle(Geom_BoundedSurface)::DownCast(TabS(isec,ipath));
2048 GeomLib::ExtendSurfByLength(BndS, ExtendFirst, 1,
2049 Sweep.ExchangeUV(), Standard_False);
2050 TabS(isec,ipath) = BndS;
2051 }
2052 if ((ipath==NbPath)&&(ExtendLast>0)){
2053 Handle(Geom_BoundedSurface) BndS;
2054 BndS = Handle(Geom_BoundedSurface)::DownCast(TabS(isec,ipath));
2055 GeomLib::ExtendSurfByLength(BndS, ExtendLast, 1,
2056 Sweep.ExchangeUV(), Standard_True);
2057 TabS(isec,ipath) = BndS;
2058 }
2059
2060#ifdef DRAW
2061 if (Affich) {
2062 sprintf(name,"Surf_%d_%d", isec, IPath);
2063 char* Temp = name ;
2064 DrawTrSurf::Set(Temp, TabS(isec,ipath));
2065 }
2066#endif
2067 }
2068 }
2069
0d969553 2070 // (2) Construction of Edges
7fd59977 2071 Standard_Real UFirst, ULast, VFirst, VLast;
2072 Standard_Boolean exuv, singu, singv;
2073 Handle(Geom_Surface) S;
2074
cf3327f4 2075 // (2.0) return preexisting Edges and vertices
2076 TopoDS_Edge E;
c8ea5b8e 2077 TColStd_Array1OfBoolean IsBuilt(1, NbLaw);
2078 IsBuilt.Init(Standard_False);
2079 TopTools_Array1OfShape StartEdges(1, NbLaw);
cf3327f4 2080 if (! FirstShape.IsNull() && (IFirst==1)) {
2081 mySec->Init(FirstShape);
2082 for (isec=1; isec<=NbLaw; isec++) {
2083 E = mySec->CurrentEdge();
8e817497 2084 TopoDS_Vertex Vfirst, Vlast;
2085 TopExp::Vertices(E, Vfirst, Vlast);
cf3327f4 2086 VEdge(isec, 1) = E;
2087 if (E.Orientation() == TopAbs_REVERSED)
8e817497 2088 Vertex(isec+1, 1) = Vfirst; //TopExp::FirstVertex(E);
cf3327f4 2089 else
8e817497 2090 Vertex(isec+1, 1) = Vlast; //TopExp::LastVertex(E);
cf3327f4 2091 UpdateVertex(IFirst-1, isec+1,
2092 TabErr(isec, 1), Vi(1), Vertex(isec+1, 1));
c8ea5b8e 2093
2094 StartEdges(isec) = E;
2095 if (Tapes.IsBound(E))
2096 {
2097 IsBuilt(isec) = Standard_True;
2098
2099 //Initialize VEdge, UEdge, Vertex and myFaces
2100 Standard_Integer j;
2101 for (j = 1; j <= NbPath+1; j++)
2102 {
2103 VEdge(isec, j) = Tapes(E)->Value(1, j);
2104 VEdge(isec, j).Reverse(); //direction of round is reversed
2105 }
2106 Standard_Integer ifirst = isec+1, ilast = isec; //direction of round is reversed
2107 for (j = 1; j <= NbPath; j++)
2108 UEdge(ifirst, j) = Tapes(E)->Value(2, j);
2109 for (j = 1; j <= NbPath; j++)
2110 UEdge(ilast, j) = Tapes(E)->Value(3, j);
2111 for (j = 1; j <= NbPath+1; j++)
2112 Vertex(ifirst, j) = Tapes(E)->Value(4, j);
2113 for (j = 1; j <= NbPath+1; j++)
2114 Vertex(ilast, j) = Tapes(E)->Value(5, j);
2115 for (j = 1; j <= NbPath; j++)
2116 myFaces->SetValue(isec, j, Tapes(E)->Value(6, j));
2117
2118 if (uclose && isec == 1)
2119 {
2120 for (j = 1; j <= NbPath; j++)
2121 UEdge(NbLaw+1, j) = UEdge(1, j);
2122 for (j = 1; j <= NbPath+1; j++)
2123 Vertex(NbLaw+1, j) = Vertex(1, j);
2124 }
2125 if (uclose && isec == NbLaw)
2126 {
2127 for (j = 1; j <= NbPath; j++)
2128 UEdge(1, j) = UEdge(NbLaw+1, j);
2129 for (j = 1; j <= NbPath+1; j++)
2130 Vertex(1, j) = Vertex(NbLaw+1, j);
2131 }
2132 }
2133 else
2134 {
2135 Handle(TopTools_HArray2OfShape) EmptyArray = new TopTools_HArray2OfShape(1, 6, 1, NbPath+1);
2136 Tapes.Bind(E, EmptyArray);
8e817497 2137 Standard_Integer j;
2138 if (Rails.IsBound(Vfirst))
2139 {
2140 Standard_Integer ind = (E.Orientation() == TopAbs_REVERSED)? isec+1 : isec;
2141 for (j = 1; j <= NbPath; j++)
2142 UEdge(ind, j) = Rails(Vfirst)->Value(1, j);
2143 for (j = 1; j <= NbPath+1; j++)
2144 Vertex(ind, j) = Rails(Vfirst)->Value(2, j);
2145 }
2146 if (Rails.IsBound(Vlast))
2147 {
2148 Standard_Integer ind = (E.Orientation() == TopAbs_FORWARD)? isec+1 : isec;
2149 for (j = 1; j <= NbPath; j++)
2150 UEdge(ind, j) = Rails(Vlast)->Value(1, j);
2151 for (j = 1; j <= NbPath+1; j++)
2152 Vertex(ind, j) = Rails(Vlast)->Value(2, j);
2153 }
c8ea5b8e 2154 }
7fd59977 2155 }
c8ea5b8e 2156
cf3327f4 2157 if (VEdge(1, 1).Orientation() == TopAbs_REVERSED)
2158 Vertex(1, 1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, 1)));
2159 else
2160 Vertex(1, 1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, 1)));
2161 UpdateVertex(IFirst-1, 1,
2162 TabErr(1, 1), Vi(1), Vertex(1, 1));
2163 }
c8ea5b8e 2164
2165 Standard_Real u, v, aux;
2166 Standard_Boolean ureverse;
2167 for (isec=1; isec<=NbLaw+1; isec++) {
2168 // Return data
2169 if (isec >NbLaw) {
2170 S = TabS(NbLaw, 1);
2171 ureverse = UReverse(NbLaw, 1);
2172 exuv = ExchUV(NbLaw, 1);
2173 }
2174 else {
2175 S = TabS(isec, 1);
2176 ureverse = UReverse(isec, 1);
2177 exuv = ExchUV(isec, 1);
2178 }
2179 S->Bounds(UFirst, ULast, VFirst, VLast);
2180
2181 // Choice of parameters
2182 if (ureverse) {
2183 if (exuv) {
2184 aux = VFirst; VFirst = VLast; VLast = aux;
7fd59977 2185 }
cf3327f4 2186 else {
c8ea5b8e 2187 aux = UFirst; UFirst = ULast; ULast = aux;
cf3327f4 2188 }
c8ea5b8e 2189 }
2190 if (isec!= NbLaw+1) {
2191 u = UFirst;
2192 v = VFirst;
2193 }
2194 else {
2195 if (exuv) {
cf3327f4 2196 u = UFirst;
8e817497 2197 v = VLast;
cf3327f4 2198 }
2199 else {
c8ea5b8e 2200 u = ULast;
2201 v = VFirst;
7fd59977 2202 }
c8ea5b8e 2203 }
2204
2205 // construction of vertices
2206 if (Vertex(isec, 1).IsNull())
cf3327f4 2207 B.MakeVertex(TopoDS::Vertex(Vertex(isec, 1)),
2208 S->Value(u,v),
2209 mySec->VertexTol(isec-1,Vi(1)));
c8ea5b8e 2210 else
2211 {
2212 TopLoc_Location Identity;
2213 Vertex(isec, 1).Location(Identity);
2214 B.UpdateVertex(TopoDS::Vertex(Vertex(isec, 1)),
2215 S->Value(u,v),
2216 mySec->VertexTol(isec-1,Vi(1)));
cf3327f4 2217 }
c8ea5b8e 2218 } //end of for (isec=1; isec<=NbLaw+1; isec++)
2219
cf3327f4 2220 if (! LastShape.IsNull() && (ILast==myLoc->NbLaw()+1) ) {
2221 mySec->Init(LastShape);
2222 for (isec=1; isec<=NbLaw; isec++) {
2223 E = mySec->CurrentEdge();
c8ea5b8e 2224 if (VEdge(isec, NbPath+1).IsNull())
2225 VEdge(isec, NbPath+1) = E;
2226
2227 if (Vertex(isec+1, NbPath+1).IsNull())
2228 {
2229 if (VEdge(isec, NbPath+1).Orientation() == TopAbs_REVERSED)
2230 Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(isec, NbPath+1)));
2231 else
2232 Vertex(isec+1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(isec, NbPath+1)));
2233 }
cf3327f4 2234 UpdateVertex(ILast-1, isec+1, TabErr(isec, NbPath),
2235 Vi(NbPath+1), Vertex(isec+1, NbPath+1));
2236 }
c8ea5b8e 2237
2238 if (Vertex(1, NbPath+1).IsNull())
2239 {
2240 if (VEdge(1, NbPath+1).Orientation() == TopAbs_REVERSED)
2241 Vertex(1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, NbPath+1)));
2242 else
2243 Vertex(1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1)));
2244 }
cf3327f4 2245 UpdateVertex(ILast-1, 1,
2246 TabErr(1, NbPath), Vi(NbPath+1), Vertex(1, NbPath+1 ));
c8ea5b8e 2247 }
2248
2249 for (isec=1; isec<=NbLaw+1; isec++) {
2250 // Return data
2251 if (isec >NbLaw) {
cf3327f4 2252 S = TabS(NbLaw, NbPath);
2253 ureverse = UReverse(NbLaw, NbPath);
2254 exuv = ExchUV(NbLaw, NbPath);
c8ea5b8e 2255 }
2256 else {
2257 S = TabS(isec, NbPath);
2258 ureverse = UReverse(isec, NbPath);
2259 exuv = ExchUV(isec, NbPath);
2260 }
2261 S->Bounds(UFirst, ULast, VFirst, VLast);
2262
2263 // Choice of parametres
2264 if (ureverse) {
2265 if (exuv) {
2266 aux = VFirst; VFirst = VLast; VLast = aux;
cf3327f4 2267 }
2268 else {
c8ea5b8e 2269 aux = UFirst; UFirst = ULast; ULast = aux;
cf3327f4 2270 }
c8ea5b8e 2271 }
2272 if (isec == NbLaw+1) {
2273 u = ULast;
2274 v = VLast;
2275 }
2276 else {
2277 if (exuv) {
cf3327f4 2278 u = ULast;
c8ea5b8e 2279 v = VFirst;
7fd59977 2280 }
cf3327f4 2281 else {
c8ea5b8e 2282 u = UFirst;
2283 v = VLast;
cf3327f4 2284 }
c8ea5b8e 2285 }
2286
2287 // construction of vertex
2288 if (Vertex(isec, NbPath+1).IsNull())
cf3327f4 2289 B.MakeVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)),
2290 S->Value(u,v),
2291 mySec->VertexTol(isec-1, Vi(NbPath+1)));
c8ea5b8e 2292 else
2293 {
2294 TopLoc_Location Identity;
2295 Vertex(isec, NbPath+1).Location(Identity);
2296 B.UpdateVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)),
2297 S->Value(u,v),
2298 mySec->VertexTol(isec-1, Vi(NbPath+1)));
2299 }
2300 } //end of for (isec=1; isec<=NbLaw+1; isec++)
7fd59977 2301
2302
0d969553 2303 // ---------- Creation of Vertex and edge ------------
f52d1b53 2304 ReversedEdges.Clear();
7fd59977 2305 for (ipath=1, IPath=IFirst; ipath<=NbPath;
2306 ipath++, IPath++) {
2307 for (isec=1; isec <=NbLaw; isec++) {
c8ea5b8e 2308 if (IsBuilt(isec))
2309 continue;
2310
7fd59977 2311 S = TabS(isec, ipath);
2312 exuv = ExchUV(isec, ipath);
2313 S->Bounds(UFirst, ULast, VFirst, VLast);
2314 if (UReverse(isec, ipath)) {
2315 Standard_Real aux;
2316 if (exuv) {
2317 aux = VFirst; VFirst = VLast; VLast = aux;
2318 }
2319 else {
2320 aux = UFirst; UFirst = ULast; ULast = aux;
2321 }
2322 }
2323
0d969553 2324 // (2.1) Construction of new vertices
7fd59977 2325 if (isec == 1) {
2326 if (ipath == 1 && Vertex(1, 1).IsNull()) {
0d969553 2327 // All first
7fd59977 2328 if (constSection)
2329 myLoc->PerformVertex(IPath-1,
2330 TopoDS::Vertex(SecVertex(1)),
2331 VError(1),
2332 TopoDS::Vertex(Vertex(1, 1)));
2333 else
2334 myLoc->PerformVertex(IPath-1,
2335 mySec->Vertex(1,Vi(1)),
2336 mySec->VertexTol(0,Vi(1)),
2337 TopoDS::Vertex(Vertex(1, 1)));
2338 }
0d969553 2339 // the first and the next column
7fd59977 2340 if (vclose &&(ipath == NbPath) ) {
2341 Vertex(1, ipath+1) = Vertex(1, 1);
2342 }
2343 else if (Vertex(1, ipath+1).IsNull()) {
2344 if (constSection)
2345 myLoc->PerformVertex(IPath,
2346 TopoDS::Vertex(SecVertex(1)),
2347 TabErr(1,ipath)+VError(1),
2348 TopoDS::Vertex(Vertex(1, ipath+1)) );
2349 else
2350 myLoc->PerformVertex(IPath,
2351 mySec->Vertex(1,Vi(ipath+1)),
2352 TabErr(1,ipath) +
2353 mySec->VertexTol(0,Vi(ipath+1)),
2354 TopoDS::Vertex(Vertex(1, ipath+1)));
2355
2356 if (MergeVertex(Vertex(1,ipath), Vertex(1,ipath+1))) {
2357 UEdge(1, ipath) = NullEdge(Vertex(1,ipath));
2358 }
2359 }
2360 }
2361
eafb234b 2362 if (ipath == 1) {
2363 if (uclose && (isec == NbLaw)) {
2364 Vertex(isec+1, 1) = Vertex(1, 1);
2365 }
2366 else if (Vertex(isec+1, 1).IsNull()) {
2367 if (constSection)
2368 myLoc->PerformVertex(IPath-1,
2369 TopoDS::Vertex(SecVertex(isec+1)),
2370 TabErr(isec,1)+VError(isec+1),
2371 TopoDS::Vertex(Vertex(isec+1, 1)) );
2372 else
2373 myLoc->PerformVertex(IPath-1,
2374 mySec->Vertex(isec+1,Vi(1)),
2375 TabErr(isec,1) +
2376 mySec->VertexTol(isec,Vi(1)),
2377 TopoDS::Vertex(Vertex(isec+1, 1)) );
c8ea5b8e 2378
eafb234b 2379 if (MergeVertex(Vertex(isec,1), Vertex(isec+1,1))) {
2380 VEdge(isec, 1) = NullEdge(Vertex(isec, 1));
2381 }
2382 }
2383 }
7fd59977 2384
2385 if (uclose && (isec == NbLaw)) {
2386 Vertex(isec+1, ipath+1) = Vertex(1, ipath+1);
2387 }
2388 else if (vclose && (ipath == NbPath)) {
2389 Vertex(isec+1, ipath+1) = Vertex(isec+1, 1);
2390 }
2391 else if (Vertex(isec+1, ipath+1).IsNull()) {
2392 if (constSection)
2393 myLoc->PerformVertex(IPath,
2394 TopoDS::Vertex(SecVertex(isec+1)),
2395 TabErr(isec, ipath)+ VError(isec+1),
2396 TopoDS::Vertex(Vertex(isec+1, ipath+1)) );
2397 else
2398 myLoc->PerformVertex(IPath,
2399 mySec->Vertex(isec+1,Vi(ipath+1)),
2400 TabErr(isec, ipath) +
2401 mySec->VertexTol(isec, Vi(ipath+1)),
2402 TopoDS::Vertex(Vertex(isec+1, ipath+1)) );
2403 }
2404
0d969553 2405 // Singular cases
7fd59977 2406 singv = MergeVertex(Vertex(isec,ipath+1), Vertex(isec+1,ipath+1));
2407 singu = MergeVertex(Vertex(isec+1,ipath), Vertex(isec+1,ipath+1));
2408
2409
2410
2411 if (singu || singv) {
2412 Degenerated(isec, ipath) = IsDegen(TabS(isec,ipath),
2413 Max(myTol3d, TabErr(isec,ipath)));
2414 }
2415 if (Degenerated(isec, ipath)) {
0797d9d3 2416#ifdef OCCT_DEBUG
0d969553 2417 cout << "Sweep : Degenerated case" << endl;
7fd59977 2418#endif
2419 hasdegen = Standard_True;
0d969553 2420 // Particular construction of edges
7fd59977 2421 if (UEdge(isec+1, ipath).IsNull()) {
2422 if (singu) {
0d969553 2423 // Degenerated edge
7fd59977 2424 UEdge(isec+1, ipath) = NullEdge(Vertex(isec+1,ipath));
2425 }
0d969553 2426 else { // Copy the previous edge
7fd59977 2427 UEdge(isec+1, ipath) = UEdge(isec, ipath);
2428 }
2429 }
2430 if (VEdge(isec, ipath+1).IsNull()) {
2431 if (singv) {
0d969553 2432 // Degenerated Edge
7fd59977 2433 VEdge(isec, ipath+1) = NullEdge(Vertex(isec,ipath+1));
2434 }
0d969553 2435 else { // Copy the previous edge
7fd59977 2436 VEdge(isec, ipath+1) = VEdge(isec, ipath);
2437 }
2438 }
2439 }
0d969553 2440 else { // Construction of edges by isos
7fd59977 2441 if (exuv) {
2442 Standard_Real UV;
2443 UV = UFirst; UFirst = VFirst; VFirst = UV;
2444 UV = ULast ; ULast = VLast ; VLast = UV;
2445 }
2446
2447 // (2.2) Iso-u
c8ea5b8e 2448 if (isec == 1 && UEdge(1, ipath).IsNull()) {
7fd59977 2449 if (!Vertex(1,ipath).IsSame(Vertex(1,ipath+1))) {
2450 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath)));
2451 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath+1)));
2452 if (P1.Distance(P2) <= myTol3d)
2453 Vertex(1,ipath+1) = Vertex(1,ipath);
2454 }
2455 UEdge(1, ipath) = BuildEdge(S, !exuv, UFirst,
2456 Vertex(1,ipath),
2457 Vertex(1,ipath+1),
2458 myTol3d);
2459 }
73920cd4 2460 else
2461 {
2462 if (UEdge(isec, ipath).IsNull()) //sweep failed
2463 return Standard_False;
2464 UpdateEdge(TopoDS::Edge(UEdge(isec, ipath)),
2465 S, !exuv, UFirst);
2466 }
7fd59977 2467
2468 if (uclose && (isec==NbLaw)) {
21b7d8be 2469 if (UEdge(1, ipath).IsNull()) //degenerated case
2470 {
2471 UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast,
2472 Vertex(isec+1, ipath),
2473 Vertex(isec+1, ipath+1),
2474 myTol3d);
2475 }
2476 else {
2477 UpdateEdge(TopoDS::Edge(UEdge(1, ipath)),
2478 S, !exuv, ULast);
2479 UEdge(isec+1, ipath) = UEdge(1, ipath);
2480 }
7fd59977 2481 }
2482 else {
c8ea5b8e 2483 if (UEdge(isec+1, ipath).IsNull())
2484 UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast,
2485 Vertex(isec+1, ipath),
2486 Vertex(isec+1, ipath+1),
2487 myTol3d);
2488 else
2489 UpdateEdge(TopoDS::Edge(UEdge(isec+1, ipath)), S, !exuv, ULast);
7fd59977 2490 }
2491
2492 // (2.3) Iso-v
c8ea5b8e 2493 if (ipath == 1)
2494 {
2495 TopoDS_Edge aNewFirstEdge = BuildEdge(S, exuv, VFirst,
2496 Vertex(isec , 1),
2497 Vertex(isec+1, 1),
2498 myTol3d);
2499 if (VEdge(isec, ipath).IsNull())
2500 VEdge(isec, ipath) = aNewFirstEdge;
2501 else //rebuild first edge
d3dfddae 2502 {
c8ea5b8e 2503 RebuildTopOrBottomEdge(aNewFirstEdge,
2504 TopoDS::Edge(VEdge(isec, ipath)),
2505 ReversedEdges);
d3dfddae 2506 if (ReversedEdges.Contains(VEdge(isec, ipath)))
2507 StartEdges(isec).Reverse();
2508 }
c8ea5b8e 2509 }
7fd59977 2510
2511 else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath)),
2512 S, exuv, VFirst);
2513
2514 if (vclose && (ipath == NbPath)) {
21b7d8be 2515 if (VEdge(isec, 1).IsNull()) //degenerated case
2516 {
2517 VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast,
2518 Vertex(isec , ipath+1),
2519 Vertex(isec+1, ipath+1),
2520 myTol3d);
2521 }
2522 else {
2523 UpdateEdge(TopoDS::Edge(VEdge(isec, 1)),
2524 S, exuv, VLast);
2525 VEdge(isec, ipath+1) = VEdge(isec, 1);
2526 }
7fd59977 2527 }
2528 else if (VEdge(isec, ipath+1).IsNull())
2529 VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast,
2530 Vertex(isec , ipath+1),
2531 Vertex(isec+1, ipath+1),
2532 myTol3d);
c8ea5b8e 2533 else
2534 {
2535 if (ipath != NbPath || vclose)
2536 UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)),
2537 S, exuv, VLast);
2538 else //ipath == NbPath && !vclose => rebuild last edge
2539 {
2540 TopoDS_Edge aNewLastEdge = BuildEdge(S, exuv, VLast,
2541 Vertex(isec , ipath+1),
2542 Vertex(isec+1, ipath+1),
2543 myTol3d);
2544 RebuildTopOrBottomEdge(aNewLastEdge,
2545 TopoDS::Edge(VEdge(isec, ipath+1)),
2546 ReversedEdges);
2547 }
2548 }
7fd59977 2549 }
0d969553 2550 }// End of construction of edges
7fd59977 2551 }
2552
0d969553 2553 // (3) Construction of Faces
7fd59977 2554 TopoDS_Face face;
2555
2556#ifdef DRAW
2557 if (Affich) {
2558 for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) {
2559 for (isec=1; isec <=NbLaw+1; isec++){
2560 sprintf(name,"uedge_%d_%d", isec, IPath);
2561 DBRep::Set(name,UEdge(isec, ipath));
2562 }
2563 }
2564
2565 for (ipath=1, IPath=IFirst; ipath<=NbPath+1; ipath++, IPath++) {
2566 for (isec=1; isec <=NbLaw; isec++){
2567 sprintf(name,"vedge_%d_%d", isec, IPath);
2568 DBRep::Set(name,VEdge(isec, ipath));
2569 }
2570
2571 for (isec=1; isec <=NbLaw+1; isec++){
2572 sprintf(name,"vertex_%d_%d", isec, IPath);
2573 DBRep::Set(name,Vertex(isec, ipath));
2574 }
2575 }
2576 }
2577#endif
2578
2579 for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) {
2580 for (isec=1; isec <=NbLaw; isec++) {
2581 if (Degenerated(isec, ipath)) {
2582 if (UEdge(isec, ipath).IsSame(UEdge(isec+1, ipath)))
2583 myFaces->SetValue(isec, IPath, UEdge(isec, ipath));
2584 else
2585 myFaces->SetValue(isec, IPath, VEdge(isec, ipath));
2586 }
c8ea5b8e 2587 else if (myFaces->Value(isec, IPath).IsNull()) {
7fd59977 2588 BuildFace(TabS(isec,ipath),
2589 TopoDS::Edge(UEdge(isec, ipath)),
2590 TopoDS::Edge(VEdge(isec, ipath)),
2591 TopoDS::Edge(UEdge(isec+1, ipath)),
2592 TopoDS::Edge(VEdge(isec, ipath+1)),
2593 myVEdgesModified,
2594 ExchUV(isec, ipath),
2595 UReverse(isec, ipath),
2596 face);
2597 myFaces->SetValue(isec, IPath, face);
2598 }
2599 }
2600 }
2601
c8ea5b8e 2602 // (3.1) Reverse the faces that have been built ealier
2603 for (ipath = 1; ipath <= NbPath; ipath++)
2604 for (isec = 1; isec <= NbLaw; isec++)
2605 if (IsBuilt(isec))
2606 myFaces->ChangeValue(isec, ipath).Reverse();
2607
7fd59977 2608
0d969553 2609 // (4) History and Continuity
7fd59977 2610
2611 if (hasdegen) {
0d969553 2612 //(4.1) // Degenerated case => Sledgehammer
7fd59977 2613 TopoDS_Compound Comp;
2614 B.MakeCompound(Comp);
2615 for (isec=1; isec <= NbLaw+1; isec++)
2616 for (ipath=1, IPath=IFirst; ipath<= NbPath+1; ipath++, IPath++) {
2617 if (ipath <= NbPath) myUEdges->SetValue(isec, IPath, UEdge(isec, ipath));
2618 if (isec <= NbLaw) myVEdges->SetValue(isec, IPath, VEdge(isec, ipath));
2619 if ((ipath <= NbPath) && (isec <= NbLaw) &&
2620 (myFaces->Value(isec, IPath).ShapeType() == TopAbs_FACE))
2621 B.Add(Comp, myFaces->Value(isec, IPath));
2622 }
2623 BRepLib::EncodeRegularity(Comp, myTolAngular);
2624 }
2625 else {
0d969553 2626 //(4.2) // General case => Tweezers
7fd59977 2627 Standard_Boolean isG1;
2628 TopoDS_Face FF;
2629 TopoDS_Edge E;
2630
2631 for (isec=1; isec <= NbLaw+1; isec++) {
2632 if (isec>1) isG1 =
2633 (mySec->Continuity(isec-1, myTolAngular) >= GeomAbs_G1);
2634 else isG1 = Standard_False;
2635 for (ipath=1, IPath=IFirst; ipath<= NbPath; ipath++, IPath++) {
2636 myUEdges->SetValue(isec, IPath, UEdge(isec, ipath));
2637 if (isG1) {
2638 if (isec == NbLaw+1) FF = TopoDS::Face(myFaces->Value(1, IPath));
2639 else FF = TopoDS::Face(myFaces->Value(isec, IPath));
2640 B.Continuity(TopoDS::Edge(myUEdges->Value(isec, IPath)),
2641 TopoDS::Face(myFaces->Value(isec-1, IPath)),
2642 FF, GeomAbs_G1);
2643 }
2644 }
2645 }
2646
2647 Standard_Integer nbpath = NbPath;
0d969553 2648 if (vclose) nbpath++; //Another test G1
7fd59977 2649 for (ipath=1, IPath=IFirst; ipath<= NbPath+1; ipath++, IPath++) {
2650 if ((ipath > 1) && (ipath <=nbpath))
2651 isG1 = (myLoc->IsG1(IPath-1, myTol3d, myTolAngular) >= 0);
2652 else isG1 = Standard_False;
2653 for (isec=1; isec <= NbLaw; isec++) {
2654 myVEdges->SetValue(isec, IPath, VEdge(isec, ipath));
2655 if (isG1) {
2656 if (ipath==NbPath+1) FF = TopoDS::Face(myFaces->Value(isec, 1));
2657 else FF = TopoDS::Face(myFaces->Value(isec, IPath));
2658 E = TopoDS::Edge(myVEdges->Value(isec, IPath));
2659 BRepLib::EncodeRegularity(E, FF,
2660 TopoDS::Face(myFaces->Value(isec, IPath-1)),
2661 myTolAngular);
2662 }
2663 }
2664 }
2665 }
c8ea5b8e 2666
8e817497 2667 // (5) Update Tapes and Rails
c8ea5b8e 2668 Standard_Integer j;
2669 if (IFirst == 1 && !Tapes.IsEmpty()) //works only in case of single shell
2670 {
2671 for (isec = 1; isec <= NbLaw; isec++)
2672 {
2673 for (j = 1; j <= NbPath+1; j++)
2674 Tapes(StartEdges(isec))->SetValue(1, j, myVEdges->Value(isec, j));
2675 for (j = 1; j <= NbPath; j++)
2676 Tapes(StartEdges(isec))->SetValue(2, j, myUEdges->Value(isec, j));
2677 for (j = 1; j <= NbPath; j++)
2678 Tapes(StartEdges(isec))->SetValue(3, j, myUEdges->Value(isec+1, j));
2679 for (j = 1; j <= NbPath+1; j++)
2680 Tapes(StartEdges(isec))->SetValue(4, j, Vertex(isec, j));
2681 for (j = 1; j <= NbPath+1; j++)
2682 Tapes(StartEdges(isec))->SetValue(5, j, Vertex(isec+1, j));
2683 for (j = 1; j <= NbPath; j++)
2684 Tapes(StartEdges(isec))->SetValue(6, j, myFaces->Value(isec, j));
8e817497 2685 TopoDS_Vertex Vfirst, Vlast;
d3dfddae 2686 TopExp::Vertices(TopoDS::Edge(StartEdges(isec)), Vfirst, Vlast, Standard_True); //with orientation
8e817497 2687 if (!Rails.IsBound(Vfirst))
2688 {
2689 Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1);
2690 for (j = 1; j <= NbPath; j++)
2691 anArray->SetValue(1, j, myUEdges->Value(isec, j));
2692 for (j = 1; j <= NbPath+1; j++)
2693 anArray->SetValue(2, j, Vertex(isec, j));
2694 Rails.Bind(Vfirst, anArray);
2695 }
2696 if (!Rails.IsBound(Vlast))
2697 {
2698 Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1);
2699 for (j = 1; j <= NbPath; j++)
2700 anArray->SetValue(1, j, myUEdges->Value(isec+1, j));
2701 for (j = 1; j <= NbPath+1; j++)
2702 anArray->SetValue(2, j, Vertex(isec+1, j));
2703 Rails.Bind(Vlast, anArray);
2704 }
c8ea5b8e 2705 }
2706 }
2707
7fd59977 2708 return Standard_True;
2709}
2710
2711//=======================================================================
2712//function : Build
0d969553 2713//purpose : Construt the result of sweeping
7fd59977 2714//======================================================================
c8ea5b8e 2715void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges,
2716 BRepFill_DataMapOfShapeHArray2OfShape& Tapes,
8e817497 2717 BRepFill_DataMapOfShapeHArray2OfShape& Rails,
c8ea5b8e 2718 const BRepFill_TransitionStyle Transition,
2719 const GeomAbs_Shape Continuity,
2720 const GeomFill_ApproxStyle Approx,
2721 const Standard_Integer Degmax,
2722 const Standard_Integer Segmax)
7fd59977 2723{
7fd59977 2724 myContinuity = Continuity;
a31abc03 2725 myApproxStyle = Approx;
7fd59977 2726 myDegmax = Degmax;
2727 mySegmax = Segmax;
2728
2729 CorrectApproxParameters();
2730
2731 // Wire
2732 if (mySec->IsVertex()) isDone = BuildWire(Transition);
2733
2734 else { // Shell
2735 Standard_Integer NbTrous = myLoc->NbHoles(myTol3d),
2736 NbPath = myLoc->NbLaw(),
2737 NbLaw = mySec->NbLaw(), ii, jj, NbPart=1;
2738 Standard_Integer ipath, isec;
2739 BRep_Builder B;
2740 myUEdges = new (TopTools_HArray2OfShape) (1, NbLaw+1, 1, NbPath);
2741 myVEdges = new (TopTools_HArray2OfShape) (1, NbLaw, 1, NbPath+1);
2742 myFaces = new (TopTools_HArray2OfShape) (1, NbLaw, 1, NbPath);
2743 Handle (TopTools_HArray2OfShape) Bounds =
2744 new (TopTools_HArray2OfShape) (1, NbLaw, 1, 2);
2745
2746 Handle(TColStd_HArray1OfInteger) Trous;
2747
0d969553 2748 if (NbTrous>0) { // How many sub-parts ?
7fd59977 2749 Trous = new (TColStd_HArray1OfInteger) (1, NbTrous);
2750 myLoc->Holes(Trous->ChangeArray1());
2751 NbPart += NbTrous;
2752 if (Trous->Value(NbTrous) == NbPath+1) NbPart--;
2753 }
0d969553 2754 if (NbPart == 1) { // This is done at once
7fd59977 2755 Standard_Real Extend = 0.0;
2756 if (NbTrous==1) Extend = EvalExtrapol(1, Transition);
2757 isDone = BuildShell(Transition,
2758 1, NbPath+1,
c8ea5b8e 2759 ReversedEdges,
8e817497 2760 Tapes, Rails,
7fd59977 2761 Extend, Extend);
2762 }
0d969553 2763 else { // This is done piece by piece
7fd59977 2764 Standard_Integer IFirst = 1, ILast;
2765 for (ii=1, isDone=Standard_True;
2766 ii<=NbPart && isDone; ii++) {
2767 if (ii > NbTrous) ILast = NbPath+1;
2768 else ILast = Trous->Value(ii);
2769 isDone = BuildShell(Transition,
2770 IFirst, ILast,
c8ea5b8e 2771 ReversedEdges,
8e817497 2772 Tapes, Rails,
7fd59977 2773 EvalExtrapol(IFirst, Transition),
2774 EvalExtrapol(ILast, Transition));
2775 if (IFirst>1) {
2776 Translate(myVEdges, IFirst, Bounds, 2);
2777 PerformCorner(IFirst,
2778 Transition, Bounds);
2779 }
2780 IFirst = ILast;
2781 Translate(myVEdges, IFirst, Bounds, 1);
2782 }
2783 }
0d969553 2784 // Management of looping ends
7fd59977 2785 if ( (NbTrous>0) && (myLoc->IsClosed()) &&
2786 (Trous->Value(NbTrous) == NbPath+1) ) {
2787 Translate(myVEdges, NbPath+1, Bounds, 1);
2788 Translate(myVEdges, 1, Bounds, 2);
2789 PerformCorner(1, Transition, Bounds);
2790 }
2791
0d969553 2792 // Construction of the shell
7fd59977 2793 TopoDS_Shell shell;
2794 B.MakeShell(shell);
2795 for (ipath=1; ipath<=NbPath; ipath++)
2796 for (isec=1; isec <=NbLaw; isec++) {
2797 const TopoDS_Shape& face = myFaces->Value(isec, ipath);
2798 if (!face.IsNull() &&
2799 (face.ShapeType() == TopAbs_FACE) ) B.Add(shell, face);
2800 }
2801
2802 TopTools_ListIteratorOfListOfShape It(myAuxShape);
2803 for (; It.More(); It.Next()) {
2804 const TopoDS_Shape& face = It.Value();
2805 if (!face.IsNull() &&
2806 (face.ShapeType() == TopAbs_FACE) ) B.Add(shell, face);
2807 }
2808 //Set common Uedges to faces
2809 BRepTools_Substitution aSubstitute;
2810 /*
2811 for (ii = 1; ii <= NbLaw; ii++)
2812 for (jj = 1; jj <= NbPath; jj++)
2813 {
2814 SetCommonEdgeInFace(aSubstitute,
2815 myFaces->Value(ii, jj),
2816 myUEdges->Value(ii, jj));
2817 SetCommonEdgeInFace(aSubstitute,
2818 myFaces->Value(ii, jj),
2819 myUEdges->Value(ii+1, jj));
2820 }
2821 if (mySec->IsUClosed())
2822 for (jj = 1; jj <= NbPath; jj++)
2823 SetCommonEdgeInFace(aSubstitute,
2824 myFaces->Value( 1, jj ),
2825 myUEdges->Value( NbLaw+1, jj));
2826 */
2827 TopTools_DataMapIteratorOfDataMapOfShapeShape mapit( myVEdgesModified );
2828 for (; mapit.More(); mapit.Next())
2829 {
2830 const TopoDS_Edge& OldEdge = TopoDS::Edge(mapit.Key());
2831 const TopoDS_Edge& NewEdge = TopoDS::Edge(mapit.Value());
2832 Substitute( aSubstitute, OldEdge, NewEdge );
2833 }
2834 aSubstitute.Build( shell );
2835 if (aSubstitute.IsCopied( shell )) {
2836 const TopTools_ListOfShape& listSh = aSubstitute.Copy( shell );
2837 shell = TopoDS::Shell( listSh.First() );
2838 }
2839
2840 for (ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
2841 for (jj = myFaces->LowerCol(); jj <= myFaces->UpperCol(); jj++) {
2842 const TopoDS_Shape& aLocalShape = myFaces->Value(ii, jj);
2843
2844 if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) {
2845 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
2846
2847 if(!aList.IsEmpty())
2848 myFaces->ChangeValue(ii, jj) = aList.First();
2849 }
2850 }
2851 }
2852
2853 for (ii = myVEdges->LowerRow(); ii <= myVEdges->UpperRow(); ii++) {
2854 for (jj = myVEdges->LowerCol(); jj <= myVEdges->UpperCol(); jj++) {
2855 const TopoDS_Shape& aLocalShape = myVEdges->Value(ii, jj);
2856
2857 if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) {
2858 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
2859
2860 if(!aList.IsEmpty())
2861 myVEdges->ChangeValue(ii, jj) = aList.First();
2862 }
2863 }
2864 }
2865
2866 for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) {
2867 for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++) {
2868 const TopoDS_Shape& aLocalShape = myUEdges->Value(ii, jj);
2869
2870 if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) {
2871 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
2872
2873 if(!aList.IsEmpty())
2874 myUEdges->ChangeValue(ii, jj) = aList.First();
2875 }
2876 }
2877 }
2878
0d969553 2879 // Is it Closed ?
7fd59977 2880 if (myLoc->IsClosed() && mySec->IsUClosed()) {
0d969553 2881 //Check
7fd59977 2882 Standard_Boolean closed = Standard_True;
2883 Standard_Integer iedge;
2884 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
2885 TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE,
2886 TopAbs_FACE, EFmap);
2887
2888 for (iedge = 1; iedge <=EFmap.Extent() && closed; iedge++) {
2889 const TopoDS_Edge& theEdge = TopoDS::Edge(EFmap.FindKey(iedge));
2890 if (BRep_Tool::Degenerated(theEdge)) continue;
2891 closed = ( EFmap(iedge).Extent() > 1);
2892 }
2893 shell.Closed(closed);
2894 }
2895 myShape = shell;
2896 }
2897}
2898
2899
2900//=======================================================================
2901//function : IsDone
2902//purpose :
2903//=======================================================================
2904 Standard_Boolean BRepFill_Sweep::IsDone() const
2905{
2906 return isDone;
2907}
2908
2909//=======================================================================
2910//function : Shape
2911//purpose :
2912//=======================================================================
2913 TopoDS_Shape BRepFill_Sweep::Shape() const
2914{
2915 return myShape;
2916}
2917
2918//=======================================================================
2919//function : ErrorOnSurface
2920//purpose :
2921//=======================================================================
2922 Standard_Real BRepFill_Sweep::ErrorOnSurface() const
2923{
2924 return Error;
2925}
2926
2927//=======================================================================
2928//function : SubShape
0d969553 2929//purpose : Faces obtained by sweeping
7fd59977 2930//=======================================================================
2931 Handle(TopTools_HArray2OfShape) BRepFill_Sweep::SubShape() const
2932{
2933 return myFaces;
2934}
2935
2936//=======================================================================
2937//function : InterFaces
0d969553 2938//purpose : Edges obtained by sweeping
7fd59977 2939//=======================================================================
2940 Handle(TopTools_HArray2OfShape) BRepFill_Sweep::InterFaces() const
2941{
2942 return myUEdges;
2943}
2944
2945//=======================================================================
2946//function : Sections
0d969553 2947//purpose : Edges or Face (or compound of 2) Transition between 2 sweepings
7fd59977 2948//=======================================================================
2949 Handle(TopTools_HArray2OfShape) BRepFill_Sweep::Sections() const
2950{
2951 return myVEdges;
2952}
2953
2954//=======================================================================
2955//function : PerformCorner
0d969553 2956//purpose : Trim and/or loop a corner
7fd59977 2957//======================================================================
2958 void BRepFill_Sweep::PerformCorner(const Standard_Integer Index,
2959 const BRepFill_TransitionStyle Transition,
2960 const Handle(TopTools_HArray2OfShape)& Bounds)
2961{
2962
0d969553 2963 if (Transition == BRepFill_Modified) return; // Do nothing.
7fd59977 2964
2965 BRepFill_TransitionStyle TheTransition = Transition;
2966 Standard_Boolean isTangent=Standard_False;
2967 Standard_Real F, L;
2968 Standard_Integer I1, I2, ii; //, jj;
2969 gp_Pnt P1,P2;
2970 gp_Vec T1, T2, Tang, Sortant;
2971// gp_Mat M;
2972 //Handle(TopTools_HArray1OfShape) TheShape =
2973 //new TopTools_HArray1OfShape( 1, mySec->NbLaw() );
2974// TopTools_ListIteratorOfListOfShape Iterator;
2975
2976 if (Index > 1) {
2977 I1 = Index-1;
2978 I2 = Index;
2979 }
2980 else {
2981 I1 = myLoc->NbLaw();
2982 I2 = 1;
2983 }
2984
0d969553 2985 // Construct an axis supported by the bissectrice
7fd59977 2986 myLoc->Law(I1)->GetDomain(F, L);
2987 myLoc->Law(I1)->GetCurve()->D1(L, P1, T1);
2988 T1.Normalize();
2989
2990 myLoc->Law(I2)->GetDomain(F, L);
2991 myLoc->Law(I2)->GetCurve()->D1(F, P2, T2);
2992 T2.Normalize();
2993
2994 if (T1.Angle(T2) < myAngMin) {
2995 isTangent = Standard_True;
2996 gp_Vec t1, t2, V;
2997 gp_Mat M;
2998 myLoc->Law(I1)->GetDomain(F, L);
2999 myLoc->Law(I1)->D0(L, M, V);
3000 t1 = M.Column(3);
3001 myLoc->Law(I2)->GetDomain(F, L);
3002 myLoc->Law(I2)->D0(L, M, V);
3003 t2 = M.Column(3);
3004
3005 if (t1.Angle(t2) < myAngMin) {
0797d9d3 3006#ifdef OCCT_DEBUG
0d969553 3007 cout << "BRepFill_Sweep::PerformCorner : This is not a corner !" << endl;
7fd59977 3008#endif
3009 return;
3010 }
3011 Sortant = t2 - t1;
3012 }
3013
3014 if ((TheTransition == BRepFill_Right)
3015 && (T1.Angle(T2) > myAngMax) ) {
3016 TheTransition = BRepFill_Round;
3017 }
3018
0d969553 3019 Tang = T1 + T2; //Average direction
7fd59977 3020 gp_Dir NormalOfBisPlane = Tang;
3021
3022 if (isTangent) {
3023 Sortant -= Tang.Dot(Tang)*Tang;
3024 }
3025 else {
0d969553
Y
3026 Sortant = T2-T1; //Direction input
3027 Sortant *= -1; // " " output
7fd59977 3028 Tang -= (Tang.Dot(T2))*T2;
3029 }
3030
3031 P1.BaryCenter(0.5, P2, 0.5);
3032 gp_Dir N(Sortant);
3033 gp_Dir Dx(Tang);
3034
3035 gp_Ax2 Axe (P1, N, Dx);
3036 gp_Ax2 AxeOfBisPlane( P1, NormalOfBisPlane );
3037
0d969553 3038 // Construct 2 intersecting Shells
7fd59977 3039 Handle (TopTools_HArray2OfShape) UEdges =
3040 new TopTools_HArray2OfShape( 1, mySec->NbLaw()+1, 1, myLoc->NbLaw() );
3041 UEdges->ChangeArray2() = myUEdges->Array2();
3042
3043// modified by NIZHNY-MKK Wed Oct 29 18:31:47 2003.BEGIN
3044 Handle (TopTools_HArray2OfShape) aFaces =
3045 new TopTools_HArray2OfShape(myFaces->LowerRow(), myFaces->UpperRow(), 1, 2);
3046 Translate(myFaces, I1, aFaces, 1);
3047 Translate(myFaces, I2, aFaces, 2);
3048
3049 Handle (TopTools_HArray2OfShape) aUEdges =
3050 new TopTools_HArray2OfShape(myUEdges->LowerRow(), myUEdges->UpperRow(), 1, 2);
3051 Translate(myUEdges, I1, aUEdges, 1);
3052 Translate(myUEdges, I2, aUEdges, 2);
3053
3054 gp_Vec aNormal = T2 + T1;
3055 TopoDS_Face aPlaneF;
3056
3057 if(aNormal.Magnitude() > gp::Resolution()) {
3058 gp_Pln pl(P1, gp_Dir(aNormal));
3059 BRepLib_MakeFace aFMaker(pl);
3060
3061 if(aFMaker.Error() == BRepLib_FaceDone) {
3062 aPlaneF = aFMaker.Face();
3063 BRep_Builder aBB;
3064 aBB.UpdateFace(aPlaneF, Precision::Confusion() * 10.);
3065 }
3066 }
3067
3068 BRepFill_TrimShellCorner aTrim(aFaces, AxeOfBisPlane, aPlaneF);
3069 aTrim.AddBounds(Bounds);
3070 aTrim.AddUEdges(aUEdges);
3071 aTrim.Perform();
3072
3073 if (aTrim.IsDone()) {
3074 TopTools_ListOfShape listmodif;
3075 Standard_Integer iit = 0;
3076
3077 for(iit = 0; iit < 2; iit++) {
3078 Standard_Integer II = (iit == 0) ? I1 : I2;
3079
3080 for (ii = 1; ii <= mySec->NbLaw(); ii++) {
3081 aTrim.Modified(myFaces->Value(ii, II), listmodif);
3082
3083 if(!listmodif.IsEmpty()) {
3084 myFaces->SetValue(ii, II, listmodif.First());
3085 }
3086 }
3087
3088 for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) {
3089 aTrim.Modified(myUEdges->Value(ii, II), listmodif);
3090
3091 if(!listmodif.IsEmpty()) {
3092 myUEdges->SetValue(ii, II, listmodif.First());
3093 }
3094 }
3095 }
3096 }
3097 else if ((TheTransition == BRepFill_Right) ||
3098 aTrim.HasSection() ) {
0797d9d3 3099#ifdef OCCT_DEBUG
0d969553 3100 cout << "Fail of TrimCorner" << endl;
7fd59977 3101#endif
0d969553 3102 return; // Nothing is touched
7fd59977 3103 }
3104
3105 if (mySec->IsUClosed())
3106 {
3107 myUEdges->SetValue( 1, I1, myUEdges->Value(mySec->NbLaw()+1, I1) );
3108 myUEdges->SetValue( 1, I2, myUEdges->Value(mySec->NbLaw()+1, I2) );
3109 }
3110
3111 if (TheTransition == BRepFill_Round) {
0d969553 3112 // Filling
7fd59977 3113 TopTools_ListOfShape list1, list2;
3114 TopoDS_Edge Bord1, Bord2, BordFirst;
3115 BordFirst.Nullify();
3116 Bord1.Nullify();
3117 Bord2.Nullify();
3118 Standard_Boolean HasFilling = Standard_False;
3119 TopoDS_Face FF;
3120 for (ii=1; ii<=mySec->NbLaw(); ii++) {
3121 KeepEdge(myFaces->Value(ii, I1), Bounds->Value(ii, 1), list1);
3122 KeepEdge(myFaces->Value(ii, I2), Bounds->Value(ii, 2), list2);
3123 if (list1.Extent() == list2.Extent()) {
3124 TopTools_ListIteratorOfListOfShape It1(list1);
3125 TopTools_ListIteratorOfListOfShape It2(list2);
3126 Standard_Boolean B;
3127 for (; It1.More(); It1.Next(), It2.Next()) {
0d969553 3128 if (HasFilling) { // Transversal choice of constraints
7fd59977 3129 TopoDS_Vertex VF, VL, VC;
3130 TopoDS_Edge E = TopoDS::Edge(It1.Value());
3131 TopoDS_Edge E1, E2;
3132 E1.Nullify();
3133 E2.Nullify();
3134 TopExp::Vertices(E, VF, VL);
3135 if (!Bord1.IsNull() &&
3136 TopExp::CommonVertex(E, Bord1, VC)) {
3137 if (VC.IsSame(VF)) E1 = Bord1;
3138 else E2 = Bord1;
3139 }
3140 if (!Bord2.IsNull() &&
3141 TopExp::CommonVertex(E, Bord2, VC)) {
3142 if (VC.IsSame(VF)) E1 = Bord2;
3143 else E2 = Bord2;
3144 }
3145 if (!BordFirst.IsNull() &&
3146 TopExp::CommonVertex(E, BordFirst, VC)) {
3147 if (VC.IsSame(VF)) E1 = BordFirst;
3148 else E2 = BordFirst;
3149 }
3150 Bord1 = E1;
3151 Bord2 = E2;
3152 }
3153
0d969553 3154 // Filling
7fd59977 3155 B = Filling(It1.Value(), myFaces->Value(ii, I1),
3156 It2.Value(), myFaces->Value(ii, I2),
3157 myVEdgesModified, myTol3d, Axe, T1, Bord1, Bord2, FF);
3158
3159 if (B) {
3160 myAuxShape.Append(FF);
3161 myVEdges->ChangeValue(ii, I2) = FF;
3162 HasFilling = Standard_True;
3163 }
3164 if (ii==1) BordFirst = Bord1;
3165 }
3166 }
0797d9d3 3167#ifdef OCCT_DEBUG
0d969553 3168 else cout << "PerformCorner : Unsymmetry of free border" << endl;
7fd59977 3169#endif
3170 }
3171 }
3172
3173/*
3174#if DRAW
3175 if (Affich) {
3176 Standard_Integer jj;
3177 char name[100];
3178 DBRep::Set("TrimmedShell", TheShape);
3179 for (jj=1; jj <=myFaces->ColLength(); jj++){
3180 sprintf(name,"Tfaces_%d_%d", jj, I1);
3181 DBRep::Set(name, myFaces->Value(jj, I1));
3182 sprintf(name,"Tfaces_%d_%d", jj, I2);
3183 DBRep::Set(name, myFaces->Value(jj, I2));
3184 }
3185 }
3186#endif
3187*/
3188}
3189
3190//=======================================================================
3191//function : EvalExtrapol
3192//purpose :
3193//======================================================================
3194Standard_Real BRepFill_Sweep::
3195 EvalExtrapol(const Standard_Integer Index,
3196 const BRepFill_TransitionStyle Transition) const
3197{
3198 Standard_Real Extrap = 0.0;
3199 if (Transition == BRepFill_Right) {
3200 Standard_Integer I1, I2;
3201 if ((Index == 1) || (Index ==myLoc->NbLaw()+1) ) {
3202 if (!myLoc->IsClosed() || !mySec->IsVClosed()) return Extrap;
3203 I1 = myLoc->NbLaw();
3204 I2 = 1;
3205 }
3206 else {
3207 I1 = Index-1;
3208 I2 = Index;
3209 }
3210
3211 gp_Vec V1, V2, T1, T2;
3212 gp_Mat M1, M2;
3213 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax, R, f, l;
3214
3215 myLoc->Law(I1)->GetDomain(f, l);
3216 myLoc->Law(I1)->D0(l, M1, V1);
3217 T1.SetXYZ(M1.Column(3));
3218 myLoc->Law(I2)->GetDomain(f, l);
3219 myLoc->Law(I2)->D0(f, M2, V2);
3220 T2.SetXYZ(M2.Column(3));
3221
3222 Standard_Real alpha = T1.Angle(T2);
3223 if ((alpha > myAngMax) || (alpha < myAngMin)) {
0d969553
Y
3224 //Angle too great => No "straight" connection
3225 //Angle too small => No connection
7fd59977 3226 return Extrap; // = 0.0
3227 }
3228
3229 Handle(GeomFill_SectionLaw) Sec;
3230 Sec = mySec->ConcatenedLaw();
3231
3232 //Calculating parameter U
3233 Standard_Real U, Length, SecFirst, SecLen, Lf, Ll;
3234 myLoc->CurvilinearBounds( myLoc->NbLaw(), Lf, Length );
3235 mySec->Law(1)->GetDomain( SecFirst, SecLen );
3236 SecLen -= SecFirst;
3237 myLoc->CurvilinearBounds( I1, Lf, Ll );
3238 U = SecFirst + (Ll/Length)*SecLen;
3239
3240 Bnd_Box box;
3241 //Box(Sec, 0., box);
3242 Box(Sec, U, box);
3243 box.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
3244
3245 R = Max(Max(Abs(Xmin), Abs(Xmax)),Max(Abs(Ymin), Abs(Ymax)));
3246 //R *= 1.1;
3247 // modified by NIZHNY-MKK Fri Oct 31 18:57:51 2003
3248 // Standard_Real coef = 1.2;
3249 Standard_Real coef = 2.;
3250 R *= coef;
3251 Extrap = Max(Abs(Zmin), Abs(Zmax)) + 100*myTol3d;
3252 Extrap += R*Tan(alpha/2);
3253 }
3254 return Extrap;
3255}
3256
3257//=======================================================================
3258//function : MergeVertex
0d969553 3259//purpose : Make V2 = V1 if V2 is too close to V1
7fd59977 3260//======================================================================
3261Standard_Boolean BRepFill_Sweep::MergeVertex(const TopoDS_Shape& V1,
3262 TopoDS_Shape& V2) const
3263{
3264// Class BRep_Tool without fields and without Constructor :
3265// BRep_Tool BT;
3266 const TopoDS_Vertex& v1 = TopoDS::Vertex(V1);
3267 const TopoDS_Vertex& v2 = TopoDS::Vertex(V2);
3268 Standard_Real tol;
3269// tol = Max(BT.Tolerance(v1), BT.Tolerance(v2));
3270 tol = Max(BRep_Tool::Tolerance(v1), BRep_Tool::Tolerance(v2));
3271 if (tol < myTol3d) tol = myTol3d;
3272// if (BT.Pnt(v1).Distance(BT.Pnt(v2)) <= tol ){
3273 if (BRep_Tool::Pnt(v1).Distance(BRep_Tool::Pnt(v2)) <= tol ){
3274 V2 = V1;
3275 return Standard_True;
3276 }
3277 return Standard_False;
3278}
3279
3280
3281//=======================================================================
3282//function : UpdateVertex
0d969553 3283//purpose : Update the Tolerance of Vertices depending on Laws.
7fd59977 3284//======================================================================
3285void BRepFill_Sweep::UpdateVertex(const Standard_Integer ipath,
3286 const Standard_Integer isec,
3287 const Standard_Real ErrApp,
3288 const Standard_Real Param,
3289 TopoDS_Shape& V) const
3290{
3291 TopoDS_Vertex vv, TheV;
3292 TheV = TopoDS::Vertex(V);
3293 myLoc->PerformVertex(ipath,
3294 mySec->Vertex(isec, Param),
3295 ErrApp+mySec->VertexTol(isec-1, Param),
3296 vv);
3297// Class BRep_Tool without fields and without Constructor :
3298// BRep_Tool BT;
3299 gp_Pnt P1, P2;
3300// P1 = BT.Pnt(vv);
3301 P1 = BRep_Tool::Pnt(vv);
3302// P2 = BT.Pnt(TheV);
3303 P2 = BRep_Tool::Pnt(TheV);
3304
3305// Standard_Real Tol = BT.Tolerance(vv);
3306 Standard_Real Tol = BRep_Tool::Tolerance(vv);
3307 Tol += P1.Distance(P2);
3308
3309// if (Tol > BT.Tolerance(TheV)) {
3310 if (Tol > BRep_Tool::Tolerance(TheV)) {
3311 BRep_Builder B;
3312 B.UpdateVertex(TheV, Tol);
3313 }
3314}
c8ea5b8e 3315
3316//=======================================================================
3317//function : RebuildTopOrBottomEdge
3318//purpose : Rebuild v-iso edge of top or bottom section
3319// inserting new 3d and 2d curves taken from swept surfaces
3320//======================================================================
3321void BRepFill_Sweep::RebuildTopOrBottomEdge(const TopoDS_Edge& aNewEdge,
3322 TopoDS_Edge& anEdge,
3323 TopTools_MapOfShape& ReversedEdges) const
3324{
3325 Standard_Real fpar, lpar;
3326 Handle(Geom_Curve) aNewCurve = BRep_Tool::Curve(aNewEdge, fpar, lpar);
3327 TopLoc_Location Identity;
3328
3329 Standard_Boolean ToReverse = Standard_False;
3330 Standard_Boolean IsDegen = BRep_Tool::Degenerated(aNewEdge);
3331 if (IsDegen)
3332 BRep_Tool::Range(aNewEdge, fpar, lpar);
3333 else
3334 {
3335 TopoDS_Vertex V1, V2, NewV1, NewV2;
3336 TopExp::Vertices(anEdge, V1, V2);
3337 if (!V1.IsSame(V2))
3338 {
3339 TopExp::Vertices(aNewEdge, NewV1, NewV2);
3340 V1.Location(Identity);
3341 if (!V1.IsSame(NewV1))
3342 {
3343 if (V1.IsSame(NewV2))
3344 ToReverse = Standard_True;
3345 else
3346 {
3347 gp_Pnt Pnt1 = BRep_Tool::Pnt(V1);
3348 gp_Pnt NewPnt1 = BRep_Tool::Pnt(NewV1);
3349 Standard_Real TolSum = BRep_Tool::Tolerance(V1) + BRep_Tool::Tolerance(NewV1);
3350 if (!Pnt1.IsEqual(NewPnt1, TolSum))
3351 ToReverse = Standard_True;
3352 }
3353 }
3354 }
3355 else
3356 {
3357 Standard_Real OldFirst, OldLast;
3358 Handle(Geom_Curve) OldCurve = BRep_Tool::Curve(anEdge, OldFirst, OldLast);
3359 gp_Vec OldD1, NewD1;
3360 gp_Pnt MidPnt;
3361 OldCurve->D1(0.5*(OldFirst + OldLast), MidPnt, OldD1);
3362 aNewCurve->D1(0.5*(fpar + lpar), MidPnt, NewD1);
3363 if (OldD1 * NewD1 < 0.)
3364 ToReverse = Standard_True;
3365 }
3366 }
3367
3368 anEdge.Location(Identity);
3369 const Handle(BRep_TEdge)& TEdge = *((Handle(BRep_TEdge)*) &anEdge.TShape());
3370 TEdge->Tolerance(BRep_Tool::Tolerance(aNewEdge));
3371 BRep_Builder BB;
3372 BB.Range(anEdge, fpar, lpar);
3373 BB.UpdateEdge(anEdge, aNewCurve, Precision::Confusion());
3374 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &aNewEdge.TShape());
3375 const BRep_ListOfCurveRepresentation& lcr = TE->Curves();
3376 BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr);
3377 for (; itrep.More(); itrep.Next())
3378 {
3379 const Handle(BRep_CurveRepresentation)& CurveRep = itrep.Value();
3380 if (CurveRep->IsCurveOnSurface())
3381 {
3382 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&CurveRep);
3383 Handle(Geom2d_Curve) aPCurve = GC->PCurve();
3384 Handle(Geom_Surface) aSurf = GC->Surface();
3385 TopLoc_Location aLoc = aNewEdge.Location() * GC->Location();
3386 BB.UpdateEdge(anEdge, aPCurve, aSurf, aLoc, Precision::Confusion());
3387 }
3388 }
3389
3390 anEdge.Free(Standard_True);
3391 TopoDS_Vertex V1, V2;
3392 TopExp::Vertices(anEdge, V1, V2);
3393
3394 TopoDS_Shape anEdgeFORWARD = anEdge.Oriented(TopAbs_FORWARD);
3395
3396 BB.Remove(anEdgeFORWARD, V1);
3397 BB.Remove(anEdgeFORWARD, V2);
3398
3399 V1.Location(Identity);
3400 V2.Location(Identity);
3401 if (ToReverse)
3402 {
3403 V2.Orientation(TopAbs_FORWARD);
3404 V1.Orientation(TopAbs_REVERSED);
3405 }
3406 BB.Add(anEdgeFORWARD, V1);
3407 BB.Add(anEdgeFORWARD, V2);
3408
3409 if (ToReverse)
3410 {
3411 anEdge.Reverse();
3412 ReversedEdges.Add(anEdge);
3413 }
3414
3415 BB.Degenerated(anEdge, IsDegen);
3416}