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