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