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