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