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