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