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