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