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