0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[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>
9b7f3f83 115//
9b7f3f83 116#include <BOPAlgo_MakerVolume.hxx>
9b7f3f83 117#include <BOPTools_AlgoTools.hxx>
ecf4f17c 118#include <BOPCol_ListOfShape.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());
162 cout <<"Vertex on at least 3 edges."<<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) {
171 cout <<"Vertex on more than 3 edges."<<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++;
0d969553 238 cout <<" distmin between VP : "<<distmin<<endl;
7fd59977 239 }
240}
241#endif
242
9b7f3f83 243
244//=======================================================================
245// static methods
246//=======================================================================
ecf4f17c 247static
248 void GetEnlargedFaces(const TopoDS_Shape& theShape,
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
256 Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
257 const BOPCol_IndexedDataMapOfShapeListOfShape& theOrigins,
258 BRepAlgo_Image& theImage,
259 TopoDS_Shape& theShells);
9b7f3f83 260
ecf4f17c 261static
262 Standard_Boolean GetSubShapes(const TopoDS_Shape& theShape,
263 const TopAbs_ShapeEnum theSSType,
264 TopoDS_Shape& theResult);
9b7f3f83 265
9b7f3f83 266static
267 void UpdateInitOffset(BRepAlgo_Image& myInitOffset,
268 BRepAlgo_Image& myImageOffset,
269 const TopoDS_Shape& myOffsetShape,
270 const TopAbs_ShapeEnum &theShapeType);
271
272static
273 void RemoveShapes(TopoDS_Shape& theS,
274 const TopTools_ListOfShape& theLS);
275
276static
277 Standard_Boolean IsSolid(const TopoDS_Shape& theS);
278
279static
280 void UpdateHistory(const TopTools_ListOfShape& theLF,
281 BOPAlgo_Builder& theGF,
282 BRepAlgo_Image& theImage);
283
284static
285 Standard_Boolean IsPlanar(const TopoDS_Shape& theS);
286
ecf4f17c 287static
288 void TrimEdge(TopoDS_Edge& NE,
289 const Handle(BRepAlgo_AsDes)& AsDes2d,
290 Handle(BRepAlgo_AsDes)& AsDes,
291 TopTools_DataMapOfShapeShape& theETrimEInf);
292
293static
294 void TrimEdges(const TopoDS_Shape& theShape,
295 const Standard_Real theOffset,
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);
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//---------------------------------------------------------------------
324//
7fd59977 325static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
9b7f3f83 326 const TopoDS_Edge& E,
327 Standard_Real& U)
7fd59977 328{
329 // Search the vertex in the edge
330
331 Standard_Boolean rev = Standard_False;
332 TopoDS_Shape VF;
333 TopAbs_Orientation orient = TopAbs_INTERNAL;
334
335 TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
336
337 // if the edge has no vertices
338 // and is degenerated use the vertex orientation
339 // RLE, june 94
340
341 if (!itv.More() && BRep_Tool::Degenerated(E)) {
342 orient = V.Orientation();
343 }
344
345 while (itv.More()) {
346 const TopoDS_Shape& Vcur = itv.Value();
347 if (V.IsSame(Vcur)) {
348 if (VF.IsNull()) {
9b7f3f83 349 VF = Vcur;
7fd59977 350 }
351 else {
9b7f3f83 352 rev = E.Orientation() == TopAbs_REVERSED;
353 if (Vcur.Orientation() == V.Orientation()) {
354 VF = Vcur;
355 }
7fd59977 356 }
357 }
358 itv.Next();
359 }
360
361 if (!VF.IsNull()) orient = VF.Orientation();
362
363 Standard_Real f,l;
364
365 if (orient == TopAbs_FORWARD) {
366 BRep_Tool::Range(E,f,l);
367 //return (rev) ? l : f;
368 U = (rev) ? l : f;
369 return Standard_True;
370 }
371
372 else if (orient == TopAbs_REVERSED) {
373 BRep_Tool::Range(E,f,l);
374 //return (rev) ? f : l;
375 U = (rev) ? f : l;
376 return Standard_True;
377 }
378
379 else {
380 TopLoc_Location L;
381 const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
382 L = L.Predivided(V.Location());
383 if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
384 BRep_ListIteratorOfListOfPointRepresentation itpr
9b7f3f83 385 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
7fd59977 386
387 while (itpr.More()) {
9b7f3f83 388 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
389 if (pr->IsPointOnCurve(C,L)) {
390 Standard_Real p = pr->Parameter();
391 Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
392 if (!C.IsNull()) {
393 // Closed curves RLE 16 june 94
394 if (Precision::IsNegativeInfinite(f))
395 {
396 //return pr->Parameter();//p;
397 U = pr->Parameter();
398 return Standard_True;
399 }
400 if (Precision::IsPositiveInfinite(l))
401 {
402 //return pr->Parameter();//p;
403 U = pr->Parameter();
404 return Standard_True;
405 }
406 gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
407 gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
408 Standard_Real tol = BRep_Tool::Tolerance(V);
409 if (Pf.Distance(Pl) < tol) {
410 if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
411 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
412 else res = l;//p = l;
413 }
414 }
415 }
416 //return res;//p;
417 U = res;
418 return Standard_True;
419 }
420 itpr.Next();
7fd59977 421 }
422 }
423 else {
424 // no 3d curve !!
425 // let us try with the first pcurve
426 Handle(Geom2d_Curve) PC;
427 Handle(Geom_Surface) S;
428 BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
429 L = L.Predivided(V.Location());
430 BRep_ListIteratorOfListOfPointRepresentation itpr
9b7f3f83 431 ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
7fd59977 432
433 while (itpr.More()) {
9b7f3f83 434 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
435 if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
436 Standard_Real p = pr->Parameter();
437 // Closed curves RLE 16 june 94
438 if (PC->IsClosed()) {
439 if ((p == PC->FirstParameter()) ||
440 (p == PC->LastParameter())) {
441 if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
442 else p = PC->LastParameter();
443 }
444 }
445 //return p;
446 U = p;
447 return Standard_True;
448 }
449 itpr.Next();
7fd59977 450 }
451 }
452 }
453
9775fa61 454 //throw Standard_NoSuchObject("BRep_Tool:: no parameter on edge");
7fd59977 455 return Standard_False;
456}
457
458//=======================================================================
459//function : GetEdgePoints
460//purpose : gets the first, last and middle points of the edge
461//=======================================================================
462static void GetEdgePoints(const TopoDS_Edge& anEdge,
463 const TopoDS_Face& aFace,
464 gp_Pnt& fPnt, gp_Pnt& mPnt,
465 gp_Pnt& lPnt)
466{
467 Standard_Real f, l;
468 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l );
469 gp_Pnt2d fPnt2d = theCurve->Value(f);
470 gp_Pnt2d lPnt2d = theCurve->Value(l);
471 gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l));
472 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
473 fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y());
474 lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y());
475 mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y());
476}
477
478//=======================================================================
479//function : FillContours
480//purpose : fills free boundary contours and faces connected (MapEF)
481//=======================================================================
482static void FillContours(const TopoDS_Shape& aShape,
9b7f3f83 483 const BRepOffset_Analyse& Analyser,
484 TopTools_DataMapOfShapeListOfShape& Contours,
485 TopTools_DataMapOfShapeShape& MapEF)
7fd59977 486{
487 TopTools_ListOfShape Edges;
488
489 TopExp_Explorer Explo(aShape, TopAbs_FACE);
490 BRepTools_WireExplorer Wexp;
491
492 for (; Explo.More(); Explo.Next())
493 {
494 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
495 TopoDS_Iterator itf(aFace);
496 for (; itf.More(); itf.Next())
9b7f3f83 497 {
498 TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
499 for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
500 {
501 TopoDS_Edge anEdge = Wexp.Current();
502 if (BRep_Tool::Degenerated(anEdge))
503 continue;
504 const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
505 if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary)
506 {
507 MapEF.Bind(anEdge, aFace);
508 Edges.Append(anEdge);
509 }
510 }
511 }
7fd59977 512 }
513
514 TopTools_ListIteratorOfListOfShape itl;
515 while (!Edges.IsEmpty())
516 {
517 TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First());
518 Edges.RemoveFirst();
519 TopoDS_Vertex StartVertex, CurVertex;
520 TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True);
521 TopTools_ListOfShape aContour;
522 aContour.Append(StartEdge);
523 while (!CurVertex.IsSame(StartVertex))
9b7f3f83 524 for (itl.Initialize(Edges); itl.More(); itl.Next())
525 {
526 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
527 TopoDS_Vertex V1, V2;
528 TopExp::Vertices(anEdge, V1, V2);
529 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
530 {
531 aContour.Append(anEdge);
532 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
533 Edges.Remove(itl);
534 break;
535 }
536 }
7fd59977 537 Contours.Bind(StartVertex, aContour);
538 }
539}
540
db2f1498 541//
542//-----------------------------------------------------------------------
543//
7fd59977 544//=======================================================================
545//function : BRepOffset_MakeOffset
546//purpose :
547//=======================================================================
548
549BRepOffset_MakeOffset::BRepOffset_MakeOffset()
550{
551 myAsDes = new BRepAlgo_AsDes();
552}
553
554
555//=======================================================================
556//function : BRepOffset_MakeOffset
557//purpose :
558//=======================================================================
559
560BRepOffset_MakeOffset::BRepOffset_MakeOffset(const TopoDS_Shape& S,
9b7f3f83 561 const Standard_Real Offset,
562 const Standard_Real Tol,
563 const BRepOffset_Mode Mode,
564 const Standard_Boolean Inter,
565 const Standard_Boolean SelfInter,
566 const GeomAbs_JoinType Join,
567 const Standard_Boolean Thickening,
ecf4f17c 568 const Standard_Boolean RemoveIntEdges)
7fd59977 569:
570myOffset (Offset),
571myTol (Tol),
572myShape (S),
573myMode (Mode),
574myInter (Inter),
575mySelfInter (SelfInter),
576myJoin (Join),
9b7f3f83 577myThickening (Thickening),
578myRemoveIntEdges(RemoveIntEdges),
7fd59977 579myDone (Standard_False)
7fd59977 580{
581 myAsDes = new BRepAlgo_AsDes();
582 MakeOffsetShape();
583}
584
585
586//=======================================================================
587//function : Initialize
588//purpose :
589//=======================================================================
590
591void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S,
9b7f3f83 592 const Standard_Real Offset,
593 const Standard_Real Tol,
594 const BRepOffset_Mode Mode,
595 const Standard_Boolean Inter,
596 const Standard_Boolean SelfInter,
597 const GeomAbs_JoinType Join,
598 const Standard_Boolean Thickening,
ecf4f17c 599 const Standard_Boolean RemoveIntEdges)
7fd59977 600{
601 myOffset = Offset;
602 myShape = S;
603 myTol = Tol;
604 myMode = Mode;
605 myInter = Inter;
606 mySelfInter = SelfInter;
607 myJoin = Join;
9b7f3f83 608 myThickening = Thickening;
609 myRemoveIntEdges = RemoveIntEdges;
7fd59977 610 myDone = Standard_False;
a8704c36 611 myIsPerformSewing = Standard_False;
9b7f3f83 612 myIsPlanar = Standard_False;
7fd59977 613 Clear();
614}
615
616
617//=======================================================================
618//function : Clear
619//purpose :
620//=======================================================================
621
622void BRepOffset_MakeOffset::Clear()
623{
624 myOffsetShape.Nullify();
625 myInitOffsetFace .Clear();
626 myInitOffsetEdge .Clear();
627 myImageOffset .Clear();
628 myFaces .Clear();
629 myFaceOffset .Clear();
630 myAsDes ->Clear();
631 myDone = Standard_False;
632}
633
634//=======================================================================
635//function : AddFace
636//purpose :
637//=======================================================================
638
639void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
640 myFaces.Add(F);
641 //-------------
642 // MAJ SD.
643 //-------------
644 myInitOffsetFace.SetRoot (F) ;
645 myInitOffsetFace.Bind (F,F);
646 myImageOffset.SetRoot (F) ;
647}
648
649//=======================================================================
650//function : SetOffsetOnFace
651//purpose :
652//=======================================================================
653
654void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F,
9b7f3f83 655 const Standard_Real Off)
7fd59977 656{
657 if ( myFaceOffset.IsBound(F)) myFaceOffset.UnBind(F);
658 myFaceOffset.Bind(F,Off);
659}
660
661//=======================================================================
662//function : RemoveCorks
663//purpose :
664//=======================================================================
665
975ec82a 666static void RemoveCorks (TopoDS_Shape& S,
9b7f3f83 667 TopTools_IndexedMapOfShape& Faces)
7fd59977 668{
669 TopoDS_Compound SS;
670 BRep_Builder B;
671 B.MakeCompound (SS);
672 //-----------------------------------------------------
0d969553
Y
673 // Construction of a shape without caps.
674 // and Orientation of caps as in shape S.
7fd59977 675 //-----------------------------------------------------
676 TopExp_Explorer exp(S,TopAbs_FACE);
677 for (; exp.More(); exp.Next()) {
678 const TopoDS_Shape& Cork = exp.Current();
679 if (!Faces.Contains(Cork)) {
680 B.Add(SS,Cork);
681 }
682 else {
3f5aa017 683 Faces.RemoveKey(Cork);
975ec82a 684 Faces.Add(Cork); // to reset it with proper orientation.
7fd59977 685 }
686 }
687 S = SS;
688#ifdef DRAW
689 if ( AffichOffC)
690 DBRep::Set("myInit", SS);
691#endif
692
693}
694
9b7f3f83 695//=======================================================================
696//function : IsConnectedShell
697//purpose :
698//=======================================================================
7fd59977 699static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
700{
701 BRepTools_Quilt Glue;
702 Glue.Add( S );
703
704 TopoDS_Shape SS = Glue.Shells();
705 TopExp_Explorer Explo( SS, TopAbs_SHELL );
706 Explo.Next();
707 if (Explo.More())
708 return Standard_False;
709
710 return Standard_True;
711}
712
713
714//=======================================================================
715//function : MakeList
716//purpose :
717//=======================================================================
718
975ec82a 719static void MakeList (TopTools_ListOfShape& OffsetFaces,
9b7f3f83 720 const BRepAlgo_Image& myInitOffsetFace,
721 const TopTools_IndexedMapOfShape& myFaces)
7fd59977 722{
723 TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots());
724 for ( ; itLOF.More(); itLOF.Next()) {
725 const TopoDS_Shape& Root = itLOF.Value();
9b7f3f83 726 if (!myFaces.Contains(Root)) {
727 if (myInitOffsetFace.HasImage(Root)) {
edfa30de 728 TopTools_ListIteratorOfListOfShape aItLS(myInitOffsetFace.Image(Root));
729 for (; aItLS.More(); aItLS.Next()) {
730 OffsetFaces.Append(aItLS.Value());
731 }
9b7f3f83 732 }
733 }
7fd59977 734 }
735}
736
737//=======================================================================
738//function : EvalMax
739//purpose :
740//=======================================================================
741
742static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
743{
744 TopExp_Explorer exp;
745 for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
746 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
747 Standard_Real TolV = BRep_Tool::Tolerance(V);
748 if (TolV > Tol) Tol = TolV;
749 }
7fd59977 750}
751
a8704c36 752
7fd59977 753//=======================================================================
754//function : MakeOffsetShape
755//purpose :
756//=======================================================================
757
758void BRepOffset_MakeOffset::MakeOffsetShape()
759{
03383c97 760 myDone = Standard_False;
9b7f3f83 761 //
762 // check if shape consists of only planar faces
763 myIsPlanar = IsPlanar(myShape);
7fd59977 764 //------------------------------------------
0d969553 765 // Construction of myShape without caps.
7fd59977 766 //------------------------------------------
db2f1498 767 if(!myFaces.IsEmpty())
768 {
769 RemoveCorks (myShape,myFaces);
770 }
03383c97 771
e1ed38e0 772 if (!CheckInputData())
03383c97 773 {
e1ed38e0 774 // There is error in input data.
775 // Check Error() method.
776 return;
03383c97 777 }
7fd59977 778
779 TopAbs_State Side = TopAbs_IN;
780 if (myOffset < 0.) Side = TopAbs_OUT;
03383c97 781
7fd59977 782 // ------------
783 // Preanalyse.
784 // ------------
785 EvalMax(myShape,myTol);
a07a0416 786 // There are possible second variant: analytical continuation of arcsin.
03383c97 787 Standard_Real TolAngleCoeff = Min(myTol / (Abs(myOffset * 0.5) + Precision::Confusion()), 1.0);
a07a0416 788 Standard_Real TolAngle = 4*ASin(TolAngleCoeff);
7fd59977 789 myAnalyse.Perform(myShape,TolAngle);
790 //---------------------------------------------------
0d969553 791 // Construction of Offset from preanalysis.
7fd59977 792 //---------------------------------------------------
793 //----------------------------
0d969553 794 // MaJ of SD Face - Offset
7fd59977 795 //----------------------------
796 UpdateFaceOffset();
797
798 if (myJoin == GeomAbs_Arc)
799 BuildOffsetByArc();
800 else if (myJoin == GeomAbs_Intersection)
801 BuildOffsetByInter();
802 //-----------------
0d969553 803 // Auto unwinding.
7fd59977 804 //-----------------
805 // if (mySelfInter) SelfInter(Modif);
806 //-----------------
807 // Intersection 3d .
808 //-----------------
809 BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
810 Intersection3D (Inter);
811 //-----------------
812 // Intersection2D
813 //-----------------
975ec82a
J
814 TopTools_IndexedMapOfShape& Modif = Inter.TouchedFaces();
815 TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
7fd59977 816
817 if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
818 //-------------------------------------------------------
0d969553 819 // Unwinding 2D and reconstruction of modified faces
7fd59977 820 //----------------------------------------------------
821 MakeLoops (Modif);
822 //-----------------------------------------------------
0d969553
Y
823 // Reconstruction of non modified faces sharing
824 // reconstructed edges
7fd59977 825 //------------------------------------------------------
826 if (!Modif.IsEmpty()) MakeFaces (Modif);
827
828 if (myThickening)
829 MakeMissingWalls();
830
831 //-------------------------
0d969553 832 // Construction of shells.
7fd59977 833 //-------------------------
834 MakeShells ();
ecf4f17c 835 if (myOffsetShape.IsNull()) {
836 // not done
837 myDone = Standard_False;
838 return;
839 }
7fd59977 840 //--------------
0d969553 841 // Unwinding 3D.
7fd59977 842 //--------------
843 SelectShells ();
844 //----------------------------------
9b7f3f83 845 // Remove INTERNAL edges if necessary
846 //----------------------------------
847 if (myRemoveIntEdges) {
848 RemoveInternalEdges();
849 }
850 //----------------------------------
0d969553 851 // Coding of regularities.
7fd59977 852 //----------------------------------
853 EncodeRegularity();
854 //----------------------
0d969553 855 // Creation of solids.
7fd59977 856 //----------------------
857 MakeSolid ();
858
859 //-----------------------------
0d969553 860 // MAJ Tolerance edge and Vertex
7fd59977 861 // ----------------------------
862 if (!myOffsetShape.IsNull()) {
863 UpdateTolerance (myOffsetShape,myFaces);
864 BRepLib::UpdateTolerances( myOffsetShape );
865 }
866
867 CorrectConicalFaces();
868
a8704c36 869 // Result solid should be computed in MakeOffset scope.
870 if (myThickening &&
871 myIsPerformSewing)
872 {
873 BRepBuilderAPI_Sewing aSew(myTol);
874 aSew.Add(myOffsetShape);
875 aSew.Perform();
876 myOffsetShape = aSew.SewedShape();
877
878 // Rebuild solid.
879 // Offset shape expected to be really closed after sewing.
880 myOffsetShape.Closed(Standard_True);
881 MakeSolid();
882 }
883
7fd59977 884 myDone = Standard_True;
885}
886
887
888
889//=======================================================================
890//function : MakeThickSolid
891//purpose :
892//=======================================================================
893
894void BRepOffset_MakeOffset::MakeThickSolid()
895{
896 //--------------------------------------------------------------
0d969553 897 // Construction of shell parallel to shell (initial without cap).
7fd59977 898 //--------------------------------------------------------------
899 MakeOffsetShape ();
900
e1ed38e0 901 if (!myDone)
902 {
903 // Save return code and myDone state.
904 return;
905 }
906
7fd59977 907 //--------------------------------------------------------------------
0d969553
Y
908 // Construction of a solid with the initial shell, parallel shell
909 // limited by caps.
7fd59977 910 //--------------------------------------------------------------------
e1ed38e0 911 if (!myFaces.IsEmpty())
912 {
7fd59977 913 TopoDS_Solid Res;
914 TopExp_Explorer exp;
915 BRep_Builder B;
916 Standard_Integer NbF = myFaces.Extent();
917
918 B.MakeSolid(Res);
919
920 BRepTools_Quilt Glue;
e1ed38e0 921 for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next())
922 {
7fd59977 923 NbF++;
924 Glue.Add (exp.Current());
925 }
926 Standard_Boolean YaResult = 0;
ab87e6fc 927 if (!myOffsetShape.IsNull())
928 {
929 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next())
930 {
931 YaResult = 1;
932 Glue.Add (exp.Current().Reversed());
933 }
0797d9d3 934#ifdef OCCT_DEBUG
ab87e6fc 935 if(YaResult == 0)
936 {
937 cout << "OffsetShape does not contain a FACES." << endl;
938 }
939#endif
7fd59977 940 }
0797d9d3 941#ifdef OCCT_DEBUG
ab87e6fc 942 else
943 {
944 cout << "OffsetShape is null!" << endl;
945 }
946#endif
947
948 if (YaResult == 0)
949 {
7fd59977 950 myDone = Standard_False;
e1ed38e0 951 myError = BRepOffset_UnknownError;
7fd59977 952 return;
ab87e6fc 953 }
954
7fd59977 955 myOffsetShape = Glue.Shells();
e1ed38e0 956 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next())
957 {
7fd59977 958 B.Add(Res,exp.Current());
959 }
960 Res.Closed(Standard_True);
961 myOffsetShape = Res;
962
0d969553
Y
963 // Test of Validity of the result of thick Solid
964 // more face than the initial solid.
7fd59977 965 Standard_Integer NbOF = 0;
e1ed38e0 966 for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next())
967 {
7fd59977 968 NbOF++;
969 }
e1ed38e0 970 if (NbOF <= NbF)
971 {
7fd59977 972 myDone = Standard_False;
e1ed38e0 973 myError = BRepOffset_UnknownError;
7fd59977 974 return;
975 }
976 }
977
e1ed38e0 978 if (myOffset > 0 ) myOffsetShape.Reverse();
7fd59977 979
980 myDone = Standard_True;
981}
982
983//=======================================================================
984//function : IsDone
985//purpose :
986//=======================================================================
987
988Standard_Boolean BRepOffset_MakeOffset::IsDone() const
989{
990 return myDone;
991}
992
993//=======================================================================
994//function : Error
995//purpose :
996//=======================================================================
997
998BRepOffset_Error BRepOffset_MakeOffset::Error() const
999{
1000 return myError;
1001}
1002
1003//=======================================================================
1004//function : Shape
1005//purpose :
1006//=======================================================================
1007
1008const TopoDS_Shape& BRepOffset_MakeOffset::Shape() const
1009{
1010 return myOffsetShape;
1011}
1012
1013//=======================================================================
ecf4f17c 1014//function : MakeOffsetFaces
1015//purpose :
7fd59977 1016//=======================================================================
ecf4f17c 1017void BRepOffset_MakeOffset::MakeOffsetFaces(BRepOffset_DataMapOfShapeOffset& theMapSF)
7fd59977 1018{
ecf4f17c 1019 Standard_Real aCurOffset;
1020 TopTools_ListOfShape aLF;
1021 TopTools_DataMapOfShapeShape ShapeTgt;
1022 TopTools_ListIteratorOfListOfShape aItLF;
9b7f3f83 1023 //
ecf4f17c 1024 Standard_Boolean OffsetOutside = (myOffset > 0.);
9b7f3f83 1025 //
ecf4f17c 1026 BRepLib::SortFaces(myShape, aLF);
9b7f3f83 1027 //
ecf4f17c 1028 aItLF.Initialize(aLF);
1029 for (; aItLF.More(); aItLF.Next()) {
1030 const TopoDS_Face& aF = TopoDS::Face(aItLF.Value());
1031 aCurOffset = myFaceOffset.IsBound(aF) ? myFaceOffset(aF) : myOffset;
1032 BRepOffset_Offset OF(aF, aCurOffset, ShapeTgt, OffsetOutside, myJoin);
7fd59977 1033 TopTools_ListOfShape Let;
ecf4f17c 1034 myAnalyse.Edges(aF,BRepOffset_Tangent,Let);
1035 TopTools_ListIteratorOfListOfShape itl(Let);
1036 for (; itl.More(); itl.Next()) {
7fd59977 1037 const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
1038 if ( !ShapeTgt.IsBound(Cur)) {
9b7f3f83 1039 TopoDS_Shape aLocalShape = OF.Generated(Cur);
1040 const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
9b7f3f83 1041 ShapeTgt.Bind(Cur,OF.Generated(Cur));
1042 TopoDS_Vertex V1,V2,OV1,OV2;
1043 TopExp::Vertices (Cur,V1,V2);
1044 TopExp::Vertices (OTE,OV1,OV2);
1045 TopTools_ListOfShape LE;
1046 if (!ShapeTgt.IsBound(V1)) {
1047 myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1048 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
1049 if (LE.Extent() == LA.Extent())
1050 ShapeTgt.Bind(V1,OV1);
1051 }
1052 if (!ShapeTgt.IsBound(V2)) {
1053 LE.Clear();
1054 myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1055 const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
1056 if (LE.Extent() == LA.Extent())
1057 ShapeTgt.Bind(V2,OV2);
1058 }
7fd59977 1059 }
1060 }
ecf4f17c 1061 theMapSF.Bind(aF,OF);
1062 }
1063}
1064
1065//=======================================================================
1066//function : BuildOffsetByInter
1067//purpose :
1068//=======================================================================
1069void BRepOffset_MakeOffset::BuildOffsetByInter()
1070{
1071#ifdef OCCT_DEBUG
1072 if ( ChronBuild) {
1073 cout << " CONSTRUCTION OF OFFSETS :" << endl;
1074 Clock.Reset();
1075 Clock.Start();
7fd59977 1076 }
ecf4f17c 1077#endif
1078
1079 TopExp_Explorer Exp, Exp2, ExpC;
1080 TopTools_ListIteratorOfListOfShape itLF;
1081
1082 //--------------------------------------------------------
1083 // Construction of faces parallel to initial faces
1084 //--------------------------------------------------------
1085 BRepOffset_DataMapOfShapeOffset MapSF;
1086 MakeOffsetFaces(MapSF);
7fd59977 1087 //--------------------------------------------------------------------
1088 // MES : Map of OffsetShape -> Extended Shapes.
1089 // Build : Map of Initial SS -> OffsetShape build by Inter.
1090 // can be an edge or a compound of edges
1091 //---------------------------------------------------------------------
1092 TopTools_DataMapOfShapeShape MES;
1093 TopTools_DataMapOfShapeShape Build;
1094 TopTools_ListOfShape Failed;
1095 TopAbs_State Side = TopAbs_IN;
1096 Handle(BRepAlgo_AsDes) AsDes = new BRepAlgo_AsDes();
1097
1098 //-------------------------------------------------------------------
0d969553 1099 // Extension of faces and calculation of new edges of intersection.
7fd59977 1100 //-------------------------------------------------------------------
1101 Standard_Boolean ExtentContext = 0;
1102 if (myOffset > 0) ExtentContext = 1;
1103
1104 BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
0d969553 1105 // Intersection between parallel faces
9b7f3f83 1106 Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
0d969553 1107 // Intersection with caps.
9b7f3f83 1108 Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
7fd59977 1109
1110
1111 //---------------------------------------------------------------------------------
0d969553 1112 // Extension of neighbor edges of new edges and intersection between neighbors.
7fd59977 1113 //--------------------------------------------------------------------------------
1114 Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
ecf4f17c 1115 IntersectEdges(myShape, MapSF, MES, Build, AsDes, AsDes2d);
7fd59977 1116 //-----------------------------------------------------------
0d969553 1117 // Great restriction of new edges and update of AsDes.
7fd59977 1118 //------------------------------------------ ----------------
ecf4f17c 1119 TopTools_DataMapOfShapeListOfShape anEdgesOrigins; // offset edge - initial edges
975ec82a 1120 TopTools_IndexedMapOfShape NewEdges;
ecf4f17c 1121 TopTools_DataMapOfShapeShape aETrimEInf; // trimmed - not trimmed edges
1122 //
1123 //Map of edges obtained after FACE-FACE (offsetted) intersection.
1124 //Key1 is edge trimmed by intersection points with other edges;
1125 //Item is not-trimmed edge.
1126 TrimEdges(myShape, myOffset, MapSF, MES, Build, AsDes, AsDes2d, NewEdges, aETrimEInf, anEdgesOrigins);
1127 //
7fd59977 1128 //---------------------------------
0d969553 1129 // Intersection 2D on //
7fd59977 1130 //---------------------------------
ecf4f17c 1131 TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
1132 TopTools_DataMapOfShapeShape aFacesOrigins; // offset face - initial face
7fd59977 1133 TopTools_ListOfShape LFE;
1134 BRepAlgo_Image IMOE;
ecf4f17c 1135 GetEnlargedFaces(myShape, MapSF, MES, aFacesOrigins, IMOE, LFE);
1136 //
7fd59977 1137 TopTools_ListIteratorOfListOfShape itLFE(LFE);
03383c97 1138 for (; itLFE.More(); itLFE.Next())
1139 {
7fd59977 1140 const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
03383c97 1141 Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(NEF);
b0fbc579 1142 BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol, aDMVV);
7fd59977 1143 }
1144 //----------------------------------------------
0d969553 1145 // Intersections 2d on caps.
7fd59977 1146 //----------------------------------------------
975ec82a 1147 Standard_Integer i;
03383c97 1148 for (i = 1; i <= myFaces.Extent(); i++)
1149 {
975ec82a 1150 const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
03383c97 1151 Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(Cork);
b0fbc579 1152 BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol, aDMVV);
7fd59977 1153 }
b0fbc579 1154 //
1155 BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes);
7fd59977 1156 //-------------------------------
0d969553 1157 // Unwinding of extended Faces.
7fd59977 1158 //-------------------------------
9b7f3f83 1159 //
1160 TopTools_MapOfShape aMFDone;
1161 //
ecf4f17c 1162 if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar) {
1163 BuildSplitsOfExtendedFaces(LFE, AsDes, anEdgesOrigins, aFacesOrigins, aETrimEInf, IMOE);
9b7f3f83 1164 //
ecf4f17c 1165 TopTools_ListIteratorOfListOfShape aItLF(LFE);
1166 for (; aItLF.More(); aItLF.Next()) {
1167 const TopoDS_Shape& aS = aItLF.Value();
1168 aMFDone.Add(aS);
9b7f3f83 1169 }
1170 }
1171 else {
1172 myMakeLoops.Build(LFE, AsDes, IMOE);
1173 }
1174 //
0797d9d3 1175#ifdef OCCT_DEBUG
975ec82a 1176 TopTools_IndexedMapOfShape COES;
7fd59977 1177#endif
1178 //---------------------------
0d969553 1179 // MAJ SD. for faces //
7fd59977 1180 //---------------------------
1181 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1182 const TopoDS_Shape& FI = Exp.Current();
1183 myInitOffsetFace.SetRoot(FI);
1184 TopoDS_Face OF = MapSF(FI).Face();
1185 if (MES.IsBound(OF)) {
1186 OF = TopoDS::Face(MES(OF));
1187 if (IMOE.HasImage(OF)) {
9b7f3f83 1188 const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
1189 myInitOffsetFace.Bind(FI,LOFE);
1190 for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
1191 const TopoDS_Shape& OFE = itLF.Value();
1192 myImageOffset.SetRoot(OFE);
7fd59977 1193#ifdef DRAW
9b7f3f83 1194 if (AffichInt2d) {
1195 sprintf(name,"AF_%d",NbAF++);
1196 DBRep::Set(name,OFE);
1197 }
7fd59977 1198#endif
9b7f3f83 1199 TopTools_MapOfShape View;
1200 for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1201 Exp2.More(); Exp2.Next()) {
1202 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1203
1204 myAsDes->Add (OFE,COE);
7fd59977 1205#ifdef DRAW
9b7f3f83 1206 if (AffichInt2d) {
1207 sprintf(name,"AE_%d",NbAE++);
1208 DBRep::Set(name,COE);
1209 COES.Add(COE);
1210 }
7fd59977 1211#endif
9b7f3f83 1212 if (View.Add(COE)){
1213 if (!myAsDes->HasDescendant(COE)) {
1214 TopoDS_Vertex CV1,CV2;
1215 TopExp::Vertices(COE,CV1,CV2);
1216 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1217 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1218 }
1219 }
1220 }
1221 }
7fd59977 1222 }
1223 else {
9b7f3f83 1224 if (aMFDone.Contains(OF)) {
1225 continue;
1226 }
1227 //
1228 myInitOffsetFace.Bind(FI,OF);
1229 myImageOffset.SetRoot(OF);
7fd59977 1230#ifdef DRAW
9b7f3f83 1231 if (AffichInt2d) {
1232 sprintf(name,"AF_%d",NbAF++);
1233 DBRep::Set(name,OF);
1234 }
7fd59977 1235#endif
9b7f3f83 1236 const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
1237 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1238 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1239 if (IMOE.HasImage(OE)) {
1240 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1241 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1242 for (; itLOE.More(); itLOE.Next()) {
1243 TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
1244 const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
1245// const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
1246 myAsDes->Add(OF,COE);
7fd59977 1247#ifdef DRAW
9b7f3f83 1248 if (AffichInt2d) {
1249 sprintf(name,"AE_%d",NbAE++);
1250 DBRep::Set(name,COE);
1251 COES.Add(COE);
1252 }
7fd59977 1253#endif
9b7f3f83 1254
1255 if (!myAsDes->HasDescendant(COE)) {
1256 TopoDS_Vertex CV1,CV2;
1257 TopExp::Vertices(COE,CV1,CV2);
1258 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1259 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1260 }
1261 }
1262 }
1263 else {
1264 myAsDes->Add(OF,OE);
7fd59977 1265#ifdef DRAW
9b7f3f83 1266 if (AffichInt2d) {
1267 sprintf(name,"AE_%d",NbAE++);
1268 DBRep::Set(name,OE);
1269 COES.Add(OE);
1270 }
7fd59977 1271#endif
1272
9b7f3f83 1273 const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
1274 myAsDes->Add(OE,LV);
1275 }
1276 }
7fd59977 1277 }
1278 }
1279 else {
1280 myInitOffsetFace.Bind(FI,OF);
1281 myImageOffset.SetRoot(OF);
1282 TopTools_MapOfShape View;
1283 for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
9b7f3f83 1284 Exp2.More(); Exp2.Next()) {
7fd59977 1285
9b7f3f83 1286 const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1287 myAsDes->Add (OF,COE);
7fd59977 1288#ifdef DRAW
9b7f3f83 1289 if (AffichInt2d) {
1290 sprintf(name,"AE_%d",NbAE++);
1291 DBRep::Set(name,COE);
1292 COES.Add(COE);
1293 }
7fd59977 1294#endif
9b7f3f83 1295
1296 if (View.Add(Exp2.Current())) {
1297 if (!myAsDes->HasDescendant(COE)) {
1298 TopoDS_Vertex CV1,CV2;
1299 TopExp::Vertices(COE,CV1,CV2);
1300 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1301 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1302 }
1303 }
7fd59977 1304 }
1305 }
1306 }
1307 // Modified by skv - Tue Mar 15 16:20:43 2005
1308 // Add methods for supporting history.
1309 TopTools_MapOfShape aMapEdges;
1310
1311 for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1312 const TopoDS_Shape& aFaceRef = Exp.Current();
1313
1314 Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1315
1316 for (; Exp2.More(); Exp2.Next()) {
1317 const TopoDS_Shape& anEdgeRef = Exp2.Current();
1318
1319 if (aMapEdges.Add(anEdgeRef)) {
9b7f3f83 1320 myInitOffsetEdge.SetRoot(anEdgeRef);
1321 if (Build.IsBound(anEdgeRef)) {
1322 TopoDS_Shape aNewShape = Build(anEdgeRef);
1323
1324 if (aNewShape.ShapeType() == TopAbs_EDGE) {
1325 if (IMOE.HasImage(aNewShape)) {
1326 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape);
1327
1328 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1329 } else
1330 myInitOffsetEdge.Bind (anEdgeRef, aNewShape);
1331 } else { // aNewShape != TopAbs_EDGE
1332 TopTools_ListOfShape aListNewEdge;
1333
1334 for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1335 const TopoDS_Shape &aResEdge = ExpC.Current();
1336
1337 if (IMOE.HasImage(aResEdge)) {
1338 const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge);
1339 TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE);
1340
1341 for (; aNewEIter.More(); aNewEIter.Next())
1342 aListNewEdge.Append(aNewEIter.Value());
1343 } else
1344 aListNewEdge.Append(aResEdge);
1345 }
1346
1347 myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge);
1348 }
1349 }
1350 else { // Free boundary.
1351 TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef);
1352
1353 if (MES.IsBound(aNewEdge))
1354 aNewEdge = MES(aNewEdge);
1355
1356 if (IMOE.HasImage(aNewEdge)) {
1357 const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge);
1358
1359 myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1360 } else
1361 myInitOffsetEdge.Bind (anEdgeRef, aNewEdge);
1362 }
7fd59977 1363 }
1364 }
1365 }
1366// Modified by skv - Tue Mar 15 16:20:43 2005
1367
1368 //---------------------------
ecf4f17c 1369 // MAJ SD. for caps
7fd59977 1370 //---------------------------
975ec82a
J
1371 //TopTools_MapOfShape View;
1372 for (i = 1; i <= myFaces.Extent(); i++) {
1373 const TopoDS_Shape& Cork = myFaces(i);
7fd59977 1374 const TopTools_ListOfShape& LE = AsDes->Descendant(Cork);
1375 for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1376 const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1377 if (IMOE.HasImage(OE)) {
9b7f3f83 1378 const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1379 TopTools_ListIteratorOfListOfShape itLOE(LOE);
1380 for (; itLOE.More(); itLOE.Next()) {
1381 const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value());
1382 myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ;
7fd59977 1383#ifdef DRAW
9b7f3f83 1384 if (AffichInt2d) {
1385 sprintf(name,"AE_%d",NbAE++);
1386 DBRep::Set(name,COE);
1387 COES.Add(COE);
1388 }
7fd59977 1389#endif
9b7f3f83 1390
1391 if (!myAsDes->HasDescendant(COE)) {
1392 TopoDS_Vertex CV1,CV2;
1393 TopExp::Vertices(COE,CV1,CV2);
1394 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1395 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
1396 }
1397 }
7fd59977 1398 }
1399 else {
9b7f3f83 1400 myAsDes->Add(Cork,OE);
1401 if (AsDes->HasDescendant(OE)) {
1402 myAsDes->Add(OE,AsDes->Descendant(OE));
1403 }
7fd59977 1404#ifdef DRAW
9b7f3f83 1405 if (AffichInt2d) {
1406 sprintf(name,"AE_%d",NbAE++);
1407 DBRep::Set(name,OE);
1408 COES.Add(OE);
1409 }
7fd59977 1410#endif
1411 }
1412 }
1413 }
1414
0797d9d3 1415#ifdef OCCT_DEBUG
7fd59977 1416 DEBVerticesControl (COES,myAsDes);
1417 if ( ChronBuild) Clock.Show();
1418#endif
1419}
1420
9b7f3f83 1421//=======================================================================
ecf4f17c 1422//function : BuildOffsetByArc
9b7f3f83 1423//purpose :
1424//=======================================================================
ecf4f17c 1425void BRepOffset_MakeOffset::BuildOffsetByArc()
9b7f3f83 1426{
ecf4f17c 1427#ifdef OCCT_DEBUG
1428 if ( ChronBuild) {
1429 cout << " CONSTRUCTION OF OFFSETS :" << endl;
1430 Clock.Reset();
1431 Clock.Start();
7fd59977 1432 }
1433#endif
1434
ecf4f17c 1435 TopExp_Explorer Exp;
1436 TopTools_ListIteratorOfListOfShape itLF;
1437 TopTools_MapOfShape Done;
1438
7fd59977 1439 //--------------------------------------------------------
0d969553 1440 // Construction of faces parallel to initial faces
7fd59977 1441 //--------------------------------------------------------
ecf4f17c 1442 BRepOffset_DataMapOfShapeOffset MapSF;
1443 MakeOffsetFaces(MapSF);
7fd59977 1444 //--------------------------------------------------------
0d969553 1445 // Construction of tubes on edge.
7fd59977 1446 //--------------------------------------------------------
1447 BRepOffset_Type OT = BRepOffset_Convex;
1448 if (myOffset < 0.) OT = BRepOffset_Concave;
1449
1450 for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1451 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1452 if (Done.Add(E)) {
1453 const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
1454 if (Anc.Extent() == 2) {
9b7f3f83 1455 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1456 if (!L.IsEmpty() && L.First().Type() == OT) {
1457 Standard_Real CurOffset = myOffset;
1458 if ( myFaceOffset.IsBound(Anc.First()))
1459 CurOffset = myFaceOffset(Anc.First());
1460 TopoDS_Shape aLocalShapeGen = MapSF(Anc.First()).Generated(E);
1461 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShapeGen);
1462 aLocalShapeGen = MapSF(Anc.Last()).Generated(E);
1463 TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShapeGen);
1464// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1465// TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
1466 // find if exits tangent edges in the original shape
1467 TopoDS_Edge E1f, E1l;
1468 TopoDS_Vertex V1f, V1l;
1469 TopExp::Vertices(E,V1f,V1l);
1470 TopTools_ListOfShape TangE;
1471 myAnalyse.TangentEdges(E,V1f,TangE);
1472 // find if the pipe on the tangent edges are soon created.
1473 TopTools_ListIteratorOfListOfShape itl(TangE);
1474 Standard_Boolean Find = Standard_False;
1475 for ( ; itl.More() && !Find; itl.Next()) {
1476 if ( MapSF.IsBound(itl.Value())) {
1477 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
1478 E1f = TopoDS::Edge(aLocalShape);
1479// E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
1480 Find = Standard_True;
1481 }
1482 }
1483 TangE.Clear();
1484 myAnalyse.TangentEdges(E,V1l,TangE);
1485 // find if the pipe on the tangent edges are soon created.
1486 itl.Initialize(TangE);
1487 Find = Standard_False;
1488 for ( ; itl.More() && !Find; itl.Next()) {
1489 if ( MapSF.IsBound(itl.Value())) {
1490 TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
1491 E1l = TopoDS::Edge(aLocalShape);
1492// E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
1493 Find = Standard_True;
1494 }
1495 }
1496 BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
1497 MapSF.Bind(E,OF);
1498 }
7fd59977 1499 }
1500 else {
9b7f3f83 1501 // ----------------------
1502 // free border.
1503 // ----------------------
1504 TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1505 TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1506/// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
7fd59977 1507 myInitOffsetEdge.SetRoot(E); // skv: supporting history.
9b7f3f83 1508 myInitOffsetEdge.Bind (E,EOn1);
7fd59977 1509 }
1510 }
1511 }
1512
1513 //--------------------------------------------------------
0d969553 1514 // Construction of spheres on vertex.
7fd59977 1515 //--------------------------------------------------------
1516 Done.Clear();
1517 TopTools_ListIteratorOfListOfShape it;
1518
1519 for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) {
1520 const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current());
1521 if (Done.Add(V)) {
1522 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V);
1523 TopTools_ListOfShape LE;
1524 myAnalyse.Edges(V,OT,LE);
1525
1526 if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) {
9b7f3f83 1527 TopTools_ListOfShape LOE;
1528 //--------------------------------------------------------
1529 // Return connected edges on tubes.
1530 //--------------------------------------------------------
1531 for (it.Initialize(LE) ; it.More(); it.Next()) {
1532 LOE.Append(MapSF(it.Value()).Generated(V).Reversed());
1533 }
1534 //----------------------
1535 // construction sphere.
1536 //-----------------------
1537 const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First());
1538 const TopoDS_Shape& FF = LLA.First();
1539 Standard_Real CurOffset = myOffset;
1540 if ( myFaceOffset.IsBound(FF))
1541 CurOffset = myFaceOffset(FF);
1542
1543 BRepOffset_Offset OF(V,LOE,CurOffset);
1544 MapSF.Bind(V,OF);
7fd59977 1545 }
1546 //--------------------------------------------------------------
0d969553 1547 // Particular processing if V is at least a free border.
7fd59977 1548 //-------------------------------------------------------------
1549 TopTools_ListOfShape LBF;
1550 myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF);
9b7f3f83 1551 if (!LBF.IsEmpty()) {
1552 Standard_Boolean First = Standard_True;
1553 for (it.Initialize(LE) ; it.More(); it.Next()) {
1554 if (First) {
1555 myInitOffsetEdge.SetRoot(V); // skv: supporting history.
1556 myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V));
1557 First = Standard_False;
1558 }
1559 else {
1560 myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V));
1561 }
1562 }
7fd59977 1563 }
1564 }
1565 }
1566
1567 //------------------------------------------------------------
0d969553
Y
1568 // Extension of parallel faces to the context.
1569 // Extended faces are ordered in DS and removed from MapSF.
7fd59977 1570 //------------------------------------------------------------
1571 if (!myFaces.IsEmpty()) ToContext (MapSF);
1572
1573 //------------------------------------------------------
1574 // MAJ SD.
1575 //------------------------------------------------------
1576 BRepOffset_Type RT = BRepOffset_Concave;
1577 if (myOffset < 0.) RT = BRepOffset_Convex;
1578 BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
7fd59977 1579 for ( ; It.More(); It.Next()) {
1580 const TopoDS_Shape& SI = It.Key();
1581 const BRepOffset_Offset& SF = It.Value();
1582 if (SF.Status() == BRepOffset_Reversed ||
9b7f3f83 1583 SF.Status() == BRepOffset_Degenerated ) {
7fd59977 1584 //------------------------------------------------
0d969553 1585 // Degenerated or returned faces are not stored.
7fd59977 1586 //------------------------------------------------
1587 continue;
9b7f3f83 1588 }
7fd59977 1589
1590 const TopoDS_Face& OF = It.Value().Face();
1591 myInitOffsetFace.Bind (SI,OF);
1592 myInitOffsetFace.SetRoot (SI); // Initial<-> Offset
0d969553 1593 myImageOffset.SetRoot (OF); // FaceOffset root of images
7fd59977 1594
1595 if (SI.ShapeType() == TopAbs_FACE) {
1596 for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
9b7f3f83 1597 Exp.More(); Exp.Next()) {
1598 //--------------------------------------------------------------------
1599 // To each face are associatedthe edges that restrict that
1600 // The edges that do not generate tubes or are not tangent
1601 // to two faces are removed.
1602 //--------------------------------------------------------------------
1603 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1604 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1605 if (!L.IsEmpty() && L.First().Type() != RT) {
1606 TopAbs_Orientation OO = E.Orientation();
1607 TopoDS_Shape aLocalShape = It.Value().Generated(E);
1608 TopoDS_Edge OE = TopoDS::Edge(aLocalShape);
1609// TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E));
1610 myAsDes->Add (OF,OE.Oriented(OO));
1611 }
7fd59977 1612 }
1613 }
1614 else {
1615 for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
9b7f3f83 1616 Exp.More(); Exp.Next()) {
1617 myAsDes->Add (OF,Exp.Current());
7fd59977 1618 }
1619 }
1620 }
1621
0797d9d3 1622#ifdef OCCT_DEBUG
7fd59977 1623 if ( ChronBuild) Clock.Show();
1624#endif
1625}
1626
1627
1628
1629//=======================================================================
1630//function : SelfInter
1631//purpose :
1632//=======================================================================
1633
35e08fe8 1634void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/)
7fd59977 1635{
0797d9d3 1636#ifdef OCCT_DEBUG
7fd59977 1637 if ( ChronBuild) {
1638 cout << " AUTODEBOUCLAGE:" << endl;
1639 Clock.Reset();
1640 Clock.Start();
1641 }
1642#endif
1643
9775fa61 1644 throw Standard_NotImplemented();
7fd59977 1645}
1646
1647
1648//=======================================================================
1649//function : ToContext
1650//purpose :
1651//=======================================================================
1652
1653void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
1654{
1655 TopTools_DataMapOfShapeShape Created;
1656 TopTools_DataMapOfShapeShape MEF;
975ec82a 1657 TopTools_IndexedMapOfShape FacesToBuild;
7fd59977 1658 TopTools_ListIteratorOfListOfShape itl;
1659 TopExp_Explorer exp;
1660
1661// TopAbs_State Side = TopAbs_IN;
1662// if (myOffset < 0.) Side = TopAbs_OUT;
1663
1664 TopAbs_State Side = TopAbs_OUT;
975ec82a
J
1665
1666 /*
1667 Standard_Integer i;
1668 for (i = 1; i <= myFaces.Extent(); i++) {
1669 const TopoDS_Face& CF = TopoDS::Face(myFaces(i));
7fd59977 1670 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
9b7f3f83 1671 exp.More(); exp.Next()) {
7fd59977 1672 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1673 if (!myAnalyse.HasAncestor(E)) {
9b7f3f83 1674 //----------------------------------------------------------------
1675 // The edges of context faces that are not in the initial shape
1676 // can appear in the result.
1677 //----------------------------------------------------------------
1678 //myAsDes->Add(CF,E);
7fd59977 1679 }
1680 }
1681 }
975ec82a
J
1682 */
1683
1684 //--------------------------------------------------------
0d969553 1685 // Determine the edges and faces reconstructed by
7fd59977 1686 // intersection.
1687 //---------------------------------------------------------
975ec82a
J
1688 Standard_Integer j;
1689 for (j = 1; j <= myFaces.Extent(); j++) {
1690 const TopoDS_Face& CF = TopoDS::Face(myFaces(j));
7fd59977 1691 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
9b7f3f83 1692 exp.More(); exp.Next()) {
7fd59977 1693 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1694 if (myAnalyse.HasAncestor(E)) {
9b7f3f83 1695 const TopTools_ListOfShape& LEA = myAnalyse.Ancestors(E);
1696 for (itl.Initialize(LEA); itl.More(); itl.Next()) {
1697 const BRepOffset_Offset& OF = MapSF(itl.Value());
1698 FacesToBuild.Add(itl.Value());
1699 MEF.Bind(OF.Generated(E),CF);
1700 }
1701 TopoDS_Vertex V[2];
1702 TopExp::Vertices(E,V[0],V[1]);
1703 for (Standard_Integer i = 0; i < 2; i++) {
1704 const TopTools_ListOfShape& LVA = myAnalyse.Ancestors(V[i]);
1705 for ( itl.Initialize(LVA); itl.More(); itl.Next()) {
1706 const TopoDS_Edge& EV = TopoDS::Edge(itl.Value());
1707 if (MapSF.IsBound(EV)) {
1708 const BRepOffset_Offset& OF = MapSF(EV);
1709 FacesToBuild.Add(EV);
1710 MEF.Bind(OF.Generated(V[i]),CF);
1711 }
1712 }
1713 }
7fd59977 1714 }
1715 }
1716 }
1717 //---------------------------
0d969553 1718 // Reconstruction of faces.
7fd59977 1719 //---------------------------
1720 TopoDS_Face F,NF;
1721 BRepOffset_Type RT = BRepOffset_Concave;
1722 if (myOffset < 0.) RT = BRepOffset_Convex;
1723 TopoDS_Shape OE,NE;
1724 TopAbs_Orientation Or;
1725
975ec82a
J
1726 for (j = 1; j <= FacesToBuild.Extent(); j++) {
1727 const TopoDS_Shape& S = FacesToBuild(j);
7fd59977 1728 BRepOffset_Offset BOF;
1729 BOF = MapSF(S);
1730 F = TopoDS::Face(BOF.Face());
1731 BRepOffset_Tool::ExtentFace(F,Created,MEF,Side,myTol,NF);
1732 MapSF.UnBind(S);
1733 //--------------
1734 // MAJ SD.
1735 //--------------
1736 myInitOffsetFace.Bind (S,NF);
1737 myInitOffsetFace.SetRoot (S); // Initial<-> Offset
1738 myImageOffset.SetRoot (NF);
1739
1740 if (S.ShapeType() == TopAbs_FACE) {
1741 for (exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
9b7f3f83 1742 exp.More(); exp.Next()) {
1743
1744 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1745 const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1746 OE = BOF.Generated(E);
1747 Or = E.Orientation();
1748 OE.Orientation(Or);
1749 if (!L.IsEmpty() && L.First().Type() != RT) {
1750 if (Created.IsBound(OE)) {
1751 NE = Created(OE);
1752 if (NE.Orientation() == TopAbs_REVERSED)
1753 NE.Orientation(TopAbs::Reverse(Or));
1754 else
1755 NE.Orientation(Or);
1756 myAsDes->Add(NF,NE);
1757 }
1758 else {
1759 myAsDes->Add(NF,OE);
1760 }
1761 }
7fd59977 1762 }
1763 }
1764 else {
1765 //------------------
0d969553 1766 // Tube
7fd59977 1767 //---------------------
1768 for (exp.Init(NF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
9b7f3f83 1769 exp.More(); exp.Next()) {
1770 myAsDes->Add (NF,exp.Current());
7fd59977 1771 }
1772 }
1773 MapSF.UnBind(S);
1774 }
1775
0d969553
Y
1776 //------------------
1777 // MAJ free borders
1778 //------------------
7fd59977 1779 TopTools_DataMapIteratorOfDataMapOfShapeShape itc;
1780 for (itc.Initialize(Created); itc.More(); itc.Next()) {
1781 OE = itc.Key();
1782 NE = itc.Value();
1783 if (myInitOffsetEdge.IsImage(OE)) {
1784 TopoDS_Shape E = myInitOffsetEdge.ImageFrom (OE);
1785 Or = myInitOffsetEdge.Image(E).First().Orientation();
1786 if (NE.Orientation() == TopAbs_REVERSED)
9b7f3f83 1787 NE.Orientation(TopAbs::Reverse(Or));
7fd59977 1788 else
9b7f3f83 1789 NE.Orientation(Or);
7fd59977 1790 myInitOffsetEdge.Remove(OE);
1791 myInitOffsetEdge.Bind(E,NE);
1792 }
1793 }
1794}
1795
1796
1797//=======================================================================
1798//function : UpdateFaceOffset
1799//purpose :
1800//=======================================================================
1801
1802void BRepOffset_MakeOffset::UpdateFaceOffset()
1803{
1804 TopTools_MapOfShape M;
1805 TopTools_DataMapOfShapeReal CopiedMap;
1806 CopiedMap.Assign(myFaceOffset);
1807 TopTools_DataMapIteratorOfDataMapOfShapeReal it(CopiedMap);
1808
1809 BRepOffset_Type RT = BRepOffset_Convex;
1810 if (myOffset < 0.) RT = BRepOffset_Concave;
1811
1812 for ( ; it.More(); it.Next()) {
1813 const TopoDS_Face& F = TopoDS::Face(it.Key());
1814 Standard_Real CurOffset = CopiedMap(F);
1815 if ( !M.Add(F)) continue;
1816 TopoDS_Compound Co;
1817 BRep_Builder Build;
1818 Build.MakeCompound(Co);
1819 TopTools_MapOfShape Dummy;
1820 Build.Add(Co,F);
1821 if (myJoin == GeomAbs_Arc)
1822 myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent,RT);
1823 else
1824 myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent);
1825
1826 TopExp_Explorer exp(Co,TopAbs_FACE);
1827 for (; exp.More(); exp.Next()) {
1828 const TopoDS_Face& FF = TopoDS::Face(exp.Current());
1829 if ( !M.Add(FF)) continue;
1830 if ( myFaceOffset.IsBound(FF))
9b7f3f83 1831 myFaceOffset.UnBind(FF);
7fd59977 1832 myFaceOffset.Bind(FF,CurOffset);
1833 }
1834 }
1835}
1836
1837//=======================================================================
1838//function : CorrectConicalFaces
1839//purpose :
1840//=======================================================================
1841
1842void BRepOffset_MakeOffset::CorrectConicalFaces()
1843{
db2f1498 1844 if(myOffsetShape.IsNull())
1845 {
1846 return;
1847 }
1848 //
7fd59977 1849 TopTools_SequenceOfShape Cones;
1850 TopTools_SequenceOfShape Circs;
1851 TopTools_SequenceOfShape Seams;
1852 Standard_Real TolApex = 1.e-5;
1853
1854 Standard_Integer i;
1855
1856 TopTools_DataMapOfShapeListOfShape FacesOfCone;
1857 //TopTools_DataMapOfShapeShape DegEdges;
1858 TopExp_Explorer Explo( myOffsetShape, TopAbs_FACE );
1859 if (myJoin == GeomAbs_Arc)
903f7584 1860 {
1861 for (; Explo.More(); Explo.Next())
7fd59977 1862 {
903f7584 1863 TopoDS_Face aFace = TopoDS::Face( Explo.Current() );
1864 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( aFace );
1865 //if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
1866 //aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface(); //???
1867
1868 TopTools_IndexedMapOfShape Emap;
1869 TopExp::MapShapes( aFace, TopAbs_EDGE, Emap );
1870 for (i = 1; i <= Emap.Extent(); i++)
1871 {
1872 TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
1873 //Standard_Real f, l;
1874 //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
1875 //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
1876 if (BRep_Tool::Degenerated(anEdge))
1877 {
1878 //Check if anEdge is a really degenerated edge or not
1879 BRepAdaptor_Curve BACurve(anEdge, aFace);
1880 gp_Pnt Pfirst, Plast, Pmid;
1881 Pfirst = BACurve.Value(BACurve.FirstParameter());
1882 Plast = BACurve.Value(BACurve.LastParameter());
1883 Pmid = BACurve.Value((BACurve.FirstParameter()+BACurve.LastParameter())/2.);
1884 if (Pfirst.Distance(Plast) <= TolApex &&
1885 Pfirst.Distance(Pmid) <= TolApex)
1886 continue;
1887 //Cones.Append( aFace );
1888 //Circs.Append( anEdge );
1889 //TopoDS_Vertex Vdeg = TopExp::FirstVertex( anEdge );
1890 TopoDS_Edge OrEdge =
1891 TopoDS::Edge( myInitOffsetEdge.Root( anEdge) );
1892 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1893 if ( FacesOfCone.IsBound(VF) )
1894 {
1895 //add a face to the existing list
1896 TopTools_ListOfShape& aFaces = FacesOfCone.ChangeFind(VF);
1897 aFaces.Append (aFace);
1898 //DegEdges.Bind(aFace, anEdge);
1899 }
1900 else
1901 {
1902 //the vertex is not in the map => create a new key and items
1903 TopTools_ListOfShape aFaces;
1904 aFaces.Append (aFace);
1905 FacesOfCone.Bind(VF, aFaces);
1906 //DegEdges.Bind(aFace, anEdge);
1907 }
1908 }
1909 } //for (i = 1; i <= Emap.Extent(); i++)
1910 } //for (; fexp.More(); fexp.Next())
1911 } //if (myJoin == GeomAbs_Arc)
7fd59977 1912
1913 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Cone(FacesOfCone);
1914 BRep_Builder BB;
1915 TopLoc_Location L;
db2f1498 1916 Standard_Boolean IsModified = Standard_False;
7fd59977 1917 for (; Cone.More(); Cone.Next() ) {
1918 gp_Sphere theSphere;
1919 Handle(Geom_SphericalSurface) aSphSurf;
1920 TopoDS_Wire SphereWire;
1921 BB.MakeWire(SphereWire);
1922 TopoDS_Vertex anApex = TopoDS::Vertex(Cone.Key());
1923 const TopTools_ListOfShape& Faces = Cone.Value(); //FacesOfCone(anApex);
1924 TopTools_ListIteratorOfListOfShape itFaces(Faces);
1925 Standard_Boolean isFirstFace = Standard_True;
1926 gp_Pnt FirstPoint;
1927 TopoDS_Vertex theFirstVertex, CurFirstVertex;
1928 for (; itFaces.More(); itFaces.Next())
903f7584 1929 {
1930 TopoDS_Face aFace = TopoDS::Face(itFaces.Value()); //TopoDS::Face(Faces.First());
1931 TopoDS_Edge DegEdge; // = TopoDS::Edge(DegEdges(aFace));
1932 for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
7fd59977 1933 {
903f7584 1934 DegEdge = TopoDS::Edge(Explo.Current());
1935 if (BRep_Tool::Degenerated(DegEdge))
1936 {
1937 TopoDS_Edge OrEdge = TopoDS::Edge( myInitOffsetEdge.Root( DegEdge) );
1938 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1939 if (VF.IsSame(anApex))
1940 break;
1941 }
1942 }
1943 TopoDS_Shape aLocalDegShape = DegEdge.Oriented(TopAbs_FORWARD);
1944 TopoDS_Edge CurEdge = TopoDS::Edge(aLocalDegShape);
1945 BB.Degenerated(CurEdge, Standard_False);
1946 BB.SameRange(CurEdge, Standard_False);
1947 BB.SameParameter(CurEdge, Standard_False);
1948 gp_Pnt fPnt, lPnt, mPnt;
1949 GetEdgePoints(CurEdge, aFace, fPnt, mPnt, lPnt);
1950 Standard_Real f, l;
1951 BRep_Tool::Range(CurEdge, f, l);
1952 if (isFirstFace)
1953 {
1954 gp_Vec aVec1(fPnt, mPnt);
1955 gp_Vec aVec2(fPnt, lPnt);
1956 gp_Vec aNorm = aVec1.Crossed(aVec2);
1957 gp_Pnt theApex = BRep_Tool::Pnt(anApex);
1958 gp_Vec ApexToFpnt(theApex, fPnt);
1959 gp_Vec Ydir = aNorm ^ ApexToFpnt;
1960 gp_Vec Xdir = Ydir ^ aNorm;
1961 //Xdir.Rotate(gp_Ax1(theApex, aNorm), -f);
1962 gp_Ax2 anAx2(theApex, gp_Dir(aNorm), gp_Dir(Xdir));
1963 theSphere.SetRadius(myOffset);
1964 theSphere.SetPosition(gp_Ax3(anAx2) /*gp_Ax3(theApex, gp_Dir(aNorm))*/);
1965 aSphSurf = new Geom_SphericalSurface(theSphere);
1966 FirstPoint = fPnt;
1967 theFirstVertex = BRepLib_MakeVertex(fPnt);
1968 CurFirstVertex = theFirstVertex;
1969 }
1970
1971 TopoDS_Vertex v1, v2, FirstVert, EndVert;
1972 TopExp::Vertices(CurEdge, v1, v2);
1973 FirstVert = CurFirstVertex;
1974 if (lPnt.Distance(FirstPoint) <= Precision::Confusion())
1975 EndVert = theFirstVertex;
1976 else
1977 EndVert = BRepLib_MakeVertex(lPnt);
1978 CurEdge.Free( Standard_True );
1979 BB.Remove(CurEdge, v1);
1980 BB.Remove(CurEdge, v2);
1981 BB.Add(CurEdge, FirstVert.Oriented(TopAbs_FORWARD));
1982 BB.Add(CurEdge, EndVert.Oriented(TopAbs_REVERSED));
1983 //take the curve from sphere an put it to the edge
1984 Standard_Real Uf, Vf, Ul, Vl;
1985 ElSLib::Parameters( theSphere, fPnt, Uf, Vf );
1986 ElSLib::Parameters( theSphere, lPnt, Ul, Vl );
1987 if (Abs(Ul) <= Precision::Confusion())
1988 Ul = 2.*M_PI;
1989 Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
1990 /*
9b7f3f83 1991 if (!isFirstFace)
903f7584 1992 {
1993 gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
1994 if (Abs(Uf - f) > Precision::Confusion())
1995 {
1996 aCircle.Rotate(aCircle.Axis(), f - Uf);
1997 aCurv = new Geom_Circle(aCircle);
1998 }
1999 }
2000 */
2001 Handle(Geom_TrimmedCurve) aTrimCurv = new Geom_TrimmedCurve(aCurv, Uf, Ul);
2002 BB.UpdateEdge(CurEdge, aTrimCurv, Precision::Confusion());
2003 BB.Range(CurEdge, Uf, Ul, Standard_True);
2004 Handle(Geom2d_Line) theLin2d = new Geom2d_Line( gp_Pnt2d( 0., Vf ), gp::DX2d() );
2005 Handle(Geom2d_TrimmedCurve) theTrimLin2d = new Geom2d_TrimmedCurve(theLin2d, Uf, Ul);
2006 BB.UpdateEdge(CurEdge, theTrimLin2d, aSphSurf, L, Precision::Confusion());
2007 BB.Range(CurEdge, aSphSurf, L, Uf, Ul);
2008 BRepLib::SameParameter(CurEdge);
2009 BB.Add(SphereWire, CurEdge);
2010 //Modifying correspondent edges in aFace: substitute vertices common with CurEdge
2011 BRepAdaptor_Curve2d BAc2d(CurEdge, aFace);
2012 gp_Pnt2d fPnt2d, lPnt2d;
2013 fPnt2d = BAc2d.Value(BAc2d.FirstParameter());
2014 lPnt2d = BAc2d.Value(BAc2d.LastParameter());
2015 TopTools_IndexedMapOfShape Emap;
2016 TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
2017 TopoDS_Edge EE [2];
2018 Standard_Integer j = 0, k;
2019 for (k = 1; k <= Emap.Extent(); k++)
2020 {
2021 const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(k));
2022 if (!BRep_Tool::Degenerated(anEdge))
2023 {
2024 TopoDS_Vertex V1, V2;
2025 TopExp::Vertices(anEdge, V1, V2);
2026 if (V1.IsSame(v1) || V2.IsSame(v1))
2027 EE[j++] = anEdge;
2028 }
2029 }
2030 for (k = 0; k < j; k++)
2031 {
2032 TopoDS_Shape aLocalShape = EE[k].Oriented(TopAbs_FORWARD);
2033 TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
2034 Eforward.Free(Standard_True);
2035 TopoDS_Vertex V1, V2;
2036 TopExp::Vertices( Eforward, V1, V2 );
2037 BRepAdaptor_Curve2d EEc( Eforward, aFace );
2038 gp_Pnt2d p2d1, p2d2;
2039 p2d1 = EEc.Value(EEc.FirstParameter());
2040 p2d2 = EEc.Value(EEc.LastParameter());
2041 if (V1.IsSame(v1))
2042 {
2043 TopoDS_Vertex NewV = (p2d1.Distance(fPnt2d) <= Precision::Confusion())?
2044 FirstVert : EndVert;
2045 BB.Remove( Eforward, V1 );
2046 BB.Add( Eforward, NewV.Oriented(TopAbs_FORWARD) );
2047 }
2048 else
2049 {
2050 TopoDS_Vertex NewV = (p2d2.Distance(fPnt2d) <= Precision::Confusion())?
2051 FirstVert : EndVert;
2052 BB.Remove( Eforward, V2 );
2053 BB.Add( Eforward, NewV.Oriented(TopAbs_REVERSED) );
2054 }
7fd59977 2055 }
903f7584 2056
2057 isFirstFace = Standard_False;
2058 CurFirstVertex = EndVert;
2059 }
7fd59977 2060 //Building new spherical face
2061 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
2062 gp_Pnt2d p2d1, p2d2;
2063 TopTools_ListOfShape EdgesOfWire;
2064 TopoDS_Iterator itw(SphereWire);
2065 for (; itw.More(); itw.Next())
903f7584 2066 {
2067 const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
2068 EdgesOfWire.Append(anEdge);
2069 Standard_Real f, l;
2070 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aSphSurf, L, f, l);
2071 p2d1 = aC2d->Value(f);
2072 p2d2 = aC2d->Value(l);
2073 if (p2d1.X() < Ufirst)
2074 Ufirst = p2d1.X();
2075 if (p2d1.X() > Ulast)
2076 Ulast = p2d1.X();
2077 if (p2d2.X() < Ufirst)
2078 Ufirst = p2d2.X();
2079 if (p2d2.X() > Ulast)
2080 Ulast = p2d2.X();
2081 }
7fd59977 2082 TopTools_ListOfShape NewEdges;
2083 TopoDS_Edge FirstEdge;
2084 TopTools_ListIteratorOfListOfShape itl(EdgesOfWire);
2085 for (; itl.More(); itl.Next())
903f7584 2086 {
2087 FirstEdge = TopoDS::Edge(itl.Value());
2088 Standard_Real f, l;
2089 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(FirstEdge, aSphSurf, L, f, l);
2090 p2d1 = aC2d->Value(f);
2091 p2d2 = aC2d->Value(l);
2092 if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion())
7fd59977 2093 {
903f7584 2094 EdgesOfWire.Remove(itl);
2095 break;
7fd59977 2096 }
903f7584 2097 }
cc9f4591 2098 NewEdges.Append(FirstEdge.Oriented(TopAbs_FORWARD));
7fd59977 2099 TopoDS_Vertex Vf1, CurVertex;
2100 TopExp::Vertices(FirstEdge, Vf1, CurVertex);
2101 itl.Initialize(EdgesOfWire);
2102 while (itl.More())
903f7584 2103 {
2104 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
2105 TopoDS_Vertex V1, V2;
2106 TopExp::Vertices(anEdge, V1, V2);
2107 if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
7fd59977 2108 {
cc9f4591 2109 NewEdges.Append(anEdge.Oriented(TopAbs_FORWARD));
903f7584 2110 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
2111 EdgesOfWire.Remove(itl);
7fd59977 2112 }
903f7584 2113 else
2114 itl.Next();
2115 }
2116
7fd59977 2117 Standard_Real Vfirst, Vlast;
2118 if (p2d1.Y() > 0.)
903f7584 2119 {
2120 Vfirst = p2d1.Y(); Vlast = M_PI/2.;
2121 }
7fd59977 2122 else
903f7584 2123 {
2124 Vfirst = -M_PI/2.; Vlast = p2d1.Y();
2125 }
1c72dff6 2126 TopoDS_Face NewSphericalFace = BRepLib_MakeFace(aSphSurf, Ufirst, Ulast, Vfirst, Vlast, Precision::Confusion());
cc9f4591 2127 TopoDS_Edge OldEdge, DegEdge;
2128 for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
2129 {
2130 DegEdge = TopoDS::Edge(Explo.Current());
2131 if (BRep_Tool::Degenerated(DegEdge))
2132 break;
2133 }
2134 TopoDS_Vertex DegVertex = TopExp::FirstVertex(DegEdge);
7fd59977 2135 for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
903f7584 2136 {
2137 OldEdge = TopoDS::Edge(Explo.Current());
cc9f4591 2138 TopoDS_Vertex V1, V2;
2139 TopExp::Vertices(OldEdge, V1, V2);
2140 if (!V1.IsSame(DegVertex) && !V2.IsSame(DegVertex))
2141 break;
903f7584 2142 }
7fd59977 2143 TopoDS_Vertex V1, V2;
2144 TopExp::Vertices(OldEdge, V1, V2);
2145 TopTools_ListOfShape LV1, LV2;
cc9f4591 2146 LV1.Append(Vf1.Oriented(TopAbs_FORWARD));
2147 LV2.Append(CurVertex.Oriented(TopAbs_FORWARD));
7fd59977 2148 BRepTools_Substitution theSubstitutor;
cc9f4591 2149 theSubstitutor.Substitute(V1.Oriented(TopAbs_FORWARD), LV1);
7fd59977 2150 if (!V1.IsSame(V2))
cc9f4591 2151 theSubstitutor.Substitute(V2.Oriented(TopAbs_FORWARD), LV2);
2152 theSubstitutor.Substitute(OldEdge.Oriented(TopAbs_FORWARD), NewEdges);
7fd59977 2153 theSubstitutor.Build(NewSphericalFace);
2154 if (theSubstitutor.IsCopied(NewSphericalFace))
903f7584 2155 {
2156 const TopTools_ListOfShape& listSh = theSubstitutor.Copy(NewSphericalFace);
2157 NewSphericalFace = TopoDS::Face(listSh.First());
2158 }
2159
7fd59977 2160 //Adding NewSphericalFace to the shell
2161 Explo.Init( myOffsetShape, TopAbs_SHELL );
2162 TopoDS_Shape theShell = Explo.Current();
2163 theShell.Free( Standard_True );
2164 BB.Add( theShell, NewSphericalFace );
db2f1498 2165 IsModified = Standard_True;
2166 if(!theShell.Closed())
2167 {
2168 if(BRep_Tool::IsClosed(theShell))
2169 {
2170 theShell.Closed(Standard_True);
2171 }
2172 }
7fd59977 2173 }
db2f1498 2174 //
2175 if(!IsModified)
2176 {
2177 return;
2178 }
2179 //
903f7584 2180 if (myShape.ShapeType() == TopAbs_SOLID || myThickening)
2181 {
db2f1498 2182 //Explo.Init( myOffsetShape, TopAbs_SHELL );
2183
2184 //if (Explo.More()) {
2185 // TopoDS_Shape theShell = Explo.Current();
2186 // theShell.Closed( Standard_True );
2187 //}
2188
903f7584 2189 Standard_Integer NbShell = 0;
2190 TopoDS_Compound NC;
2191 TopoDS_Shape S1;
2192 BB.MakeCompound (NC);
db2f1498 2193
2194 TopoDS_Solid Sol;
2195 BB.MakeSolid(Sol);
2196 Sol.Closed(Standard_True);
903f7584 2197 for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
db2f1498 2198 TopoDS_Shell Sh = TopoDS::Shell(Explo.Current());
2199 //if (myThickening && myOffset > 0.)
2200 // Sh.Reverse();
903f7584 2201 NbShell++;
2202 if (Sh.Closed()) {
db2f1498 2203 BB.Add(Sol,Sh);
903f7584 2204 }
2205 else {
2206 BB.Add (NC,Sh);
db2f1498 2207 if(NbShell == 1)
2208 {
2209 S1 = Sh;
2210 }
903f7584 2211 }
7fd59977 2212 }
db2f1498 2213 TopoDS_Iterator anIt(Sol);
2214 Standard_Boolean SolIsNull = !anIt.More();
2215 //Checking solid
2216 if(!SolIsNull)
2217 {
2218 Standard_Integer nbs = 0;
2219 while(anIt.More()) {anIt.Next(); ++nbs;}
2220 if(nbs > 1)
2221 {
2222 BRepCheck_Analyzer aCheck(Sol, Standard_False);
2223 if(!aCheck.IsValid())
2224 {
2225 TopTools_ListOfShape aSolList;
2226 CorrectSolid(Sol, aSolList);
2227 if(!aSolList.IsEmpty())
2228 {
2229 BB.Add(NC, Sol);
2230 TopTools_ListIteratorOfListOfShape aSLIt(aSolList);
2231 for(; aSLIt.More(); aSLIt.Next())
2232 {
2233 BB.Add(NC, aSLIt.Value());
2234 }
2235 SolIsNull = Standard_True;
2236 }
2237 }
2238 }
2239 }
2240 //
2241 anIt.Initialize(NC);
2242 Standard_Boolean NCIsNull = !anIt.More();
2243 if((!SolIsNull) && (!NCIsNull))
2244 {
2245 BB.Add(NC, Sol);
2246 myOffsetShape = NC;
2247 }
2248 else if(SolIsNull && (!NCIsNull))
2249 {
2250 if (NbShell == 1)
2251 {
2252 myOffsetShape = S1;
2253 }
2254 else
2255 {
2256 myOffsetShape = NC;
2257 }
2258 }
2259 else if((!SolIsNull) && NCIsNull)
2260 {
2261 myOffsetShape = Sol;
2262 }
2263 else
2264 {
2265 myOffsetShape = NC;
2266 }
7fd59977 2267 }
7fd59977 2268}
2269
2270
2271//=======================================================================
2272//function : Intersection3D
2273//purpose :
2274//=======================================================================
2275
2276void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
2277{
0797d9d3 2278#ifdef OCCT_DEBUG
7fd59977 2279 if (ChronBuild) {
2280 cout << " INTERSECTION 3D:" << endl;
2281 Clock.Reset();
2282 Clock.Start();
2283 }
2284#endif
0d969553 2285 TopTools_ListOfShape OffsetFaces; // list of faces // created.
7fd59977 2286 MakeList (OffsetFaces,myInitOffsetFace,myFaces);
2287
2288 if (!myFaces.IsEmpty()) {
0d969553
Y
2289 Standard_Boolean InSide = (myOffset < 0.); // Temporary
2290 // it is necessary to calculate Inside taking account of the concavity or convexity of edges
2291 // between the cap and the part.
7fd59977 2292
2293 if (myJoin == GeomAbs_Arc)
2294 Inter.ContextIntByArc (myFaces,InSide,myAnalyse,myInitOffsetFace,myInitOffsetEdge);
2295 }
2296 if (myInter) {
2297 //-------------
0d969553 2298 //Complete.
7fd59977 2299 //-------------
2300 Inter.CompletInt (OffsetFaces,myInitOffsetFace);
975ec82a 2301 TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
7fd59977 2302 if (myJoin == GeomAbs_Intersection) {
2303 BRepOffset_Tool::CorrectOrientation (myShape,NewEdges,myAsDes,myInitOffsetFace,myOffset);
2304 }
2305 }
2306 else {
2307 //--------------------------------
0d969553 2308 // Only between neighbor faces.
7fd59977 2309 //--------------------------------
2310 Inter.ConnexIntByArc(OffsetFaces,myShape,myAnalyse,myInitOffsetFace);
2311 }
0797d9d3 2312#ifdef OCCT_DEBUG
7fd59977 2313 if ( ChronBuild) Clock.Show();
2314#endif
2315}
2316
2317//=======================================================================
2318//function : Intersection2D
2319//purpose :
2320//=======================================================================
2321
975ec82a 2322void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Modif,
9b7f3f83 2323 const TopTools_IndexedMapOfShape& NewEdges)
7fd59977 2324{
0797d9d3 2325#ifdef OCCT_DEBUG
7fd59977 2326 if (ChronBuild) {
2327 cout << " INTERSECTION 2D:" << endl;
2328 Clock.Reset();
2329 Clock.Start();
2330 }
2331#endif
0d969553
Y
2332 //--------------------------------------------------------
2333 // calculate intersections2d on faces concerned by
7fd59977 2334 // intersection3d
975ec82a
J
2335 //---------------------------------------------------------
2336 //TopTools_MapIteratorOfMapOfShape it(Modif);
7fd59977 2337 //-----------------------------------------------
0d969553 2338 // Intersection of edges 2 by 2.
7fd59977 2339 //-----------------------------------------------
b0fbc579 2340 TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
975ec82a
J
2341 Standard_Integer i;
2342 for (i = 1; i <= Modif.Extent(); i++) {
2343 const TopoDS_Face& F = TopoDS::Face(Modif(i));
b0fbc579 2344 BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol, aDMVV);
7fd59977 2345 }
b0fbc579 2346 //
2347 BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
2348 //
0797d9d3 2349#ifdef OCCT_DEBUG
7fd59977 2350 if (AffichInt2d) {
2351 DEBVerticesControl (NewEdges,myAsDes);
2352 }
2353 if ( ChronBuild) Clock.Show();
2354#endif
2355}
2356
2357
2358//=======================================================================
2359//function : MakeLoops
2360//purpose :
2361//=======================================================================
2362
975ec82a 2363void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
7fd59977 2364{
0797d9d3 2365#ifdef OCCT_DEBUG
7fd59977 2366 if (ChronBuild) {
2367 cout << " DEBOUCLAGE 2D:" << endl;
2368 Clock.Reset();
2369 Clock.Start();
2370 }
2371#endif
975ec82a 2372 //TopTools_MapIteratorOfMapOfShape it(Modif);
7fd59977 2373 TopTools_ListOfShape LF,LC;
2374 //-----------------------------------------
0d969553 2375 // unwinding of faces // modified.
7fd59977 2376 //-----------------------------------------
975ec82a
J
2377 Standard_Integer i;
2378 for (i = 1; i <= Modif.Extent(); i++) {
2379 if (!myFaces.Contains(Modif(i)))
2380 LF.Append(Modif(i));
7fd59977 2381 }
9b7f3f83 2382 //
ecf4f17c 2383 if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar) {
2384 BuildSplitsOfTrimmedFaces(LF, myAsDes, myImageOffset);
9b7f3f83 2385 }
2386 else {
2387 myMakeLoops.Build(LF,myAsDes,myImageOffset);
2388 }
7fd59977 2389
2390 //-----------------------------------------
0d969553 2391 // unwinding of caps.
7fd59977 2392 //-----------------------------------------
975ec82a
J
2393 for (i = 1; i <= myFaces.Extent(); i++)
2394 LC.Append(myFaces(i));
2395
7fd59977 2396 Standard_Boolean InSide = 1;
2397 if (myOffset > 0 ) InSide = 0;
2398 myMakeLoops.BuildOnContext(LC,myAnalyse,myAsDes,myImageOffset,InSide);
2399
0797d9d3 2400#ifdef OCCT_DEBUG
7fd59977 2401 if ( ChronBuild) Clock.Show();
2402#endif
2403}
2404
2405//=======================================================================
2406//function : MakeFaces
0d969553
Y
2407//purpose : Reconstruction of topologically unchanged faces that
2408// share edges that were reconstructed.
7fd59977 2409//=======================================================================
2410
35e08fe8 2411void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
7fd59977 2412{
0797d9d3 2413#ifdef OCCT_DEBUG
7fd59977 2414 if (ChronBuild) {
0d969553 2415 cout << " RECONSTRUCTION OF FACES:" << endl;
7fd59977 2416 Clock.Reset();
2417 Clock.Start();
2418 }
2419#endif
2420 TopTools_ListIteratorOfListOfShape itr;
2421 const TopTools_ListOfShape& Roots = myInitOffsetFace.Roots();
2422 TopTools_ListOfShape LOF;
2423 //----------------------------------
0d969553 2424 // Loop on all faces //.
7fd59977 2425 //----------------------------------
2426 for (itr.Initialize(Roots); itr.More(); itr.Next()) {
2427 TopoDS_Face F = TopoDS::Face(myInitOffsetFace.Image(itr.Value()).First());
9b7f3f83 2428 if (!myImageOffset.HasImage(F)) {
2429 LOF.Append(F);
2430 }
2431 }
2432 //
ecf4f17c 2433 if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar) {
2434 BuildSplitsOfTrimmedFaces(LOF, myAsDes, myImageOffset);
9b7f3f83 2435 }
2436 else {
2437 myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
7fd59977 2438 }
7fd59977 2439
0797d9d3 2440#ifdef OCCT_DEBUG
7fd59977 2441 if ( ChronBuild) Clock.Show();
2442#endif
2443}
2444
2445//=======================================================================
2446//function : UpdateInitOffset
0d969553 2447//purpose : Update and cleaning of myInitOffset
7fd59977 2448//=======================================================================
7fd59977 2449static void UpdateInitOffset (BRepAlgo_Image& myInitOffset,
9b7f3f83 2450 BRepAlgo_Image& myImageOffset,
2451 const TopoDS_Shape& myOffsetShape,
2452 const TopAbs_ShapeEnum &theShapeType) // skv
7fd59977 2453{
2454 BRepAlgo_Image NIOF;
2455 const TopTools_ListOfShape& Roots = myInitOffset.Roots();
2456 TopTools_ListIteratorOfListOfShape it(Roots);
2457 for (; it.More(); it.Next()) {
2458 NIOF.SetRoot (it.Value());
2459 }
2460 for (it.Initialize(Roots); it.More(); it.Next()) {
2461 const TopoDS_Shape& SI = it.Value();
2462 TopTools_ListOfShape LI;
2463 TopTools_ListOfShape L1;
2464 myInitOffset.LastImage(SI,L1);
2465 TopTools_ListIteratorOfListOfShape itL1(L1);
2466 for (; itL1.More(); itL1.Next()) {
2467 const TopoDS_Shape& O1 = itL1.Value();
2468 TopTools_ListOfShape L2;
2469 myImageOffset.LastImage(O1,L2);
2470 LI.Append(L2);
2471 }
2472 NIOF.Bind(SI,LI);
2473 }
2474// Modified by skv - Mon Apr 4 18:17:27 2005 Begin
2475// Supporting history.
2476// NIOF.Filter(myOffsetShape,TopAbs_FACE);
2477 NIOF.Filter(myOffsetShape, theShapeType);
2478// Modified by skv - Mon Apr 4 18:17:27 2005 End
2479 myInitOffset = NIOF;
2480}
2481
2482//=======================================================================
2483//function : MakeMissingWalls
2484//purpose :
2485//=======================================================================
7fd59977 2486void BRepOffset_MakeOffset::MakeMissingWalls ()
2487{
2488 TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
2489 TopTools_DataMapOfShapeShape MapEF; //Edges of contours: edge + face
2490 Standard_Real OffsetVal = Abs(myOffset);
2491
2492 FillContours(myShape, myAnalyse, Contours, MapEF);
2493
2494 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(Contours);
2495 for (; iter.More(); iter.Next())
a8704c36 2496 {
2497 TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key());
2498 TopoDS_Edge StartEdge;
2499 const TopTools_ListOfShape& aContour = iter.Value();
2500 TopTools_ListIteratorOfListOfShape itl(aContour);
2501 Standard_Boolean FirstStep = Standard_True;
2502 TopoDS_Edge PrevEdge;
2503 TopoDS_Vertex PrevVertex = StartVertex;
2504 Standard_Boolean isBuildFromScratch = Standard_False; // Problems with edges.
2505 for (; itl.More(); itl.Next())
7fd59977 2506 {
a8704c36 2507 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
2508
2509 // Check for offset existence.
2510 if (!myInitOffsetEdge.HasImage(anEdge))
2511 continue;
2512
2513 // Check for existence of two different vertices.
2514 TopTools_ListOfShape LOE, LOE2;
2515 myInitOffsetEdge.LastImage( anEdge, LOE );
2516 myImageOffset.LastImage( LOE.Last(), LOE2 );
2517 TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
2518 TopoDS_Vertex V1, V2, V3, V4;
2519 TopExp::Vertices(OE, V4, V3);
2520 TopExp::Vertices(anEdge, V1, V2);
2521 Standard_Real aF, aL;
2522 const Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aF, aL);
2523 if (!aC.IsNull() &&
2524 (!aC->IsClosed() && !aC->IsPeriodic()))
2525 {
2526 gp_Pnt aPntF = BRep_Tool::Pnt(V1);
2527 gp_Pnt aPntL = BRep_Tool::Pnt(V2);
2528 Standard_Real aDistE = aPntF.SquareDistance(aPntL);
2529 if ( aDistE < Precision::SquareConfusion())
2530 {
2531 // Bad case: non closed, but vertexes mapped to same 3d point.
2532 continue;
2533 }
2534
2535 Standard_Real anEdgeTol = BRep_Tool::Tolerance(anEdge);
2536 if (aDistE < anEdgeTol)
2537 {
2538 // Potential problems not detected via checkshape.
2539 gp_Pnt aPntOF = BRep_Tool::Pnt(V4);
2540 gp_Pnt aPntOL = BRep_Tool::Pnt(V3);
2541 if (aPntOF.SquareDistance(aPntOL) > gp::Resolution())
de878dad 2542 {
a8704c36 2543 // To avoid computation of complex analytical continuation of Sin / ArcSin.
2544 Standard_Real aSinValue = Min(2 * anEdgeTol / aPntOF.Distance(aPntOL), 1.0);
2545 Standard_Real aMaxAngle = Min(Abs(ASin(aSinValue)), M_PI_4); // Maximal angle.
2546 Standard_Real aCurrentAngle = gp_Vec(aPntF, aPntL).Angle(gp_Vec(aPntOF, aPntOL));
2547 if (aC->IsKind(STANDARD_TYPE(Geom_Line)) &&
2548 Abs (aCurrentAngle) > aMaxAngle)
2549 {
2550 // anEdge not collinear to offset edge.
2551 isBuildFromScratch = Standard_True;
2552 myIsPerformSewing = Standard_True;
2553 continue;
2554 }
2555 }
2556 }
2557 }
2558
2559 Standard_Boolean ToReverse = Standard_False;
2560 if (!V1.IsSame(PrevVertex))
2561 {
2562 TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx;
2563 aVtx = V3; V3 = V4; V4 = aVtx;
2564 ToReverse = Standard_True;
2565 }
2566
2567 OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
2568 TopoDS_Edge E3, E4;
2569 Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
2570 if (FirstStep || isBuildFromScratch)
2571 {
2572 E4 = BRepLib_MakeEdge( V1, V4 );
2573 if (FirstStep)
2574 StartEdge = E4;
2575 }
2576 else
2577 E4 = PrevEdge;
2578 if (V2.IsSame(StartVertex) && !ArcOnV2)
2579 E3 = StartEdge;
2580 else
2581 E3 = BRepLib_MakeEdge( V2, V3 );
2582 E4.Reverse();
2583
2584 if (isBuildFromScratch)
2585 {
2586 E3.Reverse();
2587 E4.Reverse();
2588 }
2589
2590 TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
2591 const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
2592 Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
2593 Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD);
2594 BRep_Builder BB;
2595 TopoDS_Wire theWire;
2596 BB.MakeWire(theWire);
2597 if (ToReverse)
2598 {
2599 BB.Add(theWire, anEdge.Reversed());
2600 BB.Add(theWire, E3.Reversed());
2601 BB.Add(theWire, OE.Reversed());
2602 BB.Add(theWire, E4.Reversed());
2603 }
2604 else
2605 {
2606 BB.Add(theWire, anEdge);
2607 BB.Add(theWire, E3);
2608 BB.Add(theWire, OE);
2609 BB.Add(theWire, E4);
2610 }
2611
2612 BRepLib::BuildCurves3d( theWire, myTol );
2613 theWire.Closed(Standard_True);
2614 TopoDS_Face NewFace;
2615 Handle(Geom_Surface) theSurf;
2616 BRepAdaptor_Curve BAcurve(anEdge);
2617 BRepAdaptor_Curve BAcurveOE(OE);
2618 Standard_Real fpar = BAcurve.FirstParameter();
2619 Standard_Real lpar = BAcurve.LastParameter();
2620 gp_Pnt PonE = BAcurve.Value(fpar);
2621 gp_Pnt PonOE = BAcurveOE.Value(fpar);
2622 gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE );
2623 Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
2624 Standard_Boolean IsPlanar = Standard_False;
2625 if (BAcurve.GetType() == GeomAbs_Circle &&
2626 BAcurveOE.GetType() == GeomAbs_Circle)
2627 {
2628 gp_Circ aCirc = BAcurve.Circle();
2629 gp_Circ aCircOE = BAcurveOE.Circle();
2630 gp_Lin anAxisLine(aCirc.Axis());
2631 gp_Dir CircAxisDir = aCirc.Axis().Direction();
2632 if (aCirc.Axis().IsParallel(aCircOE.Axis(), Precision::Confusion()) &&
2633 anAxisLine.Contains(aCircOE.Location(), Precision::Confusion()))
2634 { //cylinder, plane or cone
2635 if (Abs(aCirc.Radius() - aCircOE.Radius()) <= Precision::Confusion()) //case of cylinder
2636 theSurf = GC_MakeCylindricalSurface(aCirc).Value();
2637 else if (aCirc.Location().Distance(aCircOE.Location()) <= Precision::Confusion()) {//case of plane
2638 IsPlanar = Standard_True;
2639 //
2640 gp_Pnt PonEL = BAcurve.Value(lpar);
2641 if (PonEL.Distance(PonE) <= Precision::PConfusion()) {
2642 Standard_Boolean bIsHole;
2643 TopoDS_Edge aE1, aE2;
2644 TopoDS_Wire aW1, aW2;
2645 Handle(Geom_Plane) aPL;
2646 IntTools_FClass2d aClsf;
2647 //
2648 if (aCirc.Radius()>aCircOE.Radius()) {
2649 aE1 = anEdge;
2650 aE2 = OE;
2651 } else {
2652 aE1 = OE;
2653 aE2 = anEdge;
2654 }
2655 //
2656 BB.MakeWire(aW1);
2657 BB.Add(aW1, aE1);
2658 BB.MakeWire(aW2);
2659 BB.Add(aW2, aE2);
2660 //
2661 aPL = new Geom_Plane(aCirc.Location(), CircAxisDir);
2662 for (Standard_Integer i = 0; i < 2; ++i) {
2663 TopoDS_Wire& aW = (i==0) ? aW1 : aW2;
2664 TopoDS_Edge& aE = (i==0) ? aE1 : aE2;
bb310307 2665 //
a8704c36 2666 TopoDS_Face aFace;
2667 BB.MakeFace(aFace, aPL, Precision::Confusion());
2668 BB.Add (aFace, aW);
2669 aClsf.Init(aFace, Precision::Confusion());
2670 bIsHole=aClsf.IsHole();
2671 if ((bIsHole && !i) || (!bIsHole && i)) {
2672 aW.Nullify();
2673 BB.MakeWire(aW);
2674 BB.Add(aW, aE.Reversed());
bb310307 2675 }
2676 }
a8704c36 2677 //
2678 BB.MakeFace(NewFace, aPL, Precision::Confusion());
2679 BB.Add(NewFace, aW1);
2680 BB.Add(NewFace, aW2);
2681 }
2682 }
2683 else //case of cone
2684 {
2685 gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(),
2686 aCirc.Radius(), aCircOE.Radius());
2687 gp_Ax3 theAx3(aCirc.Position());
2688 if (CircAxisDir * theCone.Axis().Direction() < 0.)
2689 {
2690 theAx3.ZReverse();
2691 CircAxisDir.Reverse();
2692 }
2693 theCone.SetPosition(theAx3);
2694 theSurf = new Geom_ConicalSurface(theCone);
2695 }
2696 if (!IsPlanar) {
2697 TopLoc_Location Loc;
2698 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.));
2699 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2700 Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.;
2701 OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.));
2702 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2703 aLine2d = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff));
2704 aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff));
2705 if (E3.IsSame(E4))
2706 {
2707 if (Coeff > 0.)
2708 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2709 else
de878dad 2710 {
a8704c36 2711 BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion());
2712 theWire.Nullify();
2713 BB.MakeWire(theWire);
2714 BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED));
2715 BB.Add(theWire, E4);
2716 BB.Add(theWire, OE.Oriented(TopAbs_FORWARD));
2717 BB.Add(theWire, E3);
2718 theWire.Closed(Standard_True);
de878dad 2719 }
a8704c36 2720 }
2721 else
2722 {
2723 BB.SameParameter(E3, Standard_False);
2724 BB.SameRange(E3, Standard_False);
2725 BB.SameParameter(E4, Standard_False);
2726 BB.SameRange(E4, Standard_False);
2727 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
2728 BB.Range(E3, theSurf, Loc, 0., OffsetVal);
2729 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2730 BB.Range(E4, theSurf, Loc, 0., OffsetVal);
2731 }
2732 NewFace = BRepLib_MakeFace(theSurf, theWire);
2733 }
2734 } //cylinder or cone
2735 } //if both edges are arcs of circles
2736 if (NewFace.IsNull())
2737 {
2738 BRepLib_MakeFace MF(theWire, Standard_True); //Only plane
2739 if (MF.Error() == BRepLib_FaceDone)
2740 {
2741 NewFace = MF.Face();
2742 IsPlanar = Standard_True;
2743 }
2744 else //Extrusion (by thrusections)
2745 {
2746 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
2747 Handle(Geom_TrimmedCurve) TrEdgeCurve =
2748 new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
2749 Standard_Real fparOE, lparOE;
2750 Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE);
2751 Handle(Geom_TrimmedCurve) TrOffsetCurve =
2752 new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
2753 GeomFill_Generator ThrusecGenerator;
2754 ThrusecGenerator.AddCurve( TrEdgeCurve );
2755 ThrusecGenerator.AddCurve( TrOffsetCurve );
2756 ThrusecGenerator.Perform( Precision::PConfusion() );
2757 theSurf = ThrusecGenerator.Surface();
2758 //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
2759 Standard_Real Uf, Ul, Vf, Vl;
2760 theSurf->Bounds(Uf, Ul, Vf, Vl);
2761 TopLoc_Location Loc;
2762 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
2763 BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2764 OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
2765 BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2766 Standard_Real UonV1 = (ToReverse)? Ul : Uf;
2767 Standard_Real UonV2 = (ToReverse)? Uf : Ul;
2768 aLine2d = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
2769 aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
2770 if (E3.IsSame(E4))
2771 {
2772 BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2773 Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
2774 BB.UpdateEdge(E3, BSplC34, Precision::Confusion());
2775 BB.Range(E3, Vf, Vl);
2776 }
2777 else
2778 {
2779 BB.SameParameter(E3, Standard_False);
2780 BB.SameRange(E3, Standard_False);
2781 BB.SameParameter(E4, Standard_False);
2782 BB.SameRange(E4, Standard_False);
2783 BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion());
2784 BB.Range(E3, theSurf, Loc, Vf, Vl);
2785 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2786 BB.Range(E4, theSurf, Loc, Vf, Vl);
2787 Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
2788 BB.UpdateEdge(E3, BSplC3, Precision::Confusion());
2789 BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve
2790 Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
2791 BB.UpdateEdge(E4, BSplC4, Precision::Confusion());
2792 BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve
2793 }
2794 NewFace = BRepLib_MakeFace(theSurf, theWire);
2795 }
2796 }
2797 if (!IsPlanar)
2798 {
2799 Standard_Real fparOE = BAcurveOE.FirstParameter();
2800 Standard_Real lparOE = BAcurveOE.LastParameter();
2801 TopLoc_Location Loc;
2802 if (Abs(fpar - fparOE) > Precision::Confusion())
2803 {
2804 const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4;
2805 gp_Pnt2d fp2d = EdgeLine2d->Value(fpar);
2806 gp_Pnt2d fp2dOE = OELine2d->Value(fparOE);
2807 aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value();
2808 Handle(Geom_Curve) aCurve;
2809 Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE);
2810 Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar );
2811 GeomAdaptor_Surface GAsurf( theSurf );
2812 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
2813 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
2814 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
2815 Standard_Real max_deviation = 0., average_deviation;
2816 GeomLib::BuildCurve3d(Precision::Confusion(),
2817 ConS, FirstPar, LastPar,
2818 aCurve, max_deviation, average_deviation);
2819 BB.UpdateEdge( anE4, aCurve, max_deviation );
2820 BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation );
2821 BB.Range( anE4, FirstPar, LastPar );
2822 }
2823 if (Abs(lpar - lparOE) > Precision::Confusion())
2824 {
2825 const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3;
2826 gp_Pnt2d lp2d = EdgeLine2d->Value(lpar);
2827 gp_Pnt2d lp2dOE = OELine2d->Value(lparOE);
2828 aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value();
2829 Handle(Geom_Curve) aCurve;
2830 Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE);
2831 Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar );
2832 GeomAdaptor_Surface GAsurf( theSurf );
2833 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
2834 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
2835 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
2836 Standard_Real max_deviation = 0., average_deviation;
2837 GeomLib::BuildCurve3d(Precision::Confusion(),
2838 ConS, FirstPar, LastPar,
2839 aCurve, max_deviation, average_deviation);
2840 BB.UpdateEdge( anE3, aCurve, max_deviation );
2841 BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation );
2842 BB.Range( anE3, FirstPar, LastPar );
2843 }
2844 }
2845 BRepLib::SameParameter(NewFace);
2846 BRepTools::Update(NewFace);
2847 myWalls.Append(NewFace);
2848 if (ArcOnV2)
2849 {
2850 TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First());
2851 TopoDS_Vertex arcV1, arcV2;
2852 TopExp::Vertices(anArc, arcV1, arcV2);
2853 Standard_Boolean ArcReverse = Standard_False;
2854 if (!arcV1.IsSame(V3))
2855 {
2856 TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx;
2857 ArcReverse = Standard_True;
2858 }
2859 TopoDS_Edge EA1, EA2;
2860 //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed());
2861 EA1 = E3;
2862 EA1.Reverse();
2863 if (ToReverse)
2864 EA1.Reverse();
2865 //////////////////////////////////////////////////////
2866 if (V2.IsSame(StartVertex))
2867 EA2 = StartEdge;
2868 else
2869 EA2 = BRepLib_MakeEdge( V2, arcV2 );
2870 anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) );
2871 if (EA1.Orientation() == TopAbs_REVERSED)
2872 anArc.Reverse();
2873 EA2.Orientation(TopAbs::Reverse(EA1.Orientation()));
2874 TopoDS_Wire arcWire;
2875 BB.MakeWire(arcWire);
2876 BB.Add(arcWire, EA1);
2877 BB.Add(arcWire, anArc);
2878 BB.Add(arcWire, EA2);
2879 BRepLib::BuildCurves3d( arcWire, myTol );
2880 arcWire.Closed(Standard_True);
2881 TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True);
2882 BRepTools::Update(arcFace);
2883 myWalls.Append(arcFace);
2884 TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD);
2885 const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2);
2886 PrevEdge = CEA2;
2887 PrevVertex = V2;
2888 }
2889 else
2890 {
2891 if (isBuildFromScratch)
2892 {
2893 PrevEdge = TopoDS::Edge(E4);
2894 PrevVertex = V1;
2895 isBuildFromScratch = Standard_False;
2896 }
2897 else
2898 {
2899 PrevEdge = E3;
2900 PrevVertex = V2;
2901 }
2902 }
2903 FirstStep = Standard_False;
7fd59977 2904 }
a8704c36 2905 }
7fd59977 2906}
2907
2908//=======================================================================
2909//function : MakeShells
2910//purpose :
2911//=======================================================================
2912
2913void BRepOffset_MakeOffset::MakeShells ()
2914{
0797d9d3 2915#ifdef OCCT_DEBUG
7fd59977 2916 if (ChronBuild) {
0d969553 2917 cout << " RECONSTRUCTION OF SHELLS:" << endl;
7fd59977 2918 Clock.Reset();
2919 Clock.Start();
2920 }
2921#endif
9b7f3f83 2922 //
2923 TopTools_IndexedDataMapOfShapeListOfShape anOrigins;
2924 //
2925 BOPCol_ListOfShape aLSF;
7fd59977 2926 const TopTools_ListOfShape& R = myImageOffset.Roots();
2927 TopTools_ListIteratorOfListOfShape it(R);
9b7f3f83 2928 //
2929 for (; it.More(); it.Next()) {
ecf4f17c 2930 const TopoDS_Shape& aF = it.Value();
2931 //
7fd59977 2932 TopTools_ListOfShape Image;
ecf4f17c 2933 myImageOffset.LastImage(aF,Image);
7fd59977 2934 TopTools_ListIteratorOfListOfShape it2(Image);
9b7f3f83 2935 for (; it2.More(); it2.Next()) {
ecf4f17c 2936 const TopoDS_Shape& aFIm = it2.Value();
2937 aLSF.Append(aFIm);
9b7f3f83 2938 //
ecf4f17c 2939 TopTools_ListOfShape *pLOr = anOrigins.ChangeSeek(aFIm);
2940 if (!pLOr) {
2941 pLOr = &anOrigins(anOrigins.Add(aFIm, TopTools_ListOfShape()));
9b7f3f83 2942 }
ecf4f17c 2943 pLOr->Append(aF);
7fd59977 2944 }
2945 }
9b7f3f83 2946 //
2947 if (myThickening) {
db2f1498 2948 TopExp_Explorer Explo(myShape, TopAbs_FACE);
9b7f3f83 2949 for (; Explo.More(); Explo.Next()) {
2950 const TopoDS_Shape& aF = Explo.Current();
2951 aLSF.Append(aF);
2952 }
2953 //
2954 it.Initialize(myWalls);
2955 for (; it.More(); it.Next()) {
2956 const TopoDS_Shape& aF = it.Value();
2957 aLSF.Append(aF);
2958 }
2959 }
2960 //
ecf4f17c 2961 if (aLSF.IsEmpty()) {
2962 return;
2963 }
2964 //
9b7f3f83 2965 Standard_Boolean bDone = Standard_False;
2966 if ((myJoin == GeomAbs_Intersection) && myInter &&
2967 !myThickening && myFaces.IsEmpty() &&
2968 IsSolid(myShape) && myIsPlanar) {
2969 //
ecf4f17c 2970 TopoDS_Shape aShells;
2971 bDone = BuildShellsCompleteInter(aLSF, anOrigins, myImageOffset, aShells);
9b7f3f83 2972 if (bDone) {
ecf4f17c 2973 myOffsetShape = aShells;
9b7f3f83 2974 }
2975 }
2976 //
2977 if (!bDone) {
2978 BRepTools_Quilt Glue;
ecf4f17c 2979 BOPCol_ListIteratorOfListOfShape aItLS(aLSF);
9b7f3f83 2980 for (; aItLS.More(); aItLS.Next()) {
ecf4f17c 2981 Glue.Add(aItLS.Value());
9b7f3f83 2982 }
2983 myOffsetShape = Glue.Shells();
db2f1498 2984 }
db2f1498 2985 //
2986 //Set correct value for closed flag
2987 TopExp_Explorer Explo(myOffsetShape, TopAbs_SHELL);
2988 for(; Explo.More(); Explo.Next())
2989 {
2990 TopoDS_Shape aS = Explo.Current();
2991 if(!aS.Closed())
2992 {
2993 if(BRep_Tool::IsClosed(aS))
2994 {
2995 aS.Closed(Standard_True);
2996 }
2997 }
ecf4f17c 2998 }
7fd59977 2999}
3000
3001//=======================================================================
3002//function : MakeSolid
3003//purpose :
3004//=======================================================================
3005
3006void BRepOffset_MakeOffset::MakeSolid ()
3007{
3008 if (myOffsetShape.IsNull()) return;
3009
3010// Modified by skv - Mon Apr 4 18:17:27 2005 Begin
3011// Supporting history.
3012 UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE);
3013 UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE);
3014// Modified by skv - Mon Apr 4 18:17:27 2005 End
3015 TopExp_Explorer exp;
3016 BRep_Builder B;
3017 Standard_Integer NbShell = 0;
3018 TopoDS_Compound NC;
3019 TopoDS_Shape S1;
3020 B.MakeCompound (NC);
3021
db2f1498 3022 TopoDS_Solid Sol;
3023 B.MakeSolid(Sol);
3024 Sol.Closed(Standard_True);
3025 Standard_Boolean aMakeSolid = (myShape.ShapeType() == TopAbs_SOLID) || myThickening;
7fd59977 3026 for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
3027 TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
3028 if (myThickening && myOffset > 0.)
3029 Sh.Reverse();
3030 NbShell++;
db2f1498 3031 if (Sh.Closed() && aMakeSolid) {
3032 B.Add(Sol,Sh);
7fd59977 3033 }
3034 else {
3035 B.Add (NC,Sh);
db2f1498 3036 if(NbShell == 1)
3037 {
3038 S1 = Sh;
3039 }
3040 }
3041 }
3042 TopoDS_Iterator anIt(Sol);
3043 Standard_Boolean SolIsNull = !anIt.More();
3044 //Checking solid
3045 if(!SolIsNull)
3046 {
3047 Standard_Integer nbs = 0;
3048 while(anIt.More()) {anIt.Next(); ++nbs;}
3049 if(nbs > 1)
3050 {
3051 BRepCheck_Analyzer aCheck(Sol, Standard_False);
3052 if(!aCheck.IsValid())
3053 {
3054 TopTools_ListOfShape aSolList;
3055 CorrectSolid(Sol, aSolList);
3056 if(!aSolList.IsEmpty())
3057 {
3058 B.Add(NC, Sol);
3059 TopTools_ListIteratorOfListOfShape aSLIt(aSolList);
3060 for(; aSLIt.More(); aSLIt.Next())
3061 {
3062 B.Add(NC, aSLIt.Value());
3063 }
3064 SolIsNull = Standard_True;
3065 }
3066 }
7fd59977 3067 }
3068 }
db2f1498 3069 anIt.Initialize(NC);
3070 Standard_Boolean NCIsNull = !anIt.More();
3071 if((!SolIsNull) && (!NCIsNull))
3072 {
3073 B.Add(NC, Sol);
3074 myOffsetShape = NC;
3075 }
3076 else if(SolIsNull && (!NCIsNull))
3077 {
3078 if (NbShell == 1)
3079 {
3080 myOffsetShape = S1;
3081 }
3082 else
3083 {
3084 myOffsetShape = NC;
3085 }
3086 }
3087 else if((!SolIsNull) && NCIsNull)
3088 {
3089 myOffsetShape = Sol;
3090 }
3091 else
3092 {
3093 myOffsetShape = NC;
3094 }
7fd59977 3095}
3096
3097//=======================================================================
3098//function : SelectShells
3099//purpose :
3100//=======================================================================
3101
3102void BRepOffset_MakeOffset::SelectShells ()
ecf4f17c 3103{
7fd59977 3104 TopTools_MapOfShape FreeEdges;
3105 TopExp_Explorer exp(myShape,TopAbs_EDGE);
3106 //-------------------------------------------------------------
0d969553
Y
3107 // FreeEdges all edges that can have free border in the
3108 // parallel shell
3109 // 1 - free borders of myShape .
7fd59977 3110 //-------------------------------------------------------------
3111 for ( ; exp.More(); exp.Next()) {
3112 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3113 const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
3114 if (LA.Extent() < 2) {
3115 if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
9b7f3f83 3116 FreeEdges.Add(E);
7fd59977 3117 }
3118 }
3119 }
0d969553
Y
3120 // myShape has free borders and there are no caps
3121 // no unwinding 3d.
7fd59977 3122 if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return;
3123
3124 myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges);
3125}
3126
3127//=======================================================================
3128//function : OffsetFacesFromShapes
3129//purpose :
3130//=======================================================================
3131
3132const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
3133{
3134 return myInitOffsetFace;
3135}
3136
3137// Modified by skv - Tue Mar 15 16:20:43 2005 Begin
3138
3139//=======================================================================
3140//function : GetJoinType
3141//purpose : Query offset join type.
3142//=======================================================================
3143
3144GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
3145{
3146 return myJoin;
3147}
3148
3149//=======================================================================
3150//function : OffsetEdgesFromShapes
3151//purpose :
3152//=======================================================================
3153
3154const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
3155{
3156 return myInitOffsetEdge;
3157}
3158
3159// Modified by skv - Tue Mar 15 16:20:43 2005 End
3160
3161//=======================================================================
3162//function : ClosingFaces
3163//purpose :
3164//=======================================================================
3165
975ec82a 3166const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
7fd59977 3167{
3168 return myFaces;
3169}
3170
3171
3172
3173//=======================================================================
3174//function : EncodeRegularity
3175//purpose :
3176//=======================================================================
3177
3178void BRepOffset_MakeOffset::EncodeRegularity ()
3179{
0797d9d3 3180#ifdef OCCT_DEBUG
7fd59977 3181 if (ChronBuild) {
0d969553 3182 cout << " CODING OF REGULARITIES:" << endl;
7fd59977 3183 Clock.Reset();
3184 Clock.Start();
3185 }
3186#endif
3187
3188 if (myOffsetShape.IsNull()) return;
0d969553 3189 // find edges G1 in the result
7fd59977 3190 TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE);
3191
3192 BRep_Builder B;
3193 TopTools_MapOfShape MS;
3194
3195 for ( ; exp.More(); exp.Next()) {
3196 TopoDS_Edge OE = TopoDS::Edge(exp.Current());
3197 BRepLib::BuildCurve3d(OE,myTol);
3198 TopoDS_Edge ROE = OE;
3199
3200 if ( !MS.Add(OE)) continue;
3201
3202 if ( myImageOffset.IsImage(OE))
3203 ROE = TopoDS::Edge(myImageOffset.Root(OE));
3204
3205 const TopTools_ListOfShape& LofOF = myAsDes->Ascendant(ROE);
3206
3207 if (LofOF.Extent() != 2) {
0797d9d3 3208#ifdef OCCT_DEBUG_VERB
498ce76b 3209 cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl;
7fd59977 3210#endif
3211 continue;
3212 }
3213
3214 const TopoDS_Face& F1 = TopoDS::Face(LofOF.First());
3215 const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() );
3216
3217 if ( F1.IsNull() || F2.IsNull())
3218 continue;
3219
3220 const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1);
3221 const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2);
3222
3223 TopAbs_ShapeEnum Type1 = Root1.ShapeType();
3224 TopAbs_ShapeEnum Type2 = Root2.ShapeType();
3225
3226 if (F1.IsSame(F2)) {
3227 if (BRep_Tool::IsClosed(OE,F1)) {
9b7f3f83 3228 // Temporary Debug for the Bench.
3229 // Check with YFR.
3230 // In mode intersection, the edges are not coded in myInitOffsetEdge
3231 // so, manage case by case
3232 // Note DUB; for Hidden parts, it is NECESSARY to code CN
3233 // Analytic Surfaces.
3234 if (myJoin == GeomAbs_Intersection) {
3235 BRepAdaptor_Surface BS(F1,Standard_False);
3236 GeomAbs_SurfaceType SType = BS.GetType();
3237 if (SType == GeomAbs_Cylinder ||
3238 SType == GeomAbs_Cone ||
3239 SType == GeomAbs_Sphere ||
3240 SType == GeomAbs_Torus ) {
3241 B.Continuity(OE,F1,F1,GeomAbs_CN);
3242 }
3243 else {
3244 // See YFR : MaJ of myInitOffsetFace
3245 }
3246 }
3247 else if (myInitOffsetEdge.IsImage(ROE)) {
3248 if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
3249 const TopoDS_Face& FRoot = TopoDS::Face(Root1);
3250 const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE));
3251 GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot);
3252 if (Conti == GeomAbs_CN) {
3253 B.Continuity(OE,F1,F1,GeomAbs_CN);
3254 }
3255 else if ( Conti > GeomAbs_C0) {
3256 B.Continuity(OE,F1,F1,GeomAbs_G1);
3257 }
3258 }
3259 }
7fd59977 3260 }
3261 continue;
3262 }
3263
3264
0d969553
Y
3265 // code regularities G1 between :
3266 // - sphere and tube : one root is a vertex, the other is an edge
3267 // and the vertex is included in the edge
3268 // - face and tube : one root is a face, the other an edge
3269 // and the edge is included in the face
3270 // - face and face : if two root faces are tangent in
3271 // the initial shape, they will be tangent in the offset shape
3272 // - tube and tube : if 2 edges generating tubes are
3273 // tangents, the 2 will be tangent either.
7fd59977 3274 if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) {
3275 TopoDS_Vertex V1,V2;
3276 TopExp::Vertices(TopoDS::Edge(Root1), V1, V2);
3277 if ( V1.IsSame(Root2) || V2.IsSame(Root2)) {
9b7f3f83 3278 B.Continuity(OE,F1,F2,GeomAbs_G1);
7fd59977 3279 }
3280 }
3281 else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) {
3282 TopoDS_Vertex V1,V2;
3283 TopExp::Vertices(TopoDS::Edge(Root2), V1, V2);
3284 if ( V1.IsSame(Root1) || V2.IsSame(Root1)) {
9b7f3f83 3285 B.Continuity(OE,F1,F2,GeomAbs_G1);
7fd59977 3286 }
3287 }
3288 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) {
3289 TopExp_Explorer exp2(Root1,TopAbs_EDGE);
3290 for ( ; exp2.More(); exp2.Next()) {
9b7f3f83 3291 if ( exp2.Current().IsSame(Root2)) {
3292 B.Continuity(OE,F1,F2,GeomAbs_G1);
3293 break;
3294 }
7fd59977 3295 }
3296 }
3297 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) {
3298 TopExp_Explorer exp2(Root2,TopAbs_EDGE);
3299 for ( ; exp2.More(); exp2.Next()) {
9b7f3f83 3300 if ( exp2.Current().IsSame(Root1)) {
3301 B.Continuity(OE,F1,F2,GeomAbs_G1);
3302 break;
3303 }
7fd59977 3304 }
3305 }
3306 else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
0d969553
Y
3307 // if two root faces are tangent in
3308 // the initial shape, they will be tangent in the offset shape
fe1d4d6c 3309 TopTools_ListOfShape LE;
3310 BRepOffset_Tool::FindCommonShapes(Root1, Root2, TopAbs_EDGE, LE);
3311 if ( LE.Extent() == 1) {
9b7f3f83 3312 const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
3313 if ( myAnalyse.HasAncestor(Ed)) {
3314 const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
3315 if (LI.Extent() == 1 &&
3316 LI.First().Type() == BRepOffset_Tangent) {
3317 B.Continuity(OE,F1,F2,GeomAbs_G1);
3318 }
3319 }
7fd59977 3320 }
3321 }
3322 else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) {
3323 TopTools_ListOfShape LV;
fe1d4d6c 3324 BRepOffset_Tool::FindCommonShapes(Root1, Root2, TopAbs_VERTEX, LV);
7fd59977 3325 if ( LV.Extent() == 1) {
9b7f3f83 3326 TopTools_ListOfShape LEdTg;
3327 myAnalyse.TangentEdges(TopoDS::Edge(Root1),
3328 TopoDS::Vertex(LV.First()),
3329 LEdTg);
3330 TopTools_ListIteratorOfListOfShape it(LEdTg);
3331 for (; it.More(); it.Next()) {
3332 if ( it.Value().IsSame(Root2)) {
3333 B.Continuity(OE,F1,F2,GeomAbs_G1);
3334 break;
3335 }
3336 }
7fd59977 3337 }
3338 }
3339 }
3340
0797d9d3 3341#ifdef OCCT_DEBUG
7fd59977 3342 if ( ChronBuild) Clock.Show();
3343#endif
3344}
3345
4560c054 3346//=======================================================================
3347//function : ComputeMaxDist
3348//purpose :
3349//=======================================================================
3350Standard_Real ComputeMaxDist(const gp_Pln& thePlane,
3351 const Handle(Geom_Curve)& theCrv,
3352 const Standard_Real theFirst,
3353 const Standard_Real theLast)
3354{
3355 Standard_Real aMaxDist = 0.;
3356 Standard_Integer i, NCONTROL = 23;
3357 Standard_Real aPrm, aDist2;
3358 gp_Pnt aP;
3359 for (i = 0; i< NCONTROL; i++) {
3360 aPrm = ((NCONTROL - 1 - i)*theFirst + i*theLast) / (NCONTROL - 1);
3361 aP = theCrv->Value(aPrm);
3362 if (Precision::IsInfinite(aP.X()) || Precision::IsInfinite(aP.Y())
3363 || Precision::IsInfinite(aP.Z()))
3364 {
3365 return Precision::Infinite();
3366 }
3367 aDist2 = thePlane.SquareDistance(aP);
3368 if (aDist2 > aMaxDist) aMaxDist = aDist2;
3369 }
3370 return sqrt(aMaxDist)*1.05;
3371}
7fd59977 3372//=======================================================================
3373//function : UpDateTolerance
3374//purpose :
3375//=======================================================================
3376
db2f1498 3377void UpdateTolerance (TopoDS_Shape& S,
4560c054 3378 const TopTools_IndexedMapOfShape& Faces)
7fd59977 3379{
3380 BRep_Builder B;
3381 TopTools_MapOfShape View;
3382 TopoDS_Vertex V[2];
3383
0d969553 3384 // The edges of caps are not modified.
975ec82a
J
3385 Standard_Integer j;
3386 for (j = 1; j <= Faces.Extent(); j++) {
3387 const TopoDS_Shape& F = Faces(j);
7fd59977 3388 TopExp_Explorer Exp;
3389 for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
3390 View.Add(Exp.Current());
3391 }
3392 }
3393
4560c054 3394 Standard_Real Tol;
3395 TopExp_Explorer ExpF;
3396 for (ExpF.Init(S, TopAbs_FACE); ExpF.More(); ExpF.Next())
3397 {
3398 const TopoDS_Shape& F = ExpF.Current();
3399 if (Faces.Contains(F))
3400 {
3401 continue;
3402 }
3403 BRepAdaptor_Surface aBAS(TopoDS::Face(F), Standard_False);
3404 TopExp_Explorer Exp;
3405 for (Exp.Init(F, TopAbs_EDGE); Exp.More(); Exp.Next()) {
3406 TopoDS_Edge E = TopoDS::Edge(Exp.Current());
3407 Standard_Boolean isUpdated = Standard_False;
3408 if (aBAS.GetType() == GeomAbs_Plane)
3409 {
3410 //Edge does not seem to have pcurve on plane,
3411 //so EdgeCorrector does not include it in tolerance calculation
3412 Standard_Real aFirst, aLast;
3413 Handle(Geom_Curve) aCrv = BRep_Tool::Curve(E, aFirst, aLast);
3414 Standard_Real aMaxDist = ComputeMaxDist(aBAS.Plane(), aCrv, aFirst, aLast);
3415 B.UpdateEdge(E, aMaxDist);
3416 isUpdated = Standard_True;
3417 }
3418 if (View.Add(E))
3419 {
3420
3421 BRepCheck_Edge EdgeCorrector(E);
3422 Tol = EdgeCorrector.Tolerance();
3423 B.UpdateEdge(E, Tol);
3424 isUpdated = Standard_True;
3425 }
3426 if (isUpdated)
3427 {
3428 Tol = BRep_Tool::Tolerance(E);
3429 // Update the vertices.
3430 TopExp::Vertices(E, V[0], V[1]);
3431
3432 for (Standard_Integer i = 0; i <= 1; i++) {
3433 if (View.Add(V[i])) {
3434 Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape());
3435 TV->Tolerance(0.);
3436 BRepCheck_Vertex VertexCorrector(V[i]);
3437 B.UpdateVertex(V[i], VertexCorrector.Tolerance());
3438 // use the occasion to clean the vertices.
3439 (TV->ChangePoints()).Clear();
3440 }
3441 B.UpdateVertex(V[i], Tol);
9b7f3f83 3442 }
7fd59977 3443 }
3444 }
3445 }
3446}
3447
db2f1498 3448//=======================================================================
3449//function : CorrectSolid
3450//purpose :
3451//=======================================================================
3452void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList)
3453{
3454 BRep_Builder aBB;
3455 TopoDS_Shape anOuterShell;
3456 NCollection_List<Standard_Real> aVols;
3457 Standard_Real aVolMax = 0., anOuterVol = 0.;
3458
3459 TopoDS_Iterator anIt(theSol);
3460 for(; anIt.More(); anIt.Next())
3461 {
3462 const TopoDS_Shape& aSh = anIt.Value();
3463 GProp_GProps aVProps;
3464 BRepGProp::VolumeProperties(aSh, aVProps, Standard_True);
3465 if(Abs(aVProps.Mass()) > aVolMax)
3466 {
3467 anOuterVol = aVProps.Mass();
3468 aVolMax = Abs(anOuterVol);
3469 anOuterShell = aSh;
3470 }
3471 aVols.Append(aVProps.Mass());
3472 }
3473 //
ecf4f17c 3474 if (Abs(anOuterVol) < Precision::Confusion()) {
3475 return;
3476 }
db2f1498 3477 if(anOuterVol < 0.)
3478 {
3479 anOuterShell.Reverse();
3480 }
3481 TopoDS_Solid aNewSol;
3482 aBB.MakeSolid(aNewSol);
3483 aNewSol.Closed(Standard_True);
3484 aBB.Add(aNewSol, anOuterShell);
3485 BRepClass3d_SolidClassifier aSolClass(aNewSol);
3486 //
3487 anIt.Initialize(theSol);
3488 NCollection_List<Standard_Real>::Iterator aVIt(aVols);
3489 for(; anIt.More(); anIt.Next(), aVIt.Next())
3490 {
3491 TopoDS_Shell aSh = TopoDS::Shell(anIt.Value());
3492 if(aSh.IsSame(anOuterShell))
3493 {
3494 continue;
3495 }
3496 else
3497 {
3498 TopExp_Explorer aVExp(aSh, TopAbs_VERTEX);
3499 const TopoDS_Vertex& aV = TopoDS::Vertex(aVExp.Current());
3500 gp_Pnt aP = BRep_Tool::Pnt(aV);
3501 aSolClass.Perform(aP, BRep_Tool::Tolerance(aV));
3502 if(aSolClass.State() == TopAbs_IN)
3503 {
3504 if(aVIt.Value() > 0.)
3505 {
3506 aSh.Reverse();
3507 }
3508 aBB.Add(aNewSol, aSh);
3509 }
3510 else
3511 {
3512 if(aVIt.Value() < 0.)
3513 {
3514 aSh.Reverse();
3515 }
3516 TopoDS_Solid aSol;
3517 aBB.MakeSolid(aSol);
3518 aSol.Closed(Standard_True);
3519 aBB.Add(aSol, aSh);
3520 theSolList.Append(aSol);
3521 }
3522 }
3523 }
3524 theSol = aNewSol;
3525}
e1ed38e0 3526
3527//=======================================================================
3528//function : CheckInputData
3529//purpose : Check input data for possiblity of offset perform.
3530//=======================================================================
3531Standard_Boolean BRepOffset_MakeOffset::CheckInputData()
3532{
3533 // Set initial error state.
3534 myError = BRepOffset_NoError;
3535 TopoDS_Shape aTmpShape;
3536 myBadShape = aTmpShape;
3537
3538 // Non-null offset.
3539 if (Abs(myOffset) <= myTol)
3540 {
3541 Standard_Boolean isFound = Standard_False;
3542 TopTools_DataMapIteratorOfDataMapOfShapeReal anIter(myFaceOffset);
3543 for( ; anIter.More(); anIter.Next())
3544 {
3545 if (Abs(anIter.Value()) > myTol)
3546 {
3547 isFound = Standard_True;
3548 break;
3549 }
3550 }
3551
3552 if (!isFound)
3553 {
3554 // No face with non-null offset found.
3555 myError = BRepOffset_NullOffset;
3556 return Standard_False;
3557 }
3558 }
3559
3560 // Connectivity of input shape.
3561 if (!IsConnectedShell(myShape))
3562 {
3563 myError = BRepOffset_NotConnectedShell;
3564 return Standard_False;
3565 }
3566
3567 // Normals check and continuity check.
3568 const Standard_Integer aPntPerDim = 20; // 21 points on each dimension.
3569 Standard_Real aUmin, aUmax, aVmin, aVmax;
3570 TopExp_Explorer anExpSF(myShape, TopAbs_FACE);
3571 NCollection_Map<Handle(TopoDS_TShape)> aPresenceMap;
3572 TopLoc_Location L;
3573 gp_Pnt2d aPnt2d;
3574 for( ; anExpSF.More(); anExpSF.Next())
3575 {
3576 const TopoDS_Face& aF = TopoDS::Face(anExpSF.Current());
3577
3578 if (aPresenceMap.Contains(aF.TShape()))
3579 {
3580 // Not perform computations with partner shapes,
3581 // since they are contain same geometry.
3582 continue;
3583 }
3584 aPresenceMap.Add(aF.TShape());
3585
3586 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aF, L);
3587 BRepTools::UVBounds(aF, aUmin, aUmax, aVmin, aVmax);
3588
3589 // Continuity check.
3590 if (aSurf->Continuity() == GeomAbs_C0)
3591 {
3592 myError = BRepOffset_C0Geometry;
3593 return Standard_False;
3594 }
3595
3596 // Get degenerated points, to avoid check them.
3597 NCollection_Vector<gp_Pnt> aBad3dPnts;
3598 TopExp_Explorer anExpFE(aF, TopAbs_EDGE);
3599 for( ; anExpFE.More(); anExpFE.Next())
3600 {
3601 const TopoDS_Edge &aE = TopoDS::Edge(anExpFE.Current());
3602 if (BRep_Tool::Degenerated(aE))
3603 {
3604 aBad3dPnts.Append(BRep_Tool::Pnt((TopExp::FirstVertex(aE))));
3605 }
3606 }
3607
3608 // Geometry grid check.
3609 for(Standard_Integer i = 0; i <= aPntPerDim; i++)
3610 {
3611 Standard_Real aUParam = aUmin + (aUmax - aUmin) * i / aPntPerDim;
3612 for(Standard_Integer j = 0; j <= aPntPerDim; j++)
3613 {
3614 Standard_Real aVParam = aVmin + (aVmax - aVmin) * j / aPntPerDim;
3615
3616 myError = checkSinglePoint(aUParam, aVParam, aSurf, aBad3dPnts);
3617 if (myError != BRepOffset_NoError)
3618 return Standard_False;
3619 }
3620 }
3621
3622 // Vertex list check.
3623 TopExp_Explorer anExpFV(aF, TopAbs_VERTEX);
3624 for( ; anExpFV.More(); anExpFV.Next())
3625 {
3626 const TopoDS_Vertex &aV = TopoDS::Vertex(anExpFV.Current());
3627 aPnt2d = BRep_Tool::Parameters(aV, aF);
3628
3629 myError = checkSinglePoint(aPnt2d.X(), aPnt2d.Y(), aSurf, aBad3dPnts);
3630 if (myError != BRepOffset_NoError)
3631 return Standard_False;
3632 }
3633 }
3634
3635 return Standard_True;
3636}
3637
3638
3639//=======================================================================
3640//function : GetBadShape
3641//purpose : Get shape where problems detected.
3642//=======================================================================
3643const TopoDS_Shape& BRepOffset_MakeOffset::GetBadShape() const
3644{
3645 return myBadShape;
3646}
3647
9b7f3f83 3648//=======================================================================
3649//function : RemoveInternalEdges
3650//purpose :
3651//=======================================================================
3652void BRepOffset_MakeOffset::RemoveInternalEdges()
3653{
3654 Standard_Boolean bRemoveWire, bRemoveEdge;
3655 TopExp_Explorer aExpF, aExpW, aExpE;
3656 TopTools_IndexedDataMapOfShapeListOfShape aDMELF;
3657 //
3658 TopExp::MapShapesAndAncestors(myOffsetShape, TopAbs_EDGE, TopAbs_FACE, aDMELF);
3659 //
3660 aExpF.Init(myOffsetShape, TopAbs_FACE);
3661 for (; aExpF.More(); aExpF.Next()) {
3662 TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current();
3663 //
3664 TopTools_ListOfShape aLIW;
3665 //
3666 aExpW.Init(aF, TopAbs_WIRE);
3667 for (; aExpW.More(); aExpW.Next()) {
3668 TopoDS_Wire& aW = *(TopoDS_Wire*)&aExpW.Current();
3669 //
3670 bRemoveWire = Standard_True;
3671 TopTools_ListOfShape aLIE;
3672 //
3673 aExpE.Init(aW, TopAbs_EDGE);
3674 for (; aExpE.More(); aExpE.Next()) {
3675 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
3676 if (aE.Orientation() != TopAbs_INTERNAL) {
3677 bRemoveWire = Standard_False;
3678 continue;
3679 }
3680 //
3681 const TopTools_ListOfShape& aLF = aDMELF.FindFromKey(aE);
3682 bRemoveEdge = (aLF.Extent() == 1);
3683 if (bRemoveEdge) {
3684 aLIE.Append(aE);
3685 }
3686 else {
3687 bRemoveWire = Standard_False;
3688 }
3689 }
3690 //
3691 if (bRemoveWire) {
3692 aLIW.Append(aW);
3693 }
3694 else if (aLIE.Extent()) {
3695 RemoveShapes(aW, aLIE);
3696 }
3697 }
3698 //
3699 if (aLIW.Extent()) {
3700 RemoveShapes(aF, aLIW);
3701 }
3702 }
3703}
3704
3705//=======================================================================
3706// static methods implementation
3707//=======================================================================
e1ed38e0 3708
3709//=======================================================================
3710//function : checkSinglePoint
3711//purpose : Check single point on surface for bad normals
3712//=======================================================================
3713BRepOffset_Error checkSinglePoint(const Standard_Real theUParam,
3714 const Standard_Real theVParam,
3715 const Handle(Geom_Surface)& theSurf,
3716 const NCollection_Vector<gp_Pnt>& theBadPoints)
3717{
3718 gp_Pnt aPnt;
3719 gp_Vec aD1U, aD1V;
3720 theSurf->D1(theUParam, theVParam, aPnt, aD1U, aD1V);
3721
3722 if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
3723 aD1V.SquareMagnitude() < Precision::SquareConfusion() )
3724 {
3725 Standard_Boolean isKnownBadPnt = Standard_False;
3726 for(Standard_Integer anIdx = theBadPoints.Lower();
3727 anIdx <= theBadPoints.Upper();
3728 ++anIdx)
3729 {
3730 if (aPnt.SquareDistance(theBadPoints(anIdx)) < Precision::SquareConfusion())
3731 {
3732 isKnownBadPnt = Standard_True;
3733 break;
3734 }
3735 } // for(Standard_Integer anIdx = theBadPoints.Lower();
3736
3737 if (!isKnownBadPnt)
3738 {
3739 return BRepOffset_BadNormalsOnGeometry;
3740 }
3741 else
3742 {
3743 return BRepOffset_NoError;
3744 }
3745 } // if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
3746
3747 if (aD1U.IsParallel(aD1V, Precision::Confusion()))
3748 {
3749 // Isolines are collinear.
3750 return BRepOffset_BadNormalsOnGeometry;
3751 }
3752
3753 return BRepOffset_NoError;
3754}
9b7f3f83 3755
3756//=======================================================================
3757//function : RemoveShapes
3758//purpose : Removes the shapes <theLS> from the shape <theS>
3759//=======================================================================
3760void RemoveShapes(TopoDS_Shape& theS,
3761 const TopTools_ListOfShape& theLS)
3762{
3763 BRep_Builder aBB;
3764 //
3765 Standard_Boolean bFree = theS.Free();
3766 theS.Free(Standard_True);
3767 //
3768 TopTools_ListIteratorOfListOfShape aIt(theLS);
3769 for (; aIt.More(); aIt.Next()) {
3770 const TopoDS_Shape& aSI = aIt.Value();
3771 aBB.Remove(theS, aSI);
3772 }
3773 //
3774 theS.Free(bFree);
3775}
3776
3777//=======================================================================
ecf4f17c 3778//function : UpdateHistory
3779//purpose : Updates the history information
9b7f3f83 3780//=======================================================================
ecf4f17c 3781void UpdateHistory(const TopTools_ListOfShape& theLF,
3782 BOPAlgo_Builder& theGF,
3783 BRepAlgo_Image& theImage)
9b7f3f83 3784{
ecf4f17c 3785 TopTools_ListIteratorOfListOfShape aIt(theLF);
3786 for (; aIt.More(); aIt.Next()) {
3787 const TopoDS_Shape& aF = aIt.Value();
3788 const TopTools_ListOfShape& aLFIm = theGF.Modified(aF);
3789 if (aLFIm.Extent()) {
3790 if (theImage.HasImage(aF)) {
3791 theImage.Add(aF, aLFIm);
9b7f3f83 3792 }
3793 else {
ecf4f17c 3794 theImage.Bind(aF, aLFIm);
9b7f3f83 3795 }
3796 }
9b7f3f83 3797 }
3798}
3799
3800//=======================================================================
ecf4f17c 3801//function : IntersectEdges
9b7f3f83 3802//purpose :
3803//=======================================================================
ecf4f17c 3804void BRepOffset_MakeOffset::IntersectEdges(const TopoDS_Shape& theShape,
3805 BRepOffset_DataMapOfShapeOffset& theMapSF,
3806 TopTools_DataMapOfShapeShape& theMES,
3807 TopTools_DataMapOfShapeShape& theBuild,
3808 Handle(BRepAlgo_AsDes)& theAsDes,
3809 Handle(BRepAlgo_AsDes)& theAsDes2d)
9b7f3f83 3810{
ecf4f17c 3811 Standard_Real aTolF;
3812 TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
3813 TopExp_Explorer aExp(theShape, TopAbs_FACE);
3814 // intersect edges created from edges
3815 TopTools_IndexedMapOfShape aMFV;
9b7f3f83 3816 for (; aExp.More(); aExp.Next()) {
ecf4f17c 3817 const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
3818 aTolF = BRep_Tool::Tolerance(aF);
3819 BRepOffset_Inter2d::ConnexIntByInt
3820 (aF, theMapSF(aF), theMES, theBuild, theAsDes2d, myOffset, aTolF, aMFV, aDMVV);
9b7f3f83 3821 }
ecf4f17c 3822 // intersect edges created from vertices
3823 Standard_Integer i, aNbF = aMFV.Extent();
3824 for (i = 1; i <= aNbF; ++i) {
3825 const TopoDS_Face& aF = TopoDS::Face(aMFV(i));
3826 aTolF = BRep_Tool::Tolerance(aF);
3827 BRepOffset_Inter2d::ConnexIntByIntInVert
3828 (aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d, aTolF, aDMVV);
3829 }
3830 //
3831 // fuse vertices on edges
3832 BRepOffset_Inter2d::FuseVertices(aDMVV, theAsDes2d);
9b7f3f83 3833}
3834
3835//=======================================================================
ecf4f17c 3836//function : TrimEdges
9b7f3f83 3837//purpose :
3838//=======================================================================
ecf4f17c 3839void TrimEdges(const TopoDS_Shape& theShape,
3840 const Standard_Real theOffset,
3841 BRepOffset_DataMapOfShapeOffset& theMapSF,
3842 TopTools_DataMapOfShapeShape& theMES,
3843 TopTools_DataMapOfShapeShape& theBuild,
3844 Handle(BRepAlgo_AsDes)& theAsDes,
3845 Handle(BRepAlgo_AsDes)& theAsDes2d,
3846 TopTools_IndexedMapOfShape& theNewEdges,
3847 TopTools_DataMapOfShapeShape& theETrimEInf,
3848 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins)
9b7f3f83 3849{
ecf4f17c 3850 TopExp_Explorer Exp,Exp2,ExpC;
3851 TopoDS_Shape NE;
3852 TopoDS_Edge TNE;
3853 TopoDS_Face NF;
9b7f3f83 3854 //
ecf4f17c 3855 for (Exp.Init(theShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
3856 const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
3857 NF = theMapSF(FI).Face();
3858 if (theMES.IsBound(NF)) {
3859 NF = TopoDS::Face(theMES(NF));
9b7f3f83 3860 }
3861 //
ecf4f17c 3862 TopTools_MapOfShape View;
3863 TopTools_IndexedMapOfShape VEmap;
3864 Standard_Integer i, aNb;
9b7f3f83 3865 //
ecf4f17c 3866 TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap);
3867 TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
3868 //
3869 aNb = VEmap.Extent();
3870 for (i = 1; i <= aNb; ++i) {
3871 const TopoDS_Shape& aS = VEmap(i);
3872 if (!View.Add(aS)) {
9b7f3f83 3873 continue;
3874 }
3875 //
ecf4f17c 3876 if (theBuild.IsBound(aS)) {
3877 NE = theBuild(aS);
3878 // keep connection to original edges
3879 ExpC.Init(NE, TopAbs_EDGE);
3880 for (; ExpC.More(); ExpC.Next()) {
3881 const TopoDS_Edge& NEC = TopoDS::Edge(ExpC.Current());
3882 TopTools_ListOfShape* pLEOr = theEdgesOrigins.ChangeSeek(NEC);
3883 if (!pLEOr) {
3884 pLEOr = theEdgesOrigins.Bound(NEC, TopTools_ListOfShape());
3885 }
3886 AppendToList(*pLEOr, aS);
9b7f3f83 3887 }
ecf4f17c 3888 // trim edges
3889 if (NE.ShapeType() == TopAbs_EDGE) {
3890 if (theNewEdges.Add(NE)) {
3891 TrimEdge (TopoDS::Edge(NE),theAsDes2d,theAsDes, theETrimEInf);
3892 }
3893 }
3894 else {
3895 //------------------------------------------------------------
3896 // The Intersections are on several edges.
3897 // The pieces without intersections with neighbors
3898 // are removed from AsDes.
3899 //------------------------------------------------------------
3900 for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
3901 TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
3902 if (theNewEdges.Add(NEC)) {
3903 if (!theAsDes2d->Descendant(NEC).IsEmpty()) {
3904 TrimEdge (NEC,theAsDes2d, theAsDes, theETrimEInf);
3905 }
3906 else {
3907 if (theAsDes->HasAscendant(NEC)) {
3908 theAsDes->Remove(NEC);
3909 }
3910 }
3911 }
3912 }
9b7f3f83 3913 }
3914 }
ecf4f17c 3915 else {
3916 if (aS.ShapeType() != TopAbs_EDGE) {
3917 continue;
3918 }
3919 //
3920 NE = theMapSF(FI).Generated(aS);
3921 //// modified by jgv, 19.12.03 for OCC4455 ////
3922 NE.Orientation(aS.Orientation());
3923 //
3924 TopTools_ListOfShape* pLEOr = theEdgesOrigins.ChangeSeek(NE);
3925 if (!pLEOr) {
3926 pLEOr = theEdgesOrigins.Bound(NE, TopTools_ListOfShape());
3927 }
3928 AppendToList(*pLEOr, aS);
3929 //
3930 if (theMES.IsBound(NE)) {
3931 NE = theMES(NE);
3932 NE.Orientation(aS.Orientation());
3933 if (theNewEdges.Add(NE)) {
3934 TrimEdge (TopoDS::Edge(NE), theAsDes2d, theAsDes, theETrimEInf);
3935 }
3936 }
3937 else {
3938 TopoDS_Edge& anEdge = TopoDS::Edge(NE);
3939 BRepAdaptor_Curve aBAC(anEdge);
3940 if (aBAC.GetType() == GeomAbs_Line) {
3941 TopoDS_Edge aNewEdge;
3942 BRepOffset_Inter2d::ExtentEdge(anEdge, aNewEdge, theOffset);
3943 theETrimEInf.Bind(anEdge, aNewEdge);
3944 }
3945 }
3946 theAsDes->Add(NF,NE);
3947 }
9b7f3f83 3948 }
3949 }
3950}
3951
3952//=======================================================================
ecf4f17c 3953//function : TrimEdge
3954//purpose : Trim the edge of the largest of descendants in AsDes2d.
3955// Order in AsDes two vertices that have trimmed the edge.
9b7f3f83 3956//=======================================================================
ecf4f17c 3957void TrimEdge(TopoDS_Edge& NE,
3958 const Handle(BRepAlgo_AsDes)& AsDes2d,
3959 Handle(BRepAlgo_AsDes)& AsDes,
3960 TopTools_DataMapOfShapeShape& theETrimEInf)
9b7f3f83 3961{
ecf4f17c 3962 TopoDS_Edge aSourceEdge;
3963 TopoDS_Vertex V1,V2;
3964 Standard_Real aT1, aT2;
9b7f3f83 3965 //
ecf4f17c 3966 TopExp::Vertices(NE, V1, V2);
3967 BRep_Tool::Range(NE, aT1, aT2);
3968 //
3969 BOPTools_AlgoTools::MakeSplitEdge(NE, V1, aT1, V2, aT2, aSourceEdge);
3970 //
3971 //
3972 Standard_Real aSameParTol = Precision::Confusion();
3973
3974 Standard_Real U = 0.;
3975 Standard_Real UMin = Precision::Infinite();
3976 Standard_Real UMax = -UMin;
3977
3978 const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
3979 //
3980 Standard_Boolean bTrim = Standard_False;
3981 //
3982 if (LE.Extent() > 1) {
3983 TopTools_ListIteratorOfListOfShape it (LE);
3984 for (; it.More(); it.Next()) {
3985 TopoDS_Vertex V = TopoDS::Vertex(it.Value());
3986 if (NE.Orientation() == TopAbs_REVERSED)
3987 V.Reverse();
3988 //V.Orientation(TopAbs_INTERNAL);
3989 if (!FindParameter(V, NE, U)) {
3990 Standard_Real f, l;
3991 Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
3992 gp_Pnt thePoint = BRep_Tool::Pnt(V);
3993 GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
3994 if (Projector.NbPoints() == 0)
9775fa61 3995 throw Standard_ConstructionError("BRepOffset_MakeOffset::TrimEdge no projection");
ecf4f17c 3996 U = Projector.LowerDistanceParameter();
3997 }
3998 if (U < UMin) {
3999 UMin = U; V1 = V;
4000 }
4001 if (U > UMax) {
4002 UMax = U; V2 = V;
4003 }
4004 }
4005 //
4006 if (V1.IsNull() || V2.IsNull()) {
9775fa61 4007 throw Standard_ConstructionError("BRepOffset_MakeOffset::TrimEdge");
ecf4f17c 4008 }
4009 if (!V1.IsSame(V2)) {
4010 NE.Free( Standard_True );
4011 BRep_Builder B;
4012 TopAbs_Orientation Or = NE.Orientation();
4013 NE.Orientation(TopAbs_FORWARD);
4014 TopoDS_Vertex VF,VL;
4015 TopExp::Vertices (NE,VF,VL);
4016 B.Remove(NE,VF);
4017 B.Remove(NE,VL);
4018 B.Add (NE,V1.Oriented(TopAbs_FORWARD));
4019 B.Add (NE,V2.Oriented(TopAbs_REVERSED));
4020 B.Range(NE,UMin,UMax);
4021 NE.Orientation(Or);
4022 AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
4023 AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
4024 BRepLib::SameParameter(NE, aSameParTol, Standard_True);
9b7f3f83 4025 //
ecf4f17c 4026 bTrim = Standard_True;
9b7f3f83 4027 }
4028 }
4029 //
ecf4f17c 4030 if (!bTrim) {
4031 BRepAdaptor_Curve aBAC(NE);
4032 if (aBAC.GetType() == GeomAbs_Line) {
4033 if (AsDes->HasAscendant(NE)) {
4034 AsDes->Remove(NE);
4035 }
4036 }
4037 }
4038 else
4039 {
4040 if (!theETrimEInf.IsBound(NE)) {
4041 theETrimEInf.Bind(NE, aSourceEdge);
4042 }
4043 }
9b7f3f83 4044}
4045
4046//=======================================================================
ecf4f17c 4047//function : GetEnlargedFaces
9b7f3f83 4048//purpose :
4049//=======================================================================
ecf4f17c 4050void GetEnlargedFaces(const TopoDS_Shape& theShape,
4051 const BRepOffset_DataMapOfShapeOffset& theMapSF,
4052 const TopTools_DataMapOfShapeShape& theMES,
4053 TopTools_DataMapOfShapeShape& theFacesOrigins,
4054 BRepAlgo_Image& theImage,
4055 TopTools_ListOfShape& theLSF)
9b7f3f83 4056{
ecf4f17c 4057 TopExp_Explorer aExp(theShape, TopAbs_FACE);
4058 for (; aExp.More(); aExp.Next()) {
4059 const TopoDS_Shape& FI = aExp.Current();
4060 const TopoDS_Shape& OFI = theMapSF(FI).Face();
4061 if (theMES.IsBound(OFI)) {
4062 const TopoDS_Face& aLocalFace = TopoDS::Face(theMES(OFI));
4063 theLSF.Append(aLocalFace);
4064 theImage.SetRoot(aLocalFace);
4065 //
4066 theFacesOrigins.Bind(aLocalFace, FI);
4067 }
4068 }
4069}
4070
4071//=======================================================================
4072//function : BuildShellsCompleteInter
4073//purpose : Make the shells from list of faces using MakerVolume algorithm.
4074// In case there will be more than just one solid, it will be
4075// rebuilt using only outer faces.
4076//=======================================================================
4077Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
4078 const BOPCol_IndexedDataMapOfShapeListOfShape& theOrigins,
4079 BRepAlgo_Image& theImage,
4080 TopoDS_Shape& theShells)
4081{
4082 // make solids
4083 BOPAlgo_MakerVolume aMV1;
4084 aMV1.SetArguments(theLF);
4085 // we need to intersect the faces to process the tangential faces
4086 aMV1.SetIntersect(Standard_True);
291fced1 4087 aMV1.SetAvoidInternalShapes(Standard_True);
ecf4f17c 4088 aMV1.Perform();
9b7f3f83 4089 //
33ba8565 4090 Standard_Boolean bDone = ! aMV1.HasErrors();
ecf4f17c 4091 if (!bDone) {
9b7f3f83 4092 return bDone;
4093 }
4094 //
ecf4f17c 4095 UpdateHistory(theLF, aMV1, theImage);
9b7f3f83 4096 //
ecf4f17c 4097 const TopoDS_Shape& aResult1 = aMV1.Shape();
4098 if (aResult1.ShapeType() == TopAbs_SOLID) {
4099 // result is the alone solid, nothing to do
4100 return GetSubShapes(aResult1, TopAbs_SHELL, theShells);
4101 }
9b7f3f83 4102 //
ecf4f17c 4103 // it is necessary to rebuild the solids, avoiding internal faces
9b7f3f83 4104 //
ecf4f17c 4105 // map faces to solids
4106 TopTools_IndexedDataMapOfShapeListOfShape aDMFS;
4107 TopExp::MapShapesAndAncestors(aResult1, TopAbs_FACE, TopAbs_SOLID, aDMFS);
9b7f3f83 4108 //
ecf4f17c 4109 Standard_Integer i, aNb = aDMFS.Extent();
4110 bDone = (aNb > 0);
4111 if (!bDone) {
4112 // unable to build any solid
4113 return bDone;
4114 }
9b7f3f83 4115 //
ecf4f17c 4116 // get faces attached to only one solid
4117 BOPCol_ListOfShape aLF2;
4118 for (i = 1; i <= aNb; ++i) {
4119 const TopTools_ListOfShape& aLS = aDMFS(i);
4120 if (aLS.Extent() == 1) {
4121 const TopoDS_Shape& aF = aDMFS.FindKey(i);
4122 aLF2.Append(aF);
9b7f3f83 4123 }
4124 }
4125 //
ecf4f17c 4126 // make solids from the new list
4127 BOPAlgo_MakerVolume aMV2;
4128 aMV2.SetArguments(aLF2);
4129 // no need to intersect this time
4130 aMV2.SetIntersect(Standard_False);
291fced1 4131 aMV2.SetAvoidInternalShapes(Standard_True);
ecf4f17c 4132 aMV2.Perform();
33ba8565 4133 bDone = ! aMV2.HasErrors();
ecf4f17c 4134 if (!bDone) {
4135 return bDone;
9b7f3f83 4136 }
4137 //
ecf4f17c 4138 const TopoDS_Shape& aResult2 = aMV2.Shape();
4139 if (aResult2.ShapeType() == TopAbs_SOLID) {
4140 return GetSubShapes(aResult2, TopAbs_SHELL, theShells);
9b7f3f83 4141 }
4142 //
ecf4f17c 4143 TopExp_Explorer aExp(aResult2, TopAbs_FACE);
4144 bDone = aExp.More();
4145 if (!bDone) {
4146 return bDone;
9b7f3f83 4147 }
4148 //
ecf4f17c 4149 // the result is non-manifold - resolve it comparing normals
4150 // directions of the offset faces and original faces
4151 BOPCol_ListOfShape aLF3;
4152 for (; aExp.More(); aExp.Next()) {
4153 const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
4154 //
4155 // check orientation
4156 if (!theOrigins.Contains(aF)) {
4157 aLF3.Append(aF);
4158 continue;
4159 }
4160 //
4161 const TopTools_ListOfShape& aLFOr = theOrigins.FindFromKey(aF);
4162 TopTools_ListIteratorOfListOfShape aItLF(aLFOr);
4163 for (; aItLF.More(); aItLF.Next()) {
4164 const TopoDS_Face& aFOr = TopoDS::Face(aItLF.Value());
0da0275c 4165 if (BRepOffset_Tool::CheckPlanesNormals(aF, aFOr)) {
ecf4f17c 4166 aLF3.Append(aF);
9b7f3f83 4167 break;
4168 }
4169 }
4170 }
4171 //
ecf4f17c 4172 // make solid from most outer faces with correct normal direction
4173 BOPAlgo_MakerVolume aMV3;
4174 aMV3.SetArguments(aLF3);
4175 aMV3.SetIntersect(Standard_False);
291fced1 4176 aMV3.SetAvoidInternalShapes(Standard_True);
ecf4f17c 4177 aMV3.Perform();
33ba8565 4178 bDone = ! aMV3.HasErrors();
ecf4f17c 4179 if (!bDone) {
4180 return bDone;
4181 }
4182 //
4183 const TopoDS_Shape& aResult3 = aMV3.Shape();
4184 return GetSubShapes(aResult3, TopAbs_SHELL, theShells);
9b7f3f83 4185}
4186
4187//=======================================================================
ecf4f17c 4188//function : GetSubShapes
9b7f3f83 4189//purpose :
4190//=======================================================================
ecf4f17c 4191Standard_Boolean GetSubShapes(const TopoDS_Shape& theShape,
4192 const TopAbs_ShapeEnum theSSType,
4193 TopoDS_Shape& theResult)
9b7f3f83 4194{
ecf4f17c 4195 TopExp_Explorer aExp(theShape, theSSType);
4196 if (!aExp.More()) {
4197 return Standard_False;
9b7f3f83 4198 }
4199 //
ecf4f17c 4200 TopoDS_Compound aResult;
4201 BRep_Builder().MakeCompound(aResult);
9b7f3f83 4202 //
ecf4f17c 4203 for (; aExp.More(); aExp.Next()) {
4204 const TopoDS_Shape& aSS = aExp.Current();
4205 BRep_Builder().Add(aResult, aSS);
9b7f3f83 4206 }
ecf4f17c 4207 theResult = aResult;
4208 return Standard_True;
9b7f3f83 4209}
4210
ecf4f17c 4211//=======================================================================
4212//function : IsPlanar
4213//purpose : Checks if all the faces of the shape are planes
4214//=======================================================================
4215Standard_Boolean IsPlanar(const TopoDS_Shape& theS)
4216{
4217 TopExp_Explorer aExp(theS, TopAbs_FACE);
4218 for (; aExp.More(); aExp.Next()) {
4219 const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
4220 BRepAdaptor_Surface aBAS(aF, Standard_False);
4221 if (aBAS.GetType() != GeomAbs_Plane) {
4222 break;
4223 }
4224 }
4225 return !aExp.More();
4226}
4227
9b7f3f83 4228//=======================================================================
4229//function : IsSolid
ecf4f17c 4230//purpose : Checks if the shape is solid
9b7f3f83 4231//=======================================================================
4232Standard_Boolean IsSolid(const TopoDS_Shape& theS)
4233{
4234 TopExp_Explorer aExp(theS, TopAbs_SOLID);
4235 return aExp.More();
4236}
ecf4f17c 4237
9b7f3f83 4238//=======================================================================
ecf4f17c 4239//function : AppendToList
4240//purpose : Add to a list only unique elements
9b7f3f83 4241//=======================================================================
ecf4f17c 4242void AppendToList(TopTools_ListOfShape& theList,
4243 const TopoDS_Shape& theShape)
9b7f3f83 4244{
ecf4f17c 4245 TopTools_ListIteratorOfListOfShape aIt(theList);
9b7f3f83 4246 for (; aIt.More(); aIt.Next()) {
ecf4f17c 4247 const TopoDS_Shape& aS = aIt.Value();
4248 if (aS.IsSame(theShape)) {
4249 return;
9b7f3f83 4250 }
4251 }
ecf4f17c 4252 theList.Append(theShape);
9b7f3f83 4253}