1 // File: BRepOffset_Inter3d.cxx
2 // Created: Tue Sep 3 14:19:40 1996
3 // Author: Yves FRICAUD
4 // <yfr@claquox.paris1.matra-dtv.fr>
7 // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455
9 #include <BRepOffset_Inter3d.ixx>
10 #include <BRepOffset_Tool.hxx>
11 #include <BRepOffset_Interval.hxx>
12 #include <BRepOffset_ListOfInterval.hxx>
13 #include <BRepOffset_DataMapOfShapeOffset.hxx>
14 #include <BRepOffset_Offset.hxx>
15 #include <BRepAdaptor_Curve.hxx>
16 #include <BRep_Builder.hxx>
17 #include <BRep_Tool.hxx>
18 #include <BRepLib_MakeVertex.hxx>
21 #include <TopExp_Explorer.hxx>
23 #include <TopoDS_Compound.hxx>
24 #include <TopoDS_Edge.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopOpeBRepTool_BoxSort.hxx>
27 #include <TopTools_ListIteratorOfListOfShape.hxx>
28 #include <TopTools_MapIteratorOfMapOfShape.hxx>
29 #include <TopTools_IndexedMapOfShape.hxx>
30 #include <Extrema_ExtPC.hxx>
31 #include <TopTools_MapOfShape.hxx>
35 //=======================================================================
36 //function : BRepOffset_Inter3d
38 //=======================================================================
40 BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes,
41 const TopAbs_State Side ,
42 const Standard_Real Tol)
50 //=======================================================================
51 //function : ExtentEdge
53 //=======================================================================
55 static void ExtentEdge(const TopoDS_Face& F,
59 TopoDS_Shape aLocalShape = E.EmptyCopied();
60 NE = TopoDS::Edge(aLocalShape);
61 // NE = TopoDS::Edge(E.EmptyCopied());
64 // Enough for analytic edges, in general case reconstruct the
65 // geometry of the edge recalculating the intersection of surfaces.
67 NE.Orientation(TopAbs_FORWARD);
69 BRep_Tool::Range(E,f,l);
70 Standard_Real length = l-f;
76 BRepAdaptor_Curve CE(E);
77 TopoDS_Vertex V1 = BRepLib_MakeVertex(CE.Value(f));
78 TopoDS_Vertex V2 = BRepLib_MakeVertex(CE.Value(l));
79 B.Add(NE,V1.Oriented(TopAbs_FORWARD));
80 B.Add(NE,V2.Oriented(TopAbs_REVERSED));
81 NE.Orientation(E.Orientation());
85 //=======================================================================
86 //function : SelectEdge
88 //=======================================================================
90 static void SelectEdge (const TopoDS_Face& F,
91 const TopoDS_Face& EF,
93 TopTools_ListOfShape& LInt)
95 //------------------------------------------------------------
96 // Proofing on the intersections on periodical faces
97 //------------------------------------------------------------
98 TopTools_ListIteratorOfListOfShape it(LInt);
99 // Modified by Sergey KHROMOV - Wed Jun 5 11:43:04 2002 Begin
100 // Standard_Real dU = 1.0e100;
101 Standard_Real dU = RealLast();
102 // Modified by Sergey KHROMOV - Wed Jun 5 11:43:05 2002 End
105 Standard_Real Fst, Lst, tmp;
106 BRep_Tool::Range(E, Fst, Lst);
107 BRepAdaptor_Curve Ad1(E);
109 gp_Pnt PFirst = Ad1.Value( Fst );
110 gp_Pnt PLast = Ad1.Value( Lst );
112 // Modified by Sergey KHROMOV - Wed Jun 5 11:23:10 2002 Begin
114 // Modified by Sergey KHROMOV - Wed Jun 5 11:23:11 2002 End
115 //----------------------------------------------------------------------
116 // Selection of edge that coversmost of the domain of the initial edge.
117 //----------------------------------------------------------------------
118 for (; it.More(); it.Next()) {
119 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
121 BRep_Tool::Range(EI, Fst, Lst);
122 BRepAdaptor_Curve Ad2(EI);
124 // Modified by Sergey KHROMOV - Wed Jun 5 11:25:03 2002 Begin
126 Standard_Real aTol = BRep_Tool::Tolerance(EI);
127 Standard_Boolean isMinFound = Standard_False;
128 Standard_Real aSqrDist1;
129 Standard_Real aSqrDist2;
131 anExt.Initialize(Ad2, Fst, Lst, aTol);
133 // Seek for the min distance for PFirst:
134 anExt.Perform(PFirst);
135 if (anExt.IsDone()) {
136 for (i = 1; i <= anExt.NbExt(); i++) {
137 if (anExt.IsMin(i)) {
138 const gp_Pnt &aPMin = anExt.Point(i).Value();
140 aSqrDist1 = PFirst.SquareDistance(aPMin);
141 isMinFound = Standard_True;
148 gp_Pnt aP1 = Ad2.Value(Fst);
149 gp_Pnt aP2 = Ad2.Value(Lst);
151 aSqrDist1 = Min(aP1.SquareDistance(PFirst), aP2.SquareDistance(PFirst));
154 // Seek for the min distance for PLast:
155 isMinFound = Standard_False;
156 anExt.Perform(PLast);
157 if (anExt.IsDone()) {
158 for (i = 1; i <= anExt.NbExt(); i++) {
159 if (anExt.IsMin(i)) {
160 const gp_Pnt &aPMin = anExt.Point(i).Value();
162 aSqrDist2 = PLast.SquareDistance(aPMin);
163 isMinFound = Standard_True;
170 gp_Pnt aP1 = Ad2.Value(Fst);
171 gp_Pnt aP2 = Ad2.Value(Lst);
173 aSqrDist2 = Min(aP1.SquareDistance(PLast), aP2.SquareDistance(PLast));
176 tmp = aSqrDist1 + aSqrDist2;
177 // gp_Pnt P1 = Ad2.Value(Fst);
178 // gp_Pnt P2 = Ad2.Value(Lst);
180 // tmp = P1.Distance(PFirst) + P2.Distance(PLast);
185 // Modified by Sergey KHROMOV - Wed Jun 5 11:24:54 2002 End
193 //=======================================================================
194 //function : CompletInt
196 //=======================================================================
198 void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces,
199 const BRepAlgo_Image& InitOffsetFace)
201 //---------------------------------------------------------------
202 // Calculate the intersections of offset faces
203 // Distinction of intersection between faces // tangents.
204 //---------------------------------------------------------------
206 TopTools_ListIteratorOfListOfShape it;
208 //---------------------------------------------------------------
209 // Construction of bounding boxes
210 //---------------------------------------------------------------
211 TopOpeBRepTool_BoxSort BOS;
213 TopoDS_Compound CompOS;
214 B.MakeCompound(CompOS);
216 for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
217 const TopoDS_Shape& OS = it.Value();
220 BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE);
222 //---------------------------
223 // Intersection of faces //
224 //---------------------------
225 for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
226 const TopoDS_Face& F1 = TopoDS::Face(it.Value());
227 TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1);
228 for (; itLI.More(); itLI.Next()) {
229 F2 = TopoDS::Face(BOS.TouchedShape(itLI));
230 FaceInter(F1,F2,InitOffsetFace);
236 //=======================================================================
237 //function : CompletInt
239 //=======================================================================
241 void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
242 const TopoDS_Face& F2,
243 const BRepAlgo_Image& InitOffsetFace)
245 TopTools_ListOfShape LInt1, LInt2;
246 TopoDS_Edge NullEdge;
248 if (F1.IsSame(F2)) return;
249 if (IsDone(F1,F2)) return;
250 const TopoDS_Shape& InitF1 = InitOffsetFace.ImageFrom(F1);
251 const TopoDS_Shape& InitF2 = InitOffsetFace.ImageFrom(F2);
252 Standard_Boolean InterPipes = (InitF2.ShapeType() == TopAbs_EDGE &&
253 InitF1.ShapeType() == TopAbs_EDGE );
254 Standard_Boolean InterFaces = (InitF1.ShapeType() == TopAbs_FACE &&
255 InitF2.ShapeType() == TopAbs_FACE);
256 TopTools_ListOfShape LE,LV;
257 LInt1.Clear(); LInt2.Clear();
258 if (BRepOffset_Tool::HasCommonShapes(F1,F2,LE,LV) ||
259 myAsDes->HasCommonDescendant(F1,F2,LE)) {
260 //-------------------------------------------------
261 // F1 and F2 share shapes.
262 //-------------------------------------------------
263 if ( LE.IsEmpty() && !LV.IsEmpty()) {
265 //----------------------
266 // tubes share a vertex.
267 //----------------------
268 const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1);
269 const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2);
270 TopoDS_Vertex VE1[2],VE2[2];
271 TopExp::Vertices(EE1,VE1[0],VE1[1]);
272 TopExp::Vertices(EE2,VE2[0],VE2[1]);
274 for (Standard_Integer i = 0 ; i < 2; i++) {
275 for (Standard_Integer j = 0 ; j < 2; j++) {
276 if (VE1[i].IsSame(VE2[j])) {
281 if (!InitOffsetFace.HasImage(V)) { //no sphere
282 BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
286 //--------------------------------------------------------
287 // Intersection having only common vertices
288 // and supports having common edges.
289 // UNSUFFICIENT, but a larger criterion shakes too
291 //--------------------------------------------------------
293 BRepOffset_Tool::HasCommonShapes(TopoDS::Face(InitF1),
294 TopoDS::Face(InitF2),LE,LV))
296 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
302 BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
305 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
308 Store (F1,F2,LInt1,LInt2);
312 //=======================================================================
313 //function : ConnexIntByArc
315 //=======================================================================
317 void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& SetOfFaces,
318 const TopoDS_Shape& ShapeInit,
319 const BRepOffset_Analyse& Analyse,
320 const BRepAlgo_Image& InitOffsetFace)
322 BRepOffset_Type OT = BRepOffset_Concave;
323 if (mySide == TopAbs_OUT) OT = BRepOffset_Convex;
324 TopExp_Explorer Exp(ShapeInit,TopAbs_EDGE);
325 TopTools_ListOfShape LInt1,LInt2;
327 TopoDS_Edge NullEdge;
329 //---------------------------------------------------------------------
330 // etape 1 : Intersection of faces // corresponding to the initial faces
331 // separated by a concave edge if offset > 0, otherwise convex.
332 //---------------------------------------------------------------------
333 for (; Exp.More(); Exp.Next()) {
334 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
335 const BRepOffset_ListOfInterval& L = Analyse.Type(E);
336 if (!L.IsEmpty() && L.First().Type() == OT) {
337 //-----------------------------------------------------------
338 // edge is of the proper type , return adjacent faces.
339 //-----------------------------------------------------------
340 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
341 if (Anc.Extent() == 2) {
342 F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First());
343 F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First());
344 if (!IsDone(F1,F2)) {
345 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True);
346 Store (F1,F2,LInt1,LInt2);
351 //---------------------------------------------------------------------
352 // etape 2 : Intersections of tubes sharing a vertex without sphere with:
353 // - tubes on each other edge sharing the vertex
354 // - faces containing an edge connected to vertex that has no tubes.
355 //---------------------------------------------------------------------
357 TopTools_ListIteratorOfListOfShape it;
359 for (Exp.Init(ShapeInit,TopAbs_EDGE); Exp.More(); Exp.Next()) {
360 const TopoDS_Edge& E1 = TopoDS::Edge(Exp.Current());
361 if (InitOffsetFace.HasImage(E1)) {
362 //---------------------------
363 // E1 generated a tube.
364 //---------------------------
365 F1 = TopoDS::Face(InitOffsetFace.Image(E1).First());;
366 TopExp::Vertices(E1,V[0],V[1]);
367 const TopTools_ListOfShape& AncE1 = Analyse.Ancestors(E1);
369 for (Standard_Integer i = 0; i < 2; i++) {
370 if (!InitOffsetFace.HasImage(V[i])) {
371 //-----------------------------
372 // the vertex has no sphere.
373 //-----------------------------
374 const TopTools_ListOfShape& Anc = Analyse.Ancestors(V[i]);
375 TopTools_ListOfShape TangOnV;
376 Analyse.TangentEdges(E1,V[i],TangOnV);
377 TopTools_MapOfShape MTEV;
378 for (it.Initialize(TangOnV); it.More(); it.Next()) {
379 MTEV.Add(it.Value());
381 for (it.Initialize(Anc); it.More(); it.Next()) {
382 const TopoDS_Edge& E2 = TopoDS::Edge(it.Value());
383 // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 Begin
384 // if (E1.IsSame(E2) || MTEV.Contains(E2)) continue;
385 Standard_Boolean isToSkip = Standard_False;
387 if (!E1.IsSame(E2)) {
388 const BRepOffset_ListOfInterval& aL = Analyse.Type(E2);
390 isToSkip = (MTEV.Contains(E2) &&
392 (!aL.IsEmpty() && aL.First().Type() != OT)));
395 if (E1.IsSame(E2) || isToSkip)
397 // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 End
398 if (InitOffsetFace.HasImage(E2)) {
399 //-----------------------------
400 // E2 generated a tube.
401 //-----------------------------
402 F2 = TopoDS::Face(InitOffsetFace.Image(E2).First());
403 if (!IsDone(F1,F2)) {
404 //---------------------------------------------------------------------
405 // Intersection tube/tube if the edges are not tangent (AFINIR).
406 //----------------------------------------------------------------------
407 BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide);
408 Store (F1,F2,LInt1,LInt2);
412 //-------------------------------------------------------
413 // Intersection of the tube of E1 with faces //
414 // to face containing E2 if they are not tangent
415 // to the tube or if E2 is not a tangent edge.
416 //-------------------------------------------------------
417 const BRepOffset_ListOfInterval& L = Analyse.Type(E2);
418 if (!L.IsEmpty() && L.First().Type() == BRepOffset_Tangent) {
421 const TopTools_ListOfShape& AncE2 = Analyse.Ancestors(E2);
422 Standard_Boolean TangentFaces = Standard_False;
423 if (AncE2.Extent() == 2) {
424 TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ());
425 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
426 InitF2.IsSame(AncE1.Last()));
428 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
429 if (!IsDone(F1,F2)) {
430 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
431 Store (F1,F2,LInt1,LInt2);
434 InitF2 = TopoDS::Face(AncE2.Last ());
435 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
436 InitF2.IsSame(AncE1.Last()));
438 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
439 if (!IsDone(F1,F2)) {
440 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
441 Store (F1,F2,LInt1,LInt2);
454 //=======================================================================
455 //function : ConnexIntByInt
457 //=======================================================================
459 void BRepOffset_Inter3d::ConnexIntByInt
460 (const TopoDS_Shape& SI,
461 const BRepOffset_DataMapOfShapeOffset& MapSF,
462 const BRepOffset_Analyse& Analyse,
463 TopTools_DataMapOfShapeShape& MES,
464 TopTools_DataMapOfShapeShape& Build,
465 TopTools_ListOfShape& Failed)
467 //TopExp_Explorer Exp(SI,TopAbs_EDGE);
468 TopTools_IndexedMapOfShape Emap;
469 TopExp::MapShapes( SI, TopAbs_EDGE, Emap );
470 TopoDS_Face F1,F2,OF1,OF2,NF1,NF2;
471 TopAbs_State CurSide = mySide;
473 TopTools_ListIteratorOfListOfShape it;
475 //for (; Exp.More(); Exp.Next()) {
476 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
477 //const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
478 const TopoDS_Edge& E = TopoDS::Edge(Emap(i));
479 const BRepOffset_ListOfInterval& L = Analyse.Type(E);
481 BRepOffset_Type OT = L.First().Type();
482 if (OT == BRepOffset_Convex || OT == BRepOffset_Concave) {
483 if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
484 else CurSide = TopAbs_OUT;
485 //-----------------------------------------------------------
486 // edge is of the proper type, return adjacent faces.
487 //-----------------------------------------------------------
488 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
489 if (Anc.Extent() != 2) continue;
490 F1 = TopoDS::Face(Anc.First());
491 F2 = TopoDS::Face(Anc.Last ());
492 OF1 = TopoDS::Face(MapSF(F1).Face()); OF2 = TopoDS::Face(MapSF(F2).Face());
493 if (!MES.IsBound(OF1)) {
494 Standard_Boolean enlargeU = Standard_True;
495 Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
496 BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
497 BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
501 NF1 = TopoDS::Face(MES(OF1));
503 if (!MES.IsBound(OF2)) {
504 Standard_Boolean enlargeU = Standard_True;
505 Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
506 BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
507 BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
511 NF2 = TopoDS::Face(MES(OF2));
513 if (!IsDone(NF1,NF2)) {
514 TopTools_ListOfShape LInt1,LInt2;
515 BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,Standard_True);
516 if (LInt1.Extent() > 1)
518 // intersection is in seceral edges (free sewing)
519 SelectEdge( NF1, NF2, E, LInt1 );
520 SelectEdge( NF1, NF2, E, LInt2 );
523 if (!LInt1.IsEmpty()) {
524 Store (NF1,NF2,LInt1,LInt2);
527 for (it.Initialize(LInt1) ; it.More(); it.Next()) {
535 } else { // IsDone(NF1,NF2)
536 // Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
537 const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
538 const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
540 if (!aLInt1.IsEmpty()) {
542 TopTools_ListIteratorOfListOfShape anIt2;
546 for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
547 const TopoDS_Shape &anE1 = it.Value();
549 for (anIt2.Initialize(aLInt2) ; anIt2.More(); anIt2.Next()) {
550 const TopoDS_Shape &anE2 = anIt2.Value();
552 if (anE1.IsSame(anE2))
562 // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
568 //=======================================================================
569 //function : ContextIntByInt
571 //=======================================================================
573 void BRepOffset_Inter3d::ContextIntByInt
574 (const TopTools_IndexedMapOfShape& ContextFaces,
575 const Standard_Boolean ExtentContext,
576 const BRepOffset_DataMapOfShapeOffset& MapSF,
577 const BRepOffset_Analyse& Analyse,
578 TopTools_DataMapOfShapeShape& MES,
579 TopTools_DataMapOfShapeShape& Build,
580 TopTools_ListOfShape& Failed)
582 TopTools_ListOfShape LInt1,LInt2;
583 TopTools_MapOfShape MV;
585 TopoDS_Face OF,NF,WCF;
589 TopTools_ListIteratorOfListOfShape it;
592 for (i = 1; i <= ContextFaces.Extent(); i++) {
593 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
596 BRepOffset_Tool::EnLargeFace(CF,NF,0,0);
600 TopAbs_State Side = TopAbs_OUT;
602 for (i = 1; i <= ContextFaces.Extent(); i++) {
603 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
604 if (ExtentContext) WCF = TopoDS::Face(MES(CF));
607 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
608 exp.More(); exp.Next()) {
609 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
610 if (!Analyse.HasAncestor(E)) {
611 //----------------------------------------------------------------
612 // the edges of faces of context that are not in the initial shape
613 // can appear in the result.
614 //----------------------------------------------------------------
615 if (!ExtentContext) {
620 if (!MES.IsBound(E)) {
622 Standard_Real f,l,Tol;
623 BRep_Tool::Range(E,f,l);
624 Tol = BRep_Tool::Tolerance(E);
627 TopExp::Vertices(E,V1,V2);
628 NE.Orientation(TopAbs_FORWARD);
629 myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
630 myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
631 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
632 B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
633 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
634 B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
635 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
636 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
637 NE.Orientation(E.Orientation());
643 TopoDS_Shape NE = MES(E);
644 TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation());
645 myAsDes->Add(CF,aLocalShape);
646 // myAsDes->Add(CF,NE.Oriented(E.Orientation()));
651 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
652 const TopoDS_Face& F = TopoDS::Face(Anc.First());
653 OF = TopoDS::Face(MapSF(F).Face());
654 TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
655 OE = TopoDS::Edge(aLocalShape);
656 // OE = TopoDS::Edge(MapSF(F).Generated(E));
657 if (!MES.IsBound(OF)) {
658 BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
662 NF = TopoDS::Face(MES(OF));
664 if (!IsDone(NF,CF)) {
665 TopTools_ListOfShape LInt1,LInt2;
666 TopTools_ListOfShape LOE;
668 BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,Standard_True);
670 if (!LInt1.IsEmpty()) {
671 Store (CF,NF,LInt1,LInt2);
672 if (LInt1.Extent() == 1) {
673 Build.Bind(E,LInt1.First());
677 for (it.Initialize(LInt1) ; it.More(); it.Next()) {
691 //=======================================================================
692 //function : ContextIntByArc
694 //=======================================================================
696 void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& ContextFaces,
697 const Standard_Boolean InSide,
698 const BRepOffset_Analyse& Analyse,
699 const BRepAlgo_Image& InitOffsetFace,
700 BRepAlgo_Image& InitOffsetEdge)
703 TopTools_ListOfShape LInt1,LInt2;
704 TopTools_MapOfShape MV;
709 TopoDS_Edge NullEdge;
712 for (j = 1; j <= ContextFaces.Extent(); j++) {
713 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
717 for (j = 1; j <= ContextFaces.Extent(); j++) {
718 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
719 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
720 exp.More(); exp.Next()) {
721 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
722 if (!Analyse.HasAncestor(E)) {
727 if (!InitOffsetEdge.HasImage(E)) {
728 Standard_Real f,l,Tol;
729 BRep_Tool::Range(E,f,l);
730 Tol = BRep_Tool::Tolerance(E);
733 TopExp::Vertices(E,V1,V2);
734 NE.Orientation(TopAbs_FORWARD);
735 myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
736 myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
737 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
738 B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
739 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
740 B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
741 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
742 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
743 NE.Orientation(E.Orientation());
745 InitOffsetEdge.Bind(E,NE);
748 NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
749 myAsDes->Add(CF,NE.Oriented(E.Orientation()));
755 //---------------------------------------------------
756 // OF1 parallel facee generated by the ancestor of E.
757 //---------------------------------------------------
758 const TopoDS_Shape SI = Analyse.Ancestors(E).First();
759 OF1 = TopoDS::Face(InitOffsetFace.Image(SI).First());
760 OE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
761 //--------------------------------------------------
762 // MAJ of OE on cap CF.
763 //--------------------------------------------------
764 // TopTools_ListOfShape LOE; LOE.Append(OE);
765 // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
767 // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
769 LInt1.Clear(); LInt1.Append(OE);
771 TopAbs_Orientation O1,O2;
772 BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);
773 // if (mySide == TopAbs_OUT) O1 = TopAbs::Reverse(O1);
774 O1 = TopAbs::Reverse(O1);
775 LInt1.First().Orientation(O1);
776 Store(CF,OF1,LInt1,LInt2);
778 //------------------------------------------------------
779 // Processing of offsets on the ancestors of vertices.
780 //------------------------------------------------------
782 TopExp::Vertices (E,V[0],V[1]);
783 for (Standard_Integer i = 0; i < 2; i++) {
784 if (!MV.Add(V[i])) continue;
786 const TopTools_ListOfShape& LE = Analyse.Ancestors(V[i]);
787 TopTools_ListIteratorOfListOfShape itLE(LE);
788 for ( ; itLE.More(); itLE.Next()) {
789 const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
790 if (InitOffsetFace.HasImage(EV)) {
791 //-------------------------------------------------
792 // OF1 parallel face generated by an ancester edge of V[i].
793 //-------------------------------------------------
794 OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First());
795 OE = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First());
796 //--------------------------------------------------
797 // MAj of OE on cap CF.
798 //--------------------------------------------------
799 // LOE.Clear(); LOE.Append(OE);
800 // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
802 // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
804 LInt1.Clear(); LInt1.Append(OE);
806 TopAbs_Orientation O1,O2;
807 BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);
808 // if (mySide == TopAbs_OUT);
809 O1 = TopAbs::Reverse(O1);
810 LInt1.First().Orientation(O1);
811 Store(CF,OF1,LInt1,LInt2);
817 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
818 exp.More(); exp.Next()) {
819 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
820 if (!Analyse.HasAncestor(V)) {
823 const TopTools_ListOfShape& LE = Analyse.Ancestors(V);
824 TopTools_ListIteratorOfListOfShape itLE(LE);
825 for (; itLE.More(); itLE.Next()) {
826 const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
827 const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
828 TopTools_ListIteratorOfListOfShape itLF(LF);
829 for ( ; itLF.More(); itLF.Next()) {
830 const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
831 //-------------------------------------------------
832 // OF1 parallel face generated by uneFace ancestor of V[i].
833 //-------------------------------------------------
834 OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
835 if (!IsDone(OF1,CF)) {
836 //-------------------------------------------------------
837 // Find if one of edges of OF1 has no trace in CF.
838 //-------------------------------------------------------
839 TopTools_ListOfShape LOE;
840 TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
841 for ( ;exp2.More(); exp2.Next()) {
842 LOE.Append(exp2.Current());
844 BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
845 //-------------------------------------------------------
846 // If no trace try intersection.
847 //-------------------------------------------------------
848 if (LInt1.IsEmpty()) {
849 BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge);
851 Store (CF,OF1,LInt1,LInt2);
859 //=======================================================================
860 //function : AddCommonEdges
862 //=======================================================================
864 void BRepOffset_Inter3d::AddCommonEdges(const TopTools_ListOfShape& SetOfFaces)
869 //=======================================================================
872 //=======================================================================
874 void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1,
875 const TopoDS_Face& F2)
877 if (!myDone.IsBound(F1)) {
878 TopTools_ListOfShape empty;
879 myDone.Bind(F1,empty);
881 myDone(F1).Append(F2);
882 if (!myDone.IsBound(F2)) {
883 TopTools_ListOfShape empty;
884 myDone.Bind(F2,empty);
886 myDone(F2).Append(F1);
890 //=======================================================================
893 //=======================================================================
895 Standard_Boolean BRepOffset_Inter3d::IsDone(const TopoDS_Face& F1,
896 const TopoDS_Face& F2)
899 if (myDone.IsBound(F1)) {
900 TopTools_ListIteratorOfListOfShape it (myDone(F1));
901 for (; it.More(); it.Next()) {
902 if (it.Value().IsSame(F2)) return Standard_True;
905 return Standard_False;
909 //=======================================================================
910 //function : TouchedFaces
912 //=======================================================================
914 TopTools_IndexedMapOfShape& BRepOffset_Inter3d::TouchedFaces()
920 //=======================================================================
923 //=======================================================================
925 Handle(BRepAlgo_AsDes) BRepOffset_Inter3d::AsDes() const
931 //=======================================================================
932 //function : NewEdges
934 //=======================================================================
936 TopTools_IndexedMapOfShape& BRepOffset_Inter3d::NewEdges()
943 //=======================================================================
946 //=======================================================================
948 void BRepOffset_Inter3d::Store(const TopoDS_Face& F1,
949 const TopoDS_Face& F2,
950 const TopTools_ListOfShape& LInt1,
951 const TopTools_ListOfShape& LInt2)
953 if (!LInt1.IsEmpty()) {
956 myAsDes->Add( F1,LInt1);
957 myAsDes->Add( F2,LInt2);
958 TopTools_ListIteratorOfListOfShape it(LInt1);
959 for (; it.More(); it.Next()) {
960 myNewEdges.Add(it.Value());