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