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