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