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