0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / BRepOffset / BRepOffset_MakeOffset.cxx
CommitLineData
7fd59977 1// File: BRepOffset_MakeOffset.cxx
2// Created: Fri Oct 27 10:30:44 1995
3// Author: Yves FRICAUD
4// <yfr@stylox>
5
6
7// Modified by skv - Tue Mar 15 16:20:43 2005
8// Add methods for supporting history.
9
10// Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455
11
12#include <BRepOffset_MakeOffset.ixx>
13#include <BRepOffset_Analyse.hxx>
14#include <BRepOffset_DataMapOfShapeOffset.hxx>
15#include <BRepOffset_DataMapOfShapeMapOfShape.hxx>
16#include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
17#include <BRepOffset_Interval.hxx>
18#include <BRepOffset_ListOfInterval.hxx>
19#include <BRepOffset_Offset.hxx>
20#include <BRepOffset_Tool.hxx>
21#include <BRepOffset_Inter2d.hxx>
22#include <BRepOffset_Inter3d.hxx>
23#include <BRepOffset_MakeLoops.hxx>
24
25
26#include <BRepAdaptor_Surface.hxx>
27#include <BRepCheck_Edge.hxx>
28#include <BRepCheck_Vertex.hxx>
29#include <BRepLib.hxx>
30#include <BRepLib_MakeVertex.hxx>
31#include <BRep_Builder.hxx>
32#include <BRep_Tool.hxx>
33#include <BRep_TVertex.hxx>
34#include <BRepTools_Quilt.hxx>
35#include <BRepClass3d_SolidClassifier.hxx>
36#include <gp_Pnt.hxx>
37
38#include <TopExp.hxx>
39#include <TopExp_Explorer.hxx>
40#include <TopoDS.hxx>
41#include <TopoDS_Solid.hxx>
42#include <TopoDS_Shell.hxx>
43#include <TopoDS_Compound.hxx>
44#include <TopoDS_Face.hxx>
45#include <TopoDS_Edge.hxx>
46#include <TopoDS_Vertex.hxx>
47
48#include <TopTools_MapOfShape.hxx>
49#include <TopTools_MapIteratorOfMapOfShape.hxx>
50#include <TopTools_ListOfShape.hxx>
51#include <TopTools_ListIteratorOfListOfShape.hxx>
52#include <TopTools_DataMapOfShapeShape.hxx>
53#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
54#include <TopTools_DataMapIteratorOfDataMapOfShapeReal.hxx>
55#include <TColStd_ListIteratorOfListOfInteger.hxx>
56
57#include <Standard_NotImplemented.hxx>
58#include <Standard_ConstructionError.hxx>
59#include <Precision.hxx>
60
61#include <TopTools_SequenceOfShape.hxx>
62#include <Geom_OffsetSurface.hxx>
63#include <Geom_ConicalSurface.hxx>
64#include <TopTools_IndexedMapOfShape.hxx>
65#include <BRep_TEdge.hxx>
66#include <BRepTools.hxx>
67#include <gp_Cone.hxx>
68#include <ElSLib.hxx>
69#include <ElCLib.hxx>
70#include <gp_Lin2d.hxx>
71#include <GCE2d_MakeLine.hxx>
72#include <Geom2d_Line.hxx>
73#include <TopoDS_Iterator.hxx>
74#include <BRepLib_MakeFace.hxx>
75#include <Geom_Circle.hxx>
76
77#include <BRep_PointRepresentation.hxx>
78#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
79#include <GeomAPI_ProjectPointOnCurve.hxx>
80
81#include <BRepAdaptor_Curve.hxx>
82#include <BRepAdaptor_Curve2d.hxx>
83#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
84#include <Geom_SphericalSurface.hxx>
85#include <TopoDS_Wire.hxx>
86#include <BRepTools_Substitution.hxx>
87#include <Geom_TrimmedCurve.hxx>
88#include <Geom2d_TrimmedCurve.hxx>
89
90#include <BRepTools_WireExplorer.hxx>
91#include <BRepLib_MakeEdge.hxx>
92#include <gce_MakeDir.hxx>
93#include <GC_MakeCylindricalSurface.hxx>
94#include <gce_MakeCone.hxx>
95#include <Geom_SurfaceOfLinearExtrusion.hxx>
96
97#include <Geom2dAdaptor_HCurve.hxx>
98#include <GeomAdaptor_HSurface.hxx>
99#include <Adaptor3d_CurveOnSurface.hxx>
100#include <GeomLib.hxx>
101#include <GeomFill_Generator.hxx>
102
103
0d969553 104// POP for NT
7fd59977 105#include <stdio.h>
106
107#ifdef DRAW
108
109#include <DBRep.hxx>
110#endif
111#ifdef DEB
112#include <OSD_Chronometer.hxx>
113
114 Standard_Boolean AffichInt2d = Standard_False;
115 Standard_Boolean AffichOffC = Standard_False;
116 Standard_Boolean ChronBuild = Standard_False;
117 Standard_Integer NbAE = 0;
118 Standard_Integer NbAF = 0;
119 static OSD_Chronometer Clock;
120 char name[100];
121
122
123
124
125//=======================================================================
126//function : DEBVerticesControl
127//purpose :
128//=======================================================================
129
130static void DEBVerticesControl (const TopTools_MapOfShape& NewEdges,
131 Handle(BRepAlgo_AsDes) AsDes)
132{
133 Standard_Integer NVP = 0;
134 Standard_Integer NVM = 0;
135 Standard_Integer NVN = 0;
136
137 TopTools_ListOfShape LVP;
138 TopTools_MapIteratorOfMapOfShape it;
139 TopTools_ListIteratorOfListOfShape it1LE ;
140 TopTools_ListIteratorOfListOfShape it2LE ;
141
142 for (it.Initialize(NewEdges) ; it.More(); it.Next()) {
143 const TopoDS_Edge& NE = TopoDS::Edge(it.Key());
144 if (AsDes->HasDescendant(NE)) {
145 for (it1LE.Initialize(AsDes->Descendant(NE)); it1LE.More(); it1LE.Next()) {
146 if (AsDes->Ascendant(it1LE.Value()).Extent() < 3) {
147 LVP.Append(it1LE.Value());
0d969553 148 cout <<"Vertex on at least 3 edges."<<endl;
7fd59977 149#ifdef DRAW
150 if (AffichInt2d) {
151 sprintf (name,"VP_%d",NVP++);
152 DBRep::Set(name,it1LE.Value());
153 }
154#endif
155 }
156 else if (AsDes->Ascendant(it1LE.Value()).Extent() > 3) {
0d969553 157 cout <<"Vertex on more than 3 edges."<<endl;
7fd59977 158#ifdef DRAW
159 if (AffichInt2d) {
160 sprintf (name,"VM_%d",NVM++);
161 DBRep::Set(name,it1LE.Value());
162 }
163#endif
164
165 }
166 else {
167#ifdef DRAW
168 if (AffichInt2d) {
169 sprintf (name,"VN_%d",NVN++);
170 DBRep::Set(name,it1LE.Value());
171 }
172#endif
173 }
174 }
175 }
176 }
177 //------------------------------------------------
0d969553 178 // Try to mix spoiled vertices.
7fd59977 179 //------------------------------------------------
180 BRep_Builder B;
181 TopTools_ListIteratorOfListOfShape it1(LVP);
182 Standard_Real TolConf = 1.e-5;
183 Standard_Real Tol = Precision::Confusion();
184 Standard_Integer i = 1;
185
186 for ( ; it1.More(); it1.Next()) {
187 TopoDS_Shape V1 = it1.Value();
188 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(V1));
189 Standard_Real distmin = Precision::Infinite();
190 TopTools_ListIteratorOfListOfShape it2(LVP);
191 Standard_Integer j = 1;
192
193 for ( ; it2.More(); it2.Next()) {
194 if (j > i) {
195 TopoDS_Shape V2 = it2.Value();
196 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(V2));
197 if (!V1.IsSame(V2)) {
198 Standard_Real dist = P1.Distance(P2);
199 if (dist < distmin) distmin = dist;
200 if (dist < TolConf) {
201 Standard_Real UV2;
202 TopoDS_Edge EWE2;
203 const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
204 TopTools_ListIteratorOfListOfShape itAsDes;
205 for (itAsDes.Initialize(EdgeWithV2); itAsDes.More(); itAsDes.Next()) {
206 EWE2 = TopoDS::Edge(itAsDes.Value());
207 TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_INTERNAL);
208 UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
209 aLocalShape = V1.Oriented(TopAbs_INTERNAL) ;
210 B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
211// UV2 =
212// BRep_Tool::Parameter(TopoDS::Vertex(),EWE2);
213// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
214// UV2,EWE2,Tol);
215 }
216 AsDes->Replace(V2,V1);
217 }
218 }
219 }
220 j++;
221 }
222 i++;
0d969553 223 cout <<" distmin between VP : "<<distmin<<endl;
7fd59977 224 }
225}
226#endif
227
228
229static void UpdateTolerance ( TopoDS_Shape& myShape,
230 const TopTools_MapOfShape& myFaces);
231
232
233static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
234 const TopoDS_Edge& E,
235 Standard_Real& U)
236{
237 // Search the vertex in the edge
238
239 Standard_Boolean rev = Standard_False;
240 TopoDS_Shape VF;
241 TopAbs_Orientation orient = TopAbs_INTERNAL;
242
243 TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
244
245 // if the edge has no vertices
246 // and is degenerated use the vertex orientation
247 // RLE, june 94
248
249 if (!itv.More() && BRep_Tool::Degenerated(E)) {
250 orient = V.Orientation();
251 }
252
253 while (itv.More()) {
254 const TopoDS_Shape& Vcur = itv.Value();
255 if (V.IsSame(Vcur)) {
256 if (VF.IsNull()) {
257 VF = Vcur;
258 }
259 else {
260 rev = E.Orientation() == TopAbs_REVERSED;
261 if (Vcur.Orientation() == V.Orientation()) {
262 VF = Vcur;
263 }
264 }
265 }
266 itv.Next();
267 }
268
269 if (!VF.IsNull()) orient = VF.Orientation();
270
271 Standard_Real f,l;
272
273 if (orient == TopAbs_FORWARD) {
274 BRep_Tool::Range(E,f,l);
275 //return (rev) ? l : f;
276 U = (rev) ? l : f;
277 return Standard_True;
278 }
279
280 else if (orient == TopAbs_REVERSED) {
281 BRep_Tool::Range(E,f,l);
282 //return (rev) ? f : l;
283 U = (rev) ? f : l;
284 return Standard_True;
285 }
286
287 else {
288 TopLoc_Location L;
289 const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
290 L = L.Predivided(V.Location());
291 if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
292 BRep_ListIteratorOfListOfPointRepresentation itpr
293 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
294
295 while (itpr.More()) {
296 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
297 if (pr->IsPointOnCurve(C,L)) {
298 Standard_Real p = pr->Parameter();
299 Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
300 if (!C.IsNull()) {
301 // Closed curves RLE 16 june 94
302 if (Precision::IsNegativeInfinite(f))
303 {
304 //return pr->Parameter();//p;
305 U = pr->Parameter();
306 return Standard_True;
307 }
308 if (Precision::IsPositiveInfinite(l))
309 {
310 //return pr->Parameter();//p;
311 U = pr->Parameter();
312 return Standard_True;
313 }
314 gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
315 gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
316 Standard_Real tol = BRep_Tool::Tolerance(V);
317 if (Pf.Distance(Pl) < tol) {
318 if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
319 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
320 else res = l;//p = l;
321 }
322 }
323 }
324 //return res;//p;
325 U = res;
326 return Standard_True;
327 }
328 itpr.Next();
329 }
330 }
331 else {
332 // no 3d curve !!
333 // let us try with the first pcurve
334 Handle(Geom2d_Curve) PC;
335 Handle(Geom_Surface) S;
336 BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
337 L = L.Predivided(V.Location());
338 BRep_ListIteratorOfListOfPointRepresentation itpr
339 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
340
341 while (itpr.More()) {
342 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
343 if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
344 Standard_Real p = pr->Parameter();
345 // Closed curves RLE 16 june 94
346 if (PC->IsClosed()) {
347 if ((p == PC->FirstParameter()) ||
348 (p == PC->LastParameter())) {
349 if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
350 else p = PC->LastParameter();
351 }
352 }
353 //return p;
354 U = p;
355 return Standard_True;
356 }
357 itpr.Next();
358 }
359 }
360 }
361
362 //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
363 return Standard_False;
364}
365
366//=======================================================================
367//function : GetEdgePoints
368//purpose : gets the first, last and middle points of the edge
369//=======================================================================
370static void GetEdgePoints(const TopoDS_Edge& anEdge,
371 const TopoDS_Face& aFace,
372 gp_Pnt& fPnt, gp_Pnt& mPnt,
373 gp_Pnt& lPnt)
374{
375 Standard_Real f, l;
376 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l );
377 gp_Pnt2d fPnt2d = theCurve->Value(f);
378 gp_Pnt2d lPnt2d = theCurve->Value(l);
379 gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l));
380 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
381 fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y());
382 lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y());
383 mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y());
384}
385
386//=======================================================================
387//function : FillContours
388//purpose : fills free boundary contours and faces connected (MapEF)
389//=======================================================================
390static void FillContours(const TopoDS_Shape& aShape,
391 const BRepOffset_Analyse& Analyser,
392 TopTools_DataMapOfShapeListOfShape& Contours,
393 TopTools_DataMapOfShapeShape& MapEF)
394{
395 TopTools_ListOfShape Edges;
396
397 TopExp_Explorer Explo(aShape, TopAbs_FACE);
398 BRepTools_WireExplorer Wexp;
399
400 for (; Explo.More(); Explo.Next())
401 {
402 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
403 TopoDS_Iterator itf(aFace);
404 for (; itf.More(); itf.Next())
405 {
406 TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
407 for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
408 {
409 TopoDS_Edge anEdge = Wexp.Current();
410 if (BRep_Tool::Degenerated(anEdge))
411 continue;
412 const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
413 if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary)
414 {
415 MapEF.Bind(anEdge, aFace);
416 Edges.Append(anEdge);
417 }
418 }
419 }
420 }
421
422 TopTools_ListIteratorOfListOfShape itl;
423 while (!Edges.IsEmpty())
424 {
425 TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First());
426 Edges.RemoveFirst();
427 TopoDS_Vertex StartVertex, CurVertex;
428 TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True);
429 TopTools_ListOfShape aContour;
430 aContour.Append(StartEdge);
431 while (!CurVertex.IsSame(StartVertex))
432 for (itl.Initialize(Edges); itl.More(); itl.Next())
433 {
434 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
435 TopoDS_Vertex V1, V2;
436 TopExp::Vertices(anEdge, V1, V2);
437 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
438 {
439 aContour.Append(anEdge);
440 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
441 Edges.Remove(itl);
442 break;
443 }
444 }
445 Contours.Bind(StartVertex, aContour);
446 }
447}
448
449//=======================================================================
450//function : BRepOffset_MakeOffset
451//purpose :
452//=======================================================================
453
454BRepOffset_MakeOffset::BRepOffset_MakeOffset()
455{
456 myAsDes = new BRepAlgo_AsDes();
457}
458
459
460//=======================================================================
461//function : BRepOffset_MakeOffset
462//purpose :
463//=======================================================================
464
465BRepOffset_MakeOffset::BRepOffset_MakeOffset(const TopoDS_Shape& S,
466 const Standard_Real Offset,
467 const Standard_Real Tol,
468 const BRepOffset_Mode Mode,
469 const Standard_Boolean Inter,
470 const Standard_Boolean SelfInter,
471 const GeomAbs_JoinType Join,
472 const Standard_Boolean Thickening)
473:
474myOffset (Offset),
475myTol (Tol),
476myShape (S),
477myMode (Mode),
478myInter (Inter),
479mySelfInter (SelfInter),
480myJoin (Join),
481myThickening (Thickening),
482myDone (Standard_False)
483
484{
485 myAsDes = new BRepAlgo_AsDes();
486 MakeOffsetShape();
487}
488
489
490//=======================================================================
491//function : Initialize
492//purpose :
493//=======================================================================
494
495void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S,
496 const Standard_Real Offset,
497 const Standard_Real Tol,
498 const BRepOffset_Mode Mode,
499 const Standard_Boolean Inter,
500 const Standard_Boolean SelfInter,
501 const GeomAbs_JoinType Join,
502 const Standard_Boolean Thickening)
503{
504 myOffset = Offset;
505 myShape = S;
506 myTol = Tol;
507 myMode = Mode;
508 myInter = Inter;
509 mySelfInter = SelfInter;
510 myJoin = Join;
511 myThickening = Thickening;
512 myDone = Standard_False;
513 Clear();
514}
515
516
517//=======================================================================
518//function : Clear
519//purpose :
520//=======================================================================
521
522void BRepOffset_MakeOffset::Clear()
523{
524 myOffsetShape.Nullify();
525 myInitOffsetFace .Clear();
526 myInitOffsetEdge .Clear();
527 myImageOffset .Clear();
528 myFaces .Clear();
529 myFaceOffset .Clear();
530 myAsDes ->Clear();
531 myDone = Standard_False;
532}
533
534//=======================================================================
535//function : AddFace
536//purpose :
537//=======================================================================
538
539void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
540 myFaces.Add(F);
541 //-------------
542 // MAJ SD.
543 //-------------
544 myInitOffsetFace.SetRoot (F) ;
545 myInitOffsetFace.Bind (F,F);
546 myImageOffset.SetRoot (F) ;
547}
548
549//=======================================================================
550//function : SetOffsetOnFace
551//purpose :
552//=======================================================================
553
554void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F,
555 const Standard_Real Off)
556{
557 if ( myFaceOffset.IsBound(F)) myFaceOffset.UnBind(F);
558 myFaceOffset.Bind(F,Off);
559}
560
561//=======================================================================
562//function : RemoveCorks
563//purpose :
564//=======================================================================
565
566static void RemoveCorks (TopoDS_Shape& S,
567 TopTools_MapOfShape& Faces)
568{
569 TopoDS_Compound SS;
570 BRep_Builder B;
571 B.MakeCompound (SS);
572 //-----------------------------------------------------
0d969553
Y
573 // Construction of a shape without caps.
574 // and Orientation of caps as in shape S.
7fd59977 575 //-----------------------------------------------------
576 TopExp_Explorer exp(S,TopAbs_FACE);
577 for (; exp.More(); exp.Next()) {
578 const TopoDS_Shape& Cork = exp.Current();
579 if (!Faces.Contains(Cork)) {
580 B.Add(SS,Cork);
581 }
582 else {
583 Faces.Remove (Cork);
0d969553 584 Faces.Add (Cork); // to reset it with proper orientation.
7fd59977 585 }
586 }
587 S = SS;
588#ifdef DRAW
589 if ( AffichOffC)
590 DBRep::Set("myInit", SS);
591#endif
592
593}
594
595static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
596{
597 BRepTools_Quilt Glue;
598 Glue.Add( S );
599
600 TopoDS_Shape SS = Glue.Shells();
601 TopExp_Explorer Explo( SS, TopAbs_SHELL );
602 Explo.Next();
603 if (Explo.More())
604 return Standard_False;
605
606 return Standard_True;
607}
608
609
610//=======================================================================
611//function : MakeList
612//purpose :
613//=======================================================================
614
615static void MakeList (TopTools_ListOfShape& OffsetFaces,
616 const BRepAlgo_Image& myInitOffsetFace,
617 const TopTools_MapOfShape& myFaces)
618{
619 TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots());
620 for ( ; itLOF.More(); itLOF.Next()) {
621 const TopoDS_Shape& Root = itLOF.Value();
622 if (!myFaces.Contains(Root))
623 OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
624 }
625}
626
627//=======================================================================
628//function : EvalMax
629//purpose :
630//=======================================================================
631
632static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
633{
634 TopExp_Explorer exp;
635 for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
636 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
637 Standard_Real TolV = BRep_Tool::Tolerance(V);
638 if (TolV > Tol) Tol = TolV;
639 }
640 //Patch
641 Tol *= 5.;
642}
643
644//=======================================================================
645//function : MakeOffsetShape
646//purpose :
647//=======================================================================
648
649void BRepOffset_MakeOffset::MakeOffsetShape()
650{
651 myDone = Standard_False;
652 //------------------------------------------
0d969553 653 // Construction of myShape without caps.
7fd59977 654 //------------------------------------------
655 RemoveCorks (myShape,myFaces);
656
657 if (! IsConnectedShell(myShape))
658 Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Incorrect set of faces to remove, the remaining shell is not connected");
659
660 if (Abs(myOffset) < myTol) return;
661
662 TopAbs_State Side = TopAbs_IN;
663 if (myOffset < 0.) Side = TopAbs_OUT;
664 // ------------
665 // Preanalyse.
666 // ------------
667 EvalMax(myShape,myTol);
668 if (myTol > Abs(myOffset*0.5)) {
669 Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Tol > Offset");
670 }
671 Standard_Real TolAngle = 4*ASin(myTol/Abs(myOffset*0.5));
672 myAnalyse.Perform(myShape,TolAngle);
673 //---------------------------------------------------
0d969553 674 // Construction of Offset from preanalysis.
7fd59977 675 //---------------------------------------------------
676 //----------------------------
0d969553 677 // MaJ of SD Face - Offset
7fd59977 678 //----------------------------
679 UpdateFaceOffset();
680
681 if (myJoin == GeomAbs_Arc)
682 BuildOffsetByArc();
683 else if (myJoin == GeomAbs_Intersection)
684 BuildOffsetByInter();
685 //-----------------
0d969553 686 // Auto unwinding.
7fd59977 687 //-----------------
688 // if (mySelfInter) SelfInter(Modif);
689 //-----------------
690 // Intersection 3d .
691 //-----------------
692 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
693 Intersection3D (Inter);
694 //-----------------
695 // Intersection2D
696 //-----------------
697 TopTools_MapOfShape& Modif = Inter.TouchedFaces();
698 TopTools_MapOfShape& NewEdges = Inter.NewEdges();
699
700 if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
701 //-------------------------------------------------------
0d969553 702 // Unwinding 2D and reconstruction of modified faces
7fd59977 703 //----------------------------------------------------
704 MakeLoops (Modif);
705 //-----------------------------------------------------
0d969553
Y
706 // Reconstruction of non modified faces sharing
707 // reconstructed edges
7fd59977 708 //------------------------------------------------------
709 if (!Modif.IsEmpty()) MakeFaces (Modif);
710
711 if (myThickening)
712 MakeMissingWalls();
713
714 //-------------------------
0d969553 715 // Construction of shells.
7fd59977 716 //-------------------------
717 MakeShells ();
718 //--------------
0d969553 719 // Unwinding 3D.
7fd59977 720 //--------------
721 SelectShells ();
722 //----------------------------------
0d969553 723 // Coding of regularities.
7fd59977 724 //----------------------------------
725 EncodeRegularity();
726 //----------------------
0d969553 727 // Creation of solids.
7fd59977 728 //----------------------
729 MakeSolid ();
730
731 //-----------------------------
0d969553 732 // MAJ Tolerance edge and Vertex
7fd59977 733 // ----------------------------
734 if (!myOffsetShape.IsNull()) {
735 UpdateTolerance (myOffsetShape,myFaces);
736 BRepLib::UpdateTolerances( myOffsetShape );
737 }
738
739 CorrectConicalFaces();
740
741 myDone = Standard_True;
742}
743
744
745
746//=======================================================================
747//function : MakeThickSolid
748//purpose :
749//=======================================================================
750
751void BRepOffset_MakeOffset::MakeThickSolid()
752{
753 //--------------------------------------------------------------
0d969553 754 // Construction of shell parallel to shell (initial without cap).
7fd59977 755 //--------------------------------------------------------------
756 MakeOffsetShape ();
757
758 //--------------------------------------------------------------------
0d969553
Y
759 // Construction of a solid with the initial shell, parallel shell
760 // limited by caps.
7fd59977 761 //--------------------------------------------------------------------
762 if (!myFaces.IsEmpty()) {
763 TopoDS_Solid Res;
764 TopExp_Explorer exp;
765 BRep_Builder B;
766 Standard_Integer NbF = myFaces.Extent();
767
768 B.MakeSolid(Res);
769
770 BRepTools_Quilt Glue;
771 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
772 NbF++;
773 Glue.Add (exp.Current());
774 }
775 Standard_Boolean YaResult = 0;
776 if (!myOffsetShape.IsNull()) {
777 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next()) {
778 YaResult = 1;
779 Glue.Add (exp.Current().Reversed());
780 }
781 }
782 if (YaResult == 0) {
783 myDone = Standard_False;
784 return;
785 }
786 myOffsetShape = Glue.Shells();
787 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
788 B.Add(Res,exp.Current());
789 }
790 Res.Closed(Standard_True);
791 myOffsetShape = Res;
792
0d969553
Y
793 // Test of Validity of the result of thick Solid
794 // more face than the initial solid.
7fd59977 795
796 Standard_Integer NbOF = 0;
797 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next()) {
798 NbOF++;
799 }
800 if (NbOF <= NbF) {
801 myDone = Standard_False;
802 return;
803 }
804 }
805
806 if (myOffset > 0 ) myOffsetShape.Reverse();
807
808 myDone = Standard_True;
809}
810
811//=======================================================================
812//function : IsDone
813//purpose :
814//=======================================================================
815
816Standard_Boolean BRepOffset_MakeOffset::IsDone() const
817{
818 return myDone;
819}
820
821//=======================================================================
822//function : Error
823//purpose :
824//=======================================================================
825
826BRepOffset_Error BRepOffset_MakeOffset::Error() const
827{
828 return myError;
829}
830
831//=======================================================================
832//function : Shape
833//purpose :
834//=======================================================================
835
836const TopoDS_Shape& BRepOffset_MakeOffset::Shape() const
837{
838 return myOffsetShape;
839}
840
841//=======================================================================
842//function : TrimEdge
0d969553
Y
843//purpose : Trim the edge of the largest of descendants in AsDes2d.
844// Order in AsDes two vertices that have trimmed the edge.
7fd59977 845//=======================================================================
846
847static void TrimEdge (TopoDS_Edge& NE,
848 const Handle(BRepAlgo_AsDes)& AsDes2d,
849 Handle(BRepAlgo_AsDes)& AsDes)
850{
851 Standard_Real aSameParTol = Precision::Confusion();
852
853 TopoDS_Vertex V1,V2;
854 Standard_Real U;
855 Standard_Real UMin = Precision::Infinite();
856 Standard_Real UMax = -UMin;
857
858 const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
859
860 if (LE.Extent() > 1) {
861 TopTools_ListIteratorOfListOfShape it (LE);
862 for (; it.More(); it.Next()) {
863 TopoDS_Vertex V = TopoDS::Vertex(it.Value());
864 if (NE.Orientation() == TopAbs_REVERSED)
865 V.Reverse();
866 //V.Orientation(TopAbs_INTERNAL);
867 if (!FindParameter(V, NE, U))
868 {
869 Standard_Real f, l;
870 Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
871 gp_Pnt thePoint = BRep_Tool::Pnt(V);
872 GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
873 if (Projector.NbPoints() == 0)
874 Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection");
875 U = Projector.LowerDistanceParameter();
876 }
877 if (U < UMin) {
878 UMin = U; V1 = V;
879 }
880 if (U > UMax) {
881 UMax = U; V2 = V;
882 }
883 }
884 if (V1.IsNull() || V2.IsNull()) {
885 Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge");
886 }
887 if (!V1.IsSame(V2)) {
888 NE.Free( Standard_True );
889 BRep_Builder B;
890 TopAbs_Orientation Or = NE.Orientation();
891 NE.Orientation(TopAbs_FORWARD);
892 TopoDS_Vertex VF,VL;
893 TopExp::Vertices (NE,VF,VL);
894 B.Remove(NE,VF);
895 B.Remove(NE,VL);
896 B.Add (NE,V1.Oriented(TopAbs_FORWARD));
897 B.Add (NE,V2.Oriented(TopAbs_REVERSED));
898 B.Range(NE,UMin,UMax);
899 NE.Orientation(Or);
900 AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
901 AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
902 BRepLib::SameParameter(NE, aSameParTol, Standard_True);
903 }
904 }
905}
906
907//=======================================================================
908//function : BuildOffsetByInter
909//purpose :
910//=======================================================================
911void BRepOffset_MakeOffset::BuildOffsetByInter()
912{
913#ifdef DEB
914 if ( ChronBuild) {
0d969553 915 cout << " CONSTRUCTION OF OFFSETS :" << endl;
7fd59977 916 Clock.Reset();
917 Clock.Start();
918 }
919#endif
920
921 BRepOffset_DataMapOfShapeOffset MapSF;
922 TopTools_MapOfShape Done;
923 Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
924 //--------------------------------------------------------
0d969553 925 // Construction of faces parallel to initial faces
7fd59977 926 //--------------------------------------------------------
927 TopExp_Explorer Exp;
928 TopTools_ListOfShape LF;
929 TopTools_ListIteratorOfListOfShape itLF;
930
931 BRepLib::SortFaces(myShape,LF);
932
933 TopTools_DataMapOfShapeShape ShapeTgt;
934 for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
935 const TopoDS_Face& F = TopoDS::Face(itLF.Value());
936 Standard_Real CurOffset = myOffset;
937 if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
938 BRepOffset_Offset OF(F,CurOffset,ShapeTgt,OffsetOutside,myJoin);
939 TopTools_ListOfShape Let;
940 myAnalyse.Edges(F,BRepOffset_Tangent,Let);
941 TopTools_ListIteratorOfListOfShape itl(Let);
942
943 for ( ; itl.More(); itl.Next()) {
944 const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
945 if ( !ShapeTgt.IsBound(Cur)) {
946 TopoDS_Shape aLocalShape = OF.Generated(Cur);
947 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
948// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
949 ShapeTgt.Bind(Cur,OF.Generated(Cur));
950 TopoDS_Vertex V1,V2,OV1,OV2;
951 TopExp::Vertices (Cur,V1,V2);
952 TopExp::Vertices (OTE,OV1,OV2);
953 TopTools_ListOfShape LE;
954 if (!ShapeTgt.IsBound(V1)) {
955 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
956 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
957 if (LE.Extent() == LA.Extent())
958 ShapeTgt.Bind(V1,OV1);
959 }
960 if (!ShapeTgt.IsBound(V2)) {
961 LE.Clear();
962 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
963 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
964 if (LE.Extent() == LA.Extent())
965 ShapeTgt.Bind(V2,OV2);
966 }
967 }
968 }
969 MapSF.Bind(F,OF);
970 }
971 //--------------------------------------------------------------------
972 // MES : Map of OffsetShape -> Extended Shapes.
973 // Build : Map of Initial SS -> OffsetShape build by Inter.
974 // can be an edge or a compound of edges
975 //---------------------------------------------------------------------
976 TopTools_DataMapOfShapeShape MES;
977 TopTools_DataMapOfShapeShape Build;
978 TopTools_ListOfShape Failed;
979 TopAbs_State Side = TopAbs_IN;
980 Handle(BRepAlgo_AsDes) AsDes = new BRepAlgo_AsDes();
981
982 //-------------------------------------------------------------------
0d969553 983 // Extension of faces and calculation of new edges of intersection.
7fd59977 984 //-------------------------------------------------------------------
985 Standard_Boolean ExtentContext = 0;
986 if (myOffset > 0) ExtentContext = 1;
987
988 BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
0d969553 989 // Intersection between parallel faces
7fd59977 990 Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed );
0d969553 991 // Intersection with caps.
7fd59977 992 Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed );
993
994
995 //---------------------------------------------------------------------------------
0d969553 996 // Extension of neighbor edges of new edges and intersection between neighbors.
7fd59977 997 //--------------------------------------------------------------------------------
998 Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
999 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1000 const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
1001// Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin
1002// BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol);
1003 BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myOffset, myTol);
1004// Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End
1005 }
1006 //-----------------------------------------------------------
0d969553 1007 // Great restriction of new edges and update of AsDes.
7fd59977 1008 //------------------------------------------ ----------------
1009 TopTools_MapOfShape NewEdges;
1010 TopExp_Explorer Exp2,ExpC;
1011 TopoDS_Shape NE;
1012 TopoDS_Edge TNE;
1013 TopoDS_Face NF;
1014#ifdef DEB
1015 TopAbs_Orientation Or;
1016#endif
1017
1018 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1019 const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
1020 NF = MapSF(FI).Face();
1021 if (MES.IsBound(NF)) {NF = TopoDS::Face(MES(NF));}
1022 TopTools_MapOfShape View;
1023 for (Exp2.Init(FI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); Exp2.More(); Exp2.Next()) {
1024 const TopoDS_Edge& EI = TopoDS::Edge(Exp2.Current());
1025 if (View.Add(EI)) {
1026 if (Build.IsBound(EI)) {
1027 NE = Build(EI);
1028 if (NE.ShapeType() == TopAbs_EDGE) {
1029 if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
1030 }
1031 else {
1032 //------------------------------------------------------------
0d969553
Y
1033 // The Intersections are on several edges.
1034 // The pieces without intersections with neighbors
1035 // are removed from AsDes.
7fd59977 1036 //------------------------------------------------------------
1037 for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1038 if (NewEdges.Add(ExpC.Current())) {
1039 TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
1040 NEC.Free(Standard_True);
1041 if (!AsDes2d->Descendant(NEC).IsEmpty()) {
1042 TrimEdge (NEC,AsDes2d,AsDes);
1043 }
1044 else {
1045 AsDes->Remove(NEC);
1046 }
1047 }
1048 }
1049 }
1050 }
1051 else {
1052 NE = MapSF(FI).Generated(EI);
1053 //// modified by jgv, 19.12.03 for OCC4455 ////
1054 NE.Orientation( EI.Orientation() );
1055 ///////////////////////////////////////////////
1056 if (MES.IsBound(NE)) {
1057 NE = MES(NE);
1058 NE.Orientation(EI.Orientation());
1059 if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
1060 }
1061 AsDes->Add(NF,NE);
1062 }
1063 }
1064 }
1065 }
1066
1067 //---------------------------------
0d969553 1068 // Intersection 2D on //
7fd59977 1069 //---------------------------------
1070 TopTools_ListOfShape LFE;
1071 BRepAlgo_Image IMOE;
1072 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1073 const TopoDS_Shape& FI = Exp.Current();
1074 const TopoDS_Shape& OFI = MapSF(FI).Face();
1075 if (MES.IsBound(OFI)) {
1076 const TopoDS_Face& NF = TopoDS::Face(MES(OFI));
1077 LFE.Append(NF);
1078 IMOE.SetRoot(NF);
1079 }
1080 }
1081
1082 TopTools_ListIteratorOfListOfShape itLFE(LFE);
1083 for (; itLFE.More(); itLFE.Next()) {
1084 const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
1085 BRepOffset_Inter2d::Compute(AsDes,NEF,NewEdges,myTol);
1086 }
1087 //----------------------------------------------
0d969553 1088 // Intersections 2d on caps.
7fd59977 1089 //----------------------------------------------
1090 TopTools_MapIteratorOfMapOfShape itCork(myFaces);
1091 for (; itCork.More(); itCork.Next()) {
1092 const TopoDS_Face& Cork = TopoDS::Face(itCork.Key());
1093 BRepOffset_Inter2d::Compute(AsDes,Cork,NewEdges,myTol);
1094 }
1095
1096 //-------------------------------
0d969553 1097 // Unwinding of extended Faces.
7fd59977 1098 //-------------------------------
1099 myMakeLoops.Build(LFE ,AsDes,IMOE);
1100
1101#ifdef DEB
1102 TopTools_MapOfShape COES;
1103#endif
1104 //---------------------------
0d969553 1105 // MAJ SD. for faces //
7fd59977 1106 //---------------------------
1107 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1108 const TopoDS_Shape& FI = Exp.Current();
1109 myInitOffsetFace.SetRoot(FI);
1110 TopoDS_Face OF = MapSF(FI).Face();
1111 if (MES.IsBound(OF)) {
1112 OF = TopoDS::Face(MES(OF));
1113 if (IMOE.HasImage(OF)) {
1114 const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
1115 myInitOffsetFace.Bind(FI,LOFE);
1116 for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
1117 const TopoDS_Shape& OFE = itLF.Value();
1118 myImageOffset.SetRoot(OFE);
1119#ifdef DRAW
1120 if (AffichInt2d) {
1121 sprintf(name,"AF_%d",NbAF++);
1122 DBRep::Set(name,OFE);
1123 }
1124#endif
1125 TopTools_MapOfShape View;
1126 for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1127 Exp2.More(); Exp2.Next()) {
1128 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1129
1130 myAsDes->Add (OFE,COE);
1131#ifdef DRAW
1132 if (AffichInt2d) {
1133 sprintf(name,"AE_%d",NbAE++);
1134 DBRep::Set(name,COE);
1135 COES.Add(COE);
1136 }
1137#endif
1138 if (View.Add(COE)){
1139 if (!myAsDes->HasDescendant(COE)) {
1140 TopoDS_Vertex CV1,CV2;
1141 TopExp::Vertices(COE,CV1,CV2);
1142 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1143 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1144 }
1145 }
1146 }
1147 }
1148 }
1149 else {
1150 myInitOffsetFace.Bind(FI,OF);
1151 myImageOffset.SetRoot(OF);
1152#ifdef DRAW
1153 if (AffichInt2d) {
1154 sprintf(name,"AF_%d",NbAF++);
1155 DBRep::Set(name,OF);
1156 }
1157#endif
1158 const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
1159 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1160 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1161 if (IMOE.HasImage(OE)) {
1162 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1163 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1164 for (; itLOE.More(); itLOE.Next()) {
1165 TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
1166 const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
1167// const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
1168 myAsDes->Add(OF,COE);
1169#ifdef DRAW
1170 if (AffichInt2d) {
1171 sprintf(name,"AE_%d",NbAE++);
1172 DBRep::Set(name,COE);
1173 COES.Add(COE);
1174 }
1175#endif
1176
1177 if (!myAsDes->HasDescendant(COE)) {
1178 TopoDS_Vertex CV1,CV2;
1179 TopExp::Vertices(COE,CV1,CV2);
1180 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1181 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1182 }
1183 }
1184 }
1185 else {
1186 myAsDes->Add(OF,OE);
1187#ifdef DRAW
1188 if (AffichInt2d) {
1189 sprintf(name,"AE_%d",NbAE++);
1190 DBRep::Set(name,OE);
1191 COES.Add(OE);
1192 }
1193#endif
1194
1195 const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
1196 myAsDes->Add(OE,LV);
1197 }
1198 }
1199 }
1200 }
1201 else {
1202 myInitOffsetFace.Bind(FI,OF);
1203 myImageOffset.SetRoot(OF);
1204 TopTools_MapOfShape View;
1205 for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1206 Exp2.More(); Exp2.Next()) {
1207
1208 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1209 myAsDes->Add (OF,COE);
1210#ifdef DRAW
1211 if (AffichInt2d) {
1212 sprintf(name,"AE_%d",NbAE++);
1213 DBRep::Set(name,COE);
1214 COES.Add(COE);
1215 }
1216#endif
1217
1218 if (View.Add(Exp2.Current())) {
1219 if (!myAsDes->HasDescendant(COE)) {
1220 TopoDS_Vertex CV1,CV2;
1221 TopExp::Vertices(COE,CV1,CV2);
1222 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1223 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1224 }
1225 }
1226 }
1227 }
1228 }
1229 // Modified by skv - Tue Mar 15 16:20:43 2005
1230 // Add methods for supporting history.
1231 TopTools_MapOfShape aMapEdges;
1232
1233 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1234 const TopoDS_Shape& aFaceRef = Exp.Current();
1235
1236 Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1237
1238 for (; Exp2.More(); Exp2.Next()) {
1239 const TopoDS_Shape& anEdgeRef = Exp2.Current();
1240
1241 if (aMapEdges.Add(anEdgeRef)) {
1242 myInitOffsetEdge.SetRoot(anEdgeRef);
1243 if (Build.IsBound(anEdgeRef)) {
1244 TopoDS_Shape aNewShape = Build(anEdgeRef);
1245
1246 if (aNewShape.ShapeType() == TopAbs_EDGE) {
1247 if (IMOE.HasImage(aNewShape)) {
1248 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape);
1249
1250 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1251 } else
1252 myInitOffsetEdge.Bind (anEdgeRef, aNewShape);
1253 } else { // aNewShape != TopAbs_EDGE
1254 TopTools_ListOfShape aListNewEdge;
1255
1256 for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1257 const TopoDS_Shape &aResEdge = ExpC.Current();
1258
1259 if (IMOE.HasImage(aResEdge)) {
1260 const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge);
1261 TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE);
1262
1263 for (; aNewEIter.More(); aNewEIter.Next())
1264 aListNewEdge.Append(aNewEIter.Value());
1265 } else
1266 aListNewEdge.Append(aResEdge);
1267 }
1268
1269 myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge);
1270 }
1271 }
1272 else { // Free boundary.
1273 TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef);
1274
1275 if (MES.IsBound(aNewEdge))
1276 aNewEdge = MES(aNewEdge);
1277
1278 if (IMOE.HasImage(aNewEdge)) {
1279 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge);
1280
1281 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1282 } else
1283 myInitOffsetEdge.Bind (anEdgeRef, aNewEdge);
1284 }
1285 }
1286 }
1287 }
1288// Modified by skv - Tue Mar 15 16:20:43 2005
1289
1290 //---------------------------
0d969553 1291 // MAJ SD. for caps
7fd59977 1292 //---------------------------
1293 TopTools_MapOfShape View;
1294 for (itCork.Initialize(myFaces); itCork.More(); itCork.Next()) {
1295 const TopoDS_Shape& Cork = itCork.Key();
1296 const TopTools_ListOfShape& LE = AsDes->Descendant(Cork);
1297 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1298 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1299 if (IMOE.HasImage(OE)) {
1300 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1301 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1302 for (; itLOE.More(); itLOE.Next()) {
1303 const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value());
1304 myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ;
1305#ifdef DRAW
1306 if (AffichInt2d) {
1307 sprintf(name,"AE_%d",NbAE++);
1308 DBRep::Set(name,COE);
1309 COES.Add(COE);
1310 }
1311#endif
1312
1313 if (!myAsDes->HasDescendant(COE)) {
1314 TopoDS_Vertex CV1,CV2;
1315 TopExp::Vertices(COE,CV1,CV2);
1316 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1317 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1318 }
1319 }
1320 }
1321 else {
1322 myAsDes->Add(Cork,OE);
1323 if (AsDes->HasDescendant(OE)) {
1324 myAsDes->Add(OE,AsDes->Descendant(OE));
1325 }
1326#ifdef DRAW
1327 if (AffichInt2d) {
1328 sprintf(name,"AE_%d",NbAE++);
1329 DBRep::Set(name,OE);
1330 COES.Add(OE);
1331 }
1332#endif
1333 }
1334 }
1335 }
1336
1337#ifdef DEB
1338 DEBVerticesControl (COES,myAsDes);
1339 if ( ChronBuild) Clock.Show();
1340#endif
1341}
1342
1343
1344//=======================================================================
1345//function : BuildOffsetByArc
1346//purpose :
1347//=======================================================================
1348void BRepOffset_MakeOffset::BuildOffsetByArc()
1349{
1350#ifdef DEB
1351 if ( ChronBuild) {
0d969553 1352 cout << " CONSTRUCTION OF OFFSETS :" << endl;
7fd59977 1353 Clock.Reset();
1354 Clock.Start();
1355 }
1356#endif
1357
1358 BRepOffset_DataMapOfShapeOffset MapSF;
1359 TopTools_MapOfShape Done;
1360 Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
1361 //--------------------------------------------------------
0d969553 1362 // Construction of faces parallel to initial faces
7fd59977 1363 //--------------------------------------------------------
1364 TopExp_Explorer Exp;
1365 TopTools_ListOfShape LF;
1366 TopTools_ListIteratorOfListOfShape itLF;
1367
1368 BRepLib::SortFaces(myShape,LF);
1369
1370 TopTools_DataMapOfShapeShape EdgeTgt;
1371 for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
1372 const TopoDS_Face& F = TopoDS::Face(itLF.Value());
1373 Standard_Real CurOffset = myOffset;
1374 if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
1375 BRepOffset_Offset OF(F,CurOffset,EdgeTgt,OffsetOutside,myJoin);
1376 TopTools_ListOfShape Let;
1377 myAnalyse.Edges(F,BRepOffset_Tangent,Let);
1378 TopTools_ListIteratorOfListOfShape itl(Let);
1379
1380 for ( ; itl.More(); itl.Next()) {
1381 const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
1382 if ( !EdgeTgt.IsBound(Cur)) {
1383 TopoDS_Shape aLocalShape = OF.Generated(Cur);
1384 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1385// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
1386 EdgeTgt.Bind(Cur,OF.Generated(Cur));
1387 TopoDS_Vertex V1,V2,OV1,OV2;
1388 TopExp::Vertices (Cur,V1,V2);
1389 TopExp::Vertices (OTE,OV1,OV2);
1390 TopTools_ListOfShape LE;
1391 if (!EdgeTgt.IsBound(V1)) {
1392 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1393 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
1394 if (LE.Extent() == LA.Extent())
1395 EdgeTgt.Bind(V1,OV1);
1396 }
1397 if (!EdgeTgt.IsBound(V2)) {
1398 LE.Clear();
1399 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1400 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
1401 if (LE.Extent() == LA.Extent())
1402 EdgeTgt.Bind(V2,OV2);
1403 }
1404 }
1405 }
1406 MapSF.Bind(F,OF);
1407 }
1408 //--------------------------------------------------------
0d969553 1409 // Construction of tubes on edge.
7fd59977 1410 //--------------------------------------------------------
1411 BRepOffset_Type OT = BRepOffset_Convex;
1412 if (myOffset < 0.) OT = BRepOffset_Concave;
1413
1414 for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1415 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1416 if (Done.Add(E)) {
1417 const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
1418 if (Anc.Extent() == 2) {
1419 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1420 if (!L.IsEmpty() && L.First().Type() == OT) {
1421 Standard_Real CurOffset = myOffset;
1422 if ( myFaceOffset.IsBound(Anc.First()))
1423 CurOffset = myFaceOffset(Anc.First());
1424 TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1425 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1426 aLocalShape = MapSF(Anc.Last()).Generated(E);
1427 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
1428// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1429// TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
1430 // find if exits tangent edges in the original shape
1431 TopoDS_Edge E1f, E1l;
1432 TopoDS_Vertex V1f, V1l;
1433 TopExp::Vertices(E,V1f,V1l);
1434 TopTools_ListOfShape TangE;
1435 myAnalyse.TangentEdges(E,V1f,TangE);
1436 // find if the pipe on the tangent edges are soon created.
1437 TopTools_ListIteratorOfListOfShape itl(TangE);
1438 Standard_Boolean Find = Standard_False;
1439 for ( ; itl.More() && !Find; itl.Next()) {
1440 if ( MapSF.IsBound(itl.Value())) {
1441 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
1442 E1f = TopoDS::Edge(aLocalShape);
1443// E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
1444 Find = Standard_True;
1445 }
1446 }
1447 TangE.Clear();
1448 myAnalyse.TangentEdges(E,V1l,TangE);
1449 // find if the pipe on the tangent edges are soon created.
1450 itl.Initialize(TangE);
1451 Find = Standard_False;
1452 for ( ; itl.More() && !Find; itl.Next()) {
1453 if ( MapSF.IsBound(itl.Value())) {
1454 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
1455 E1l = TopoDS::Edge(aLocalShape);
1456// E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
1457 Find = Standard_True;
1458 }
1459 }
1460 BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
1461 MapSF.Bind(E,OF);
1462 }
1463 }
1464 else {
1465 // ----------------------
0d969553 1466 // free border.
7fd59977 1467 // ----------------------
1468 TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1469 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1470/// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1471 myInitOffsetEdge.SetRoot(E); // skv: supporting history.
1472 myInitOffsetEdge.Bind (E,EOn1);
1473 }
1474 }
1475 }
1476
1477 //--------------------------------------------------------
0d969553 1478 // Construction of spheres on vertex.
7fd59977 1479 //--------------------------------------------------------
1480 Done.Clear();
1481 TopTools_ListIteratorOfListOfShape it;
1482
1483 for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) {
1484 const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current());
1485 if (Done.Add(V)) {
1486 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V);
1487 TopTools_ListOfShape LE;
1488 myAnalyse.Edges(V,OT,LE);
1489
1490 if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) {
1491 TopTools_ListOfShape LOE;
1492 //--------------------------------------------------------
0d969553 1493 // Return connected edges on tubes.
7fd59977 1494 //--------------------------------------------------------
1495 for (it.Initialize(LE) ; it.More(); it.Next()) {
1496 LOE.Append(MapSF(it.Value()).Generated(V).Reversed());
1497 }
1498 //----------------------
1499 // construction sphere.
1500 //-----------------------
1501 const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First());
1502 const TopoDS_Shape& FF = LLA.First();
1503 Standard_Real CurOffset = myOffset;
1504 if ( myFaceOffset.IsBound(FF))
1505 CurOffset = myFaceOffset(FF);
1506
1507 BRepOffset_Offset OF(V,LOE,CurOffset);
1508 MapSF.Bind(V,OF);
1509 }
1510 //--------------------------------------------------------------
0d969553 1511 // Particular processing if V is at least a free border.
7fd59977 1512 //-------------------------------------------------------------
1513 TopTools_ListOfShape LBF;
1514 myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF);
1515 if (!LBF.IsEmpty()) {
1516 Standard_Boolean First = Standard_True;
1517 for (it.Initialize(LE) ; it.More(); it.Next()) {
1518 if (First) {
1519 myInitOffsetEdge.SetRoot(V); // skv: supporting history.
1520 myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V));
1521 First = Standard_False;
1522 }
1523 else {
1524 myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V));
1525 }
1526 }
1527 }
1528 }
1529 }
1530
1531 //------------------------------------------------------------
0d969553
Y
1532 // Extension of parallel faces to the context.
1533 // Extended faces are ordered in DS and removed from MapSF.
7fd59977 1534 //------------------------------------------------------------
1535 if (!myFaces.IsEmpty()) ToContext (MapSF);
1536
1537 //------------------------------------------------------
1538 // MAJ SD.
1539 //------------------------------------------------------
1540 BRepOffset_Type RT = BRepOffset_Concave;
1541 if (myOffset < 0.) RT = BRepOffset_Convex;
1542 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
1543#ifdef DEB
1544 Standard_Integer MapSFNb = MapSF.Extent();
1545#endif
1546 for ( ; It.More(); It.Next()) {
1547 const TopoDS_Shape& SI = It.Key();
1548 const BRepOffset_Offset& SF = It.Value();
1549 if (SF.Status() == BRepOffset_Reversed ||
1550 SF.Status() == BRepOffset_Degenerated ) {
1551 //------------------------------------------------
0d969553 1552 // Degenerated or returned faces are not stored.
7fd59977 1553 //------------------------------------------------
1554 continue;
1555 }
1556
1557 const TopoDS_Face& OF = It.Value().Face();
1558 myInitOffsetFace.Bind (SI,OF);
1559 myInitOffsetFace.SetRoot (SI); // Initial<-> Offset
0d969553 1560 myImageOffset.SetRoot (OF); // FaceOffset root of images
7fd59977 1561
1562 if (SI.ShapeType() == TopAbs_FACE) {
1563 for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1564 Exp.More(); Exp.Next()) {
1565 //--------------------------------------------------------------------
0d969553
Y
1566 // To each face are associatedthe edges that restrict that
1567 // The edges that do not generate tubes or are not tangent
1568 // to two faces are removed.
7fd59977 1569 //--------------------------------------------------------------------
1570 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1571 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1572 if (!L.IsEmpty() && L.First().Type() != RT) {
1573 TopAbs_Orientation OO = E.Orientation();
1574 TopoDS_Shape aLocalShape = It.Value().Generated(E);
1575 TopoDS_Edge OE = TopoDS::Edge(aLocalShape);
1576// TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E));
1577 myAsDes->Add (OF,OE.Oriented(OO));
1578 }
1579 }
1580 }
1581 else {
1582 for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1583 Exp.More(); Exp.Next()) {
1584 myAsDes->Add (OF,Exp.Current());
1585 }
1586 }
1587 }
1588
1589#ifdef DEB
1590 if ( ChronBuild) Clock.Show();
1591#endif
1592}
1593
1594
1595
1596//=======================================================================
1597//function : SelfInter
1598//purpose :
1599//=======================================================================
1600
1601void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& Modif)
1602{
1603#ifdef DEB
1604 if ( ChronBuild) {
1605 cout << " AUTODEBOUCLAGE:" << endl;
1606 Clock.Reset();
1607 Clock.Start();
1608 }
1609#endif
1610
1611 Standard_NotImplemented::Raise();
1612
1613#ifdef DEB
1614 if ( ChronBuild) Clock.Show();
1615#endif
1616}
1617
1618
1619//=======================================================================
1620//function : ToContext
1621//purpose :
1622//=======================================================================
1623
1624void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
1625{
1626 TopTools_DataMapOfShapeShape Created;
1627 TopTools_DataMapOfShapeShape MEF;
1628 TopTools_MapOfShape FacesToBuild;
1629 TopTools_MapIteratorOfMapOfShape it(myFaces);
1630 TopTools_ListIteratorOfListOfShape itl;
1631 TopExp_Explorer exp;
1632
1633// TopAbs_State Side = TopAbs_IN;
1634// if (myOffset < 0.) Side = TopAbs_OUT;
1635
1636 TopAbs_State Side = TopAbs_OUT;
1637
1638 for (; it.More(); it.Next()) {
1639 const TopoDS_Face& CF = TopoDS::Face(it.Key());
1640 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1641 exp.More(); exp.Next()) {
1642 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1643 if (!myAnalyse.HasAncestor(E)) {
1644 //----------------------------------------------------------------
0d969553
Y
1645 // The edges of context faces that are not in the initial shape
1646 // can appear in the result.
7fd59977 1647 //----------------------------------------------------------------
1648 //myAsDes->Add(CF,E);
1649 }
1650 }
1651 }
0d969553
Y
1652 //-------------------------------------------------------
1653 // Determine the edges and faces reconstructed by
7fd59977 1654 // intersection.
1655 //---------------------------------------------------------
1656 for ( it.Initialize(myFaces); it.More(); it.Next()) {
1657 const TopoDS_Face& CF = TopoDS::Face(it.Key());
1658 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1659 exp.More(); exp.Next()) {
1660 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1661 if (myAnalyse.HasAncestor(E)) {
1662 const TopTools_ListOfShape& LEA = myAnalyse.Ancestors(E);
1663 for (itl.Initialize(LEA); itl.More(); itl.Next()) {
1664 const BRepOffset_Offset& OF = MapSF(itl.Value());
1665 FacesToBuild.Add(itl.Value());
1666 MEF.Bind(OF.Generated(E),CF);
1667 }
1668 TopoDS_Vertex V[2];
1669 TopExp::Vertices(E,V[0],V[1]);
1670 for (Standard_Integer i = 0; i < 2; i++) {
1671 const TopTools_ListOfShape& LVA = myAnalyse.Ancestors(V[i]);
1672 for ( itl.Initialize(LVA); itl.More(); itl.Next()) {
1673 const TopoDS_Edge& EV = TopoDS::Edge(itl.Value());
1674 if (MapSF.IsBound(EV)) {
1675 const BRepOffset_Offset& OF = MapSF(EV);
1676 FacesToBuild.Add(EV);
1677 MEF.Bind(OF.Generated(V[i]),CF);
1678 }
1679 }
1680 }
1681 }
1682 }
1683 }
1684 //---------------------------
0d969553 1685 // Reconstruction of faces.
7fd59977 1686 //---------------------------
1687 TopoDS_Face F,NF;
1688 BRepOffset_Type RT = BRepOffset_Concave;
1689 if (myOffset < 0.) RT = BRepOffset_Convex;
1690 TopoDS_Shape OE,NE;
1691 TopAbs_Orientation Or;
1692
1693 for (it.Initialize(FacesToBuild); it.More(); it.Next()) {
1694 const TopoDS_Shape& S = it.Key();
1695 BRepOffset_Offset BOF;
1696 BOF = MapSF(S);
1697 F = TopoDS::Face(BOF.Face());
1698 BRepOffset_Tool::ExtentFace(F,Created,MEF,Side,myTol,NF);
1699 MapSF.UnBind(S);
1700 //--------------
1701 // MAJ SD.
1702 //--------------
1703 myInitOffsetFace.Bind (S,NF);
1704 myInitOffsetFace.SetRoot (S); // Initial<-> Offset
1705 myImageOffset.SetRoot (NF);
1706
1707 if (S.ShapeType() == TopAbs_FACE) {
1708 for (exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1709 exp.More(); exp.Next()) {
1710
1711 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1712 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1713 OE = BOF.Generated(E);
1714 Or = E.Orientation();
1715 OE.Orientation(Or);
1716 if (!L.IsEmpty() && L.First().Type() != RT) {
1717 if (Created.IsBound(OE)) {
1718 NE = Created(OE);
1719 if (NE.Orientation() == TopAbs_REVERSED)
1720 NE.Orientation(TopAbs::Reverse(Or));
1721 else
1722 NE.Orientation(Or);
1723 myAsDes->Add(NF,NE);
1724 }
1725 else {
1726 myAsDes->Add(NF,OE);
1727 }
1728 }
1729 }
1730 }
1731 else {
1732 //------------------
0d969553 1733 // Tube
7fd59977 1734 //---------------------
1735 for (exp.Init(NF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1736 exp.More(); exp.Next()) {
1737 myAsDes->Add (NF,exp.Current());
1738 }
1739 }
1740 MapSF.UnBind(S);
1741 }
1742
0d969553
Y
1743 //------------------
1744 // MAJ free borders
1745 //------------------
7fd59977 1746 TopTools_DataMapIteratorOfDataMapOfShapeShape itc;
1747 for (itc.Initialize(Created); itc.More(); itc.Next()) {
1748 OE = itc.Key();
1749 NE = itc.Value();
1750 if (myInitOffsetEdge.IsImage(OE)) {
1751 TopoDS_Shape E = myInitOffsetEdge.ImageFrom (OE);
1752 Or = myInitOffsetEdge.Image(E).First().Orientation();
1753 if (NE.Orientation() == TopAbs_REVERSED)
1754 NE.Orientation(TopAbs::Reverse(Or));
1755 else
1756 NE.Orientation(Or);
1757 myInitOffsetEdge.Remove(OE);
1758 myInitOffsetEdge.Bind(E,NE);
1759 }
1760 }
1761}
1762
1763
1764//=======================================================================
1765//function : UpdateFaceOffset
1766//purpose :
1767//=======================================================================
1768
1769void BRepOffset_MakeOffset::UpdateFaceOffset()
1770{
1771 TopTools_MapOfShape M;
1772 TopTools_DataMapOfShapeReal CopiedMap;
1773 CopiedMap.Assign(myFaceOffset);
1774 TopTools_DataMapIteratorOfDataMapOfShapeReal it(CopiedMap);
1775
1776 BRepOffset_Type RT = BRepOffset_Convex;
1777 if (myOffset < 0.) RT = BRepOffset_Concave;
1778
1779 for ( ; it.More(); it.Next()) {
1780 const TopoDS_Face& F = TopoDS::Face(it.Key());
1781 Standard_Real CurOffset = CopiedMap(F);
1782 if ( !M.Add(F)) continue;
1783 TopoDS_Compound Co;
1784 BRep_Builder Build;
1785 Build.MakeCompound(Co);
1786 TopTools_MapOfShape Dummy;
1787 Build.Add(Co,F);
1788 if (myJoin == GeomAbs_Arc)
1789 myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent,RT);
1790 else
1791 myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent);
1792
1793 TopExp_Explorer exp(Co,TopAbs_FACE);
1794 for (; exp.More(); exp.Next()) {
1795 const TopoDS_Face& FF = TopoDS::Face(exp.Current());
1796 if ( !M.Add(FF)) continue;
1797 if ( myFaceOffset.IsBound(FF))
1798 myFaceOffset.UnBind(FF);
1799 myFaceOffset.Bind(FF,CurOffset);
1800 }
1801 }
1802}
1803
1804//=======================================================================
1805//function : CorrectConicalFaces
1806//purpose :
1807//=======================================================================
1808
1809void BRepOffset_MakeOffset::CorrectConicalFaces()
1810{
1811 TopTools_SequenceOfShape Cones;
1812 TopTools_SequenceOfShape Circs;
1813 TopTools_SequenceOfShape Seams;
1814 Standard_Real TolApex = 1.e-5;
1815
1816 Standard_Integer i;
1817
1818 TopTools_DataMapOfShapeListOfShape FacesOfCone;
1819 //TopTools_DataMapOfShapeShape DegEdges;
1820 TopExp_Explorer Explo( myOffsetShape, TopAbs_FACE );
1821 if (myJoin == GeomAbs_Arc)
1822 {
1823 for (; Explo.More(); Explo.Next())
1824 {
1825 TopoDS_Face aFace = TopoDS::Face( Explo.Current() );
1826 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( aFace );
1827 //if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
1828 //aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface(); //???
1829
1830 TopTools_IndexedMapOfShape Emap;
1831 TopExp::MapShapes( aFace, TopAbs_EDGE, Emap );
1832 for (i = 1; i <= Emap.Extent(); i++)
1833 {
1834 TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
1835 //Standard_Real f, l;
1836 //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
1837 //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
1838 if (BRep_Tool::Degenerated(anEdge))
1839 {
0d969553 1840 //Check if anEdge is a really degenerated edge or not
7fd59977 1841 BRepAdaptor_Curve BACurve(anEdge, aFace);
1842 gp_Pnt Pfirst, Plast, Pmid;
1843 Pfirst = BACurve.Value(BACurve.FirstParameter());
1844 Plast = BACurve.Value(BACurve.LastParameter());
1845 Pmid = BACurve.Value((BACurve.FirstParameter()+BACurve.LastParameter())/2.);
1846 if (Pfirst.Distance(Plast) <= TolApex &&
1847 Pfirst.Distance(Pmid) <= TolApex)
1848 continue;
1849 //Cones.Append( aFace );
1850 //Circs.Append( anEdge );
1851 //TopoDS_Vertex Vdeg = TopExp::FirstVertex( anEdge );
1852 TopoDS_Edge OrEdge =
1853 TopoDS::Edge( myInitOffsetEdge.Root( anEdge) );
1854 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1855 if ( FacesOfCone.IsBound(VF) )
1856 {
1857 //add a face to the existing list
1858 TopTools_ListOfShape& aFaces = FacesOfCone.ChangeFind(VF);
1859 aFaces.Append (aFace);
1860 //DegEdges.Bind(aFace, anEdge);
1861 }
1862 else
1863 {
1864 //the vertex is not in the map => create a new key and items
1865 TopTools_ListOfShape aFaces;
1866 aFaces.Append (aFace);
1867 FacesOfCone.Bind(VF, aFaces);
1868 //DegEdges.Bind(aFace, anEdge);
1869 }
1870 }
1871 } //for (i = 1; i <= Emap.Extent(); i++)
1872 } //for (; fexp.More(); fexp.Next())
1873 } //if (myJoin == GeomAbs_Arc)
1874
1875 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Cone(FacesOfCone);
1876 BRep_Builder BB;
1877 TopLoc_Location L;
1878 for (; Cone.More(); Cone.Next() ) {
1879 gp_Sphere theSphere;
1880 Handle(Geom_SphericalSurface) aSphSurf;
1881 TopoDS_Wire SphereWire;
1882 BB.MakeWire(SphereWire);
1883 TopoDS_Vertex anApex = TopoDS::Vertex(Cone.Key());
1884 const TopTools_ListOfShape& Faces = Cone.Value(); //FacesOfCone(anApex);
1885 TopTools_ListIteratorOfListOfShape itFaces(Faces);
1886 Standard_Boolean isFirstFace = Standard_True;
1887 gp_Pnt FirstPoint;
1888 TopoDS_Vertex theFirstVertex, CurFirstVertex;
1889 for (; itFaces.More(); itFaces.Next())
1890 {
1891 TopoDS_Face aFace = TopoDS::Face(itFaces.Value()); //TopoDS::Face(Faces.First());
1892 TopoDS_Edge DegEdge; // = TopoDS::Edge(DegEdges(aFace));
1893 for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
1894 {
1895 DegEdge = TopoDS::Edge(Explo.Current());
1896 if (BRep_Tool::Degenerated(DegEdge))
1897 {
1898 TopoDS_Edge OrEdge = TopoDS::Edge( myInitOffsetEdge.Root( DegEdge) );
1899 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1900 if (VF.IsSame(anApex))
1901 break;
1902 }
1903 }
1904 TopoDS_Shape aLocalDegShape = DegEdge.Oriented(TopAbs_FORWARD);
1905 TopoDS_Edge CurEdge = TopoDS::Edge(aLocalDegShape);
1906 BB.Degenerated(CurEdge, Standard_False);
1907 BB.SameRange(CurEdge, Standard_False);
1908 BB.SameParameter(CurEdge, Standard_False);
1909 gp_Pnt fPnt, lPnt, mPnt;
1910 GetEdgePoints(CurEdge, aFace, fPnt, mPnt, lPnt);
1911 Standard_Real f, l;
1912 BRep_Tool::Range(CurEdge, f, l);
1913 if (isFirstFace)
1914 {
1915 gp_Vec aVec1(fPnt, mPnt);
1916 gp_Vec aVec2(fPnt, lPnt);
1917 gp_Vec aNorm = aVec1.Crossed(aVec2);
1918 gp_Pnt theApex = BRep_Tool::Pnt(anApex);
1919 gp_Vec ApexToFpnt(theApex, fPnt);
1920 gp_Vec Ydir = aNorm ^ ApexToFpnt;
1921 gp_Vec Xdir = Ydir ^ aNorm;
1922 //Xdir.Rotate(gp_Ax1(theApex, aNorm), -f);
1923 gp_Ax2 anAx2(theApex, gp_Dir(aNorm), gp_Dir(Xdir));
1924 theSphere.SetRadius(myOffset);
1925 theSphere.SetPosition(gp_Ax3(anAx2) /*gp_Ax3(theApex, gp_Dir(aNorm))*/);
1926 aSphSurf = new Geom_SphericalSurface(theSphere);
1927 FirstPoint = fPnt;
1928 theFirstVertex = BRepLib_MakeVertex(fPnt);
1929 CurFirstVertex = theFirstVertex;
1930 }
1931
1932 TopoDS_Vertex v1, v2, FirstVert, EndVert;
1933 TopExp::Vertices(CurEdge, v1, v2);
1934 FirstVert = CurFirstVertex;
1935 if (lPnt.Distance(FirstPoint) <= Precision::Confusion())
1936 EndVert = theFirstVertex;
1937 else
1938 EndVert = BRepLib_MakeVertex(lPnt);
1939 CurEdge.Free( Standard_True );
1940 BB.Remove(CurEdge, v1);
1941 BB.Remove(CurEdge, v2);
1942 BB.Add(CurEdge, FirstVert.Oriented(TopAbs_FORWARD));
1943 BB.Add(CurEdge, EndVert.Oriented(TopAbs_REVERSED));
1944 //take the curve from sphere an put it to the edge
1945 Standard_Real Uf, Vf, Ul, Vl;
1946 ElSLib::Parameters( theSphere, fPnt, Uf, Vf );
1947 ElSLib::Parameters( theSphere, lPnt, Ul, Vl );
1948 if (Abs(Ul) <= Precision::Confusion())
c6541a0c 1949 Ul = 2.*M_PI;
7fd59977 1950 Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
1951 /*
1952 if (!isFirstFace)
1953 {
1954 gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
1955 if (Abs(Uf - f) > Precision::Confusion())
1956 {
1957 aCircle.Rotate(aCircle.Axis(), f - Uf);
1958 aCurv = new Geom_Circle(aCircle);
1959 }
1960 }
1961 */
1962 Handle(Geom_TrimmedCurve) aTrimCurv = new Geom_TrimmedCurve(aCurv, Uf, Ul);
1963 BB.UpdateEdge(CurEdge, aTrimCurv, Precision::Confusion());
1964 BB.Range(CurEdge, Uf, Ul, Standard_True);
1965 Handle(Geom2d_Line) theLin2d = new Geom2d_Line( gp_Pnt2d( 0., Vf ), gp::DX2d() );
1966 Handle(Geom2d_TrimmedCurve) theTrimLin2d = new Geom2d_TrimmedCurve(theLin2d, Uf, Ul);
1967 BB.UpdateEdge(CurEdge, theTrimLin2d, aSphSurf, L, Precision::Confusion());
1968 BB.Range(CurEdge, aSphSurf, L, Uf, Ul);
1969 BRepLib::SameParameter(CurEdge);
1970 BB.Add(SphereWire, CurEdge);
1971 //Modifying correspondent edges in aFace: substitute vertices common with CurEdge
1972 BRepAdaptor_Curve2d BAc2d(CurEdge, aFace);
1973 gp_Pnt2d fPnt2d, lPnt2d;
1974 fPnt2d = BAc2d.Value(BAc2d.FirstParameter());
1975 lPnt2d = BAc2d.Value(BAc2d.LastParameter());
1976 TopTools_IndexedMapOfShape Emap;
1977 TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
1978 TopoDS_Edge EE [2];
1979 Standard_Integer j = 0, k;
1980 for (k = 1; k <= Emap.Extent(); k++)
1981 {
1982 const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(k));
1983 if (!BRep_Tool::Degenerated(anEdge))
1984 {
1985 TopoDS_Vertex V1, V2;
1986 TopExp::Vertices(anEdge, V1, V2);
1987 if (V1.IsSame(v1) || V2.IsSame(v1))
1988 EE[j++] = anEdge;
1989 }
1990 }
1991 for (k = 0; k < j; k++)
1992 {
1993 TopoDS_Shape aLocalShape = EE[k].Oriented(TopAbs_FORWARD);
1994 TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
1995 Eforward.Free(Standard_True);
1996 TopoDS_Vertex V1, V2;
1997 TopExp::Vertices( Eforward, V1, V2 );
1998 BRepAdaptor_Curve2d EEc( Eforward, aFace );
1999 gp_Pnt2d p2d1, p2d2;
2000 p2d1 = EEc.Value(EEc.FirstParameter());
2001 p2d2 = EEc.Value(EEc.LastParameter());
2002 if (V1.IsSame(v1))
2003 {
2004 TopoDS_Vertex NewV = (p2d1.Distance(fPnt2d) <= Precision::Confusion())?
2005 FirstVert : EndVert;
2006 BB.Remove( Eforward, V1 );
2007 BB.Add( Eforward, NewV.Oriented(TopAbs_FORWARD) );
2008 }
2009 else
2010 {
2011 TopoDS_Vertex NewV = (p2d2.Distance(fPnt2d) <= Precision::Confusion())?
2012 FirstVert : EndVert;
2013 BB.Remove( Eforward, V2 );
2014 BB.Add( Eforward, NewV.Oriented(TopAbs_REVERSED) );
2015 }
2016 }
2017
2018 isFirstFace = Standard_False;
2019 CurFirstVertex = EndVert;
2020 }
2021 //Building new spherical face
2022 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
2023 gp_Pnt2d p2d1, p2d2;
2024 TopTools_ListOfShape EdgesOfWire;
2025 TopoDS_Iterator itw(SphereWire);
2026 for (; itw.More(); itw.Next())
2027 {
2028 const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
2029 EdgesOfWire.Append(anEdge);
2030 Standard_Real f, l;
2031 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aSphSurf, L, f, l);
2032 p2d1 = aC2d->Value(f);
2033 p2d2 = aC2d->Value(l);
2034 if (p2d1.X() < Ufirst)
2035 Ufirst = p2d1.X();
2036 if (p2d1.X() > Ulast)
2037 Ulast = p2d1.X();
2038 if (p2d2.X() < Ufirst)
2039 Ufirst = p2d2.X();
2040 if (p2d2.X() > Ulast)
2041 Ulast = p2d2.X();
2042 }
2043 TopTools_ListOfShape NewEdges;
2044 TopoDS_Edge FirstEdge;
2045 TopTools_ListIteratorOfListOfShape itl(EdgesOfWire);
2046 for (; itl.More(); itl.Next())
2047 {
2048 FirstEdge = TopoDS::Edge(itl.Value());
2049 Standard_Real f, l;
2050 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(FirstEdge, aSphSurf, L, f, l);
2051 p2d1 = aC2d->Value(f);
2052 p2d2 = aC2d->Value(l);
2053 if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion())
2054 {
2055 EdgesOfWire.Remove(itl);
2056 break;
2057 }
2058 }
2059 NewEdges.Append(FirstEdge);
2060 TopoDS_Vertex Vf1, CurVertex;
2061 TopExp::Vertices(FirstEdge, Vf1, CurVertex);
2062 itl.Initialize(EdgesOfWire);
2063 while (itl.More())
2064 {
2065 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
2066 TopoDS_Vertex V1, V2;
2067 TopExp::Vertices(anEdge, V1, V2);
2068 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
2069 {
2070 NewEdges.Append(anEdge);
2071 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
2072 EdgesOfWire.Remove(itl);
2073 }
2074 else
2075 itl.Next();
2076 }
2077
2078 Standard_Real Vfirst, Vlast;
2079 if (p2d1.Y() > 0.)
2080 {
c6541a0c 2081 Vfirst = p2d1.Y(); Vlast = M_PI/2.;
7fd59977 2082 }
2083 else
2084 {
c6541a0c 2085 Vfirst = -M_PI/2.; Vlast = p2d1.Y();
7fd59977 2086 }
1c72dff6 2087 TopoDS_Face NewSphericalFace = BRepLib_MakeFace(aSphSurf, Ufirst, Ulast, Vfirst, Vlast, Precision::Confusion());
7fd59977 2088 TopoDS_Edge OldEdge;
2089 for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
2090 {
2091 OldEdge = TopoDS::Edge(Explo.Current());
2092 if (!BRep_Tool::Degenerated(OldEdge))
2093 {
2094 BRepAdaptor_Curve2d BAc2d(OldEdge, NewSphericalFace);
2095 p2d1 = BAc2d.Value(BAc2d.FirstParameter());
2096 p2d2 = BAc2d.Value(BAc2d.LastParameter());
2097 if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion() &&
2098 Abs(p2d2.X() - Ulast) <= Precision::Confusion())
2099 break;
2100 }
2101 }
2102 TopoDS_Vertex V1, V2;
2103 TopExp::Vertices(OldEdge, V1, V2);
2104 TopTools_ListOfShape LV1, LV2;
2105 LV1.Append(Vf1);
2106 LV2.Append(CurVertex);
2107 BRepTools_Substitution theSubstitutor;
2108 theSubstitutor.Substitute(V1, LV1);
2109 if (!V1.IsSame(V2))
2110 theSubstitutor.Substitute(V2, LV2);
2111 theSubstitutor.Substitute(OldEdge, NewEdges);
2112 theSubstitutor.Build(NewSphericalFace);
2113 if (theSubstitutor.IsCopied(NewSphericalFace))
2114 {
2115 const TopTools_ListOfShape& listSh = theSubstitutor.Copy(NewSphericalFace);
2116 NewSphericalFace = TopoDS::Face(listSh.First());
2117 }
2118
2119 //Adding NewSphericalFace to the shell
2120 Explo.Init( myOffsetShape, TopAbs_SHELL );
2121 TopoDS_Shape theShell = Explo.Current();
2122 theShell.Free( Standard_True );
2123 BB.Add( theShell, NewSphericalFace );
2124 }
2125
2126 Explo.Init( myOffsetShape, TopAbs_SHELL );
2127
2128 if (Explo.More()) {
2129 TopoDS_Shape theShell = Explo.Current();
2130 theShell.Closed( Standard_True );
2131 }
2132
2133/*
2134 //Reconstructing
2135 BRep_Builder BB;
2136 for (i = 1; i <= Cones.Length(); i++)
2137 {
2138 TopoDS_Face Cone = TopoDS::Face( Cones(i) );
2139 TopoDS_Edge Circ = TopoDS::Edge( Circs(i) );
2140 TopoDS_Edge Seam = TopoDS::Edge( Seams(i) );
2141 if (Circ.IsNull()) //case 1 with big offset
2142 {
2143 //ExtraFace is absent
2144
2145 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2146
2147 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2148 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2149 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2150 gp_Pnt apex = theCone.Apex();
2151 Standard_Real Uapex, Vapex;
2152 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2153 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2154 apex = OffSurf->Value( Uapex, Vapex );
2155
2156 //Making new degenerated edge
c6541a0c 2157 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
7fd59977 2158 TopoDS_Edge NewEdge;
2159 BB.MakeEdge( NewEdge );
2160 NewEdge.Orientation(TopAbs_FORWARD);
2161 BB.UpdateEdge( NewEdge, theLine, Cone, Precision::Confusion() );
c6541a0c 2162 BB.Range( NewEdge, 0., 2.*M_PI );
7fd59977 2163 BB.SameParameter( NewEdge, Standard_True );
2164 BB.SameRange( NewEdge, Standard_True );
2165 BB.Degenerated( NewEdge, Standard_True );
2166 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2167 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2168 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2169
2170 //Reconstructing Seam
2171 Standard_Real f, l, par, cpar;
2172 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2173 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2174 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2175 TopoDS_Shape aLocalShape = Seam.Oriented(TopAbs_FORWARD);
2176 TopoDS_Vertex cver = TopExp::LastVertex( TopoDS::Edge(aLocalShape) );
2177 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2178 if (Abs(f-cpar) < Abs(l-cpar))
2179 BB.Range( Seam, par, l );
2180 else
2181 BB.Range( Seam, f, par );
2182 Seam.Free( Standard_True );
2183 TopoDS_Shape cver1;
2184 TopoDS_Iterator iter( Seam );
2185 for (; iter.More(); iter.Next())
2186 {
2187 cver1 = iter.Value();
2188 if (cver1.IsSame(cver))
2189 break;
2190 }
2191 BB.Remove( Seam, cver1 );
2192 if (Abs(f-cpar) < Abs(l-cpar))
2193 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2194 else
2195 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2196
2197 //Adding NewEdge into Cone
2198 TopoDS_Shape theWire;
2199 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2200 {
2201 theWire = fexp.Current();
2202 Standard_Boolean found = Standard_False;
2203 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2204 {
2205 if (Seam.IsSame( iter.Value() ))
2206 {
2207 found = Standard_True;
2208 break;
2209 }
2210 }
2211 if (found)
2212 break;
2213 }
2214 theWire.Free( Standard_True );
2215 NewEdge.Orientation( TopAbs::Compose(theWire.Orientation(),TopAbs_REVERSED) );
2216 BB.Add( theWire, NewEdge );
2217 } //end of case 1 with big offset
2218 else
2219 {
2220 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Circ.TShape());
2221 if (! TE->Degenerated()) //case 1
2222 {
2223 //Find ExtraFace
2224 TopoDS_Face ExtraFace;
2225 for (fexp.Init( myOffsetShape, TopAbs_FACE ); fexp.More(); fexp.Next())
2226 {
2227 ExtraFace = TopoDS::Face( fexp.Current() );
2228 if (ExtraFace.IsSame( Cone ))
2229 continue;
2230 Standard_Boolean found = Standard_False;
2231 TopExp_Explorer eexp( ExtraFace, TopAbs_EDGE );
2232 for (; eexp.More(); eexp.Next())
2233 if (Circ.IsSame( eexp.Current() ))
2234 {
2235 found = Standard_True;
2236 break;
2237 }
2238 if (found)
2239 break;
2240 }
2241
2242 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2243 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2244 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2245 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2246 gp_Pnt apex = theCone.Apex();
2247 Standard_Real Uapex, Vapex;
2248 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2249 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2250 apex = OffSurf->Value( Uapex, Vapex );
2251
2252 //Making new degenerated edge
c6541a0c 2253 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
7fd59977 2254 TopoDS_Edge NewEdge;
2255 BB.MakeEdge( NewEdge );
2256 NewEdge.Orientation(TopAbs_FORWARD);
2257 BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
c6541a0c 2258 BB.Range( NewEdge, 0., 2.*M_PI );
7fd59977 2259 BB.SameParameter( NewEdge, Standard_True );
2260 BB.SameRange( NewEdge, Standard_True );
2261 BB.Degenerated( NewEdge, Standard_True );
2262 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2263 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2264 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2265
2266 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2267
2268 //Reconstructing Seam
2269 Standard_Real f, l, par, cpar;
2270 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2271 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2272 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2273 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2274 if (Abs(f-cpar) < Abs(l-cpar))
2275 BB.Range( Seam, par, l );
2276 else
2277 BB.Range( Seam, f, par );
2278 Seam.Free( Standard_True );
2279 TopoDS_Shape cver1;
2280 TopoDS_Iterator iter( Seam );
2281 for (; iter.More(); iter.Next())
2282 {
2283 cver1 = iter.Value();
2284 if (cver1.IsSame(cver))
2285 break;
2286 }
2287 BB.Remove( Seam, cver1 );
2288 if (Abs(f-cpar) < Abs(l-cpar))
2289 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2290 else
2291 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2292
2293 //Removing ExtraFace from the shell
2294 fexp.Init( myOffsetShape, TopAbs_SHELL );
2295 TopoDS_Shape theShell = fexp.Current();
2296 theShell.Free( Standard_True );
2297 TopoDS_Shape ExtraFace1;
2298 for (iter.Initialize( theShell ); iter.More(); iter.Next())
2299 {
2300 ExtraFace1 = iter.Value();
2301 if (ExtraFace1.IsSame(ExtraFace))
2302 break;
2303 }
2304 BB.Remove( theShell, ExtraFace1 );
2305
2306 //Substitute Circ by NewEdge in Cone
2307 TopoDS_Shape theWire;
2308 TopoDS_Shape Circ1;
2309 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2310 {
2311 theWire = fexp.Current();
2312 Standard_Boolean found = Standard_False;
2313 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2314 {
2315 Circ1 = iter.Value();
2316 if (Circ1.IsSame(Circ))
2317 {
2318 found = Standard_True;
2319 break;
2320 }
2321 }
2322 if (found)
2323 break;
2324 }
2325 TopAbs_Orientation Or = Circ1.Orientation();
2326 theWire.Free( Standard_True );
2327 BB.Remove( theWire, Circ1 );
2328 BB.Add( theWire, NewEdge.Oriented(Or) );
2329 } //end of case 1
2330 else // Circ is degenerated
2331 {
2332 if (myOffset > 0. && myJoin == GeomAbs_Arc) //case 2
2333 {
2334 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2335
2336 TopoDS_Face OrCone = TopoDS::Face( myInitOffsetFace.Root( Cone ) );
2337 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( OrCone ), OffSurf = aSurf;
2338 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2339 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2340 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2341 gp_Pnt apex = theCone.Apex();
2342 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2343 {
2344 Standard_Real Uapex, Vapex;
2345 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2346 apex = OffSurf->Value( Uapex, Vapex );
2347 }
2348
2349 Standard_Real f, l;
2350 Handle(Geom_Curve) ccur = BRep_Tool::Curve( Circ, f, l );
2351 gp_Ax2 Axe2 = (Handle(Geom_Circle)::DownCast(ccur))->Circ().Position();
2352 gp_Ax3 Axe3( Axe2 );
2353 Axe3.SetLocation( apex );
2354 gp_Sphere theSphere( Axe3, myOffset );
2355
2356 gp_Pnt OrPnt = BRep_Tool::Pnt(cver);
2357 Standard_Real Uor, Vor;
2358 ElSLib::Parameters( theSphere, OrPnt, Uor, Vor );
2359 TopoDS_Face NewFace;
2360 if (Vor > 0.)
c6541a0c 2361 NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, Vor, M_PI/2. );
7fd59977 2362 else
c6541a0c 2363 NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, -M_PI/2., Vor );
7fd59977 2364
2365 //Updating the bound of NewFace
2366 TopoDS_Edge Bound;
2367 TopExp_Explorer eexp( NewFace, TopAbs_EDGE );
2368 for (; eexp.More(); eexp.Next())
2369 {
2370 Bound = TopoDS::Edge( eexp.Current() );
2371 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Bound.TShape());
2372 if (!TE->Degenerated() && !BRepTools::IsReallyClosed( Bound, NewFace ))
2373 break;
2374 }
2375 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( Circ, Cone, f, l );
2376 BB.UpdateEdge( Bound, pcurve, Cone, BRep_Tool::Tolerance(Circ) );
2377 TopoDS_Vertex bver = TopExp::FirstVertex( Bound );
2378 BB.UpdateVertex( bver, BRep_Tool::Tolerance(cver) );
2379
2380 //Updating cver in Seam
2381 TopoDS_Vertex cver1;
2382 TopoDS_Iterator iter( Seam );
2383 for (; iter.More(); iter.Next())
2384 {
2385 cver1 = TopoDS::Vertex( iter.Value() );
2386 if (cver1.IsSame(cver))
2387 break;
2388 }
2389 TopAbs_Orientation Or = cver1.Orientation();
2390 Seam.Free( Standard_True );
2391 BB.Remove( Seam, cver1 );
2392 BB.Add( Seam, bver.Oriented(Or) );
2393
2394 //Substitute Circ by Bound in Cone
2395 TopoDS_Shape theWire;
2396 TopoDS_Shape Circ1;
2397 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2398 {
2399 theWire = fexp.Current();
2400 Standard_Boolean found = Standard_False;
2401 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2402 {
2403 Circ1 = iter.Value();
2404 if (Circ1.IsSame(Circ))
2405 {
2406 found = Standard_True;
2407 break;
2408 }
2409 }
2410 if (found)
2411 break;
2412 }
2413 Or = Circ1.Orientation();
2414 theWire.Free( Standard_True );
2415 BB.Remove( theWire, Circ1 );
2416 BB.Add( theWire, Bound.Oriented(Or) );
2417
2418 //Adding NewFace to the shell
2419 fexp.Init( myOffsetShape, TopAbs_SHELL );
2420 TopoDS_Shape theShell = fexp.Current();
2421 theShell.Free( Standard_True );
2422 BB.Add( theShell, NewFace );
2423
2424 theShell.Closed( Standard_True );
2425 } //end of case 2
2426 else // if ((myOffset > 0. && myJoin == GeomAbs_Intersection) || myOffset < 0.) //case 3, 4
2427 {
2428 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2429 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2430 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2431 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2432 gp_Pnt apex = theCone.Apex();
2433 Standard_Real Uapex, Vapex;
2434 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2435 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2436 apex = OffSurf->Value( Uapex, Vapex );
2437
2438 //Making new degenerated edge
c6541a0c 2439 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
7fd59977 2440 TopoDS_Edge NewEdge;
2441 BB.MakeEdge( NewEdge );
2442 NewEdge.Orientation(TopAbs_FORWARD);
2443 BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
c6541a0c 2444 BB.Range( NewEdge, 0., 2.*M_PI );
7fd59977 2445 BB.SameParameter( NewEdge, Standard_True );
2446 BB.SameRange( NewEdge, Standard_True );
2447 BB.Degenerated( NewEdge, Standard_True );
2448 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2449 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2450 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2451
2452 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2453
2454 //Reconstructing Seam
2455 Standard_Real f, l, par, cpar;
2456 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2457 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2458 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2459 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2460 if (Abs(f-cpar) < Abs(l-cpar))
2461 BB.Range( Seam, par, l );
2462 else
2463 BB.Range( Seam, f, par );
2464 Seam.Free( Standard_True );
2465 TopoDS_Shape cver1;
2466 TopoDS_Iterator iter( Seam );
2467 for (; iter.More(); iter.Next())
2468 {
2469 cver1 = iter.Value();
2470 if (cver1.IsSame(cver))
2471 break;
2472 }
2473 BB.Remove( Seam, cver1 );
2474 if (Abs(f-cpar) < Abs(l-cpar))
2475 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2476 else
2477 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2478
2479 //Substitute Circ by NewEdge in Cone
2480 TopoDS_Shape theWire;
2481 TopoDS_Shape Circ1;
2482 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2483 {
2484 theWire = fexp.Current();
2485 Standard_Boolean found = Standard_False;
2486 for (iter.Initialize( theWire ); iter.More(); iter.Next())
2487 {
2488 Circ1 = iter.Value();
2489 if (Circ1.IsSame(Circ))
2490 {
2491 found = Standard_True;
2492 break;
2493 }
2494 }
2495 if (found)
2496 break;
2497 }
2498 TopAbs_Orientation Or = Circ1.Orientation();
2499 theWire.Free( Standard_True );
2500 BB.Remove( theWire, Circ1 );
2501 BB.Add( theWire, NewEdge.Oriented(Or) );
2502
2503 fexp.Init( myOffsetShape, TopAbs_SHELL );
2504 TopoDS_Shape theShell = fexp.Current();
2505 theShell.Closed( Standard_True );
2506 } //end of case 3, 4
2507 }
2508 } //else (! Circ.IsNull())
2509 }
2510*/
2511
2512 Standard_Integer NbShell = 0;
2513 TopoDS_Compound NC;
2514 TopoDS_Shape S1;
2515 BB.MakeCompound (NC);
2516
2517 for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
2518 const TopoDS_Shell& Sh = TopoDS::Shell(Explo.Current());
2519 NbShell++;
2520 if (Sh.Closed()) {
2521 TopoDS_Solid Sol;
2522 BB.MakeSolid (Sol);
2523 BB.Add (Sol,Sh);
2524 Sol.Closed(Standard_True);
2525 BB.Add (NC,Sol);
2526 if (NbShell == 1) S1 = Sol;
2527 }
2528 else {
2529 BB.Add (NC,Sh);
2530 if (NbShell == 1) S1 = Sh;
2531 }
2532 }
2533 if (NbShell == 1) myOffsetShape = S1;
2534 else myOffsetShape = NC;
2535}
2536
2537
2538//=======================================================================
2539//function : Intersection3D
2540//purpose :
2541//=======================================================================
2542
2543void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
2544{
2545#ifdef DEB
2546 if (ChronBuild) {
2547 cout << " INTERSECTION 3D:" << endl;
2548 Clock.Reset();
2549 Clock.Start();
2550 }
2551#endif
0d969553 2552 TopTools_ListOfShape OffsetFaces; // list of faces // created.
7fd59977 2553 MakeList (OffsetFaces,myInitOffsetFace,myFaces);
2554
2555 if (!myFaces.IsEmpty()) {
0d969553
Y
2556 Standard_Boolean InSide = (myOffset < 0.); // Temporary
2557 // it is necessary to calculate Inside taking account of the concavity or convexity of edges
2558 // between the cap and the part.
7fd59977 2559
2560 if (myJoin == GeomAbs_Arc)
2561 Inter.ContextIntByArc (myFaces,InSide,myAnalyse,myInitOffsetFace,myInitOffsetEdge);
2562 }
2563 if (myInter) {
2564 //-------------
0d969553 2565 //Complete.
7fd59977 2566 //-------------
2567 Inter.CompletInt (OffsetFaces,myInitOffsetFace);
2568 TopTools_MapOfShape& NewEdges = Inter.NewEdges();
2569 if (myJoin == GeomAbs_Intersection) {
2570 BRepOffset_Tool::CorrectOrientation (myShape,NewEdges,myAsDes,myInitOffsetFace,myOffset);
2571 }
2572 }
2573 else {
2574 //--------------------------------
0d969553 2575 // Only between neighbor faces.
7fd59977 2576 //--------------------------------
2577 Inter.ConnexIntByArc(OffsetFaces,myShape,myAnalyse,myInitOffsetFace);
2578 }
2579#ifdef DEB
2580 if ( ChronBuild) Clock.Show();
2581#endif
2582}
2583
2584//=======================================================================
2585//function : Intersection2D
2586//purpose :
2587//=======================================================================
2588
2589void BRepOffset_MakeOffset::Intersection2D(const TopTools_MapOfShape& Modif,
2590 const TopTools_MapOfShape& NewEdges)
2591{
2592#ifdef DEB
2593 if (ChronBuild) {
2594 cout << " INTERSECTION 2D:" << endl;
2595 Clock.Reset();
2596 Clock.Start();
2597 }
2598#endif
0d969553
Y
2599 //--------------------------------------------------------
2600 // calculate intersections2d on faces concerned by
7fd59977 2601 // intersection3d
0d969553 2602 //--------------------------------------------------------
7fd59977 2603 TopTools_MapIteratorOfMapOfShape it(Modif);
2604 //-----------------------------------------------
0d969553 2605 // Intersection of edges 2 by 2.
7fd59977 2606 //-----------------------------------------------
2607 for ( it.Initialize(Modif); it.More(); it.Next()) {
2608 const TopoDS_Face& F = TopoDS::Face(it.Key());
2609 BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol);
2610 }
2611
2612#ifdef DEB
2613 if (AffichInt2d) {
2614 DEBVerticesControl (NewEdges,myAsDes);
2615 }
2616 if ( ChronBuild) Clock.Show();
2617#endif
2618}
2619
2620
2621//=======================================================================
2622//function : MakeLoops
2623//purpose :
2624//=======================================================================
2625
2626void BRepOffset_MakeOffset::MakeLoops(TopTools_MapOfShape& Modif)
2627{
2628#ifdef DEB
2629 if (ChronBuild) {
2630 cout << " DEBOUCLAGE 2D:" << endl;
2631 Clock.Reset();
2632 Clock.Start();
2633 }
2634#endif
2635 TopTools_MapIteratorOfMapOfShape it(Modif);
2636 TopTools_ListOfShape LF,LC;
2637 //-----------------------------------------
0d969553 2638 // unwinding of faces // modified.
7fd59977 2639 //-----------------------------------------
2640 for (; it.More(); it.Next()) {
2641 if (!myFaces.Contains(it.Key())) LF.Append(it.Key());
2642 }
2643 myMakeLoops.Build(LF,myAsDes,myImageOffset);
2644
2645 //-----------------------------------------
0d969553 2646 // unwinding of caps.
7fd59977 2647 //-----------------------------------------
2648 for (it.Initialize(myFaces); it.More(); it.Next()) {
2649 LC.Append(it.Key());
2650 }
2651 Standard_Boolean InSide = 1;
2652 if (myOffset > 0 ) InSide = 0;
2653 myMakeLoops.BuildOnContext(LC,myAnalyse,myAsDes,myImageOffset,InSide);
2654
2655#ifdef DEB
2656 if ( ChronBuild) Clock.Show();
2657#endif
2658}
2659
2660//=======================================================================
2661//function : MakeFaces
0d969553
Y
2662//purpose : Reconstruction of topologically unchanged faces that
2663// share edges that were reconstructed.
7fd59977 2664//=======================================================================
2665
2666void BRepOffset_MakeOffset::MakeFaces(TopTools_MapOfShape& Modif)
2667{
2668#ifdef DEb
2669 if (ChronBuild) {
0d969553 2670 cout << " RECONSTRUCTION OF FACES:" << endl;
7fd59977 2671 Clock.Reset();
2672 Clock.Start();
2673 }
2674#endif
2675 TopTools_ListIteratorOfListOfShape itr;
2676 const TopTools_ListOfShape& Roots = myInitOffsetFace.Roots();
2677 TopTools_ListOfShape LOF;
2678 //----------------------------------
0d969553 2679 // Loop on all faces //.
7fd59977 2680 //----------------------------------
2681 for (itr.Initialize(Roots); itr.More(); itr.Next()) {
2682 TopoDS_Face F = TopoDS::Face(myInitOffsetFace.Image(itr.Value()).First());
2683 LOF.Append(F);
2684 }
2685 myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
2686
2687#ifdef DEB
2688 if ( ChronBuild) Clock.Show();
2689#endif
2690}
2691
2692//=======================================================================
2693//function : UpdateInitOffset
0d969553 2694//purpose : Update and cleaning of myInitOffset
7fd59977 2695//=======================================================================
2696
2697static void UpdateInitOffset (BRepAlgo_Image& myInitOffset,
2698 BRepAlgo_Image& myImageOffset,
2699 const TopoDS_Shape& myOffsetShape,
2700 const TopAbs_ShapeEnum &theShapeType) // skv
2701{
2702 BRepAlgo_Image NIOF;
2703 const TopTools_ListOfShape& Roots = myInitOffset.Roots();
2704 TopTools_ListIteratorOfListOfShape it(Roots);
2705 for (; it.More(); it.Next()) {
2706 NIOF.SetRoot (it.Value());
2707 }
2708 for (it.Initialize(Roots); it.More(); it.Next()) {
2709 const TopoDS_Shape& SI = it.Value();
2710 TopTools_ListOfShape LI;
2711 TopTools_ListOfShape L1;
2712 myInitOffset.LastImage(SI,L1);
2713 TopTools_ListIteratorOfListOfShape itL1(L1);
2714 for (; itL1.More(); itL1.Next()) {
2715 const TopoDS_Shape& O1 = itL1.Value();
2716 TopTools_ListOfShape L2;
2717 myImageOffset.LastImage(O1,L2);
2718 LI.Append(L2);
2719 }
2720 NIOF.Bind(SI,LI);
2721 }
2722// Modified by skv - Mon Apr 4 18:17:27 2005 Begin
2723// Supporting history.
2724// NIOF.Filter(myOffsetShape,TopAbs_FACE);
2725 NIOF.Filter(myOffsetShape, theShapeType);
2726// Modified by skv - Mon Apr 4 18:17:27 2005 End
2727 myInitOffset = NIOF;
2728}
2729
2730//=======================================================================
2731//function : MakeMissingWalls
2732//purpose :
2733//=======================================================================
2734
2735void BRepOffset_MakeOffset::MakeMissingWalls ()
2736{
2737 TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
2738 TopTools_DataMapOfShapeShape MapEF; //Edges of contours: edge + face
2739 Standard_Real OffsetVal = Abs(myOffset);
2740
2741 FillContours(myShape, myAnalyse, Contours, MapEF);
2742
2743 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(Contours);
2744 for (; iter.More(); iter.Next())
2745 {
2746 TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key());
2747 TopoDS_Edge StartEdge;
2748 const TopTools_ListOfShape& aContour = iter.Value();
2749 TopTools_ListIteratorOfListOfShape itl(aContour);
2750 Standard_Boolean FirstStep = Standard_True;
2751 TopoDS_Edge PrevEdge;
2752 TopoDS_Vertex PrevVertex = StartVertex;
2753 for (; itl.More(); itl.Next())
2754 {
2755 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
2756 if (!myInitOffsetEdge.HasImage(anEdge))
2757 continue;
2758 //if (BRep_Tool::Degenerated(anEdge))
2759 //continue;
2760 TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
2761 //TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First());
2762 TopTools_ListOfShape LOE, LOE2;
2763 myInitOffsetEdge.LastImage( anEdge, LOE );
2764 myImageOffset.LastImage( LOE.Last(), LOE2 );
2765 TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
2766 ////////////////////////////////////////////////////////////////////////
2767 TopoDS_Vertex V1, V2, V3, V4;
2768 TopExp::Vertices(anEdge, V1, V2/*, Standard_True*/);
2769 TopExp::Vertices(OE, V4, V3/*, Standard_True*/);
2770 Standard_Boolean ToReverse = Standard_False;
2771 if (!V1.IsSame(PrevVertex))
2772 {
2773 TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx;
2774 aVtx = V3; V3 = V4; V4 = aVtx;
2775 ToReverse = Standard_True;
2776 }
2777 //Temporary
2778 //anEdge.Reverse();
2779 OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
2780 TopoDS_Edge E3, E4;
2781 if (FirstStep)
2782 {
2783 E4 = BRepLib_MakeEdge( V1, V4 );
2784 StartEdge = E4;
2785 }
2786 else
2787 E4 = PrevEdge;
2788 Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
2789 if (V2.IsSame(StartVertex) && !ArcOnV2)
2790 E3 = StartEdge;
2791 else
2792 E3 = BRepLib_MakeEdge( V2, V3 );
2793 E4.Reverse();
2794 TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
2795 const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
2796 Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
2797 Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD);
2798 BRep_Builder BB;
2799 TopoDS_Wire theWire;
2800 BB.MakeWire(theWire);
2801 if (ToReverse)
2802 {
2803 BB.Add(theWire, anEdge.Reversed());
2804 BB.Add(theWire, E3.Reversed());
2805 BB.Add(theWire, OE.Reversed());
2806 BB.Add(theWire, E4.Reversed());
2807 }
2808 else
2809 {
2810 BB.Add(theWire, anEdge);
2811 BB.Add(theWire, E3);
2812 BB.Add(theWire, OE);
2813 BB.Add(theWire, E4);
2814 }
2815 BRepLib::BuildCurves3d( theWire, myTol );
2816 theWire.Closed(Standard_True);
2817 TopoDS_Face NewFace;
2818 Handle(Geom_Surface) theSurf;
2819 BRepAdaptor_Curve BAcurve(anEdge);
2820 BRepAdaptor_Curve BAcurveOE(OE);
2821 Standard_Real fpar = BAcurve.FirstParameter();
2822 Standard_Real lpar = BAcurve.LastParameter();
2823 gp_Pnt PonE = BAcurve.Value(fpar);
2824 gp_Pnt PonOE = BAcurveOE.Value(fpar);
2825 gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE );
2826 Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
2827 Standard_Boolean IsPlanar = Standard_False;
2828 if (BAcurve.GetType() == GeomAbs_Circle &&
2829 BAcurveOE.GetType() == GeomAbs_Circle)
2830 {
2831 gp_Circ aCirc = BAcurve.Circle();
2832 gp_Dir CircAxisDir = aCirc.Axis().Direction();
2833 if (OffsetDir.IsParallel( CircAxisDir, Precision::Confusion() )) //case of cylinder
2834 theSurf = GC_MakeCylindricalSurface(aCirc).Value();
2835 else if (Abs(OffsetDir * CircAxisDir) > Precision::PConfusion()) //case of cone
2836 {
2837 gp_Circ aCircOE = BAcurveOE.Circle();
2838 gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(),
2839 aCirc.Radius(), aCircOE.Radius());
2840 gp_Ax3 theAx3(aCirc.Position());
2841 if (CircAxisDir * theCone.Axis().Direction() < 0.)
2842 {
2843 theAx3.ZReverse();
2844 CircAxisDir.Reverse();
2845 }
2846 theCone.SetPosition(theAx3);
2847 theSurf = new Geom_ConicalSurface(theCone);
2848 }
2849 if (!theSurf.IsNull())
2850 {
2851 TopLoc_Location Loc;
2852 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.));
2853 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2854 Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.;
2855 OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.));
2856 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2857 aLine2d = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff));
2858 aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff));
2859 if (E3.IsSame(E4))
2860 {
2861 if (Coeff > 0.)
2862 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2863 else
2864 {
2865 BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion());
2866 theWire.Nullify();
2867 BB.MakeWire(theWire);
2868 BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED));
2869 BB.Add(theWire, E4);
2870 BB.Add(theWire, OE.Oriented(TopAbs_FORWARD));
2871 BB.Add(theWire, E3);
2872 theWire.Closed(Standard_True);
2873 }
2874 }
2875 else
2876 {
2877 BB.SameParameter(E3, Standard_False);
2878 BB.SameRange(E3, Standard_False);
2879 BB.SameParameter(E4, Standard_False);
2880 BB.SameRange(E4, Standard_False);
2881 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
2882 BB.Range(E3, theSurf, Loc, 0., OffsetVal);
2883 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2884 BB.Range(E4, theSurf, Loc, 0., OffsetVal);
2885 }
2886 NewFace = BRepLib_MakeFace(theSurf, theWire);
2887 }
2888 }
2889 if (NewFace.IsNull())
2890 {
2891 BRepLib_MakeFace MF(theWire, Standard_True); //Only plane
2892 if (MF.Error() == BRepLib_FaceDone)
2893 {
2894 NewFace = MF.Face();
2895 IsPlanar = Standard_True;
2896 }
2897 else //Extrusion (by thrusections)
2898 {
2899 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
2900 Handle(Geom_TrimmedCurve) TrEdgeCurve =
2901 new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
2902 Standard_Real fparOE, lparOE;
2903 Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE);
2904 Handle(Geom_TrimmedCurve) TrOffsetCurve =
2905 new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
2906 GeomFill_Generator ThrusecGenerator;
2907 ThrusecGenerator.AddCurve( TrEdgeCurve );
2908 ThrusecGenerator.AddCurve( TrOffsetCurve );
2909 ThrusecGenerator.Perform( Precision::PConfusion() );
2910 theSurf = ThrusecGenerator.Surface();
2911 //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
2912 Standard_Real Uf, Ul, Vf, Vl;
2913 theSurf->Bounds(Uf, Ul, Vf, Vl);
2914 TopLoc_Location Loc;
2915 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
2916 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2917 OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
2918 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2919 Standard_Real UonV1 = (ToReverse)? Ul : Uf;
2920 Standard_Real UonV2 = (ToReverse)? Uf : Ul;
2921 aLine2d = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
2922 aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
2923 if (E3.IsSame(E4))
2924 {
2925 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2926 Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
2927 BB.UpdateEdge(E3, BSplC34, Precision::Confusion());
2928 BB.Range(E3, Vf, Vl);
2929 }
2930 else
2931 {
2932 BB.SameParameter(E3, Standard_False);
2933 BB.SameRange(E3, Standard_False);
2934 BB.SameParameter(E4, Standard_False);
2935 BB.SameRange(E4, Standard_False);
2936 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
2937 BB.Range(E3, theSurf, Loc, Vf, Vl);
2938 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2939 BB.Range(E4, theSurf, Loc, Vf, Vl);
2940 Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
2941 BB.UpdateEdge(E3, BSplC3, Precision::Confusion());
2942 BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve
2943 Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
2944 BB.UpdateEdge(E4, BSplC4, Precision::Confusion());
2945 BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve
2946 }
2947 NewFace = BRepLib_MakeFace(theSurf, theWire);
2948 }
2949 }
2950 if (!IsPlanar)
2951 {
2952 Standard_Real fparOE = BAcurveOE.FirstParameter();
2953 Standard_Real lparOE = BAcurveOE.LastParameter();
2954 TopLoc_Location Loc;
2955 if (Abs(fpar - fparOE) > Precision::Confusion())
2956 {
2957 const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4;
2958 gp_Pnt2d fp2d = EdgeLine2d->Value(fpar);
2959 gp_Pnt2d fp2dOE = OELine2d->Value(fparOE);
2960 aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value();
2961 Handle(Geom_Curve) aCurve;
2962 Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE);
2963 Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar );
2964 GeomAdaptor_Surface GAsurf( theSurf );
2965 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
2966 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
2967 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
2968 Standard_Real max_deviation = 0., average_deviation;
2969 GeomLib::BuildCurve3d(Precision::Confusion(),
2970 ConS, FirstPar, LastPar,
2971 aCurve, max_deviation, average_deviation);
2972 BB.UpdateEdge( anE4, aCurve, max_deviation );
2973 BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation );
2974 BB.Range( anE4, FirstPar, LastPar );
2975 }
2976 if (Abs(lpar - lparOE) > Precision::Confusion())
2977 {
2978 const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3;
2979 gp_Pnt2d lp2d = EdgeLine2d->Value(lpar);
2980 gp_Pnt2d lp2dOE = OELine2d->Value(lparOE);
2981 aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value();
2982 Handle(Geom_Curve) aCurve;
2983 Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE);
2984 Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar );
2985 GeomAdaptor_Surface GAsurf( theSurf );
2986 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
2987 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
2988 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
2989 Standard_Real max_deviation = 0., average_deviation;
2990 GeomLib::BuildCurve3d(Precision::Confusion(),
2991 ConS, FirstPar, LastPar,
2992 aCurve, max_deviation, average_deviation);
2993 BB.UpdateEdge( anE3, aCurve, max_deviation );
2994 BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation );
2995 BB.Range( anE3, FirstPar, LastPar );
2996 }
2997 }
2998 BRepLib::SameParameter(NewFace);
2999 BRepTools::Update(NewFace);
3000 myWalls.Append(NewFace);
3001 if (ArcOnV2)
3002 {
3003 TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First());
3004 TopoDS_Vertex arcV1, arcV2;
3005 TopExp::Vertices(anArc, arcV1, arcV2);
3006 Standard_Boolean ArcReverse = Standard_False;
3007 if (!arcV1.IsSame(V3))
3008 {
3009 TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx;
3010 ArcReverse = Standard_True;
3011 }
3012 TopoDS_Edge EA1, EA2;
3013 //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed());
3014 EA1 = E3;
3015 EA1.Reverse();
3016 if (ToReverse)
3017 EA1.Reverse();
3018 //////////////////////////////////////////////////////
3019 if (V2.IsSame(StartVertex))
3020 EA2 = StartEdge;
3021 else
3022 EA2 = BRepLib_MakeEdge( V2, arcV2 );
3023 anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) );
3024 if (EA1.Orientation() == TopAbs_REVERSED)
3025 anArc.Reverse();
3026 EA2.Orientation(TopAbs::Reverse(EA1.Orientation()));
3027 TopoDS_Wire arcWire;
3028 BB.MakeWire(arcWire);
3029 BB.Add(arcWire, EA1);
3030 BB.Add(arcWire, anArc);
3031 BB.Add(arcWire, EA2);
3032 BRepLib::BuildCurves3d( arcWire, myTol );
3033 arcWire.Closed(Standard_True);
3034 TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True);
3035 BRepTools::Update(arcFace);
3036 myWalls.Append(arcFace);
3037 TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD);
3038 const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2);
3039 PrevEdge = CEA2;
3040 PrevVertex = V2;
3041 }
3042 else
3043 {
3044 PrevEdge = E3;
3045 PrevVertex = V2;
3046 }
3047 FirstStep = Standard_False;
3048 }
3049 }
3050}
3051
3052//=======================================================================
3053//function : MakeShells
3054//purpose :
3055//=======================================================================
3056
3057void BRepOffset_MakeOffset::MakeShells ()
3058{
3059#ifdef DEB
3060 if (ChronBuild) {
0d969553 3061 cout << " RECONSTRUCTION OF SHELLS:" << endl;
7fd59977 3062 Clock.Reset();
3063 Clock.Start();
3064 }
3065#endif
3066 BRepTools_Quilt Glue;
3067 const TopTools_ListOfShape& R = myImageOffset.Roots();
3068 TopTools_ListIteratorOfListOfShape it(R);
3069
3070 for ( ; it.More(); it.Next()) {
3071 TopTools_ListOfShape Image;
3072 myImageOffset.LastImage(it.Value(),Image);
3073 TopTools_ListIteratorOfListOfShape it2(Image);
3074 for ( ; it2.More(); it2.Next()) {
3075 Glue.Add(it2.Value());
3076 }
3077 }
3078
3079 if (myThickening)
3080 {
3081 TopExp_Explorer Explo(myShape, TopAbs_FACE);
3082 for (; Explo.More(); Explo.Next())
3083 Glue.Add(Explo.Current());
3084
3085 for (it.Initialize(myWalls); it.More(); it.Next())
3086 Glue.Add(it.Value());
3087 }
3088
3089 myOffsetShape = Glue.Shells();
3090}
3091
3092//=======================================================================
3093//function : MakeSolid
3094//purpose :
3095//=======================================================================
3096
3097void BRepOffset_MakeOffset::MakeSolid ()
3098{
3099 if (myOffsetShape.IsNull()) return;
3100
3101// Modified by skv - Mon Apr 4 18:17:27 2005 Begin
3102// Supporting history.
3103 UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE);
3104 UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE);
3105// Modified by skv - Mon Apr 4 18:17:27 2005 End
3106 TopExp_Explorer exp;
3107 BRep_Builder B;
3108 Standard_Integer NbShell = 0;
3109 TopoDS_Compound NC;
3110 TopoDS_Shape S1;
3111 B.MakeCompound (NC);
3112
3113 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
3114 TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
3115 if (myThickening && myOffset > 0.)
3116 Sh.Reverse();
3117 NbShell++;
3118 if (Sh.Closed()) {
3119 TopoDS_Solid Sol;
3120 B.MakeSolid (Sol);
3121 B.Add (Sol,Sh);
3122 Sol.Closed(Standard_True);
3123 B.Add (NC,Sol);
3124 if (NbShell == 1) S1 = Sol;
3125 }
3126 else {
3127 B.Add (NC,Sh);
3128 if (NbShell == 1) S1 = Sh;
3129 }
3130 }
3131 if (NbShell == 1) myOffsetShape = S1;
3132 else myOffsetShape = NC;
3133}
3134
3135//=======================================================================
3136//function : SelectShells
3137//purpose :
3138//=======================================================================
3139
3140void BRepOffset_MakeOffset::SelectShells ()
3141{
3142 TopTools_MapOfShape FreeEdges;
3143 TopExp_Explorer exp(myShape,TopAbs_EDGE);
3144 //-------------------------------------------------------------
0d969553
Y
3145 // FreeEdges all edges that can have free border in the
3146 // parallel shell
3147 // 1 - free borders of myShape .
7fd59977 3148 //-------------------------------------------------------------
3149 for ( ; exp.More(); exp.Next()) {
3150 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3151 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
3152 if (LA.Extent() < 2) {
3153 if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
3154 FreeEdges.Add(E);
3155 }
3156 }
3157 }
0d969553
Y
3158 // myShape has free borders and there are no caps
3159 // no unwinding 3d.
7fd59977 3160 if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return;
3161
3162 myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges);
3163}
3164
3165//=======================================================================
3166//function : OffsetFacesFromShapes
3167//purpose :
3168//=======================================================================
3169
3170const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
3171{
3172 return myInitOffsetFace;
3173}
3174
3175// Modified by skv - Tue Mar 15 16:20:43 2005 Begin
3176
3177//=======================================================================
3178//function : GetJoinType
3179//purpose : Query offset join type.
3180//=======================================================================
3181
3182GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
3183{
3184 return myJoin;
3185}
3186
3187//=======================================================================
3188//function : OffsetEdgesFromShapes
3189//purpose :
3190//=======================================================================
3191
3192const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
3193{
3194 return myInitOffsetEdge;
3195}
3196
3197// Modified by skv - Tue Mar 15 16:20:43 2005 End
3198
3199//=======================================================================
3200//function : ClosingFaces
3201//purpose :
3202//=======================================================================
3203
3204const TopTools_MapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
3205{
3206 return myFaces;
3207}
3208
3209
3210
3211//=======================================================================
3212//function : EncodeRegularity
3213//purpose :
3214//=======================================================================
3215
3216void BRepOffset_MakeOffset::EncodeRegularity ()
3217{
3218#ifdef DEB
3219 if (ChronBuild) {
0d969553 3220 cout << " CODING OF REGULARITIES:" << endl;
7fd59977 3221 Clock.Reset();
3222 Clock.Start();
3223 }
3224#endif
3225
3226 if (myOffsetShape.IsNull()) return;
0d969553 3227 // find edges G1 in the result
7fd59977 3228 TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE);
3229
3230 BRep_Builder B;
3231 TopTools_MapOfShape MS;
3232
3233 for ( ; exp.More(); exp.Next()) {
3234 TopoDS_Edge OE = TopoDS::Edge(exp.Current());
3235 BRepLib::BuildCurve3d(OE,myTol);
3236 TopoDS_Edge ROE = OE;
3237
3238 if ( !MS.Add(OE)) continue;
3239
3240 if ( myImageOffset.IsImage(OE))
3241 ROE = TopoDS::Edge(myImageOffset.Root(OE));
3242
3243 const TopTools_ListOfShape& LofOF = myAsDes->Ascendant(ROE);
3244
3245 if (LofOF.Extent() != 2) {
3246#ifdef DEB
3247 if ( Standard_False)
0d969553 3248 cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl;
7fd59977 3249#endif
3250 continue;
3251 }
3252
3253 const TopoDS_Face& F1 = TopoDS::Face(LofOF.First());
3254 const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() );
3255
3256 if ( F1.IsNull() || F2.IsNull())
3257 continue;
3258
3259 const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1);
3260 const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2);
3261
3262 TopAbs_ShapeEnum Type1 = Root1.ShapeType();
3263 TopAbs_ShapeEnum Type2 = Root2.ShapeType();
3264
3265 if (F1.IsSame(F2)) {
3266 if (BRep_Tool::IsClosed(OE,F1)) {
0d969553
Y
3267 // Temporary Debug for the Bench.
3268 // Check with YFR.
3269 // In mode intersection, the edges are not coded in myInitOffsetEdge
3270 // so, manage case by case
3271 // Note DUB; for Hidden parts, it is NECESSARY to code CN
3272 // Analytic Surfaces.
7fd59977 3273 if (myJoin == GeomAbs_Intersection) {
3274 BRepAdaptor_Surface BS(F1,Standard_False);
3275 GeomAbs_SurfaceType SType = BS.GetType();
3276 if (SType == GeomAbs_Cylinder ||
3277 SType == GeomAbs_Cone ||
3278 SType == GeomAbs_Sphere ||
3279 SType == GeomAbs_Torus ) {
3280 B.Continuity(OE,F1,F1,GeomAbs_CN);
3281 }
3282 else {
0d969553 3283 // See YFR : MaJ of myInitOffsetFace
7fd59977 3284 }
3285 }
3286 else if (myInitOffsetEdge.IsImage(ROE)) {
3287 if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
3288 const TopoDS_Face& FRoot = TopoDS::Face(Root1);
3289 const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE));
3290 GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot);
3291 if (Conti == GeomAbs_CN) {
3292 B.Continuity(OE,F1,F1,GeomAbs_CN);
3293 }
3294 else if ( Conti > GeomAbs_C0) {
3295 B.Continuity(OE,F1,F1,GeomAbs_G1);
3296 }
3297 }
3298 }
3299 }
3300 continue;
3301 }
3302
3303
0d969553
Y
3304 // code regularities G1 between :
3305 // - sphere and tube : one root is a vertex, the other is an edge
3306 // and the vertex is included in the edge
3307 // - face and tube : one root is a face, the other an edge
3308 // and the edge is included in the face
3309 // - face and face : if two root faces are tangent in
3310 // the initial shape, they will be tangent in the offset shape
3311 // - tube and tube : if 2 edges generating tubes are
3312 // tangents, the 2 will be tangent either.
7fd59977 3313 if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) {
3314 TopoDS_Vertex V1,V2;
3315 TopExp::Vertices(TopoDS::Edge(Root1), V1, V2);
3316 if ( V1.IsSame(Root2) || V2.IsSame(Root2)) {
3317 B.Continuity(OE,F1,F2,GeomAbs_G1);
3318 }
3319 }
3320 else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) {
3321 TopoDS_Vertex V1,V2;
3322 TopExp::Vertices(TopoDS::Edge(Root2), V1, V2);
3323 if ( V1.IsSame(Root1) || V2.IsSame(Root1)) {
3324 B.Continuity(OE,F1,F2,GeomAbs_G1);
3325 }
3326 }
3327 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) {
3328 TopExp_Explorer exp2(Root1,TopAbs_EDGE);
3329 for ( ; exp2.More(); exp2.Next()) {
3330 if ( exp2.Current().IsSame(Root2)) {
3331 B.Continuity(OE,F1,F2,GeomAbs_G1);
3332 break;
3333 }
3334 }
3335 }
3336 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) {
3337 TopExp_Explorer exp2(Root2,TopAbs_EDGE);
3338 for ( ; exp2.More(); exp2.Next()) {
3339 if ( exp2.Current().IsSame(Root1)) {
3340 B.Continuity(OE,F1,F2,GeomAbs_G1);
3341 break;
3342 }
3343 }
3344 }
3345 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
0d969553
Y
3346 // if two root faces are tangent in
3347 // the initial shape, they will be tangent in the offset shape
7fd59977 3348 TopTools_ListOfShape LE,LV;
3349 BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1),
3350 TopoDS::Face(Root2),
3351 LE,LV);
3352 if ( LE.Extent() == 1) {
3353 const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
3354 if ( myAnalyse.HasAncestor(Ed)) {
3355 const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
3356 if (LI.Extent() == 1 &&
3357 LI.First().Type() == BRepOffset_Tangent) {
3358 B.Continuity(OE,F1,F2,GeomAbs_G1);
3359 }
3360 }
3361 }
3362 }
3363 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) {
3364 TopTools_ListOfShape LV;
3365 TopExp_Explorer exp1,exp2;
3366 for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
3367 TopExp_Explorer exp2(F2,TopAbs_EDGE);
3368 for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
3369 if (exp1.Current().IsSame(exp2.Current())) {
3370 LV.Append(exp1.Current());
3371 }
3372 }
3373 }
3374 if ( LV.Extent() == 1) {
3375 TopTools_ListOfShape LEdTg;
3376 myAnalyse.TangentEdges(TopoDS::Edge(Root1),
3377 TopoDS::Vertex(LV.First()),
3378 LEdTg);
3379 TopTools_ListIteratorOfListOfShape it(LEdTg);
3380 for (; it.More(); it.Next()) {
3381 if ( it.Value().IsSame(Root2)) {
3382 B.Continuity(OE,F1,F2,GeomAbs_G1);
3383 break;
3384 }
3385 }
3386 }
3387 }
3388 }
3389
3390#ifdef DEB
3391 if ( ChronBuild) Clock.Show();
3392#endif
3393}
3394
3395
3396
3397//=======================================================================
3398//function : UpDateTolerance
3399//purpose :
3400//=======================================================================
3401
3402static void UpdateTolerance (TopoDS_Shape& S,
3403 const TopTools_MapOfShape& Faces)
3404{
3405 BRep_Builder B;
3406 TopTools_MapOfShape View;
3407 TopoDS_Vertex V[2];
3408
0d969553 3409 // The edges of caps are not modified.
7fd59977 3410 TopTools_MapIteratorOfMapOfShape it;
3411 for (it.Initialize(Faces); it.More(); it.Next()) {
3412 const TopoDS_Shape& F = it.Key();
3413 TopExp_Explorer Exp;
3414 for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
3415 View.Add(Exp.Current());
3416 }
3417 }
3418
3419 TopExp_Explorer Exp;
3420 for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) {
3421 TopoDS_Edge E = TopoDS::Edge(Exp.Current());
3422 if (View.Add(E)) {
3423 Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E);
3424 Standard_Real Tol = EdgeCorrector->Tolerance();
3425 B.UpdateEdge (E,Tol);
3426
3427 // Update the vertices.
3428 TopExp::Vertices(E,V[0],V[1]);
3429
3430 for (Standard_Integer i = 0 ; i <=1 ; i++) {
3431 if (View.Add(V[i])) {
3432 Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape());
3433 TV->Tolerance(0.);
3434 Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]);
3435 B.UpdateVertex (V[i],VertexCorrector->Tolerance());
0d969553 3436 // use the occasion to clean the vertices.
7fd59977 3437 (TV->ChangePoints()).Clear();
3438 }
3439 B.UpdateVertex(V[i],Tol);
3440 }
3441 }
3442 }
3443}
3444