1 // Created on: 1996-09-03
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455
19 #include <BRepOffset_Inter3d.ixx>
20 #include <BRepOffset_Tool.hxx>
21 #include <BRepOffset_Interval.hxx>
22 #include <BRepOffset_ListOfInterval.hxx>
23 #include <BRepOffset_DataMapOfShapeOffset.hxx>
24 #include <BRepOffset_Offset.hxx>
25 #include <BRepAdaptor_Curve.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <BRepLib_MakeVertex.hxx>
31 #include <TopExp_Explorer.hxx>
33 #include <TopoDS_Compound.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <TopoDS_Vertex.hxx>
36 #include <TopOpeBRepTool_BoxSort.hxx>
37 #include <TopTools_ListIteratorOfListOfShape.hxx>
38 #include <TopTools_MapIteratorOfMapOfShape.hxx>
39 #include <TopTools_IndexedMapOfShape.hxx>
40 #include <Extrema_ExtPC.hxx>
41 #include <TopTools_MapOfShape.hxx>
42 #include <Precision.hxx>
46 //=======================================================================
47 //function : BRepOffset_Inter3d
49 //=======================================================================
51 BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes,
52 const TopAbs_State Side ,
53 const Standard_Real Tol)
61 //=======================================================================
62 //function : ExtentEdge
64 //=======================================================================
66 static void ExtentEdge(const TopoDS_Face& /*F*/,
70 TopoDS_Shape aLocalShape = E.EmptyCopied();
71 NE = TopoDS::Edge(aLocalShape);
72 // NE = TopoDS::Edge(E.EmptyCopied());
75 // Enough for analytic edges, in general case reconstruct the
76 // geometry of the edge recalculating the intersection of surfaces.
78 NE.Orientation(TopAbs_FORWARD);
80 BRep_Tool::Range(E,f,l);
81 Standard_Real length = l-f;
87 BRepAdaptor_Curve CE(E);
88 TopoDS_Vertex V1 = BRepLib_MakeVertex(CE.Value(f));
89 TopoDS_Vertex V2 = BRepLib_MakeVertex(CE.Value(l));
90 B.Add(NE,V1.Oriented(TopAbs_FORWARD));
91 B.Add(NE,V2.Oriented(TopAbs_REVERSED));
92 NE.Orientation(E.Orientation());
96 //=======================================================================
97 //function : SelectEdge
99 //=======================================================================
101 static void SelectEdge (const TopoDS_Face& /*F*/,
102 const TopoDS_Face& /*EF*/,
103 const TopoDS_Edge& E,
104 TopTools_ListOfShape& LInt)
106 //------------------------------------------------------------
107 // Proofing on the intersections on periodical faces
108 //------------------------------------------------------------
109 TopTools_ListIteratorOfListOfShape it(LInt);
110 // Modified by Sergey KHROMOV - Wed Jun 5 11:43:04 2002 Begin
111 // Standard_Real dU = 1.0e100;
112 Standard_Real dU = RealLast();
113 // Modified by Sergey KHROMOV - Wed Jun 5 11:43:05 2002 End
116 Standard_Real Fst, Lst, tmp;
117 BRep_Tool::Range(E, Fst, Lst);
118 BRepAdaptor_Curve Ad1(E);
120 gp_Pnt PFirst = Ad1.Value( Fst );
121 gp_Pnt PLast = Ad1.Value( Lst );
123 // Modified by Sergey KHROMOV - Wed Jun 5 11:23:10 2002 Begin
125 // Modified by Sergey KHROMOV - Wed Jun 5 11:23:11 2002 End
126 //----------------------------------------------------------------------
127 // Selection of edge that coversmost of the domain of the initial edge.
128 //----------------------------------------------------------------------
129 for (; it.More(); it.Next()) {
130 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
132 BRep_Tool::Range(EI, Fst, Lst);
133 BRepAdaptor_Curve Ad2(EI);
135 // Modified by Sergey KHROMOV - Wed Jun 5 11:25:03 2002 Begin
137 Standard_Real aTol = BRep_Tool::Tolerance(EI);
138 Standard_Boolean isMinFound = Standard_False;
139 Standard_Real aSqrDist1 = Precision::Infinite();
140 Standard_Real aSqrDist2 = Precision::Infinite();
142 anExt.Initialize(Ad2, Fst, Lst, aTol);
144 // Seek for the min distance for PFirst:
145 anExt.Perform(PFirst);
146 if (anExt.IsDone()) {
147 for (i = 1; i <= anExt.NbExt(); i++) {
148 if (anExt.IsMin(i)) {
149 const gp_Pnt &aPMin = anExt.Point(i).Value();
151 aSqrDist1 = PFirst.SquareDistance(aPMin);
152 isMinFound = Standard_True;
159 gp_Pnt aP1 = Ad2.Value(Fst);
160 gp_Pnt aP2 = Ad2.Value(Lst);
162 aSqrDist1 = Min(aP1.SquareDistance(PFirst), aP2.SquareDistance(PFirst));
165 // Seek for the min distance for PLast:
166 isMinFound = Standard_False;
167 anExt.Perform(PLast);
168 if (anExt.IsDone()) {
169 for (i = 1; i <= anExt.NbExt(); i++) {
170 if (anExt.IsMin(i)) {
171 const gp_Pnt &aPMin = anExt.Point(i).Value();
173 aSqrDist2 = PLast.SquareDistance(aPMin);
174 isMinFound = Standard_True;
181 gp_Pnt aP1 = Ad2.Value(Fst);
182 gp_Pnt aP2 = Ad2.Value(Lst);
184 aSqrDist2 = Min(aP1.SquareDistance(PLast), aP2.SquareDistance(PLast));
187 tmp = aSqrDist1 + aSqrDist2;
188 // gp_Pnt P1 = Ad2.Value(Fst);
189 // gp_Pnt P2 = Ad2.Value(Lst);
191 // tmp = P1.Distance(PFirst) + P2.Distance(PLast);
196 // Modified by Sergey KHROMOV - Wed Jun 5 11:24:54 2002 End
204 //=======================================================================
205 //function : CompletInt
207 //=======================================================================
209 void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces,
210 const BRepAlgo_Image& InitOffsetFace)
212 //---------------------------------------------------------------
213 // Calculate the intersections of offset faces
214 // Distinction of intersection between faces // tangents.
215 //---------------------------------------------------------------
217 TopTools_ListIteratorOfListOfShape it;
219 //---------------------------------------------------------------
220 // Construction of bounding boxes
221 //---------------------------------------------------------------
222 TopOpeBRepTool_BoxSort BOS;
224 TopoDS_Compound CompOS;
225 B.MakeCompound(CompOS);
227 for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
228 const TopoDS_Shape& OS = it.Value();
231 BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE);
233 //---------------------------
234 // Intersection of faces //
235 //---------------------------
236 for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
237 const TopoDS_Face& F1 = TopoDS::Face(it.Value());
238 TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1);
239 for (; itLI.More(); itLI.Next()) {
240 F2 = TopoDS::Face(BOS.TouchedShape(itLI));
241 FaceInter(F1,F2,InitOffsetFace);
247 //=======================================================================
248 //function : CompletInt
250 //=======================================================================
252 void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
253 const TopoDS_Face& F2,
254 const BRepAlgo_Image& InitOffsetFace)
256 TopTools_ListOfShape LInt1, LInt2;
257 TopoDS_Edge NullEdge;
259 if (F1.IsSame(F2)) return;
260 if (IsDone(F1,F2)) return;
261 const TopoDS_Shape& InitF1 = InitOffsetFace.ImageFrom(F1);
262 const TopoDS_Shape& InitF2 = InitOffsetFace.ImageFrom(F2);
263 Standard_Boolean InterPipes = (InitF2.ShapeType() == TopAbs_EDGE &&
264 InitF1.ShapeType() == TopAbs_EDGE );
265 Standard_Boolean InterFaces = (InitF1.ShapeType() == TopAbs_FACE &&
266 InitF2.ShapeType() == TopAbs_FACE);
267 TopTools_ListOfShape LE,LV;
268 LInt1.Clear(); LInt2.Clear();
269 if (BRepOffset_Tool::HasCommonShapes(F1,F2,LE,LV) ||
270 myAsDes->HasCommonDescendant(F1,F2,LE)) {
271 //-------------------------------------------------
272 // F1 and F2 share shapes.
273 //-------------------------------------------------
274 if ( LE.IsEmpty() && !LV.IsEmpty()) {
276 //----------------------
277 // tubes share a vertex.
278 //----------------------
279 const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1);
280 const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2);
281 TopoDS_Vertex VE1[2],VE2[2];
282 TopExp::Vertices(EE1,VE1[0],VE1[1]);
283 TopExp::Vertices(EE2,VE2[0],VE2[1]);
285 for (Standard_Integer i = 0 ; i < 2; i++) {
286 for (Standard_Integer j = 0 ; j < 2; j++) {
287 if (VE1[i].IsSame(VE2[j])) {
292 if (!InitOffsetFace.HasImage(V)) { //no sphere
293 BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
297 //--------------------------------------------------------
298 // Intersection having only common vertices
299 // and supports having common edges.
300 // UNSUFFICIENT, but a larger criterion shakes too
302 //--------------------------------------------------------
304 BRepOffset_Tool::HasCommonShapes(TopoDS::Face(InitF1),
305 TopoDS::Face(InitF2),LE,LV))
307 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
313 BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
316 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
319 Store (F1,F2,LInt1,LInt2);
323 //=======================================================================
324 //function : ConnexIntByArc
326 //=======================================================================
328 void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces*/,
329 const TopoDS_Shape& ShapeInit,
330 const BRepOffset_Analyse& Analyse,
331 const BRepAlgo_Image& InitOffsetFace)
333 BRepOffset_Type OT = BRepOffset_Concave;
334 if (mySide == TopAbs_OUT) OT = BRepOffset_Convex;
335 TopExp_Explorer Exp(ShapeInit,TopAbs_EDGE);
336 TopTools_ListOfShape LInt1,LInt2;
338 TopoDS_Edge NullEdge;
340 //---------------------------------------------------------------------
341 // etape 1 : Intersection of faces // corresponding to the initial faces
342 // separated by a concave edge if offset > 0, otherwise convex.
343 //---------------------------------------------------------------------
344 for (; Exp.More(); Exp.Next()) {
345 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
346 const BRepOffset_ListOfInterval& L = Analyse.Type(E);
347 if (!L.IsEmpty() && L.First().Type() == OT) {
348 //-----------------------------------------------------------
349 // edge is of the proper type , return adjacent faces.
350 //-----------------------------------------------------------
351 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
352 if (Anc.Extent() == 2) {
353 F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First());
354 F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First());
355 if (!IsDone(F1,F2)) {
356 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True);
357 Store (F1,F2,LInt1,LInt2);
362 //---------------------------------------------------------------------
363 // etape 2 : Intersections of tubes sharing a vertex without sphere with:
364 // - tubes on each other edge sharing the vertex
365 // - faces containing an edge connected to vertex that has no tubes.
366 //---------------------------------------------------------------------
368 TopTools_ListIteratorOfListOfShape it;
370 for (Exp.Init(ShapeInit,TopAbs_EDGE); Exp.More(); Exp.Next()) {
371 const TopoDS_Edge& E1 = TopoDS::Edge(Exp.Current());
372 if (InitOffsetFace.HasImage(E1)) {
373 //---------------------------
374 // E1 generated a tube.
375 //---------------------------
376 F1 = TopoDS::Face(InitOffsetFace.Image(E1).First());;
377 TopExp::Vertices(E1,V[0],V[1]);
378 const TopTools_ListOfShape& AncE1 = Analyse.Ancestors(E1);
380 for (Standard_Integer i = 0; i < 2; i++) {
381 if (!InitOffsetFace.HasImage(V[i])) {
382 //-----------------------------
383 // the vertex has no sphere.
384 //-----------------------------
385 const TopTools_ListOfShape& Anc = Analyse.Ancestors(V[i]);
386 TopTools_ListOfShape TangOnV;
387 Analyse.TangentEdges(E1,V[i],TangOnV);
388 TopTools_MapOfShape MTEV;
389 for (it.Initialize(TangOnV); it.More(); it.Next()) {
390 MTEV.Add(it.Value());
392 for (it.Initialize(Anc); it.More(); it.Next()) {
393 const TopoDS_Edge& E2 = TopoDS::Edge(it.Value());
394 // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 Begin
395 // if (E1.IsSame(E2) || MTEV.Contains(E2)) continue;
396 Standard_Boolean isToSkip = Standard_False;
398 if (!E1.IsSame(E2)) {
399 const BRepOffset_ListOfInterval& aL = Analyse.Type(E2);
401 isToSkip = (MTEV.Contains(E2) &&
403 (!aL.IsEmpty() && aL.First().Type() != OT)));
406 if (E1.IsSame(E2) || isToSkip)
408 // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 End
409 if (InitOffsetFace.HasImage(E2)) {
410 //-----------------------------
411 // E2 generated a tube.
412 //-----------------------------
413 F2 = TopoDS::Face(InitOffsetFace.Image(E2).First());
414 if (!IsDone(F1,F2)) {
415 //---------------------------------------------------------------------
416 // Intersection tube/tube if the edges are not tangent (AFINIR).
417 //----------------------------------------------------------------------
418 BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide);
419 Store (F1,F2,LInt1,LInt2);
423 //-------------------------------------------------------
424 // Intersection of the tube of E1 with faces //
425 // to face containing E2 if they are not tangent
426 // to the tube or if E2 is not a tangent edge.
427 //-------------------------------------------------------
428 const BRepOffset_ListOfInterval& L = Analyse.Type(E2);
429 if (!L.IsEmpty() && L.First().Type() == BRepOffset_Tangent) {
432 const TopTools_ListOfShape& AncE2 = Analyse.Ancestors(E2);
433 Standard_Boolean TangentFaces = Standard_False;
434 if (AncE2.Extent() == 2) {
435 TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ());
436 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
437 InitF2.IsSame(AncE1.Last()));
439 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
440 if (!IsDone(F1,F2)) {
441 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
442 Store (F1,F2,LInt1,LInt2);
445 InitF2 = TopoDS::Face(AncE2.Last ());
446 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
447 InitF2.IsSame(AncE1.Last()));
449 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
450 if (!IsDone(F1,F2)) {
451 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
452 Store (F1,F2,LInt1,LInt2);
465 //=======================================================================
466 //function : ConnexIntByInt
468 //=======================================================================
470 void BRepOffset_Inter3d::ConnexIntByInt
471 (const TopoDS_Shape& SI,
472 const BRepOffset_DataMapOfShapeOffset& MapSF,
473 const BRepOffset_Analyse& Analyse,
474 TopTools_DataMapOfShapeShape& MES,
475 TopTools_DataMapOfShapeShape& Build,
476 TopTools_ListOfShape& Failed)
478 //TopExp_Explorer Exp(SI,TopAbs_EDGE);
479 TopTools_IndexedMapOfShape Emap;
480 TopExp::MapShapes( SI, TopAbs_EDGE, Emap );
481 TopoDS_Face F1,F2,OF1,OF2,NF1,NF2;
482 TopAbs_State CurSide = mySide;
484 TopTools_ListIteratorOfListOfShape it;
486 //for (; Exp.More(); Exp.Next()) {
487 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
488 //const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
489 const TopoDS_Edge& E = TopoDS::Edge(Emap(i));
490 const BRepOffset_ListOfInterval& L = Analyse.Type(E);
492 BRepOffset_Type OT = L.First().Type();
493 if (OT == BRepOffset_Convex || OT == BRepOffset_Concave) {
494 if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
495 else CurSide = TopAbs_OUT;
496 //-----------------------------------------------------------
497 // edge is of the proper type, return adjacent faces.
498 //-----------------------------------------------------------
499 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
500 if (Anc.Extent() != 2) continue;
501 F1 = TopoDS::Face(Anc.First());
502 F2 = TopoDS::Face(Anc.Last ());
503 OF1 = TopoDS::Face(MapSF(F1).Face()); OF2 = TopoDS::Face(MapSF(F2).Face());
504 if (!MES.IsBound(OF1)) {
505 Standard_Boolean enlargeU = Standard_True;
506 Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
507 BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
508 BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
512 NF1 = TopoDS::Face(MES(OF1));
514 if (!MES.IsBound(OF2)) {
515 Standard_Boolean enlargeU = Standard_True;
516 Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
517 BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
518 BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
522 NF2 = TopoDS::Face(MES(OF2));
524 if (!IsDone(NF1,NF2)) {
525 TopTools_ListOfShape LInt1,LInt2;
526 BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,Standard_True);
527 if (LInt1.Extent() > 1)
529 // intersection is in seceral edges (free sewing)
530 SelectEdge( NF1, NF2, E, LInt1 );
531 SelectEdge( NF1, NF2, E, LInt2 );
534 if (!LInt1.IsEmpty()) {
535 Store (NF1,NF2,LInt1,LInt2);
538 for (it.Initialize(LInt1) ; it.More(); it.Next()) {
546 } else { // IsDone(NF1,NF2)
547 // Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
548 const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
549 const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
551 if (!aLInt1.IsEmpty()) {
553 TopTools_ListIteratorOfListOfShape anIt2;
557 for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
558 const TopoDS_Shape &anE1 = it.Value();
560 for (anIt2.Initialize(aLInt2) ; anIt2.More(); anIt2.Next()) {
561 const TopoDS_Shape &anE2 = anIt2.Value();
563 if (anE1.IsSame(anE2))
573 // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
579 //=======================================================================
580 //function : ContextIntByInt
582 //=======================================================================
584 void BRepOffset_Inter3d::ContextIntByInt
585 (const TopTools_IndexedMapOfShape& ContextFaces,
586 const Standard_Boolean ExtentContext,
587 const BRepOffset_DataMapOfShapeOffset& MapSF,
588 const BRepOffset_Analyse& Analyse,
589 TopTools_DataMapOfShapeShape& MES,
590 TopTools_DataMapOfShapeShape& Build,
591 TopTools_ListOfShape& Failed)
593 TopTools_ListOfShape LInt1,LInt2;
594 TopTools_MapOfShape MV;
596 TopoDS_Face OF,NF,WCF;
600 TopTools_ListIteratorOfListOfShape it;
603 for (i = 1; i <= ContextFaces.Extent(); i++) {
604 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
607 BRepOffset_Tool::EnLargeFace(CF,NF,0,0);
611 TopAbs_State Side = TopAbs_OUT;
613 for (i = 1; i <= ContextFaces.Extent(); i++) {
614 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
615 if (ExtentContext) WCF = TopoDS::Face(MES(CF));
618 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
619 exp.More(); exp.Next()) {
620 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
621 if (!Analyse.HasAncestor(E)) {
622 //----------------------------------------------------------------
623 // the edges of faces of context that are not in the initial shape
624 // can appear in the result.
625 //----------------------------------------------------------------
626 if (!ExtentContext) {
631 if (!MES.IsBound(E)) {
633 Standard_Real f,l,Tol;
634 BRep_Tool::Range(E,f,l);
635 Tol = BRep_Tool::Tolerance(E);
638 TopExp::Vertices(E,V1,V2);
639 NE.Orientation(TopAbs_FORWARD);
640 myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
641 myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
642 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
643 B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
644 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
645 B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
646 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
647 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
648 NE.Orientation(E.Orientation());
654 TopoDS_Shape NE = MES(E);
655 TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation());
656 myAsDes->Add(CF,aLocalShape);
657 // myAsDes->Add(CF,NE.Oriented(E.Orientation()));
662 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
663 const TopoDS_Face& F = TopoDS::Face(Anc.First());
664 OF = TopoDS::Face(MapSF(F).Face());
665 TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
666 OE = TopoDS::Edge(aLocalShape);
667 // OE = TopoDS::Edge(MapSF(F).Generated(E));
668 if (!MES.IsBound(OF)) {
669 BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
673 NF = TopoDS::Face(MES(OF));
675 if (!IsDone(NF,CF)) {
676 TopTools_ListOfShape LInt1,LInt2;
677 TopTools_ListOfShape LOE;
679 BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,Standard_True);
681 if (!LInt1.IsEmpty()) {
682 Store (CF,NF,LInt1,LInt2);
683 if (LInt1.Extent() == 1) {
684 Build.Bind(E,LInt1.First());
688 for (it.Initialize(LInt1) ; it.More(); it.Next()) {
702 //=======================================================================
703 //function : ContextIntByArc
705 //=======================================================================
707 void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& ContextFaces,
708 const Standard_Boolean InSide,
709 const BRepOffset_Analyse& Analyse,
710 const BRepAlgo_Image& InitOffsetFace,
711 BRepAlgo_Image& InitOffsetEdge)
714 TopTools_ListOfShape LInt1,LInt2;
715 TopTools_MapOfShape MV;
720 TopoDS_Edge NullEdge;
723 for (j = 1; j <= ContextFaces.Extent(); j++) {
724 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
728 for (j = 1; j <= ContextFaces.Extent(); j++) {
729 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
730 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
731 exp.More(); exp.Next()) {
732 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
733 if (!Analyse.HasAncestor(E)) {
738 if (!InitOffsetEdge.HasImage(E)) {
739 Standard_Real f,l,Tol;
740 BRep_Tool::Range(E,f,l);
741 Tol = BRep_Tool::Tolerance(E);
744 TopExp::Vertices(E,V1,V2);
745 NE.Orientation(TopAbs_FORWARD);
746 myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
747 myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
748 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
749 B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
750 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
751 B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
752 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
753 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
754 NE.Orientation(E.Orientation());
756 InitOffsetEdge.Bind(E,NE);
759 NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
760 myAsDes->Add(CF,NE.Oriented(E.Orientation()));
766 //---------------------------------------------------
767 // OF1 parallel facee generated by the ancestor of E.
768 //---------------------------------------------------
769 const TopoDS_Shape SI = Analyse.Ancestors(E).First();
770 OF1 = TopoDS::Face(InitOffsetFace.Image(SI).First());
771 OE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
772 //--------------------------------------------------
773 // MAJ of OE on cap CF.
774 //--------------------------------------------------
775 // TopTools_ListOfShape LOE; LOE.Append(OE);
776 // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
778 // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
780 LInt1.Clear(); LInt1.Append(OE);
782 TopAbs_Orientation O1,O2;
783 BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);
784 // if (mySide == TopAbs_OUT) O1 = TopAbs::Reverse(O1);
785 O1 = TopAbs::Reverse(O1);
786 LInt1.First().Orientation(O1);
787 Store(CF,OF1,LInt1,LInt2);
789 //------------------------------------------------------
790 // Processing of offsets on the ancestors of vertices.
791 //------------------------------------------------------
793 TopExp::Vertices (E,V[0],V[1]);
794 for (Standard_Integer i = 0; i < 2; i++) {
795 if (!MV.Add(V[i])) continue;
797 const TopTools_ListOfShape& LE = Analyse.Ancestors(V[i]);
798 TopTools_ListIteratorOfListOfShape itLE(LE);
799 for ( ; itLE.More(); itLE.Next()) {
800 const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
801 if (InitOffsetFace.HasImage(EV)) {
802 //-------------------------------------------------
803 // OF1 parallel face generated by an ancester edge of V[i].
804 //-------------------------------------------------
805 OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First());
806 OE = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First());
807 //--------------------------------------------------
808 // MAj of OE on cap CF.
809 //--------------------------------------------------
810 // LOE.Clear(); LOE.Append(OE);
811 // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
813 // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
815 LInt1.Clear(); LInt1.Append(OE);
817 TopAbs_Orientation O1,O2;
818 BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);
819 // if (mySide == TopAbs_OUT);
820 O1 = TopAbs::Reverse(O1);
821 LInt1.First().Orientation(O1);
822 Store(CF,OF1,LInt1,LInt2);
828 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
829 exp.More(); exp.Next()) {
830 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
831 if (!Analyse.HasAncestor(V)) {
834 const TopTools_ListOfShape& LE = Analyse.Ancestors(V);
835 TopTools_ListIteratorOfListOfShape itLE(LE);
836 for (; itLE.More(); itLE.Next()) {
837 const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
838 const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
839 TopTools_ListIteratorOfListOfShape itLF(LF);
840 for ( ; itLF.More(); itLF.Next()) {
841 const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
842 //-------------------------------------------------
843 // OF1 parallel face generated by uneFace ancestor of V[i].
844 //-------------------------------------------------
845 OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
846 if (!IsDone(OF1,CF)) {
847 //-------------------------------------------------------
848 // Find if one of edges of OF1 has no trace in CF.
849 //-------------------------------------------------------
850 TopTools_ListOfShape LOE;
851 TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
852 for ( ;exp2.More(); exp2.Next()) {
853 LOE.Append(exp2.Current());
855 BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
856 //-------------------------------------------------------
857 // If no trace try intersection.
858 //-------------------------------------------------------
859 if (LInt1.IsEmpty()) {
860 BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge);
862 Store (CF,OF1,LInt1,LInt2);
870 //=======================================================================
871 //function : AddCommonEdges
873 //=======================================================================
875 void BRepOffset_Inter3d::AddCommonEdges(const TopTools_ListOfShape&)
880 //=======================================================================
883 //=======================================================================
885 void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1,
886 const TopoDS_Face& F2)
888 if (!myDone.IsBound(F1)) {
889 TopTools_ListOfShape empty;
890 myDone.Bind(F1,empty);
892 myDone(F1).Append(F2);
893 if (!myDone.IsBound(F2)) {
894 TopTools_ListOfShape empty;
895 myDone.Bind(F2,empty);
897 myDone(F2).Append(F1);
901 //=======================================================================
904 //=======================================================================
906 Standard_Boolean BRepOffset_Inter3d::IsDone(const TopoDS_Face& F1,
907 const TopoDS_Face& F2)
910 if (myDone.IsBound(F1)) {
911 TopTools_ListIteratorOfListOfShape it (myDone(F1));
912 for (; it.More(); it.Next()) {
913 if (it.Value().IsSame(F2)) return Standard_True;
916 return Standard_False;
920 //=======================================================================
921 //function : TouchedFaces
923 //=======================================================================
925 TopTools_IndexedMapOfShape& BRepOffset_Inter3d::TouchedFaces()
931 //=======================================================================
934 //=======================================================================
936 Handle(BRepAlgo_AsDes) BRepOffset_Inter3d::AsDes() const
942 //=======================================================================
943 //function : NewEdges
945 //=======================================================================
947 TopTools_IndexedMapOfShape& BRepOffset_Inter3d::NewEdges()
954 //=======================================================================
957 //=======================================================================
959 void BRepOffset_Inter3d::Store(const TopoDS_Face& F1,
960 const TopoDS_Face& F2,
961 const TopTools_ListOfShape& LInt1,
962 const TopTools_ListOfShape& LInt2)
964 if (!LInt1.IsEmpty()) {
967 myAsDes->Add( F1,LInt1);
968 myAsDes->Add( F2,LInt2);
969 TopTools_ListIteratorOfListOfShape it(LInt1);
970 for (; it.More(); it.Next()) {
971 myNewEdges.Add(it.Value());