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