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