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