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