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