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