0030560: Modeling Algorithms - Improvement of the method BRepTools::DetectClosedness
[occt.git] / src / BRepOffset / BRepOffset_Tool.cxx
CommitLineData
b311480e 1// Created on: 1995-10-23
2// Created by: Yves FRICAUD
3// Copyright (c) 1995-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
42cf5bc1 18#include <Bnd_Box2d.hxx>
19#include <BndLib_Add3dCurve.hxx>
20#include <BOPAlgo_PaveFiller.hxx>
21#include <BOPDS_DS.hxx>
bad76cfc 22#include <BOPTools_AlgoTools.hxx>
42cf5bc1 23#include <BOPTools_AlgoTools2D.hxx>
24#include <BRep_CurveRepresentation.hxx>
25#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
26#include <BRep_TEdge.hxx>
27#include <BRep_Tool.hxx>
3b77eff6 28#include <BRep_Builder.hxx>
7fd59977 29#include <BRepAdaptor_Curve.hxx>
42cf5bc1 30#include <BRepAdaptor_Curve2d.hxx>
7fd59977 31#include <BRepAdaptor_HCurve.hxx>
32#include <BRepAdaptor_HSurface.hxx>
42cf5bc1 33#include <BRepAdaptor_Surface.hxx>
34#include <BRepAlgo_AsDes.hxx>
35#include <BRepAlgo_Image.hxx>
36#include <BRepAlgo_Tool.hxx>
7fd59977 37#include <BRepBndLib.hxx>
7fd59977 38#include <BRepLib.hxx>
39#include <BRepLib_MakeEdge.hxx>
7fd59977 40#include <BRepLib_MakeFace.hxx>
42cf5bc1 41#include <BRepLib_MakePolygon.hxx>
42#include <BRepLib_MakeVertex.hxx>
42cf5bc1 43#include <BRepOffset_Analyse.hxx>
44#include <BRepOffset_Interval.hxx>
45#include <BRepOffset_ListOfInterval.hxx>
46#include <BRepOffset_Tool.hxx>
7fd59977 47#include <BRepTools.hxx>
7fd59977 48#include <BRepTools_Modifier.hxx>
49#include <BRepTools_TrsfModification.hxx>
42cf5bc1 50#include <BRepTools_WireExplorer.hxx>
7fd59977 51#include <BRepTopAdaptor_FClass2d.hxx>
42cf5bc1 52#include <ElCLib.hxx>
53#include <ElSLib.hxx>
7fd59977 54#include <Extrema_ExtPC.hxx>
42cf5bc1 55#include <Extrema_ExtPC2d.hxx>
bad76cfc 56#include <BRepExtrema_DistShapeShape.hxx>
42cf5bc1 57#include <GCPnts_AbscissaPoint.hxx>
58#include <GCPnts_QuasiUniformDeflection.hxx>
59#include <GCPnts_UniformAbscissa.hxx>
60#include <Geom2d_BezierCurve.hxx>
61#include <Geom2d_BSplineCurve.hxx>
62#include <Geom2d_Circle.hxx>
63#include <Geom2d_Curve.hxx>
64#include <Geom2d_Ellipse.hxx>
65#include <Geom2d_Hyperbola.hxx>
66#include <Geom2d_Line.hxx>
67#include <Geom2d_Parabola.hxx>
68#include <Geom2d_TrimmedCurve.hxx>
69#include <Geom2dAdaptor_Curve.hxx>
70#include <Geom2dConvert_ApproxCurve.hxx>
71#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
72#include <Geom2dInt_GInter.hxx>
7fd59977 73#include <Geom_BezierSurface.hxx>
42cf5bc1 74#include <Geom_BSplineCurve.hxx>
7fd59977 75#include <Geom_BSplineSurface.hxx>
42cf5bc1 76#include <Geom_Conic.hxx>
7fd59977 77#include <Geom_ConicalSurface.hxx>
78#include <Geom_Curve.hxx>
79#include <Geom_Line.hxx>
42cf5bc1 80#include <Geom_OffsetSurface.hxx>
9b0fb8cd 81#include <Geom_Plane.hxx>
42cf5bc1 82#include <Geom_RectangularTrimmedSurface.hxx>
83#include <Geom_Surface.hxx>
84#include <Geom_SurfaceOfLinearExtrusion.hxx>
85#include <Geom_SurfaceOfRevolution.hxx>
7fd59977 86#include <Geom_TrimmedCurve.hxx>
42cf5bc1 87#include <GeomAdaptor_Surface.hxx>
7fd59977 88#include <GeomAPI.hxx>
42cf5bc1 89#include <GeomAPI_ExtremaCurveCurve.hxx>
7fd59977 90#include <GeomAPI_ProjectPointOnCurve.hxx>
42cf5bc1 91#include <GeomConvert_ApproxCurve.hxx>
92#include <GeomConvert_CompCurveToBSplineCurve.hxx>
7fd59977 93#include <GeomInt_IntSS.hxx>
42cf5bc1 94#include <GeomLib.hxx>
95#include <GeomProjLib.hxx>
7fd59977 96#include <gp.hxx>
97#include <gp_Pnt.hxx>
98#include <gp_Vec.hxx>
42cf5bc1 99#include <IntRes2d_IntersectionPoint.hxx>
100#include <IntRes2d_IntersectionSegment.hxx>
501d0d38 101#include <IntTools_FaceFace.hxx>
7fd59977 102#include <Precision.hxx>
42cf5bc1 103#include <ProjLib_HProjectedCurve.hxx>
104#include <ProjLib_ProjectedCurve.hxx>
105#include <ShapeCustom_Curve2d.hxx>
7fd59977 106#include <Standard_ConstructionError.hxx>
7fd59977 107#include <TColgp_Array1OfPnt2d.hxx>
42cf5bc1 108#include <TopAbs.hxx>
109#include <TopExp.hxx>
110#include <TopExp_Explorer.hxx>
111#include <TopoDS.hxx>
112#include <TopoDS_Compound.hxx>
113#include <TopoDS_Edge.hxx>
114#include <TopoDS_Face.hxx>
115#include <TopoDS_Iterator.hxx>
116#include <TopoDS_Shape.hxx>
117#include <TopoDS_Vertex.hxx>
118#include <TopoDS_Wire.hxx>
42cf5bc1 119#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
120#include <TopTools_ListIteratorOfListOfShape.hxx>
121#include <TopTools_SequenceOfShape.hxx>
7fd59977 122
42cf5bc1 123#include <stdio.h>
501d0d38 124
125// The constant defines the maximal value to enlarge surfaces.
126// It is limited to 1.e+7. This limitation is justified by the
127// floating point format. As we can have only 15
128// valuable decimal numbers, then during intersection of surfaces with
129// bounds of 1.e+8 the possible inaccuracy might appear already in seventh
130// decimal place which will be more than Precision::Confusion value -
131// 1.e-7, default tolerance value for the section curves.
132// By decreasing the max enlarge value to 1.e+7 the inaccuracy will be
133// shifted to eighth decimal place, i.e. the inaccuracy will be
134// decreased to values less than 1.e-7.
135const Standard_Real TheInfini = 1.e+7;
136
42cf5bc1 137//tma: for new boolean operation
7fd59977 138#ifdef DRAW
139#include <DBRep.hxx>
ec357c5c 140#include <Geom2d_Conic.hxx>
ec357c5c 141#include <Geom_BoundedCurve.hxx>
7fd59977 142Standard_Boolean AffichInter = Standard_False;
7fd59977 143static Standard_Integer NbNewEdges = 1;
144static Standard_Integer NbFaces = 1;
145static Standard_Integer NbFOB = 1;
146static Standard_Integer NbFTE = 1;
147static Standard_Integer NbExtE = 1;
7fd59977 148#endif
149
0797d9d3 150#ifdef OCCT_DEBUG
1896126e 151static Standard_Boolean AffichExtent = Standard_False;
152#endif
7fd59977 153
501d0d38 154static
155 void PerformPlanes(const TopoDS_Face& theFace1,
156 const TopoDS_Face& theFace2,
157 const TopAbs_State theState,
158 TopTools_ListOfShape& theL1,
159 TopTools_ListOfShape& theL2);
160
bad76cfc 161static void UpdateVertexTolerances(const TopoDS_Face& theFace);
162
501d0d38 163inline
164 Standard_Boolean IsInf(const Standard_Real theVal);
165
7fd59977 166//=======================================================================
167//function : EdgeVertices
168//purpose :
169//=======================================================================
170
171void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
ab87e6fc 172 TopoDS_Vertex& V1,
173 TopoDS_Vertex& V2)
7fd59977 174{
175 if (E.Orientation() == TopAbs_REVERSED) {
176 TopExp::Vertices(E,V2,V1);
177 }
178 else {
179 TopExp::Vertices(E,V1,V2);
180 }
181}
182
183//=======================================================================
184//function : OriEdgeInFace
185//purpose :
186//=======================================================================
187
188TopAbs_Orientation BRepOffset_Tool::OriEdgeInFace (const TopoDS_Edge& E,
ab87e6fc 189 const TopoDS_Face& F )
190
7fd59977 191{
7fd59977 192 TopExp_Explorer Exp;
193 Exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
194
195 for (; Exp.More() ;Exp.Next()) {
196 if (Exp.Current().IsSame(E)) {
197 return Exp.Current().Orientation();
198 }
199 }
9775fa61 200 throw Standard_ConstructionError("BRepOffset_Tool::OriEdgeInFace");
7fd59977 201}
202
7fd59977 203//=======================================================================
204//function : FindPeriod
205//purpose :
206//=======================================================================
207
208static void FindPeriod (const TopoDS_Face& F,
ab87e6fc 209 Standard_Real& umin,
210 Standard_Real& umax,
211 Standard_Real& vmin,
212 Standard_Real& vmax)
7fd59977 213{
214
215 Bnd_Box2d B;
216 TopExp_Explorer exp;
217 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
218 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
219
220 Standard_Real pf,pl;
221 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
222 if (C.IsNull()) return;
223 Geom2dAdaptor_Curve PC(C,pf,pl);
224 Standard_Real i, nbp = 20;
225 if (PC.GetType() == GeomAbs_Line) nbp = 2;
226 Standard_Real step = (pl - pf) / nbp;
227 gp_Pnt2d P;
228 PC.D0(pf,P);
229 B.Add(P);
230 for (i = 2; i < nbp; i++) {
231 pf += step;
232 PC.D0(pf,P);
233 B.Add(P);
234 }
235 PC.D0(pl,P);
236 B.Add(P);
237 B.Get(umin,vmin,umax,vmax);
238 }
239}
240
241//=======================================================================
242//function : PutInBounds
243//purpose : Recadre la courbe 2d dans les bounds de la face
244//=======================================================================
245
246static void PutInBounds (const TopoDS_Face& F,
ab87e6fc 247 const TopoDS_Edge& E,
248 Handle(Geom2d_Curve)& C2d)
7fd59977 249{
250 Standard_Real umin,umax,vmin,vmax;
251 Standard_Real f,l;
252 BRep_Tool::Range(E,f,l);
253
254 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
255 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
256
257 if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
c5f3a425 258 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
7fd59977 259 }
260 //---------------
261 // Recadre en U.
262 //---------------
263 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
264
265 FindPeriod (F,umin,umax,vmin,vmax);
266
267 if (S->IsUPeriodic()) {
268 Standard_Real period = S->UPeriod();
269 Standard_Real eps = period*1.e-6;
270 gp_Pnt2d Pf = C2d->Value(f);
271 gp_Pnt2d Pl = C2d->Value(l);
272 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
273 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
274 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
275 Standard_Real du = 0.;
276 if (minC< umin - eps) {
277 du = (int((umin - minC)/period) + 1)*period;
278 }
279 if (minC > umax + eps) {
280 du = -(int((minC - umax)/period) + 1)*period;
281 }
282 if (du != 0) {
283 gp_Vec2d T1(du,0.);
284 C2d->Translate(T1);
285 minC += du; maxC += du;
286 }
287 // Ajuste au mieux la courbe dans le domaine.
288 if (maxC > umax +100*eps) {
289 Standard_Real d1 = maxC - umax;
290 Standard_Real d2 = umin - minC + period;
291 if (d2 < d1) du =-period;
292 if ( du != 0.) {
ab87e6fc 293 gp_Vec2d T2(du,0.);
294 C2d->Translate(T2);
7fd59977 295 }
296 }
297 }
298 //------------------
299 // Recadre en V.
300 //------------------
301 if (S->IsVPeriodic()) {
302 Standard_Real period = S->VPeriod();
303 Standard_Real eps = period*1.e-6;
304 gp_Pnt2d Pf = C2d->Value(f);
305 gp_Pnt2d Pl = C2d->Value(l);
306 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
307 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
308 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
309 Standard_Real dv = 0.;
310 if (minC< vmin - eps) {
311 dv = (int((vmin - minC)/period) + 1)*period;
312 }
313 if (minC > vmax + eps) {
314 dv = -(int((minC - vmax)/period) + 1)*period;
315 }
316 if (dv != 0) {
317 gp_Vec2d T1(0.,dv);
318 C2d->Translate(T1);
319 minC += dv; maxC += dv;
320 }
321 // Ajuste au mieux la courbe dans le domaine.
322 if (maxC > vmax +100*eps) {
323 Standard_Real d1 = maxC - vmax;
324 Standard_Real d2 = vmin - minC + period;
325 if (d2 < d1) dv =-period;
326 if ( dv != 0.) {
ab87e6fc 327 gp_Vec2d T2(0.,dv);
328 C2d->Translate(T2);
7fd59977 329 }
330 }
331 }
332}
333
334//=======================================================================
335//function : Gabarit
336//purpose :
337//=======================================================================
338
339Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
340{
341 GeomAdaptor_Curve GC( aCurve );
342 Bnd_Box aBox;
343 BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
344 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
345 aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
346 dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
347 dist = Max( dist, (aZmax-aZmin) );
348 return dist;
349}
350
351//=======================================================================
352//function : BuildPCurves
353//purpose :
354//=======================================================================
355
356static void BuildPCurves (const TopoDS_Edge& E,
ab87e6fc 357 const TopoDS_Face& F)
7fd59977 358{
359 Standard_Real ff,ll;
360 Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
361 if (!C2d.IsNull()) return;
362
363 //Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
364 Standard_Real Tolerance = Precision::Confusion();
365
366 BRepAdaptor_Surface AS(F,0);
367 BRepAdaptor_Curve AC(E);
368
369 //Try to find pcurve on a bound of BSpline or Bezier surface
370 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
371 Handle( Standard_Type ) typS = theSurf->DynamicType();
372 if (typS == STANDARD_TYPE(Geom_OffsetSurface))
c5f3a425 373 typS = Handle(Geom_OffsetSurface)::DownCast (theSurf)->BasisSurface()->DynamicType();
7fd59977 374 if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
375 {
376 gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
377 gp_Pnt lpoint = AC.Value( AC.LastParameter() );
1c72dff6 378 TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
7fd59977 379 Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
380 TopoDS_Edge theEdge;
381 TopExp_Explorer Explo;
382 Explo.Init( theFace, TopAbs_EDGE );
383 for (; Explo.More(); Explo.Next())
ab87e6fc 384 {
385 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
386 BRepAdaptor_Curve aCurve( anEdge );
387 Extrema_ExtPC fextr( fpoint, aCurve );
388 if (!fextr.IsDone() || fextr.NbExt() < 1)
389 continue;
390 Standard_Real dist2, dist2min = RealLast();
7fd59977 391 Standard_Integer i;
ab87e6fc 392 for (i = 1; i <= fextr.NbExt(); i++)
393 {
394 dist2 = fextr.SquareDistance(i);
395 if (dist2 < dist2min)
396 {
397 dist2min = dist2;
398 U1 = fextr.Point(i).Parameter();
399 }
400 }
401 if (dist2min > TolProj * TolProj)
402 continue;
403 Extrema_ExtPC lextr( lpoint, aCurve );
404 if (!lextr.IsDone() || lextr.NbExt() <1)
405 continue;
406 dist2min = RealLast();
407 for (i = 1; i <= lextr.NbExt(); i++)
408 {
409 dist2 = lextr.SquareDistance(i);
410 if (dist2 < dist2min)
411 {
412 dist2min = dist2;
413 U2 = lextr.Point(i).Parameter();
414 }
415 }
416 if (dist2min <= TolProj * TolProj)
417 {
418 theEdge = anEdge;
419 break;
420 }
421 } // for (; Explo.More(); Explo.Current())
7fd59977 422
423 if (! theEdge.IsNull())
ab87e6fc 424 {
425 //Construction of pcurve
426 if (U2 < U1)
427 {
428 Standard_Real temp = U1;
429 U1 = U2;
430 U2 = temp;
431 }
432 Standard_Real f, l;
433 C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
434 C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
435
436 if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
437 PutInBounds( F, E, C2d );
438
439 BRep_Builder B;
440 B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
441 BRepLib::SameRange( E );
442
443 return;
444 }
7fd59977 445 } // if (typS == ...
446
447 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface(AS);
448 Handle(BRepAdaptor_HCurve) HC = new BRepAdaptor_HCurve(AC);
449
450 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
451
452 switch ( Proj.GetType()) {
453
454 case GeomAbs_Line:
455 C2d = new Geom2d_Line(Proj.Line());
456 break;
457
458 case GeomAbs_Circle:
459 C2d = new Geom2d_Circle(Proj.Circle());
460 break;
461
462 case GeomAbs_Ellipse:
463 C2d = new Geom2d_Ellipse(Proj.Ellipse());
464 break;
465
466 case GeomAbs_Parabola:
467 C2d = new Geom2d_Parabola(Proj.Parabola());
468 break;
469
470 case GeomAbs_Hyperbola:
471 C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
472 break;
473
474 case GeomAbs_BezierCurve:
475 C2d = Proj.Bezier();
476 break;
477
478 case GeomAbs_BSplineCurve:
479 C2d = Proj.BSpline();
480 break;
7fd59977 481 default:
482 break;
7fd59977 483 }
484
485 if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
486 PutInBounds(F,E,C2d);
487 }
488 if (!C2d.IsNull()) {
489 BRep_Builder B;
490 B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
491 }
492 else {
9775fa61 493 throw Standard_ConstructionError("BRepOffset_Tool::BuildPCurves");
7fd59977 494 }
495}
496
497//=======================================================================
498//function : OriSect
499//purpose :
500//=======================================================================
501
502void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
ab87e6fc 503 const TopoDS_Face& F1,
504 const TopoDS_Face& F2,
505 TopAbs_Orientation& O1,
506 TopAbs_Orientation& O2)
7fd59977 507{
508 TopLoc_Location L;
509 Standard_Real f,l;
ab87e6fc 510
7fd59977 511
512 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
513 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
514 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
515 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
516 Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
517
518 BRepAdaptor_Curve BAcurve( E );
4e57c75e 519
ab87e6fc 520 GCPnts_AbscissaPoint AP(BAcurve,GCPnts_AbscissaPoint::Length(BAcurve)/2.0,f);
521 Standard_Real ParOnC;
522
523 if(AP.IsDone())
524 ParOnC = AP.Parameter();
525 else
526 ParOnC = BOPTools_AlgoTools2D::IntermediatePoint(f, l);
7fd59977 527
528 gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
529 if (T1.SquareMagnitude() > gp::Resolution()) {
530 T1.Normalize();
531 }
532
533 gp_Pnt2d P = C1->Value(ParOnC);
534 gp_Pnt P3;
535 gp_Vec D1U,D1V;
536
537 S1->D1(P.X(),P.Y(),P3,D1U,D1V);
538 gp_Vec DN1(D1U^D1V);
539 if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
540
541 P = C2->Value(ParOnC);
542 S2->D1(P.X(),P.Y(),P3,D1U,D1V);
543 gp_Vec DN2(D1U^D1V);
544 if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
545
546 gp_Vec ProVec = DN2^T1;
547 Standard_Real Prod = DN1.Dot(ProVec);
548 if (Prod < 0.0) {
549 O1 = TopAbs_FORWARD;
550 }
551 else {
552 O1 = TopAbs_REVERSED;
553 }
554 ProVec = DN1^T1;
555 Prod = DN2.Dot(ProVec);
556 if (Prod < 0.0) {
557 O2 = TopAbs_FORWARD;
558 }
559 else {
560 O2 = TopAbs_REVERSED;
561 }
562 if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
563 if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
564}
565
566//=======================================================================
fe1d4d6c 567//function : FindCommonShapes
7fd59977 568//purpose :
569//=======================================================================
fe1d4d6c 570Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Face& theF1,
571 const TopoDS_Face& theF2,
572 TopTools_ListOfShape& theLE,
573 TopTools_ListOfShape& theLV)
574{
575 Standard_Boolean bFoundEdges =
576 FindCommonShapes(theF1, theF2, TopAbs_EDGE, theLE);
577 Standard_Boolean bFoundVerts =
578 FindCommonShapes(theF1, theF2, TopAbs_VERTEX, theLV);
579 return bFoundEdges || bFoundVerts;
580}
7fd59977 581
fe1d4d6c 582//=======================================================================
583//function : FindCommonShapes
584//purpose :
585//=======================================================================
586Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Shape& theS1,
587 const TopoDS_Shape& theS2,
588 const TopAbs_ShapeEnum theType,
589 TopTools_ListOfShape& theLSC)
7fd59977 590{
fe1d4d6c 591 theLSC.Clear();
592 //
593 TopTools_MapOfShape aMS;
594 TopExp_Explorer aExp(theS1, theType);
595 for (; aExp.More(); aExp.Next()) {
596 aMS.Add(aExp.Current());
597 }
598 //
599 if (aMS.IsEmpty()) {
600 return Standard_False;
7fd59977 601 }
fe1d4d6c 602 //
603 TopTools_MapOfShape aMFence;
604 aExp.Init(theS2, theType);
605 for (; aExp.More(); aExp.Next()) {
606 const TopoDS_Shape& aS2 = aExp.Current();
607 if (aMS.Contains(aS2)) {
608 if (aMFence.Add(aS2)) {
609 theLSC.Append(aS2);
7fd59977 610 }
611 }
612 }
fe1d4d6c 613 //
614 return !theLSC.IsEmpty();
7fd59977 615}
616
617//=======================================================================
618//function : ToSmall
619//purpose :
620//=======================================================================
621
622static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
623{
624 Standard_Real Tol = 10*Precision::Confusion();
625 Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
626 gp_Pnt P1 = C->Value(C->FirstParameter());
627 gp_Pnt P2 = C->Value(C->LastParameter());
628 gp_Pnt P3 = C->Value(m);
629 if (P1.Distance(P2) > Tol) return Standard_False;
630 if (P2.Distance(P3) > Tol) return Standard_False;
631 return Standard_True;
632}
633
634
635//=======================================================================
636//function : IsOnSurface
637//purpose :
638//=======================================================================
639
640static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
ab87e6fc 641 const Handle(Geom_Surface)& S,
642 Standard_Real TolConf,
643 Standard_Real& TolReached)
7fd59977 644{
645 Standard_Real f = C->FirstParameter();
646 Standard_Real l = C->LastParameter();
647 Standard_Integer n = 5;
648 Standard_Real du = (f-l)/(n-1);
649 TolReached = 0.;
650
651 gp_Pnt P;
652 Standard_Real U,V;
653
654 GeomAdaptor_Surface AS(S);
655
656 switch ( AS.GetType()) {
657 case GeomAbs_Plane:
658 {
659 gp_Ax3 Ax = AS.Plane().Position();
660 for ( Standard_Integer i = 0; i < n; i++) {
ab87e6fc 661 P = C->Value(f+i*du);
662 ElSLib::PlaneParameters(Ax,P,U,V);
663 TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
664 if ( TolReached > TolConf)
665 return Standard_False;
7fd59977 666 }
667 break;
668 }
669 case GeomAbs_Cylinder:
670 {
671 gp_Ax3 Ax = AS.Cylinder().Position();
672 Standard_Real Rad = AS.Cylinder().Radius();
673 for ( Standard_Integer i = 0; i < n; i++) {
ab87e6fc 674 P = C->Value(f+i*du);
675 ElSLib::CylinderParameters(Ax,Rad,P,U,V);
676 TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
677 if ( TolReached > TolConf)
678 return Standard_False;
7fd59977 679 }
680 break;
681 }
682 case GeomAbs_Cone:
683 {
684 gp_Ax3 Ax = AS.Cone().Position();
685 Standard_Real Rad = AS.Cone().RefRadius();
686 Standard_Real Alp = AS.Cone().SemiAngle();
687 for ( Standard_Integer i = 0; i < n; i++) {
ab87e6fc 688 P = C->Value(f+i*du);
689 ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
690 TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
691 if ( TolReached > TolConf)
692 return Standard_False;
7fd59977 693 }
694 break;
695 }
696 case GeomAbs_Sphere:
697 {
698 gp_Ax3 Ax = AS.Sphere().Position();
699 Standard_Real Rad = AS.Sphere().Radius();
700 for ( Standard_Integer i = 0; i < n; i++) {
ab87e6fc 701 P = C->Value(f+i*du);
702 ElSLib::SphereParameters(Ax,Rad,P,U,V);
703 TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
704 if ( TolReached > TolConf)
705 return Standard_False;
7fd59977 706 }
707 break;
708 }
709 case GeomAbs_Torus:
710 {
711 gp_Ax3 Ax = AS.Torus().Position();
712 Standard_Real R1 = AS.Torus().MajorRadius();
713 Standard_Real R2 = AS.Torus().MinorRadius();
714 for ( Standard_Integer i = 0; i < n; i++) {
ab87e6fc 715 P = C->Value(f+i*du);
716 ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
717 TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
718 if ( TolReached > TolConf)
719 return Standard_False;
7fd59977 720 }
721 break;
722 }
723
724 default:
725 {
726 return Standard_False;
727 }
728 }
729
730 return Standard_True;
731}
732
733
734//=======================================================================
735//function : PipeInter
736//purpose :
737//=======================================================================
738
739void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
ab87e6fc 740 const TopoDS_Face& F2,
741 TopTools_ListOfShape& L1,
742 TopTools_ListOfShape& L2,
743 const TopAbs_State Side)
7fd59977 744{
745#ifdef DRAW
746 if (AffichInter) {
1896126e 747 char name[256];
7fd59977 748 sprintf(name,"FF_%d",NbFaces++);
749 DBRep::Set(name,F1);
750 sprintf(name,"FF_%d",NbFaces++);
751 DBRep::Set(name,F2);
752 }
753#endif
754
755 Handle (Geom_Curve) CI;
7fd59977 756 TopAbs_Orientation O1,O2;
757 L1.Clear(); L2.Clear();
758 BRep_Builder B;
759 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
760 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
761
762 GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
763
764 if (Inter.IsDone()) {
765 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
766 CI = Inter.Line(i);
767 if (ToSmall(CI)) continue;
768 TopoDS_Edge E = BRepLib_MakeEdge(CI);
769 if (Inter.HasLineOnS1(i)) {
ab87e6fc 770 Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
771 PutInBounds (F1,E,C2);
772 B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
7fd59977 773 }
774 else {
ab87e6fc 775 BuildPCurves (E,F1);
7fd59977 776 }
777 if (Inter.HasLineOnS2(i)) {
ab87e6fc 778 Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
779 PutInBounds (F2,E,C2);
780 B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
7fd59977 781 }
782 else {
ab87e6fc 783 BuildPCurves (E,F2);
7fd59977 784 }
785 OrientSection (E,F1,F2,O1,O2);
786 if (Side == TopAbs_OUT) {
ab87e6fc 787 O1 = TopAbs::Reverse(O1);
788 O2 = TopAbs::Reverse(O2);
7fd59977 789 }
790 L1.Append (E.Oriented(O1));
791 L2.Append (E.Oriented(O2));
792#ifdef DRAW
793 if (AffichInter) {
1896126e 794 char name[256];
ab87e6fc 795 sprintf(name,"EI_%d",NbNewEdges++);
796 DBRep::Set(name,E.Oriented(O1));
7fd59977 797 }
798#endif
799 }
800 }
801}
802
bad76cfc 803//=======================================================================
804//function : IsAutonomVertex
805//purpose : Checks wether a vertex is "autonom" or not
806//=======================================================================
807
808static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& theVertex,
809 const BOPDS_PDS& thePDS,
810 const TopoDS_Face& theFace1,
811 const TopoDS_Face& theFace2)
812{
813 Standard_Integer nV = thePDS->Index(theVertex);
814 Standard_Integer nF [2];
815 nF[0] = thePDS->Index(theFace1);
816 nF[1] = thePDS->Index(theFace2);
817
818 for (Standard_Integer i = 0; i < 2; i++)
819 {
820 const BOPDS_FaceInfo& aFaceInfo = thePDS->FaceInfo(nF[i]);
821 const TColStd_MapOfInteger& IndMap = aFaceInfo.VerticesOn();
822 if (IndMap.Contains(nV))
823 return Standard_False;
824 }
825
826 return Standard_True;
827}
7fd59977 828
829//=======================================================================
830//function : IsAutonomVertex
831//purpose : Checks wether a vertex is "autonom" or not
832//=======================================================================
833
834static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
96a95605 835 const BOPDS_PDS& pDS)
7fd59977 836{
96a95605 837 Standard_Integer index;
4e57c75e 838 Standard_Integer aNbVVs, aNbEEs, aNbEFs, aInt;
839 //
840 index = pDS->Index(aVertex);
841 if (index == -1) {
842 Standard_Integer i, i1, i2;
843 i1=pDS->NbSourceShapes();
844 i2=pDS->NbShapes();
845 for (i=i1; i<i2; ++i) {
846 const TopoDS_Shape& aSx=pDS->Shape(i);
847 if(aSx.IsSame(aVertex)) {
ab87e6fc 848 index = i;
849 break;
850 }
851 }
852 }
4e57c75e 853 //
4e57c75e 854 if (!pDS->IsNewShape(index)) {
855 return Standard_False;
ab87e6fc 856 }
4e57c75e 857 //check if vertex with index "index" is not created in VV or EE or EF interference
858 //VV
859 BOPDS_VectorOfInterfVV& aVVs=pDS->InterfVV();
1155d05a 860 aNbVVs = aVVs.Length();
4e57c75e 861 for(aInt = 0; aInt < aNbVVs; aInt++) {
862 const BOPDS_InterfVV& aVV = aVVs(aInt);
863 if (aVV.HasIndexNew()) {
864 if (aVV.IndexNew() == index) {
ab87e6fc 865 return Standard_False;
866 }
867 }
7fd59977 868 }
4e57c75e 869 //EE
870 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
1155d05a 871 aNbEEs = aEEs.Length();
4e57c75e 872 for(aInt = 0; aInt < aNbEEs; aInt++) {
873 const BOPDS_InterfEE& aEE = aEEs(aInt);
874 IntTools_CommonPrt aCP = aEE.CommonPart();
875 if(aCP.Type() == TopAbs_VERTEX) {
876 if (aEE.IndexNew() == index) {
ab87e6fc 877 return Standard_False;
878 }
879 }
880 }
4e57c75e 881 //EF
882 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
1155d05a 883 aNbEFs = aEFs.Length();
4e57c75e 884 for(aInt = 0; aInt < aNbEFs; aInt++) {
885 const BOPDS_InterfEF& aEF = aEFs(aInt);
886 IntTools_CommonPrt aCP = aEF.CommonPart();
887 if(aCP.Type() == TopAbs_VERTEX) {
888 if (aEF.IndexNew() == index) {
889 return Standard_False;
ab87e6fc 890 }
4e57c75e 891 }
892 }
7fd59977 893 return Standard_True;
894}
895
896
897//=======================================================================
898//function : AreConnex
899//purpose : define if two shapes are connex by a vertex (vertices)
900//=======================================================================
901
902static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
bad76cfc 903 const TopoDS_Wire& W2)
7fd59977 904{
905 TopoDS_Vertex V11, V12, V21, V22;
906 TopExp::Vertices( W1, V11, V12 );
907 TopExp::Vertices( W2, V21, V22 );
908
909 if (V11.IsSame(V21) || V11.IsSame(V22) ||
910 V12.IsSame(V21) || V12.IsSame(V22))
bad76cfc 911 return Standard_True;
7fd59977 912
913 return Standard_False;
914}
915
916//=======================================================================
917//function : AreClosed
918//purpose : define if two edges are connex by two vertices
919//=======================================================================
920
921static Standard_Boolean AreClosed(const TopoDS_Edge& E1,
ab87e6fc 922 const TopoDS_Edge& E2)
7fd59977 923{
924 TopoDS_Vertex V11, V12, V21, V22;
925 TopExp::Vertices( E1, V11, V12 );
926 TopExp::Vertices( E2, V21, V22 );
927
0ebaa4db 928 if ((V11.IsSame(V21) && V12.IsSame(V22)) ||
929 (V11.IsSame(V22) && V12.IsSame(V21)))
7fd59977 930 return Standard_True;
931
932 return Standard_False;
933}
934
935//=======================================================================
936//function : BSplineEdges
937//purpose :
938//=======================================================================
939
940static Standard_Boolean BSplineEdges(const TopoDS_Edge& E1,
ab87e6fc 941 const TopoDS_Edge& E2,
942 const Standard_Integer par1,
943 const Standard_Integer par2,
944 Standard_Real& angle)
7fd59977 945{
946 Standard_Real first1, last1, first2, last2, Param1, Param2;
947
948 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, first1, last1 );
949 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
c5f3a425 950 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
7fd59977 951
952 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, first2, last2 );
953 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
c5f3a425 954 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
7fd59977 955
956 if (!C1->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)) ||
957 !C2->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
958 return Standard_False;
959
960 Param1 = (par1 == 0)? first1 : last1;
961 Param2 = (par2 == 0)? first2 : last2;
962
963 gp_Pnt Pnt1, Pnt2;
964 gp_Vec Der1, Der2;
965 C1->D1( Param1, Pnt1, Der1 );
966 C2->D1( Param2, Pnt2, Der2 );
967
968 if (Der1.Magnitude() <= gp::Resolution() ||
969 Der2.Magnitude() <= gp::Resolution())
c6541a0c 970 angle = M_PI/2.;
7fd59977 971 else
972 angle = Der1.Angle(Der2);
973
974 return Standard_True;
975}
976
977//=======================================================================
978//function : AngleWireEdge
979//purpose :
980//=======================================================================
981
982static Standard_Real AngleWireEdge(const TopoDS_Wire& aWire,
ab87e6fc 983 const TopoDS_Edge& anEdge)
7fd59977 984{
985 TopoDS_Vertex V11, V12, V21, V22, CV;
986 TopExp::Vertices( aWire, V11, V12 );
987 TopExp::Vertices( anEdge, V21, V22 );
988 CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
989 TopoDS_Edge FirstEdge;
990 TopoDS_Iterator itw(aWire);
991 for (; itw.More(); itw.Next())
992 {
993 FirstEdge = TopoDS::Edge(itw.Value());
994 TopoDS_Vertex v1, v2;
995 TopExp::Vertices( FirstEdge, v1, v2 );
996 if (v1.IsSame(CV) || v2.IsSame(CV))
ab87e6fc 997 {
998 V11 = v1;
999 V12 = v2;
1000 break;
1001 }
7fd59977 1002 }
1003 Standard_Real Angle;
1004 if (V11.IsSame(CV) && V21.IsSame(CV))
1005 {
1006 BSplineEdges( FirstEdge, anEdge, 0, 0, Angle );
c6541a0c 1007 Angle = M_PI - Angle;
7fd59977 1008 }
1009 else if (V11.IsSame(CV) && V22.IsSame(CV))
1010 BSplineEdges( FirstEdge, anEdge, 0, 1, Angle );
1011 else if (V12.IsSame(CV) && V21.IsSame(CV))
1012 BSplineEdges( FirstEdge, anEdge, 1, 0, Angle );
1013 else
1014 {
1015 BSplineEdges( FirstEdge, anEdge, 1, 1, Angle );
c6541a0c 1016 Angle = M_PI - Angle;
7fd59977 1017 }
1018 return Angle;
1019}
1020
1021
1022//=======================================================================
1023//function : ReconstructPCurves
1024//purpose :
1025//=======================================================================
1026
1027static void ReconstructPCurves(const TopoDS_Edge& anEdge)
1028{
1029 Standard_Real f, l;
1030 Handle(Geom_Curve) C3d = BRep_Tool::Curve(anEdge, f, l);
1031
1032 BRep_ListIteratorOfListOfCurveRepresentation
1033 itcr( (Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->ChangeCurves() );
1034 for (; itcr.More(); itcr.Next())
1035 {
1036 Handle( BRep_CurveRepresentation ) CurveRep = itcr.Value();
1037 if (CurveRep->IsCurveOnSurface())
ab87e6fc 1038 {
1039 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1040 TopLoc_Location theLoc = CurveRep->Location();
1041 theLoc = anEdge.Location() * theLoc;
1042 theSurf = Handle(Geom_Surface)::DownCast
1043 (theSurf->Transformed(theLoc.Transformation()));
1044 Handle(Geom2d_Curve) ProjPCurve =
1045 GeomProjLib::Curve2d( C3d, f, l, theSurf );
f4dee9bb 1046 if(!ProjPCurve.IsNull())
1047 {
1048 CurveRep->PCurve( ProjPCurve );
1049 }
ab87e6fc 1050 }
7fd59977 1051 }
1052}
1053
1054//=======================================================================
1055//function : ConcatPCurves
1056//purpose :
1057//=======================================================================
1058
1059static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
ab87e6fc 1060 const TopoDS_Edge& E2,
1061 const TopoDS_Face& F,
1062 const Standard_Boolean After,
1063 Standard_Real& newFirst,
1064 Standard_Real& newLast)
7fd59977 1065{
1066 Standard_Real Tol = 1.e-7;
1067 GeomAbs_Shape Continuity = GeomAbs_C1;
1068 Standard_Integer MaxDeg = 14;
1069 Standard_Integer MaxSeg = 16;
1070
1071 Standard_Real first1, last1, first2, last2;
1072 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1073
1074 PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
1075 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
c5f3a425 1076 PCurve1 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve1)->BasisCurve();
7fd59977 1077
1078 PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
1079 if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
c5f3a425 1080 PCurve2 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve2)->BasisCurve();
7fd59977 1081
1082 if (PCurve1 == PCurve2)
1083 {
1084 newPCurve = PCurve1;
1085 newFirst = Min( first1, first2 );
1086 newLast = Max( last1, last2 );
1087 }
1088 else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
ab87e6fc 1089 (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
1090 PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
7fd59977 1091 {
1092 newPCurve = PCurve1;
1093 gp_Pnt2d P1, P2;
1094 P1 = PCurve2->Value( first2 );
1095 P2 = PCurve2->Value( last2 );
1096 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
ab87e6fc 1097 {
c5f3a425 1098 Handle(Geom2d_Line) Lin1 = Handle(Geom2d_Line)::DownCast (PCurve1);
ab87e6fc 1099 gp_Lin2d theLin = Lin1->Lin2d();
1100 first2 = ElCLib::Parameter( theLin, P1 );
1101 last2 = ElCLib::Parameter( theLin, P2 );
1102 }
7fd59977 1103 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
ab87e6fc 1104 {
c5f3a425 1105 Handle(Geom2d_Circle) Circ1 = Handle(Geom2d_Circle)::DownCast (PCurve1);
ab87e6fc 1106 gp_Circ2d theCirc = Circ1->Circ2d();
1107 first2 = ElCLib::Parameter( theCirc, P1 );
1108 last2 = ElCLib::Parameter( theCirc, P2 );
1109 }
7fd59977 1110 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
ab87e6fc 1111 {
c5f3a425 1112 Handle(Geom2d_Ellipse) Ell1 = Handle(Geom2d_Ellipse)::DownCast (PCurve1);
ab87e6fc 1113 gp_Elips2d theElips = Ell1->Elips2d();
1114 first2 = ElCLib::Parameter( theElips, P1 );
1115 last2 = ElCLib::Parameter( theElips, P2 );
1116 }
7fd59977 1117 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
ab87e6fc 1118 {
c5f3a425 1119 Handle(Geom2d_Parabola) Parab1 = Handle(Geom2d_Parabola)::DownCast (PCurve1);
ab87e6fc 1120 gp_Parab2d theParab = Parab1->Parab2d();
1121 first2 = ElCLib::Parameter( theParab, P1 );
1122 last2 = ElCLib::Parameter( theParab, P2 );
1123 }
7fd59977 1124 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
ab87e6fc 1125 {
c5f3a425 1126 Handle(Geom2d_Hyperbola) Hypr1 = Handle(Geom2d_Hyperbola)::DownCast (PCurve1);
ab87e6fc 1127 gp_Hypr2d theHypr = Hypr1->Hypr2d();
1128 first2 = ElCLib::Parameter( theHypr, P1 );
1129 last2 = ElCLib::Parameter( theHypr, P2 );
1130 }
7fd59977 1131 newFirst = Min( first1, first2 );
1132 newLast = Max( last1, last2 );
1133 }
1134 else
1135 {
1136 Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
1137 Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
1138 Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
1139 Concat2d.Add( TC2, Precision::Confusion(), After );
1140 newPCurve = Concat2d.BSplineCurve();
1141 if (newPCurve->Continuity() < GeomAbs_C1)
ab87e6fc 1142 {
1143 Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
1144 if (Approx2d.HasResult())
1145 newPCurve = Approx2d.Curve();
1146 }
7fd59977 1147 newFirst = newPCurve->FirstParameter();
1148 newLast = newPCurve->LastParameter();
1149 }
1150
1151 return newPCurve;
1152}
1153
1154//=======================================================================
1155//function : Glue
1156//purpose : glue two edges.
1157//=======================================================================
1158
1159static TopoDS_Edge Glue(const TopoDS_Edge& E1,
a07a0416 1160 const TopoDS_Edge& E2,
1161 const TopoDS_Vertex& Vfirst,
1162 const TopoDS_Vertex& Vlast,
1163 const Standard_Boolean After,
1164 const TopoDS_Face& F1,
1165 const Standard_Boolean addPCurve1,
1166 const TopoDS_Face& F2,
1167 const Standard_Boolean addPCurve2,
1168 const Standard_Real theGlueTol)
7fd59977 1169{
bad76cfc 1170 TopoDS_Edge newEdge;
1171
7fd59977 1172 Standard_Real Tol = 1.e-7;
1173 GeomAbs_Shape Continuity = GeomAbs_C1;
1174 Standard_Integer MaxDeg = 14;
1175 Standard_Integer MaxSeg = 16;
1176
1177 Handle(Geom_Curve) C1, C2, newCurve;
1178 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1179 Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
1180 Standard_Boolean IsCanonic = Standard_False;
1181
1182 C1 = BRep_Tool::Curve( E1, first1, last1 );
1183 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
c5f3a425 1184 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
7fd59977 1185
1186 C2 = BRep_Tool::Curve( E2, first2, last2 );
1187 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
c5f3a425 1188 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
7fd59977 1189
1190 if (C1 == C2)
1191 {
1192 newCurve = C1;
1193 fparam = Min( first1, first2 );
1194 lparam = Max( last1, last2 );
1195 }
1196 else if (C1->DynamicType() == C2->DynamicType() &&
ab87e6fc 1197 (C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
1198 C1->IsKind(STANDARD_TYPE(Geom_Conic))))
7fd59977 1199 {
1200 IsCanonic = Standard_True;
1201 newCurve = C1;
1202 }
1203 else
1204 {
1205 Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
1206 Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
1207 GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
bad76cfc 1208 if (!Concat.Add( TC2, theGlueTol, After ))
1209 return newEdge;
7fd59977 1210 newCurve = Concat.BSplineCurve();
1211 if (newCurve->Continuity() < GeomAbs_C1)
ab87e6fc 1212 {
1213 GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
1214 if (Approx3d.HasResult())
1215 newCurve = Approx3d.Curve();
1216 }
7fd59977 1217 fparam = newCurve->FirstParameter();
1218 lparam = newCurve->LastParameter();
1219 }
1220
7fd59977 1221 BRep_Builder BB;
1222
1223 if (IsCanonic)
1224 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
1225 else
1226 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
1227
1228 Standard_Real newFirst, newLast;
1229 if (addPCurve1)
1230 {
1231 newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
1232 BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
1233 BB.Range( newEdge, F1, newFirst, newLast );
1234 }
1235 if (addPCurve2)
1236 {
1237 newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
1238 BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
1239 BB.Range( newEdge, F2, newFirst, newLast );
1240 }
1241
1242 return newEdge;
1243}
1244
7fd59977 1245//=======================================================================
1246//function : CheckIntersFF
1247//purpose :
1248//=======================================================================
1249
bad76cfc 1250static void CheckIntersFF(const BOPDS_PDS& pDS,
1251 const TopoDS_Edge& RefEdge,
1252 TopTools_IndexedMapOfShape& TrueEdges)
7fd59977 1253{
4e57c75e 1254 BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
1155d05a 1255 Standard_Integer aNb = aFFs.Length();
7fd59977 1256 Standard_Integer i, j, nbe = 0;
1257
bad76cfc 1258 TopoDS_Compound Edges;
1259 BRep_Builder BB;
1260 BB.MakeCompound(Edges);
7fd59977 1261
4e57c75e 1262 for (i = 0; i < aNb; ++i)
bad76cfc 1263 {
1264 BOPDS_InterfFF& aFFi=aFFs(i);
1265 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1155d05a 1266 Standard_Integer aNbCurves = aBCurves.Length();
bad76cfc 1267
1268 for (j = 0; j < aNbCurves; ++j)
7fd59977 1269 {
bad76cfc 1270 const BOPDS_Curve& aBC=aBCurves(j);
1271 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1272
1273 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1274 aPBIt.Initialize(aSectEdges);
1275
1276 for (; aPBIt.More(); aPBIt.Next())
1277 {
1278 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1279 Standard_Integer nSect = aPB->Edge();
1280 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1281 BB.Add(Edges, anEdge);
1282 nbe++;
1283 }
7fd59977 1284 }
bad76cfc 1285 }
7fd59977 1286
bad76cfc 1287 if (nbe == 0)
1288 return;
1289
1290 TopTools_ListOfShape CompList;
1291 BOPTools_AlgoTools::MakeConnexityBlocks(Edges, TopAbs_VERTEX, TopAbs_EDGE, CompList);
7fd59977 1292
bad76cfc 1293 TopoDS_Shape NearestCompound;
1294 if (CompList.Extent() == 1)
1295 NearestCompound = CompList.First();
1296 else
1297 {
1298 BRepAdaptor_Curve BAcurve(RefEdge);
1299 gp_Pnt Pref = BAcurve.Value((BAcurve.FirstParameter()+BAcurve.LastParameter())/2);
1300 TopoDS_Vertex Vref = BRepLib_MakeVertex(Pref);
1301 Standard_Real MinDist = RealLast();
1302 TopTools_ListIteratorOfListOfShape itl(CompList);
1303 for (; itl.More(); itl.Next())
7fd59977 1304 {
bad76cfc 1305 const TopoDS_Shape& aCompound = itl.Value();
1306
1307 BRepExtrema_DistShapeShape Projector(Vref, aCompound);
1308 if (!Projector.IsDone() || Projector.NbSolution() == 0)
1309 continue;
1310
1311 Standard_Real aDist = Projector.Value();
1312 if (aDist < MinDist)
0ebaa4db 1313 {
bad76cfc 1314 MinDist = aDist;
1315 NearestCompound = aCompound;
0ebaa4db 1316 }
7fd59977 1317 }
bad76cfc 1318 }
7fd59977 1319
bad76cfc 1320 TopExp::MapShapes(NearestCompound, TopAbs_EDGE, TrueEdges);
7fd59977 1321}
1322
1323//=======================================================================
1324//function : AssembleEdge
1325//purpose :
1326//=======================================================================
1327
4e57c75e 1328static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
bad76cfc 1329 const TopoDS_Face& F1,
1330 const TopoDS_Face& F2,
1331 const Standard_Boolean addPCurve1,
1332 const Standard_Boolean addPCurve2,
1333 const TopTools_SequenceOfShape& EdgesForConcat)
7fd59977 1334{
bad76cfc 1335 TopoDS_Edge NullEdge;
7fd59977 1336 TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
a07a0416 1337 Standard_Real aGlueTol = Precision::Confusion();
bad76cfc 1338
7fd59977 1339 for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
bad76cfc 1340 {
1341 TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
1342 Standard_Boolean After = Standard_False;
1343 TopoDS_Vertex Vfirst, Vlast;
1344 Standard_Boolean AreClosedWire = AreClosed( CurEdge, anEdge );
1345 if (AreClosedWire)
7fd59977 1346 {
bad76cfc 1347 TopoDS_Vertex V1, V2;
1348 TopExp::Vertices( CurEdge, V1, V2 );
1349 Standard_Boolean IsAutonomV1 = IsAutonomVertex( V1, pDS, F1, F2 );
1350 Standard_Boolean IsAutonomV2 = IsAutonomVertex( V2, pDS, F1, F2 );
1351 if (IsAutonomV1)
1352 {
1353 After = Standard_False;
1354 Vfirst = Vlast = V2;
1355 }
1356 else if (IsAutonomV2)
1357 {
1358 After = Standard_True;
1359 Vfirst = Vlast = V1;
1360 }
7fd59977 1361 else
bad76cfc 1362 return NullEdge;
1363 }
1364 else
1365 {
1366 TopoDS_Vertex CV, V11, V12, V21, V22;
1367 TopExp::CommonVertex( CurEdge, anEdge, CV );
1368 Standard_Boolean IsAutonomCV = IsAutonomVertex( CV, pDS, F1, F2 );
1369 if (IsAutonomCV)
1370 {
1371 aGlueTol = BRep_Tool::Tolerance(CV);
1372 TopExp::Vertices( CurEdge, V11, V12 );
1373 TopExp::Vertices( anEdge, V21, V22 );
1374 if (V11.IsSame(CV) && V21.IsSame(CV))
1375 {
1376 Vfirst = V22;
1377 Vlast = V12;
1378 }
1379 else if (V11.IsSame(CV) && V22.IsSame(CV))
1380 {
1381 Vfirst = V21;
1382 Vlast = V12;
1383 }
1384 else if (V12.IsSame(CV) && V21.IsSame(CV))
1385 {
1386 Vfirst = V11;
1387 Vlast = V22;
1388 }
1389 else
1390 {
1391 Vfirst = V11;
1392 Vlast = V21;
1393 }
1394 }
1395 else
1396 return NullEdge;
1397 } //end of else (open wire)
1398
1399 TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After,
1400 F1, addPCurve1, F2, addPCurve2, aGlueTol);
1401 if (NewEdge.IsNull())
1402 return NullEdge;
1403 else
7fd59977 1404 CurEdge = NewEdge;
bad76cfc 1405 } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
7fd59977 1406
1407 return CurEdge;
1408}
1409
1410//=======================================================================
1411//function : Inter3D
1412//purpose :
1413//=======================================================================
1414
1415void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
ab87e6fc 1416 const TopoDS_Face& F2,
1417 TopTools_ListOfShape& L1,
1418 TopTools_ListOfShape& L2,
1419 const TopAbs_State Side,
1420 const TopoDS_Edge& RefEdge,
1421 const Standard_Boolean IsRefEdgeDefined)
7fd59977 1422{
1423#ifdef DRAW
1424 if (AffichInter) {
1896126e 1425 char name[256];
7fd59977 1426 sprintf(name,"FF_%d",NbFaces++);
1427 DBRep::Set(name,F1);
1428 sprintf(name,"FF_%d",NbFaces++);
1429 DBRep::Set(name,F2);
1430 }
1431#endif
1432
501d0d38 1433 // Check if the faces are planar and not trimmed - in this case
1434 // the IntTools_FaceFace intersection algorithm will be used directly.
1435 BRepAdaptor_Surface aBAS1(F1, Standard_False), aBAS2(F2, Standard_False);
1436 if (aBAS1.GetType() == GeomAbs_Plane &&
1437 aBAS2.GetType() == GeomAbs_Plane) {
1438 aBAS1.Initialize(F1, Standard_True);
1439 if (IsInf(aBAS1.LastUParameter()) && IsInf(aBAS1.LastVParameter())) {
1440 aBAS2.Initialize(F2, Standard_True);
1441 if (IsInf(aBAS2.LastUParameter()) && IsInf(aBAS2.LastVParameter())) {
1442 // Intersect the planes without pave filler
1443 PerformPlanes(F1, F2, Side, L1, L2);
1444 return;
1445 }
1446 }
1447 }
bad76cfc 1448
7fd59977 1449 // create 3D curves on faces
bad76cfc 1450 BRepLib::BuildCurves3d(F1);
1451 BRepLib::BuildCurves3d(F2);
1452 UpdateVertexTolerances(F1);
1453 UpdateVertexTolerances(F2);
7fd59977 1454
bad76cfc 1455 BOPAlgo_PaveFiller aPF;
1155d05a 1456 TopTools_ListOfShape aLS;
bad76cfc 1457 aLS.Append(F1);
1458 aLS.Append(F2);
1459 aPF.SetArguments(aLS);
4e57c75e 1460 //
bad76cfc 1461 aPF.Perform();
7fd59977 1462
7fd59977 1463 TopTools_IndexedMapOfShape TrueEdges;
bad76cfc 1464 if (IsRefEdgeDefined)
1465 CheckIntersFF( aPF.PDS(), RefEdge, TrueEdges );
7fd59977 1466
4e57c75e 1467 Standard_Boolean addPCurve1 = 1;
1468 Standard_Boolean addPCurve2 = 1;
7fd59977 1469
bad76cfc 1470 const BOPDS_PDS& pDS = aPF.PDS();
4e57c75e 1471 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
1155d05a 1472 Standard_Integer aNb = aFFs.Length();
7fd59977 1473 Standard_Integer i = 0, j = 0, k;
1474 // Store Result
1475 L1.Clear(); L2.Clear();
1476 TopAbs_Orientation O1,O2;
bad76cfc 1477 BRep_Builder BB;
51db0179 1478 //
bad76cfc 1479 const Handle(IntTools_Context)& aContext = aPF.Context();
51db0179 1480 //
4e57c75e 1481 for (i = 0; i < aNb; i++) {
1482 BOPDS_InterfFF& aFFi=aFFs(i);
1483 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
7fd59977 1484
1155d05a 1485 Standard_Integer aNbCurves = aBCurves.Length();
ab87e6fc 1486
4e57c75e 1487 for (j = 0; j < aNbCurves; j++) {
1488 const BOPDS_Curve& aBC=aBCurves(j);
1489 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
ab87e6fc 1490
4e57c75e 1491 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1492 aPBIt.Initialize(aSectEdges);
7fd59977 1493
1494 for (; aPBIt.More(); aPBIt.Next()) {
4e57c75e 1495 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1496 Standard_Integer nSect = aPB->Edge();
1497 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
ab87e6fc 1498 if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
1499 continue;
7fd59977 1500
1501 Standard_Real f, l;
ab87e6fc 1502 const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
1503 Handle(Geom_TrimmedCurve) aC3DETrim;
1504
1505 if(!aC3DE.IsNull())
7fd59977 1506 aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
1507
ab87e6fc 1508 Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
1509
bad76cfc 1510 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F1)) {
7fd59977 1511 Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
1512 if(!aC3DETrim.IsNull()) {
ab87e6fc 1513 Handle(Geom2d_Curve) aC2dNew;
1514
1515 if(aC3DE->IsPeriodic()) {
bad76cfc 1516 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l, aC2d, aC2dNew, aContext);
ab87e6fc 1517 }
1518 else {
bad76cfc 1519 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext);
ab87e6fc 1520 }
1521 aC2d = aC2dNew;
1522 }
bad76cfc 1523 BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge);
7fd59977 1524 }
1525
bad76cfc 1526 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F2)) {
7fd59977 1527 Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
1528 if(!aC3DETrim.IsNull()) {
ab87e6fc 1529 Handle(Geom2d_Curve) aC2dNew;
1530
1531 if(aC3DE->IsPeriodic()) {
bad76cfc 1532 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l, aC2d, aC2dNew, aContext);
ab87e6fc 1533 }
1534 else {
bad76cfc 1535 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext);
ab87e6fc 1536 }
1537 aC2d = aC2dNew;
1538 }
bad76cfc 1539 BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge);
7fd59977 1540 }
1541
1542 OrientSection (anEdge, F1, F2, O1, O2);
1543 if (Side == TopAbs_OUT) {
1544 O1 = TopAbs::Reverse(O1);
1545 O2 = TopAbs::Reverse(O2);
1546 }
1547
1548 L1.Append (anEdge.Oriented(O1));
1549 L2.Append (anEdge.Oriented(O2));
1550
1551#ifdef DRAW
1552 if (AffichInter) {
1896126e 1553 char name[256];
ab87e6fc 1554 sprintf(name,"EI_%d",NbNewEdges++);
7fd59977 1555 DBRep::Set(name,anEdge.Oriented(O1));
1556
1557 }
1558#endif
1559 }
1560 }
1561 }
1562
1563 Standard_Real aSameParTol = Precision::Confusion();
1564 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1565
bad76cfc 1566 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
7fd59977 1567 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
c5f3a425 1568 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
7fd59977 1569 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1570 addPCurve1 = Standard_False;
1571 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1572 isEl1 = Standard_True;
1573
bad76cfc 1574 aSurf = BRep_Tool::Surface(F2);
7fd59977 1575 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
c5f3a425 1576 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
7fd59977 1577 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1578 addPCurve2 = Standard_False;
1579 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1580 isEl2 = Standard_True;
1581
1582 if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
1583 TopTools_SequenceOfShape eseq;
1584 TopTools_SequenceOfShape EdgesForConcat;
bad76cfc 1585
7fd59977 1586 if (!TrueEdges.IsEmpty())
bad76cfc 1587 {
1588 for (i = TrueEdges.Extent(); i >= 1; i--)
1589 EdgesForConcat.Append( TrueEdges(i) );
1590 TopoDS_Edge AssembledEdge =
1591 AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, EdgesForConcat );
1592 if (AssembledEdge.IsNull())
1593 for (i = TrueEdges.Extent(); i >= 1; i--)
1594 eseq.Append( TrueEdges(i) );
1595 else
1596 eseq.Append(AssembledEdge);
1597 }
7fd59977 1598 else
bad76cfc 1599 {
1600 TopTools_SequenceOfShape wseq;
1601 TopTools_SequenceOfShape edges;
1602 TopTools_ListIteratorOfListOfShape itl(L1);
1603 for (; itl.More(); itl.Next())
1604 edges.Append( itl.Value() );
1605 while (!edges.IsEmpty())
7fd59977 1606 {
bad76cfc 1607 TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
1608 TopoDS_Wire aWire, resWire;
1609 BB.MakeWire(aWire);
1610 BB.Add( aWire, anEdge );
1611 TColStd_SequenceOfInteger Candidates;
1612 for (k = 1; k <= wseq.Length(); k++)
1613 {
1614 resWire = TopoDS::Wire(wseq(k));
1615 if (AreConnex( resWire, aWire ))
1616 {
1617 Candidates.Append( 1 );
1618 break;
1619 }
1620 }
1621 if (Candidates.IsEmpty())
1622 {
1623 wseq.Append( aWire );
1624 edges.Remove(1);
1625 }
1626 else
1627 {
1628 for (j = 2; j <= edges.Length(); j++)
1629 {
1630 anEdge = TopoDS::Edge( edges(j) );
1631 aWire.Nullify();
1632 BB.MakeWire(aWire);
1633 BB.Add( aWire, anEdge );
1634 if (AreConnex( resWire, aWire ))
1635 Candidates.Append( j );
1636 }
1637 Standard_Integer minind = 1;
1638 if (Candidates.Length() > 1)
1639 {
1640 Standard_Real MinAngle = RealLast();
1641 for (j = 1; j <= Candidates.Length(); j++)
1642 {
1643 anEdge = TopoDS::Edge( edges(Candidates(j)) );
1644 Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
1645 if (anAngle < MinAngle)
1646 {
1647 MinAngle = anAngle;
1648 minind = j;
1649 }
1650 }
1651 }
1652 BB.Add( resWire, TopoDS::Edge(edges(Candidates(minind))) );
1653 wseq(k) = resWire;
1654 edges.Remove(Candidates(minind));
1655 }
1656 } //end of while (!edges.IsEmpty())
1657
1658 for (i = 1; i <= wseq.Length(); i++)
1659 {
1660 TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
1661 TopTools_SequenceOfShape aLocalEdgesForConcat;
1662 if (aWire.Closed())
1663 {
1664 TopoDS_Vertex StartVertex;
1665 TopoDS_Edge StartEdge;
1666 Standard_Boolean StartFound = Standard_False;
1667 TopTools_ListOfShape Elist;
1668
1669 TopoDS_Iterator itw(aWire);
1670 for (; itw.More(); itw.Next())
1671 {
1672 TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
1673 if (StartFound)
1674 Elist.Append(anEdge);
1675 else
1676 {
1677 TopoDS_Vertex V1, V2;
1678 TopExp::Vertices( anEdge, V1, V2 );
1679 if (!IsAutonomVertex( V1, pDS ))
1680 {
1681 StartVertex = V2;
1682 StartEdge = anEdge;
1683 StartFound = Standard_True;
1684 }
1685 else if (!IsAutonomVertex( V2, pDS ))
1686 {
1687 StartVertex = V1;
1688 StartEdge = anEdge;
1689 StartFound = Standard_True;
1690 }
1691 else
1692 Elist.Append(anEdge);
1693 }
1694 } //end of for (; itw.More(); itw.Next())
1695 if (!StartFound)
1696 {
1697 itl.Initialize(Elist);
1698 StartEdge = TopoDS::Edge(itl.Value());
1699 Elist.Remove(itl);
1700 TopoDS_Vertex V1, V2;
1701 TopExp::Vertices( StartEdge, V1, V2 );
1702 StartVertex = V1;
1703 }
1704 aLocalEdgesForConcat.Append( StartEdge );
1705 while (!Elist.IsEmpty())
1706 {
1707 for (itl.Initialize(Elist); itl.More(); itl.Next())
1708 {
1709 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
1710 TopoDS_Vertex V1, V2;
1711 TopExp::Vertices( anEdge, V1, V2 );
1712 if (V1.IsSame(StartVertex))
1713 {
1714 StartVertex = V2;
1715 aLocalEdgesForConcat.Append( anEdge );
1716 Elist.Remove(itl);
1717 break;
1718 }
1719 else if (V2.IsSame(StartVertex))
1720 {
1721 StartVertex = V1;
1722 aLocalEdgesForConcat.Append( anEdge );
1723 Elist.Remove(itl);
1724 break;
1725 }
1726 }
1727 } //end of while (!Elist.IsEmpty())
1728 } //end of if (aWire.Closed())
1729 else
1730 {
1731 BRepTools_WireExplorer Wexp( aWire );
1732 for (; Wexp.More(); Wexp.Next())
1733 aLocalEdgesForConcat.Append( Wexp.Current() );
1734 }
ab87e6fc 1735
bad76cfc 1736 TopoDS_Edge AssembledEdge =
1737 AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, aLocalEdgesForConcat );
1738 if (AssembledEdge.IsNull())
1739 for (j = aLocalEdgesForConcat.Length(); j >= 1; j--)
1740 eseq.Append( aLocalEdgesForConcat(j) );
1741 else
1742 eseq.Append( AssembledEdge );
1743 }
1744 } //end of else (when TrueEdges is empty)
7fd59977 1745
1746 if (eseq.Length() < L1.Extent())
bad76cfc 1747 {
1748 L1.Clear();
1749 L2.Clear();
1750 for (i = 1; i <= eseq.Length(); i++)
7fd59977 1751 {
bad76cfc 1752 TopoDS_Shape aShape = eseq(i);
1753 TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
1754 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1755 Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
0797d9d3 1756#ifdef OCCT_DEBUG
bad76cfc 1757 cout<<"Tolerance of glued E = "<<EdgeTol<<endl;
7fd59977 1758#endif
bad76cfc 1759 if (EdgeTol > 1.e-2)
1760 continue;
1761
1762 if (EdgeTol >= 1.e-4)
1763 {
1764 ReconstructPCurves(anEdge);
1765 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
0797d9d3 1766#ifdef OCCT_DEBUG
bad76cfc 1767 cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<endl;
7fd59977 1768#endif
bad76cfc 1769 }
1770
1771 OrientSection( anEdge, F1, F2, O1, O2 );
1772 if (Side == TopAbs_OUT)
1773 {
1774 O1 = TopAbs::Reverse(O1);
1775 O2 = TopAbs::Reverse(O2);
1776 }
1777
1778 L1.Append( anEdge.Oriented(O1) );
1779 L2.Append( anEdge.Oriented(O2) );
7fd59977 1780 }
bad76cfc 1781 }
7fd59977 1782 } //end of if (L1.Extent() > 1)
bad76cfc 1783
7fd59977 1784 else
bad76cfc 1785 {
1786 TopTools_ListIteratorOfListOfShape itl(L1);
1787 for (; itl.More(); itl.Next())
7fd59977 1788 {
bad76cfc 1789 const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
1790 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
7fd59977 1791 }
bad76cfc 1792 }
7fd59977 1793}
1794
1795//=======================================================================
1796//function : TryProject
1797//purpose :
1798//=======================================================================
1799
1800Standard_Boolean BRepOffset_Tool::TryProject
1801(const TopoDS_Face& F1,
1802 const TopoDS_Face& F2,
1803 const TopTools_ListOfShape& Edges,
1804 TopTools_ListOfShape& LInt1,
1805 TopTools_ListOfShape& LInt2,
1806 const TopAbs_State Side,
1807 const Standard_Real TolConf)
1808{
1809#ifdef DRAW
1810 if (AffichInter) {
1896126e 1811 char name[256];
7fd59977 1812 sprintf(name,"FF_%d",NbFaces++);
1813 DBRep::Set(name,F1);
1814 sprintf(name,"FF_%d",NbFaces++);
1815 DBRep::Set(name,F2);
1816 }
1817#endif
1818
1819 // try to find if the edges <Edges> are laying on the face F1.
1820 LInt1.Clear(); LInt2.Clear();
1821 TopTools_ListIteratorOfListOfShape it(Edges);
1822 Standard_Boolean isOk = Standard_True;
1823 Standard_Boolean Ok = Standard_True;
1824 TopAbs_Orientation O1,O2;
1825 Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
1826 BRep_Builder B;
1827
1828 for ( ; it.More(); it.Next()) {
1829 TopLoc_Location L;
1830 Standard_Real f,l;
1831 TopoDS_Edge CurE = TopoDS::Edge(it.Value());
1832 Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
1833 if (C.IsNull()) {
1834 BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
1835 C = BRep_Tool::Curve(CurE,L,f,l);
1836 }
1837 C = new Geom_TrimmedCurve(C,f,l);
1838 if ( !L.IsIdentity()) C->Transform(L);
1839 Standard_Real TolReached;
1840 isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
1841
1842 if ( isOk) {
1843 B.UpdateEdge(CurE,TolReached);
1844 BuildPCurves(CurE,F1);
1845 OrientSection (CurE,F1,F2,O1,O2);
1846 if (Side == TopAbs_OUT) {
ab87e6fc 1847 O1 = TopAbs::Reverse(O1);
1848 O2 = TopAbs::Reverse(O2);
7fd59977 1849 }
1850 LInt1.Append (CurE.Oriented(O1));
1851 LInt2.Append (CurE.Oriented(O2));
1852#ifdef DRAW
1853 if (AffichInter) {
1896126e 1854 char name[256];
1855 sprintf(name,"EI_%d",NbNewEdges++);
ab87e6fc 1856 DBRep::Set(name,CurE.Oriented(O1));
7fd59977 1857 }
1858#endif
1859 }
1860 else
1861 Ok = Standard_False;
1862 }
1863 return Ok;
1864}
1865
1866
1867//=======================================================================
1868//function : InterOrExtent
1869//purpose :
1870//=======================================================================
1871
1872void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
ab87e6fc 1873 const TopoDS_Face& F2,
1874 TopTools_ListOfShape& L1,
1875 TopTools_ListOfShape& L2,
1876 const TopAbs_State Side)
7fd59977 1877{
1878#ifdef DRAW
1879 if (AffichInter) {
1896126e 1880 char name[256];
7fd59977 1881 sprintf(name,"FF_%d",NbFaces++);
1882 DBRep::Set(name,F1);
1883 sprintf(name,"FF_%d",NbFaces++);
1884 DBRep::Set(name,F2);
1885 }
1886#endif
1887
1888 Handle (Geom_Curve) CI;
7fd59977 1889 TopAbs_Orientation O1,O2;
1890 L1.Clear(); L2.Clear();
1891 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
1892 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
1893
1894 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1895 Handle(Geom_RectangularTrimmedSurface) RTS ;
c5f3a425 1896 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S1);
7fd59977 1897 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1898 S1 = RTS->BasisSurface();
1899 }
1900 }
1901 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1902 Handle(Geom_RectangularTrimmedSurface) RTS ;
c5f3a425 1903 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S2);
7fd59977 1904 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1905 S2 = RTS->BasisSurface();
1906 }
1907 }
1908
1909 GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
1910
1911 if (Inter.IsDone()) {
1912 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
1913 CI = Inter.Line(i);
1914
1915 if (ToSmall(CI)) continue;
1916 TopoDS_Edge E = BRepLib_MakeEdge(CI);
1917 BuildPCurves (E,F1);
1918 BuildPCurves (E,F2);
1919 OrientSection (E,F1,F2,O1,O2);
1920 if (Side == TopAbs_OUT) {
ab87e6fc 1921 O1 = TopAbs::Reverse(O1);
1922 O2 = TopAbs::Reverse(O2);
7fd59977 1923 }
1924 L1.Append (E.Oriented(O1));
1925 L2.Append (E.Oriented(O2));
1926#ifdef DRAW
1927 if (AffichInter) {
1896126e 1928 char name[256];
ab87e6fc 1929 sprintf(name,"EI_%d",NbNewEdges++);
1930 DBRep::Set(name,E.Oriented(O1));
7fd59977 1931 }
1932#endif
1933 }
1934 }
1935}
1936
1937//=======================================================================
1938//function : ExtentEdge
1939//purpose :
1940//=======================================================================
1941
1942static void ExtentEdge(const TopoDS_Face& F,
ab87e6fc 1943 const TopoDS_Face& EF,
1944 const TopoDS_Edge& E,
1945 TopoDS_Edge& NE)
7fd59977 1946{
1947 BRepAdaptor_Curve CE(E);
1948 GeomAbs_CurveType Type = CE.GetType();
1949 TopoDS_Shape aLocalEdge = E.EmptyCopied();
1950 NE = TopoDS::Edge(aLocalEdge);
1951// NE = TopoDS::Edge(E.EmptyCopied());
1952
1953 if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
1954 Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
1955 return;
1956 }
1957 // Extension en tangence jusqu'au bord de la surface.
1958 Standard_Real PMax = 1.e2;
1959 TopLoc_Location L;
1960 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
1961 Standard_Real umin,umax,vmin,vmax;
1962
1963 S->Bounds(umin,umax,vmin,vmax);
1964 umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
1965 umax = Min(umax, PMax);vmax = Min(vmax, PMax);
1966
1967
1968 Standard_Real f,l;
1969 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
1970
1971 //calcul point cible . ie point d'intersection du prolongement tangent et des bords.
1972 gp_Pnt2d P;
1973 gp_Vec2d Tang;
1974 C2d->D1(CE.FirstParameter(),P,Tang);
1975 Standard_Real tx,ty,tmin;
1976 tx = ty = Precision::Infinite();
1977 if (Abs(Tang.X()) > Precision::Confusion())
1978 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
1979 if (Abs(Tang.Y()) > Precision::Confusion())
1980 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
1981 tmin = Min (tx,ty);
1982 Tang = tmin*Tang;
1983 gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
1984
1985 C2d->D1(CE.LastParameter(),P,Tang);
1986 tx = ty = Precision::Infinite();
1987 if (Abs(Tang.X()) > Precision::Confusion())
1988 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
1989 if (Abs(Tang.Y()) > Precision::Confusion())
1990 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
1991 tmin = Min (tx,ty);
1992 Tang = tmin*Tang;
1993 gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
1994
1995 Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
1996 gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
1997 gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
1998
1999 Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
2000 if (ExtC.IsNull()) return;
2001
2002 GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
2003 GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
2004
2005 Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
2006
2007 //Construction de la nouvelle arrete;
2008 BRep_Builder B;
2009 B.MakeEdge(NE);
2010// B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
2011 B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
2012 B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
2013 NE.Orientation(E.Orientation());
2014#ifdef DRAW
2015 if (AffichExtent) {
1896126e 2016 char name[256];
7fd59977 2017 sprintf (name,"F_%d",NbExtE);
2018 DBRep::Set(name,EF);
2019 sprintf (name,"OE_%d",NbExtE);
2020 DBRep::Set (name,E);
2021 sprintf (name,"ExtE_%d",NbExtE++);
2022 DBRep::Set(name,NE);
2023 }
2024#endif
2025}
2026
2027//=======================================================================
2028//function : ProjectVertexOnEdge
2029//purpose :
2030//=======================================================================
2031
2032static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
ab87e6fc 2033 const TopoDS_Edge& E,
2034 Standard_Real TolConf)
7fd59977 2035{
2036#ifdef DRAW
2037 if (AffichExtent) {
2038 DBRep::Set("V",V);
2039 DBRep::Set("E",E);
2040 }
2041#endif
2042 BRep_Builder B;
2043 Standard_Real f,l;
7fd59977 2044 Standard_Real U = 0.;
7fd59977 2045 TopLoc_Location L;
2046 Standard_Boolean found = Standard_False;
2047
2048 gp_Pnt P = BRep_Tool::Pnt (V);
2049 BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
2050 f = C.FirstParameter(); l = C.LastParameter();
2051
2052 if (V.Orientation() == TopAbs_FORWARD) {
2053 if (Abs(f) < Precision::Infinite()) {
2054 gp_Pnt PF = C.Value (f);
2055 if (PF.IsEqual(P,TolConf)) {
ab87e6fc 2056 U = f;
2057 found = Standard_True;
7fd59977 2058 }
2059 }
2060 }
2061 if (V.Orientation() == TopAbs_REVERSED) {
2062 if (!found && Abs(l) < Precision::Infinite()) {
2063 gp_Pnt PL = C.Value (l);
2064 if (PL.IsEqual(P,TolConf)) {
ab87e6fc 2065 U = l;
2066 found = Standard_True;
7fd59977 2067 }
2068 }
2069 }
2070 if (!found) {
2071 Extrema_ExtPC Proj(P,C);
2072 if (Proj.IsDone() && Proj.NbExt() > 0) {
2073 Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
2074 U = Proj.Point(1).Parameter();
2075 for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
ab87e6fc 2076 Dist2 = Proj.SquareDistance(i);
2077 if (Dist2 < Dist2Min) {
2078 Dist2Min = Dist2;
2079 U = Proj.Point(i).Parameter();
2080 }
7fd59977 2081 }
2082 found = Standard_True;
2083 }
2084 }
2085
0797d9d3 2086#ifdef OCCT_DEBUG
7fd59977 2087 if (AffichExtent) {
2088 Standard_Real Dist = P.Distance(C.Value(U));
2089 if (Dist > TolConf) {
2090 cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<endl;
2091 }
2092 if (U < f - Precision::Confusion() ||
ab87e6fc 2093 U > l + Precision::Confusion()) {
7fd59977 2094 cout << " ProjectVertexOnEdge : hors borne :"<<endl;
2095 cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<endl;
2096 }
2097 }
2098 if (!found) {
2099 cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<endl;
2100 if (Abs(f) < Precision::Infinite() &&
ab87e6fc 2101 Abs(l) < Precision::Infinite()) {
7fd59977 2102#ifdef DRAW
2103 DBRep::Set("E",E);
2104#endif
2105 }
2106 }
2107#endif
2108 if (found) {
2109 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
2110 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
2111 aLocalShape = V.Oriented(TopAbs_INTERNAL);
2112// TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
2113 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
ab87e6fc 2114 U,EE,BRep_Tool::Tolerance(E));
7fd59977 2115
2116 }
2117 return found;
2118}
2119
2120//=======================================================================
ab87e6fc 2121//function : Inter2d
7fd59977 2122//purpose :
2123//=======================================================================
2124
2125void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
ab87e6fc 2126 const TopoDS_Edge& E1,
2127 const TopoDS_Edge& E2,
2128 TopTools_ListOfShape& LV,
2129 const Standard_Real TolConf)
7fd59977 2130{
2131#ifdef DRAW
2132 if (AffichExtent) {
2133 DBRep::Set("E1",E1);
2134 DBRep::Set("E2",E2);
2135 DBRep::Set("F",F);
2136 }
2137#endif
2138 BRep_Builder B;
2139 Standard_Real fl1[2],fl2[2];
2140 LV.Clear();
2141
2142 // Si l edge a ete etendu les pcurves ne sont pas forcement
2143 // a jour.
2144 BuildPCurves(E1,F);
2145 BuildPCurves(E2,F);
2146
2147
2148 // Construction des curves 3d si elles n existent pas
2149 // utile pour coder correctement les parametres des vertex
2150 // d intersection sur les edges.
2151 //TopLoc_Location L;
2152 //Standard_Real f,l;
2153 //Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
2154 //if (C3d1.IsNull()) {
2155 // BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
2156 //}
2157 //Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
2158 //if (C3d2.IsNull()) {
2159 // BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
2160 //}
2161
2162 Standard_Integer NbPC1 = 1, NbPC2 = 1;
2163 if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
2164 if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
2165
2166 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
2167 Handle(Geom2d_Curve) C1, C2;
2168 Standard_Boolean YaSol = Standard_False;
2169 Standard_Integer itry = 0;
2170
2171 while (!YaSol && itry < 2) {
2172 for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
51740958 2173 TopoDS_Shape aLocalEdgeReversedE1 = E1.Reversed();
7fd59977 2174 if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
51740958 2175 else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdgeReversedE1),
ab87e6fc 2176 F,fl1[0],fl1[1]);
7fd59977 2177// if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2178// else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
ab87e6fc 2179// F,fl1[0],fl1[1]);
7fd59977 2180 for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
ab87e6fc 2181 TopoDS_Shape aLocalEdge = E2.Reversed();
2182 if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2183 else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2184 F,fl2[0],fl2[1]);
2185// if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2186// else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
2187// F,fl2[0],fl2[1]);
0797d9d3 2188#ifdef OCCT_DEBUG
ab87e6fc 2189 if (C1.IsNull() || C2.IsNull()) {
2190 cout <<"Inter2d : Pas de pcurve"<<endl;
7fd59977 2191#ifdef DRAW
ab87e6fc 2192 DBRep::Set("E1",E1);
2193 DBRep::Set("E2",E2);
2194 DBRep::Set("F",F);
7fd59977 2195#endif
ab87e6fc 2196 return;
2197 }
7fd59977 2198#endif
ab87e6fc 2199 Standard_Real U1 = 0.,U2 = 0.;
2200 gp_Pnt2d P2d;
3cdf48fe 2201 Standard_Boolean aCurrentFind = Standard_False;
ab87e6fc 2202 if (itry == 1) {
2203 fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
2204 fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
2205 }
2206 Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
2207 Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
2208
2209 if (itry == 0) {
2210 gp_Pnt2d P1[2],P2[2];
2211 P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
2212 P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
2213
2214 Standard_Integer i1 ;
2215 for ( i1 = 0; i1 < 2; i1++) {
2216 for (Standard_Integer i2 = 0; i2 < 2; i2++) {
2217 if (Abs(fl1[i1]) < Precision::Infinite() &&
2218 Abs(fl2[i2]) < Precision::Infinite() ) {
2219 if (P1[i1].IsEqual(P2[i2],TolConf)) {
2220 YaSol = Standard_True;
3cdf48fe 2221 aCurrentFind = Standard_True;
ab87e6fc 2222 U1 = fl1[i1]; U2 = fl2[i2];
2223 P2d = C1->Value(U1);
2224 }
2225 }
2226 }
2227 }
2228 if (!YaSol)
2229 for (i1 = 0; i1 < 2; i1++)
2230 {
2231 Extrema_ExtPC2d extr( P1[i1], AC2 );
2232 if (extr.IsDone() && extr.NbExt() > 0)
2233 {
2234 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2235 Standard_Integer IndexMin = 1;
2236 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2237 {
2238 Dist2 = extr.SquareDistance(ind);
2239 if (Dist2 < Dist2Min)
2240 {
2241 Dist2Min = Dist2;
2242 IndexMin = ind;
2243 }
2244 }
08cd2f6b 2245 if (Dist2Min <= Precision::SquareConfusion())
ab87e6fc 2246 {
3cdf48fe 2247 YaSol = Standard_True;
2248 aCurrentFind = Standard_True;
ab87e6fc 2249 P2d = P1[i1];
2250 U1 = fl1[i1];
2251 U2 = (extr.Point(IndexMin)).Parameter();
2252 break;
2253 }
2254 }
2255 }
2256 if (!YaSol)
2257 for (Standard_Integer i2 = 0; i2 < 2; i2++)
2258 {
2259 Extrema_ExtPC2d extr( P2[i2], AC1 );
2260 if (extr.IsDone() && extr.NbExt() > 0)
2261 {
2262 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2263 Standard_Integer IndexMin = 1;
2264 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2265 {
2266 Dist2 = extr.SquareDistance(ind);
2267 if (Dist2 < Dist2Min)
2268 {
2269 Dist2Min = Dist2;
2270 IndexMin = ind;
2271 }
2272 }
08cd2f6b 2273 if (Dist2Min <= Precision::SquareConfusion())
ab87e6fc 2274 {
2275 YaSol = Standard_True;
3cdf48fe 2276 aCurrentFind = Standard_True;
ab87e6fc 2277 P2d = P2[i2];
2278 U2 = fl2[i2];
2279 U1 = (extr.Point(IndexMin)).Parameter();
2280 break;
2281 }
2282 }
2283 }
2284 }
2285
2286 if (!YaSol) {
2287 Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
2288
2289 if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
3cdf48fe 2290 YaSol = Standard_True;
2291 aCurrentFind = Standard_True;
ab87e6fc 2292 U1 = Inter.Point(1).ParamOnFirst();
2293 U2 = Inter.Point(1).ParamOnSecond();
2294 P2d = Inter.Point(1).Value();
2295 }
2296 else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
3cdf48fe 2297 YaSol = Standard_True;
2298 aCurrentFind = Standard_True;
ab87e6fc 2299 IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
2300 IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
2301 IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
2302 Standard_Real U1on1 = IntP1.ParamOnFirst();
2303 Standard_Real U1on2 = IntP2.ParamOnFirst();
2304 Standard_Real U2on1 = IntP1.ParamOnSecond();
2305 Standard_Real U2on2 = IntP2.ParamOnSecond();
0797d9d3 2306#ifdef OCCT_DEBUG
ab87e6fc 2307 cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << endl;
2308 cout << " ===> Parametres sur Curve1 : ";
2309 cout << U1on1 << " " << U1on2 << endl;
2310 cout << " ===> Parametres sur Curve2 : ";
2311 cout << U2on1 << " " << U2on2 << endl;
7fd59977 2312#endif
ab87e6fc 2313 U1 = (U1on1 + U1on2)/2.;
2314 U2 = (U2on1 + U2on2)/2.;
2315 gp_Pnt2d P2d1 = C1->Value(U1);
2316 gp_Pnt2d P2d2 = C2->Value(U2);
2317 P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
2318 P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
2319 }
2320 }
3cdf48fe 2321 if (aCurrentFind) {
ab87e6fc 2322 gp_Pnt P = S->Value(P2d.X(),P2d.Y());
2323 TopoDS_Vertex V = BRepLib_MakeVertex(P);
2324 V.Orientation(TopAbs_INTERNAL);
51740958 2325 TopoDS_Shape aLocalEdgeOrientedE1 = E1.Oriented(TopAbs_FORWARD);
2326 B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
2327 aLocalEdgeOrientedE1 = E2.Oriented(TopAbs_FORWARD);
2328 B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
ab87e6fc 2329// B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
2330// B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
2331 LV.Append(V);
2332 }
7fd59977 2333 }
2334 }
2335 itry++;
2336 }
2337
2338 if (LV.Extent() > 1) {
2339 //------------------------------------------------
2340 // garde seulement les vertex les plus proches du
2341 //debut et de la fin.
2342 //------------------------------------------------
2343 TopTools_ListIteratorOfListOfShape it(LV);
2344 TopoDS_Vertex VF,VL;
2345 Standard_Real UMin = Precision::Infinite();
2346 Standard_Real UMax = -Precision::Infinite();
2347 Standard_Real U;
2348
2349 for ( ; it.More(); it.Next()) {
2350 TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
2351 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2352 U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
2353// U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
2354 if ( U < UMin) {
ab87e6fc 2355 VF = CV; UMin = U;
7fd59977 2356 }
2357 if ( U > UMax) {
ab87e6fc 2358 VL = CV; UMax = U;
7fd59977 2359 }
2360 }
2361 LV.Clear();LV.Append(VF); LV.Append(VL);
2362 }
2363
0797d9d3 2364#ifdef OCCT_DEBUG
7fd59977 2365 if (!YaSol) {
2366 cout <<"Inter2d : Pas de solution"<<endl;
2367#ifdef DRAW
2368 DBRep::Set("E1",E1);
2369 DBRep::Set("E2",E2);
2370 DBRep::Set("F",F);
2371#endif
2372 }
2373#endif
2374}
2375
2376//=======================================================================
2377//function : SelectEdge
2378//purpose :
2379//=======================================================================
2380
35e08fe8 2381static void SelectEdge (const TopoDS_Face& /*F*/,
2382 const TopoDS_Face& /*EF*/,
ab87e6fc 2383 const TopoDS_Edge& E,
2384 TopTools_ListOfShape& LInt)
7fd59977 2385{
2386 //------------------------------------------------------------
2387 // detrompeur sur les intersections sur les faces periodiques
2388 //------------------------------------------------------------
2389 TopTools_ListIteratorOfListOfShape it(LInt);
2390 Standard_Real dU = 1.0e100;
2391 TopoDS_Edge GE;
2392
2393 Standard_Real Fst, Lst, tmp;
2394 BRep_Tool::Range(E, Fst, Lst);
2395 BRepAdaptor_Curve Ad1(E);
2396
2397 gp_Pnt PFirst = Ad1.Value( Fst );
2398 gp_Pnt PLast = Ad1.Value( Lst );
2399
2400 //----------------------------------------------------------------------
2401 // Selection de l edge qui couvre le plus le domaine de l edge initiale.
2402 //----------------------------------------------------------------------
2403 for (; it.More(); it.Next()) {
2404 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
2405
2406 BRep_Tool::Range(EI, Fst, Lst);
2407 BRepAdaptor_Curve Ad2(EI);
2408 gp_Pnt P1 = Ad2.Value(Fst);
2409 gp_Pnt P2 = Ad2.Value(Lst);
2410
2411 tmp = P1.Distance(PFirst) + P2.Distance(PLast);
2412 if( tmp <= dU ) {
2413 dU = tmp;
2414 GE = EI;
2415 }
2416
2417 }
2418 LInt.Clear();
2419 LInt.Append(GE);
2420}
2421
2422
2423//=======================================================================
2424//function : Init
2425//purpose :
2426//=======================================================================
2427
2428static void MakeFace(const Handle(Geom_Surface)& S,
ab87e6fc 2429 const Standard_Real Um,
2430 const Standard_Real UM,
2431 const Standard_Real Vm,
2432 const Standard_Real VM,
11af6cdd 2433 const Standard_Boolean uclosed,
2434 const Standard_Boolean vclosed,
ab87e6fc 2435 const Standard_Boolean isVminDegen,
2436 const Standard_Boolean isVmaxDegen,
2437 TopoDS_Face& F)
7fd59977 2438{
2439 Standard_Real UMin = Um;
2440 Standard_Real UMax = UM;
2441 Standard_Real VMin = Vm;
2442 Standard_Real VMax = VM;
7fd59977 2443
2444 // compute infinite flags
2445 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
2446 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
2447 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
2448 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
2449
7fd59977 2450 // degenerated flags (for cones)
2451 Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
2452 Handle(Geom_Surface) theSurf = S;
2453 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
c5f3a425 2454 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
7fd59977 2455 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
2456 {
c5f3a425 2457 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
7fd59977 2458 gp_Cone theCone = ConicalS->Cone();
2459 gp_Pnt theApex = theCone.Apex();
2460 Standard_Real Uapex, Vapex;
2461 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
2462 if (Abs(VMin - Vapex) <= Precision::Confusion())
ab87e6fc 2463 vmindegen = Standard_True;
7fd59977 2464 if (Abs(VMax - Vapex) <= Precision::Confusion())
ab87e6fc 2465 vmaxdegen = Standard_True;
7fd59977 2466 }
2467
2468 // compute vertices
2469 BRep_Builder B;
2470 Standard_Real tol = Precision::Confusion();
2471
2472 TopoDS_Vertex V00,V10,V11,V01;
2473
2474 if (!umininf) {
2475 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
2476 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
2477 }
2478 if (!umaxinf) {
2479 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
2480 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
2481 }
2482
2483 if (uclosed) {
2484 V10 = V00;
2485 V11 = V01;
2486 }
2487
2488 if (vclosed) {
2489 V01 = V00;
2490 V11 = V10;
2491 }
2492
2493 if (vmindegen)
2494 V10 = V00;
2495 if (vmaxdegen)
2496 V11 = V01;
2497
2498 // make the lines
2499 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
2500 if (!umininf)
2501 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
2502 if (!umaxinf)
2503 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
2504 if (!vmininf)
2505 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
2506 if (!vmaxinf)
2507 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
2508
2509 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
2510 Standard_Real TolApex = 1.e-5;
2511 //Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
2512 Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
2513 if (hasiso) {
2514 if (!umininf)
2515 Cumin = S->UIso(UMin);
2516 if (!umaxinf)
2517 Cumax = S->UIso(UMax);
2518 if (!vmininf)
2519 {
ab87e6fc 2520 Cvmin = S->VIso(VMin);
2521 if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
2522 vmindegen = Standard_True;
7fd59977 2523 }
2524 if (!vmaxinf)
2525 {
ab87e6fc 2526 Cvmax = S->VIso(VMax);
2527 if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
2528 vmaxdegen = Standard_True;
7fd59977 2529 }
2530 }
2531
2532 // make the face
2533 B.MakeFace(F,S,tol);
2534
2535 // make the edges
2536 TopoDS_Edge eumin,eumax,evmin,evmax;
2537
2538 if (!umininf) {
2539 if (hasiso)
2540 B.MakeEdge(eumin,Cumin,tol);
2541 else
2542 B.MakeEdge(eumin);
2543 if (uclosed)
2544 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
2545 else
2546 B.UpdateEdge(eumin,Lumin,F,tol);
2547 if (!vmininf) {
2548 V00.Orientation(TopAbs_FORWARD);
2549 B.Add(eumin,V00);
2550 }
2551 if (!vmaxinf) {
2552 V01.Orientation(TopAbs_REVERSED);
2553 B.Add(eumin,V01);
2554 }
2555 B.Range(eumin,VMin,VMax);
2556 }
2557
2558 if (!umaxinf) {
2559 if (uclosed)
2560 eumax = eumin;
2561 else {
2562 if (hasiso)
ab87e6fc 2563 B.MakeEdge(eumax,Cumax,tol);
7fd59977 2564 else
ab87e6fc 2565 B.MakeEdge(eumax);
7fd59977 2566 B.UpdateEdge(eumax,Lumax,F,tol);
2567 if (!vmininf) {
ab87e6fc 2568 V10.Orientation(TopAbs_FORWARD);
2569 B.Add(eumax,V10);
7fd59977 2570 }
2571 if (!vmaxinf) {
ab87e6fc 2572 V11.Orientation(TopAbs_REVERSED);
2573 B.Add(eumax,V11);
7fd59977 2574 }
2575 B.Range(eumax,VMin,VMax);
2576 }
2577 }
2578
2579 if (!vmininf) {
2580 if (hasiso && !vmindegen)
2581 B.MakeEdge(evmin,Cvmin,tol);
2582 else
2583 B.MakeEdge(evmin);
2584 if (vclosed)
2585 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
2586 else
2587 B.UpdateEdge(evmin,Lvmin,F,tol);
2588 if (!umininf) {
2589 V00.Orientation(TopAbs_FORWARD);
2590 B.Add(evmin,V00);
2591 }
2592 if (!umaxinf) {
2593 V10.Orientation(TopAbs_REVERSED);
2594 B.Add(evmin,V10);
2595 }
2596 B.Range(evmin,UMin,UMax);
2597 if (vmindegen)
2598 B.Degenerated(evmin, Standard_True);
2599 }
2600
2601 if (!vmaxinf) {
2602 if (vclosed)
2603 evmax = evmin;
2604 else {
2605 if (hasiso && !vmaxdegen)
ab87e6fc 2606 B.MakeEdge(evmax,Cvmax,tol);
7fd59977 2607 else
ab87e6fc 2608 B.MakeEdge(evmax);
7fd59977 2609 B.UpdateEdge(evmax,Lvmax,F,tol);
2610 if (!umininf) {
ab87e6fc 2611 V01.Orientation(TopAbs_FORWARD);
2612 B.Add(evmax,V01);
7fd59977 2613 }
2614 if (!umaxinf) {
ab87e6fc 2615 V11.Orientation(TopAbs_REVERSED);
2616 B.Add(evmax,V11);
7fd59977 2617 }
2618 B.Range(evmax,UMin,UMax);
2619 if (vmaxdegen)
ab87e6fc 2620 B.Degenerated(evmax, Standard_True);
7fd59977 2621 }
2622 }
2623
2624 // make the wires and add them to the face
2625 eumin.Orientation(TopAbs_REVERSED);
2626 evmax.Orientation(TopAbs_REVERSED);
2627
2628 TopoDS_Wire W;
2629
2630 if (!umininf && !umaxinf && vmininf && vmaxinf) {
2631 // two wires in u
2632 B.MakeWire(W);
2633 B.Add(W,eumin);
2634 B.Add(F,W);
2635 B.MakeWire(W);
2636 B.Add(W,eumax);
2637 B.Add(F,W);
2638 F.Closed(uclosed);
2639 }
2640
2641 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
2642 // two wires in v
2643 B.MakeWire(W);
2644 B.Add(W,evmin);
2645 B.Add(F,W);
2646 B.MakeWire(W);
2647 B.Add(W,evmax);
2648 B.Add(F,W);
2649 F.Closed(vclosed);
2650 }
2651
2652 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
2653 // one wire
2654 B.MakeWire(W);
2655 if (!umininf) B.Add(W,eumin);
2656 if (!vmininf) B.Add(W,evmin);
2657 if (!umaxinf) B.Add(W,eumax);
2658 if (!vmaxinf) B.Add(W,evmax);
2659 B.Add(F,W);
2660 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
2661 F.Closed(uclosed && vclosed);
2662 }
2663}
2664
2665//=======================================================================
2666//function : EnLargeGeometry
2667//purpose :
2668//=======================================================================
2669
405b6fc5 2670static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
2671 Standard_Real& U1,
2672 Standard_Real& U2,
2673 Standard_Real& V1,
2674 Standard_Real& V2,
2675 Standard_Boolean& IsV1degen,
2676 Standard_Boolean& IsV2degen,
2677 const Standard_Real uf1,
2678 const Standard_Real uf2,
2679 const Standard_Real vf1,
2680 const Standard_Real vf2,
2681 const Standard_Real coeff,
2682 const Standard_Boolean theGlobalEnlargeU,
2683 const Standard_Boolean theGlobalEnlargeVfirst,
2684 const Standard_Boolean theGlobalEnlargeVlast,
2685 const Standard_Real theLenBeforeUfirst,
2686 const Standard_Real theLenAfterUlast,
2687 const Standard_Real theLenBeforeVfirst,
2688 const Standard_Real theLenAfterVlast)
7fd59977 2689{
7fd59977 2690 const Standard_Real TolApex = 1.e-5;
2691
2692 Standard_Boolean SurfaceChange = Standard_False;
2693 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
c5f3a425 2694 Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
7fd59977 2695 EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
405b6fc5 2696 uf1,uf2,vf1,vf2,coeff,
2697 theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
2698 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
2699 if (!theGlobalEnlargeVfirst)
7fd59977 2700 V1 = vf1;
405b6fc5 2701 if (!theGlobalEnlargeVlast)
7fd59977 2702 V2 = vf2;
405b6fc5 2703 if (!theGlobalEnlargeVfirst || !theGlobalEnlargeVlast)
c5f3a425 2704 //Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->SetTrim( U1, U2, V1, V2 );
7fd59977 2705 S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
2706 else
2707 S = BS;
2708 SurfaceChange = Standard_True;
2709 }
2710 else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
c5f3a425 2711 Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface();
7fd59977 2712 SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
405b6fc5 2713 uf1,uf2,vf1,vf2,coeff,
2714 theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
2715 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
7fd59977 2716 Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
2717 }
2718 else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
ab87e6fc 2719 S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
405b6fc5 2720 {
2721 Standard_Real du_first = 0., du_last = 0.,
2722 dv_first = 0., dv_last = 0.;
2723 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2724 Standard_Real u1, u2, v1, v2;
2725 Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
2726 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2727 Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
2728 S->Bounds( u1, u2, v1, v2 );
2729 if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
7fd59977 2730 {
405b6fc5 2731 du_first = du_last = uf2-uf1;
2732 u1 = uf1 - du_first;
2733 u2 = uf2 + du_last;
2734 enlargeU = Standard_False;
2735 }
2736 else if (S->IsUClosed())
2737 enlargeU = Standard_False;
2738 else
2739 {
2740 viso = S->VIso( vf1 );
2741 GeomAdaptor_Curve gac( viso );
2742 Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2743 du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
2744 du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
2745 uiso1 = S->UIso( uf1 );
2746 uiso2 = S->UIso( uf2 );
2747 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2748 enlargeUfirst = Standard_False;
2749 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2750 enlargeUlast = Standard_False;
2751 }
2752 if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
2753 {
2754 dv_first = dv_last = vf2-vf1;
2755 v1 = vf1 - dv_first;
2756 v2 = vf2 + dv_last;
2757 enlargeV = Standard_False;
2758 }
2759 else if (S->IsVClosed())
2760 enlargeV = Standard_False;
2761 else
2762 {
2763 uiso = S->UIso( uf1 );
2764 GeomAdaptor_Curve gac( uiso );
2765 Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2766 dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
2767 dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
2768 viso1 = S->VIso( vf1 );
2769 viso2 = S->VIso( vf2 );
2770 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2771 {
2772 enlargeVfirst = Standard_False;
2773 IsV1degen = Standard_True;
2774 }
2775 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2776 {
2777 enlargeVlast = Standard_False;
2778 IsV2degen = Standard_True;
2779 }
7fd59977 2780 }
405b6fc5 2781 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
2782 if (enlargeU)
2783 {
2784 if (enlargeUfirst && du_first != 0.)
2785 GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
2786 if (enlargeUlast && du_last != 0.)
2787 GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
2788 }
2789 if (enlargeV)
2790 {
2791 if (enlargeVfirst && dv_first != 0.)
2792 GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
2793 if (enlargeVlast && dv_last != 0.)
2794 GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
2795 }
2796 S = aSurf;
2797 S->Bounds( U1, U2, V1, V2 );
2798 SurfaceChange = Standard_True;
2799 }
7fd59977 2800 else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
ab87e6fc 2801 S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
405b6fc5 2802 {
2803 Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
2804 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2805 Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
2806 if (S->IsUClosed())
2807 enlargeU = Standard_False;
2808 if (S->IsVClosed())
2809 enlargeV = Standard_False;
2810
2811 Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
2812 Standard_Real u1, u2, v1, v2;
2813 S->Bounds( u1, u2, v1, v2 );
2814
2815 Standard_Real du_first = 0., du_last = 0.,
2816 dv_first = 0., dv_last = 0.;
2817 Handle( Geom_Curve ) uiso1, uiso2, viso1, viso2;
2818 Standard_Real gabarit_uiso1, gabarit_uiso2, gabarit_viso1, gabarit_viso2;
2819
2820 uiso1 = S->UIso( u1 );
2821 uiso2 = S->UIso( u2 );
2822 viso1 = S->VIso( v1 );
2823 viso2 = S->VIso( v2 );
2824 gabarit_uiso1 = BRepOffset_Tool::Gabarit( uiso1 );
2825 gabarit_uiso2 = BRepOffset_Tool::Gabarit( uiso2 );
2826 gabarit_viso1 = BRepOffset_Tool::Gabarit( viso1 );
2827 gabarit_viso2 = BRepOffset_Tool::Gabarit( viso2 );
2828 if (gabarit_viso1 <= TolApex ||
2829 gabarit_viso2 <= TolApex)
2830 enlargeU = Standard_False;
2831 if (gabarit_uiso1 <= TolApex ||
2832 gabarit_uiso2 <= TolApex)
2833 enlargeV = Standard_False;
2834
2835 GeomAdaptor_Curve gac;
2836 if (enlargeU)
7fd59977 2837 {
405b6fc5 2838 gac.Load( viso1 );
2839 Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2840 du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
2841 du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
2842 if (gabarit_uiso1 <= TolApex)
2843 enlargeUfirst = Standard_False;
2844 if (gabarit_uiso2 <= TolApex)
2845 enlargeUlast = Standard_False;
2846 }
2847 if (enlargeV)
2848 {
2849 gac.Load( uiso1 );
2850 Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2851 dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
2852 dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
2853 if (gabarit_viso1 <= TolApex)
2854 {
2855 enlargeVfirst = Standard_False;
2856 IsV1degen = Standard_True;
2857 }
2858 if (gabarit_viso2 <= TolApex)
2859 {
2860 enlargeVlast = Standard_False;
2861 IsV2degen = Standard_True;
2862 }
7fd59977 2863 }
405b6fc5 2864
2865 Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
2866 if (enlargeU)
2867 {
2868 if (enlargeUfirst && uf1-u1 < duf && du_first != 0.)
2869 GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
2870 if (enlargeUlast && u2-uf2 < duf && du_last != 0.)
2871 GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
2872 }
2873 if (enlargeV)
2874 {
2875 if (enlargeVfirst && vf1-v1 < dvf && dv_first != 0.)
2876 GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
2877 if (enlargeVlast && v2-vf2 < dvf && dv_last != 0.)
2878 GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
2879 }
2880 S = aSurf;
2881
2882 S->Bounds( U1, U2, V1, V2 );
2883 SurfaceChange = Standard_True;
2884 }
7fd59977 2885 else {
2886 Standard_Real UU1,UU2,VV1,VV2;
2887 S->Bounds(UU1,UU2,VV1,VV2);
2888 // Pas d extension au dela des bornes de la surface.
2889 U1 = Max(UU1,U1);
2890 V1 = Max(VV1,V1);
2891 U2 = Min(UU2,U2);
2892 V2 = Min(VV2,V2);
2893 }
2894 return SurfaceChange;
2895}
2896
2897//=======================================================================
2898//function : UpDatePCurve
2899//purpose : Mise a jour des pcurves de F sur la surface de de BF.
2900// F and BF has to be FORWARD,
2901//=======================================================================
2902
2903static void UpdatePCurves (const TopoDS_Face& F,
ab87e6fc 2904 TopoDS_Face& BF)
7fd59977 2905{
2906 Standard_Real f,l;
2907 Standard_Integer i;
2908 BRep_Builder B;
2909 TopTools_IndexedMapOfShape Emap;
2910 Handle(Geom2d_Curve) NullPCurve;
2911
2912 TopExp::MapShapes( F, TopAbs_EDGE, Emap );
2913
2914 for (i = 1; i <= Emap.Extent(); i++)
2915 {
2916 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
2917 CE.Orientation( TopAbs_FORWARD );
2918 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
2919 if (!C2.IsNull())
ab87e6fc 2920 {
2921 if (BRep_Tool::IsClosed( CE, F ))
2922 {
2923 CE.Reverse();
2924 Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
2925 B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
2926 B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
2927 }
2928 else
2929 {
2930 B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
2931 B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
2932 }
2933
2934 B.Range(CE,f,l);
2935 }
7fd59977 2936 }
2937}
2938
2939//=======================================================================
2940//function :CompactUVBounds
2941//purpose :
2942//=======================================================================
2943
2944static void CompactUVBounds (const TopoDS_Face& F,
ab87e6fc 2945 Standard_Real& UMin,
2946 Standard_Real& UMax,
2947 Standard_Real& VMin,
2948 Standard_Real& VMax)
7fd59977 2949{
2950 // Calcul serre pour que les bornes ne couvrent pas plus d une periode
2951 Standard_Real U1,U2;
2952 Standard_Real N = 33;
2953 Bnd_Box2d B;
2954
ab87e6fc 2955 TopExp_Explorer exp;
7fd59977 2956 for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
2957 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
2958 BRepAdaptor_Curve2d C(E,F);
2959 BRep_Tool::Range(E,U1,U2);
2960 gp_Pnt2d P;
2961 Standard_Real U = U1;
2962 Standard_Real DU = (U2-U1)/(N-1);
2963 for (Standard_Integer j=1;j<N;j++) {
2964 C.D0(U,P);
2965 U+=DU;
2966 B.Add(P);
2967 }
2968 C.D0(U2,P);
2969 B.Add(P);
2970 }
2971 B.Get(UMin,VMin,UMax,VMax);
2972}
2973
2974//=======================================================================
2975//function : CheckBounds
2976//purpose :
2977//=======================================================================
2978
2979void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
ab87e6fc 2980 const BRepOffset_Analyse& Analyse,
2981 Standard_Boolean& enlargeU,
2982 Standard_Boolean& enlargeVfirst,
2983 Standard_Boolean& enlargeVlast)
7fd59977 2984{
2985 enlargeU = Standard_True;
2986 enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
2987
2988 Standard_Integer Ubound = 0, Vbound = 0;
2989 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
2990 Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
2991
2992 Standard_Real UF1,UF2,VF1,VF2;
2993 CompactUVBounds(F,UF1,UF2,VF1,VF2);
2994
2995 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
2996 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
c5f3a425 2997 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (theSurf)->BasisSurface();
7fd59977 2998
2999 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
3000 theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
3001 theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3002 theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
3003 {
3004 TopExp_Explorer Explo(F, TopAbs_EDGE);
3005 for (; Explo.More(); Explo.Next())
ab87e6fc 3006 {
3007 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
3008 const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
3009 if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
3010 {
3011 BRepOffset_Type OT = L.First().Type();
3012 if (OT == BRepOffset_Tangent || BRep_Tool::Degenerated(anEdge))
3013 {
3014 Standard_Real fpar, lpar;
3015 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
3016 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
c5f3a425 3017 aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve)->BasisCurve();
ab87e6fc 3018
3019 Handle(Geom2d_Line) theLine;
3020 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
c5f3a425 3021 theLine = Handle(Geom2d_Line)::DownCast (aCurve);
ab87e6fc 3022 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
3023 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
3024 {
3025 Standard_Real newFpar, newLpar, deviation;
3026 theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
3027 newFpar, newLpar, deviation);
3028 }
3029
3030 if (!theLine.IsNull())
3031 {
3032 gp_Dir2d theDir = theLine->Direction();
3033 if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
3034 {
3035 Vbound++;
3036 if (BRep_Tool::Degenerated(anEdge))
3037 {
3038 if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
3039 enlargeVfirst = Standard_False;
3040 else //theLine->Location().Y() is near VF2
3041 enlargeVlast = Standard_False;
3042 }
3043 else
3044 {
3045 if (theLine->Location().Y() < Vfirst)
3046 Vfirst = theLine->Location().Y();
3047 if (theLine->Location().Y() > Vlast)
3048 Vlast = theLine->Location().Y();
3049 }
3050 }
3051 else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
3052 {
3053 Ubound++;
3054 if (theLine->Location().X() < Ufirst)
3055 Ufirst = theLine->Location().X();
3056 if (theLine->Location().X() > Ulast)
3057 Ulast = theLine->Location().X();
3058 }
3059 }
3060 }
3061 }
3062 }
7fd59977 3063 }
3064
3065 if (Ubound >= 2 || Vbound >= 2)
3066 {
3067 if (Ubound >= 2 &&
ab87e6fc 3068 Abs(UF1-Ufirst) <= Precision::Confusion() &&
3069 Abs(UF2-Ulast) <= Precision::Confusion())
3070 enlargeU = Standard_False;
7fd59977 3071 if (Vbound >= 2 &&
ab87e6fc 3072 Abs(VF1-Vfirst) <= Precision::Confusion() &&
3073 Abs(VF2-Vlast) <= Precision::Confusion())
3074 {
3075 enlargeVfirst = Standard_False;
3076 enlargeVlast = Standard_False;
3077 }
7fd59977 3078 }
3079}
3080
3081//=======================================================================
3082//function : EnLargeFace
3083//purpose :
3084//=======================================================================
3085
3086Standard_Boolean BRepOffset_Tool::EnLargeFace
3087(const TopoDS_Face& F,
3088 TopoDS_Face& BF,
3089 const Standard_Boolean CanExtentSurface,
3090 const Standard_Boolean UpdatePCurve,
405b6fc5 3091 const Standard_Boolean theEnlargeU,
3092 const Standard_Boolean theEnlargeVfirst,
3093 const Standard_Boolean theEnlargeVlast,
3094 const Standard_Integer theExtensionMode,
3095 const Standard_Real theLenBeforeUfirst,
3096 const Standard_Real theLenAfterUlast,
3097 const Standard_Real theLenBeforeVfirst,
3098 const Standard_Real theLenAfterVlast)
7fd59977 3099{
3100 //---------------------------
3101 // extension de la geometrie.
3102 //---------------------------
3103 TopLoc_Location L;
3104 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
3105 Standard_Real UU1,VV1,UU2,VV2;
85c103d2 3106 Standard_Boolean uperiodic = Standard_False, vperiodic = Standard_False;
7fd59977 3107 Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
3108 Standard_Real US1,VS1,US2,VS2;
3109 Standard_Real UF1,VF1,UF2,VF2;
7fd59977 3110 Standard_Boolean SurfaceChange = Standard_False;
3111
3112 if (S->IsUPeriodic() || S->IsVPeriodic()) {
3113 // Calcul serre pour que les bornes ne couvre pas plus d une periode
ab87e6fc 3114 CompactUVBounds(F,UF1,UF2,VF1,VF2);
7fd59977 3115 }
3116 else {
3117 BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
3118 }
3119
3120 S->Bounds (US1,US2,VS1,VS2);
11af6cdd 3121 Standard_Real coeff;
405b6fc5 3122 if (theExtensionMode == 1)
11af6cdd 3123 {
3124 UU1 = VV1 = - TheInfini;
3125 UU2 = VV2 = TheInfini;
3126 coeff = 0.25;
3127 }
3128 else
3129 {
3130 Standard_Real FaceDU = UF2 - UF1;
3131 Standard_Real FaceDV = VF2 - VF1;
3132 UU1 = UF1 - 10*FaceDU;
3133 UU2 = UF2 + 10*FaceDU;
3134 VV1 = VF1 - 10*FaceDV;
3135 VV2 = VF2 + 10*FaceDV;
3136 coeff = 1.;
3137 }
7fd59977 3138
3139 if (CanExtentSurface) {
405b6fc5 3140 SurfaceChange = EnlargeGeometry(S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, coeff,
3141 theEnlargeU, theEnlargeVfirst, theEnlargeVlast,
3142 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
7fd59977 3143 }
3144 else {
3145 UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
3146 VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
3147 }
3148
3149 if (S->IsUPeriodic()) {
85c103d2 3150 uperiodic = Standard_True;
7fd59977 3151 Standard_Real Period = S->UPeriod();
3152 Standard_Real Delta = Period - (UF2 - UF1);
3153 Standard_Real alpha = 0.1;
3154 UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
3155 if ((UU2 - UU1) > Period) {
3156 UU2 = UU1 + Period;
3157 }
3158 }
3159 if (S->IsVPeriodic()) {
85c103d2 3160 vperiodic = Standard_True;
7fd59977 3161 Standard_Real Period = S->VPeriod();
3162 Standard_Real Delta = Period - (VF2 - VF1);
3163 Standard_Real alpha = 0.1;
3164 VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
3165 if ((VV2 - VV1) > Period) {
3166 VV2 = VV1 + Period;
3167 }
3168 }
3169
3170 //Special treatment for conical surfaces
3171 Handle(Geom_Surface) theSurf = S;
3172 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
c5f3a425 3173 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
7fd59977 3174 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
3175 {
c5f3a425 3176 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
7fd59977 3177 gp_Cone theCone = ConicalS->Cone();
3178 gp_Pnt theApex = theCone.Apex();
3179 Standard_Real Uapex, Vapex;
3180 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
3181 if (VV1 < Vapex && Vapex < VV2)
ab87e6fc 3182 {
3183 //consider that VF1 and VF2 are on the same side from apex
3184 Standard_Real TolApex = 1.e-5;
3185 if (Vapex - VF1 >= TolApex ||
3186 Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
3187 VV2 = Vapex;
3188 else
3189 VV1 = Vapex;
3190 }
7fd59977 3191 }
3192
405b6fc5 3193 if (!theEnlargeU)
7fd59977 3194 {
3195 UU1 = UF1; UU2 = UF2;
3196 }
405b6fc5 3197 if (!theEnlargeVfirst)
7fd59977 3198 VV1 = VF1;
405b6fc5 3199 if (!theEnlargeVlast)
7fd59977 3200 VV2 = VF2;
3201
11af6cdd 3202 //Detect closedness in U and V directions
3203 Standard_Boolean uclosed = Standard_False, vclosed = Standard_False;
3204 BRepTools::DetectClosedness(F, uclosed, vclosed);
85c103d2 3205 if (uclosed && !uperiodic &&
3206 (theLenBeforeUfirst != 0. || theLenAfterUlast != 0.))
3207 uclosed = Standard_False;
3208 if (vclosed && !vperiodic &&
3209 (theLenBeforeVfirst != 0. && theLenAfterVlast != 0.))
3210 vclosed = Standard_False;
11af6cdd 3211
3212 MakeFace(S,UU1,UU2,VV1,VV2,uclosed,vclosed,isVV1degen,isVV2degen,BF);
7fd59977 3213 BF.Location(L);
3214/*
3215 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
3216 BRep_Builder B;
3217 //----------------------------------------------------------------
3218 // utile pour les bouchons on ne doit pas changer leur geometrie.
3219 // (Ce que fait BRepLib_MakeFace si S est restreinte).
3220 // On remet S et on update les pcurves.
3221 //----------------------------------------------------------------
3222 TopExp_Explorer exp;
3223 exp.Init(BF,TopAbs_EDGE);
3224 Standard_Real f=0.,l=0.;
3225 for (; exp.More(); exp.Next()) {
3226 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
3227 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
3228 B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
3229 }
3230 B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
3231 }
3232*/
3233 if (SurfaceChange && UpdatePCurve) {
3234 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3235 UpdatePCurves(TopoDS::Face(aLocalFace),BF);
3236 //UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
3237 BRep_Builder BB;
3238 BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
3239 }
3240
3241 BF.Orientation(F.Orientation());
3242 return SurfaceChange;
3243}
3244
3245//=======================================================================
3246//function : TryParameter
3247//purpose :
3248//=======================================================================
3249
3250static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
ab87e6fc 3251 TopoDS_Vertex& V,
3252 const TopoDS_Edge& NE,
3253 Standard_Real TolConf)
7fd59977 3254{
3255 BRepAdaptor_Curve OC(OE);
3256 BRepAdaptor_Curve NC(NE);
3257 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
3258 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
7fd59977 3259 Standard_Real U = 0.;
7fd59977 3260 gp_Pnt P = BRep_Tool::Pnt(V);
3261 Standard_Boolean OK = Standard_False;
3262
3263 if (P.Distance(OC.Value(Of)) < TolConf) {
3264 if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
3265 OK = Standard_True;
3266 U = Of;
3267 }
3268 }
3269 if (P.Distance(OC.Value(Ol)) < TolConf) {
3270 if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
3271 OK = Standard_True;
3272 U = Ol;
3273 }
3274 }
3275 if (OK) {
3276 BRep_Builder B;
3277 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
3278 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
3279// TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
3280 aLocalShape = V.Oriented(TopAbs_INTERNAL);
3281 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
ab87e6fc 3282 U,NE,BRep_Tool::Tolerance(NE));
7fd59977 3283// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
ab87e6fc 3284// U,NE,BRep_Tool::Tolerance(NE));
7fd59977 3285 }
3286 return OK;
3287}
3288
3289//=======================================================================
3290//function :
3291//purpose :
3292//=======================================================================
3293
3294void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
ab87e6fc 3295 TopTools_DataMapOfShapeListOfShape& MEV)
7fd59977 3296{
3297 TopExp_Explorer exp;
3298 exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3299 TopTools_MapOfShape DejaVu;
3300 for ( ; exp.More(); exp.Next()) {
3301 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3302 if (DejaVu.Add(E)) {
3303 TopoDS_Vertex V1,V2;
3304 TopExp::Vertices (E,V1,V2);
3305 if (!MEV.IsBound(V1)) {
ab87e6fc 3306 TopTools_ListOfShape empty;
3307 MEV.Bind(V1,empty);
7fd59977 3308 }
3309 MEV(V1).Append(E);
3310 if (!V1.IsSame(V2)) {
ab87e6fc 3311 if (!MEV.IsBound(V2)) {
3312 TopTools_ListOfShape empty;
3313 MEV.Bind(V2,empty);
3314 }
3315 MEV(V2).Append(E);
7fd59977 3316 }
3317 }
3318 }
3319}
3320
3321//=======================================================================
3322//function :
3323//purpose :
3324//=======================================================================
3325
3326void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
ab87e6fc 3327 const TopoDS_Face& F,
3328 TopTools_DataMapOfShapeShape& NOnV1,
3329 TopTools_DataMapOfShapeShape& NOnV2)
7fd59977 3330{
3331 TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
3332 TopoDS_Edge CurE,FirstE,PrecE;
3333 BRepTools_WireExplorer wexp;
3334
3335 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3336 TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
3337 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
3338// wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
ab87e6fc 3339// TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
7fd59977 3340 CurE = FirstE = PrecE = wexp.Current();
3341 TopExp::Vertices(CurE,V1,V2);
3342 FV1 = VP1 = V1; FV2 = VP2 = V2;
3343 wexp.Next();
3344 while (wexp.More()) {
3345 CurE = wexp.Current();
3346 TopExp::Vertices(CurE,V1,V2);
3347 if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3348 if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3349 if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3350 if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3351 PrecE = CurE;
3352 VP1 = V1; VP2 = V2;
3353 wexp.Next();
3354 }
3355 if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3356 if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3357 if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3358 if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3359}
3360
3361//=======================================================================
3362//function : ExtentFace
3363//purpose :
3364//=======================================================================
3365
3366void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
ab87e6fc 3367 TopTools_DataMapOfShapeShape& ConstShapes,
3368 TopTools_DataMapOfShapeShape& ToBuild,
3369 const TopAbs_State Side,
3370 const Standard_Real TolConf,
3371 TopoDS_Face& NF)
7fd59977 3372{
3373#ifdef DRAW
3374 if (AffichInter) {
1896126e 3375 char name[256];
7fd59977 3376 sprintf(name,"FTE_%d",NbFTE++);
3377 DBRep::Set(name,F);
3378 }
3379#endif
3380
3381 TopExp_Explorer exp,exp2;
3382 TopTools_DataMapOfShapeShape Build;
3383 TopTools_DataMapOfShapeShape Extent;
3384 TopoDS_Edge FirstE,PrecE,CurE,NE;
3385 BRep_Builder B;
3386 TopoDS_Face EF;
3387
3388 // Construction de la boite englobante de la face a etendre et des bouchons pour
3389 // limiter les extensions.
3390 //Bnd_Box ContextBox;
3391 //BRepBndLib::Add(F,B);
3392 //TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
3393 //for (; itTB.More(); itTB.Next()) {
3394 //BRepBndLib::Add(TopBuild.Value(), ContextBox);
3395 //}
3396
3397
3398 Standard_Boolean SurfaceChange;
3399 SurfaceChange = EnLargeFace (F,EF,Standard_True);
3400
3401 TopoDS_Shape aLocalShape = EF.EmptyCopied();
3402 NF = TopoDS::Face(aLocalShape);
3403// NF = TopoDS::Face(EF.EmptyCopied());
3404 NF.Orientation(TopAbs_FORWARD);
3405
3406 if (SurfaceChange) {
3407 //------------------------------------------------
3408 // Mise a jour des pcurves sur la surface de base.
3409 //------------------------------------------------
3410 TopoDS_Face Fforward = F;
3411 Fforward.Orientation(TopAbs_FORWARD);
3412 TopTools_IndexedMapOfShape Emap;
3413 TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
3414 Standard_Real f,l;
3415 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
3416 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3417 CE.Orientation(TopAbs_FORWARD);
3418 TopoDS_Edge Ecs; //patch
3419 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
3420 if (!C2.IsNull()) {
ab87e6fc