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