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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455
18
19 #include <Bnd_Tools.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepAdaptor_Curve.hxx>
23 #include <BRepAlgo_AsDes.hxx>
24 #include <BRepAlgo_Image.hxx>
25 #include <BRepLib_MakeVertex.hxx>
26 #include <BRepOffset_Analyse.hxx>
27 #include <BRepOffset_DataMapOfShapeOffset.hxx>
28 #include <BRepOffset_Inter3d.hxx>
29 #include <BRepOffset_Interval.hxx>
30 #include <BRepOffset_ListOfInterval.hxx>
31 #include <BRepOffset_Offset.hxx>
32 #include <BRepOffset_Tool.hxx>
33 #include <Extrema_ExtPC.hxx>
34 #include <GeomAPI_ProjectPointOnCurve.hxx>
35 #include <Precision.hxx>
36 #include <TopExp.hxx>
37 #include <TopExp_Explorer.hxx>
38 #include <TopoDS.hxx>
39 #include <TopoDS_Compound.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Shape.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <TopTools_IndexedMapOfShape.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopTools_MapIteratorOfMapOfShape.hxx>
47 #include <TopTools_MapOfShape.hxx>
48 //
49 #include <BRepBndLib.hxx>
50 #include <BOPTools_BoxTree.hxx>
51 //
52 #include <BOPTools_AlgoTools.hxx>
53
54 //=======================================================================
55 //function : BRepOffset_Inter3d
56 //purpose :
57 //=======================================================================
BRepOffset_Inter3d(const Handle (BRepAlgo_AsDes)& AsDes,const TopAbs_State Side,const Standard_Real Tol)58 BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes,
59 const TopAbs_State Side ,
60 const Standard_Real Tol)
61 :myAsDes(AsDes),
62 mySide(Side),
63 myTol(Tol)
64 {
65 }
66
67
68 //=======================================================================
69 //function : ExtentEdge
70 //purpose :
71 //=======================================================================
72
ExtentEdge(const TopoDS_Face &,const TopoDS_Edge & E,TopoDS_Edge & NE)73 static void ExtentEdge(const TopoDS_Face& /*F*/,
74 const TopoDS_Edge& E,
75 TopoDS_Edge& NE)
76 {
77 TopoDS_Shape aLocalShape = E.EmptyCopied();
78 NE = TopoDS::Edge(aLocalShape);
79 // NE = TopoDS::Edge(E.EmptyCopied());
80
81
82 // Enough for analytic edges, in general case reconstruct the
83 // geometry of the edge recalculating the intersection of surfaces.
84
85 NE.Orientation(TopAbs_FORWARD);
86 Standard_Real f,l;
87 BRep_Tool::Range(E,f,l);
88 Standard_Real length = l-f;
89 f -= 100*length;
90 l += 100*length;
91
92 BRep_Builder B;
93 B.Range(NE,f,l);
94 BRepAdaptor_Curve CE(E);
95 TopoDS_Vertex V1 = BRepLib_MakeVertex(CE.Value(f));
96 TopoDS_Vertex V2 = BRepLib_MakeVertex(CE.Value(l));
97 B.Add(NE,V1.Oriented(TopAbs_FORWARD));
98 B.Add(NE,V2.Oriented(TopAbs_REVERSED));
99 NE.Orientation(E.Orientation());
100
101 }
102
103 //=======================================================================
104 //function : CompletInt
105 //purpose :
106 //=======================================================================
107
CompletInt(const TopTools_ListOfShape & SetOfFaces,const BRepAlgo_Image & InitOffsetFace,const Message_ProgressRange & theRange)108 void BRepOffset_Inter3d::CompletInt (const TopTools_ListOfShape& SetOfFaces,
109 const BRepAlgo_Image& InitOffsetFace,
110 const Message_ProgressRange& theRange)
111 {
112 //---------------------------------------------------------------
113 // Calculate the intersections of offset faces
114 // Distinction of intersection between faces // tangents.
115 //---------------------------------------------------------------
116
117 // Prepare tools for sorting the bounding boxes
118 BOPTools_BoxTree aBBTree;
119 aBBTree.SetSize (SetOfFaces.Extent());
120 //
121 NCollection_IndexedDataMap<TopoDS_Shape, Bnd_Box, TopTools_ShapeMapHasher> aMFaces;
122 // Construct bounding boxes for faces and add them to the tree
123 TopTools_ListIteratorOfListOfShape aItL(SetOfFaces);
124 for (; aItL.More(); aItL.Next()) {
125 const TopoDS_Face& aF = TopoDS::Face(aItL.Value());
126 //
127 // compute bounding box
128 Bnd_Box aBoxF;
129 BRepBndLib::Add(aF, aBoxF);
130 //
131 Standard_Integer i = aMFaces.Add (aF, aBoxF);
132 //
133 aBBTree.Add(i, Bnd_Tools::Bnd2BVH(aBoxF));
134 }
135
136 // Build BVH
137 aBBTree.Build();
138
139 // Perform selection of the pairs
140 BOPTools_BoxPairSelector aSelector;
141 aSelector.SetBVHSets (&aBBTree, &aBBTree);
142 aSelector.SetSame (Standard_True);
143 aSelector.Select();
144 aSelector.Sort();
145
146 // Treat the selected pairs
147 const std::vector<BOPTools_BoxPairSelector::PairIDs>& aPairs = aSelector.Pairs();
148 const Standard_Integer aNbPairs = static_cast<Standard_Integer> (aPairs.size());
149 Message_ProgressScope aPS(theRange, "Complete intersection", aNbPairs);
150 for (Standard_Integer iPair = 0; iPair < aNbPairs; ++iPair, aPS.Next())
151 {
152 if (!aPS.More())
153 {
154 return;
155 }
156 const BOPTools_BoxPairSelector::PairIDs& aPair = aPairs[iPair];
157
158 const TopoDS_Face& aF1 = TopoDS::Face (aMFaces.FindKey (Min (aPair.ID1, aPair.ID2)));
159 const TopoDS_Face& aF2 = TopoDS::Face (aMFaces.FindKey (Max (aPair.ID1, aPair.ID2)));
160
161 // intersect faces
162 FaceInter(aF1, aF2, InitOffsetFace);
163 }
164 }
165
166 //=======================================================================
167 //function : FaceInter
168 //purpose : Performs intersection of the given faces
169 //=======================================================================
170
FaceInter(const TopoDS_Face & F1,const TopoDS_Face & F2,const BRepAlgo_Image & InitOffsetFace)171 void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
172 const TopoDS_Face& F2,
173 const BRepAlgo_Image& InitOffsetFace)
174 {
175 TopTools_ListOfShape LInt1, LInt2;
176 TopoDS_Edge NullEdge;
177 TopoDS_Face NullFace;
178
179 if (F1.IsSame(F2)) return;
180 if (IsDone(F1,F2)) return;
181
182 const TopoDS_Shape& InitF1 = InitOffsetFace.ImageFrom(F1);
183 const TopoDS_Shape& InitF2 = InitOffsetFace.ImageFrom(F2);
184 if (InitF1.IsSame(InitF2)) return;
185
186 Standard_Boolean InterPipes = (InitF2.ShapeType() == TopAbs_EDGE &&
187 InitF1.ShapeType() == TopAbs_EDGE );
188 Standard_Boolean InterFaces = (InitF1.ShapeType() == TopAbs_FACE &&
189 InitF2.ShapeType() == TopAbs_FACE);
190 TopTools_ListOfShape LE,LV;
191 LInt1.Clear(); LInt2.Clear();
192 if (BRepOffset_Tool::FindCommonShapes(F1,F2,LE,LV) ||
193 myAsDes->HasCommonDescendant(F1,F2,LE)) {
194 //-------------------------------------------------
195 // F1 and F2 share shapes.
196 //-------------------------------------------------
197 if ( LE.IsEmpty() && !LV.IsEmpty()) {
198 if (InterPipes) {
199 //----------------------
200 // tubes share a vertex.
201 //----------------------
202 const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1);
203 const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2);
204 TopoDS_Vertex VE1[2],VE2[2];
205 TopExp::Vertices(EE1,VE1[0],VE1[1]);
206 TopExp::Vertices(EE2,VE2[0],VE2[1]);
207 TopoDS_Vertex V;
208 for (Standard_Integer i = 0 ; i < 2; i++) {
209 for (Standard_Integer j = 0 ; j < 2; j++) {
210 if (VE1[i].IsSame(VE2[j])) {
211 V = VE1[i];
212 }
213 }
214 }
215 if (!InitOffsetFace.HasImage(V)) { //no sphere
216 BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
217 }
218 }
219 else {
220 //--------------------------------------------------------
221 // Intersection having only common vertices
222 // and supports having common edges.
223 // UNSUFFICIENT, but a larger criterion shakes too
224 // many sections.
225 //--------------------------------------------------------
226 if (InterFaces) {
227 if (BRepOffset_Tool::FindCommonShapes(TopoDS::Face(InitF1),
228 TopoDS::Face(InitF2),LE,LV)) {
229 if (!LE.IsEmpty()) {
230 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
231 }
232 }
233 else {
234 BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
235 }
236 }
237 }
238 }
239 }
240 else {
241 if (InterPipes) {
242 BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
243 }
244 else {
245 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
246 }
247 }
248 Store (F1,F2,LInt1,LInt2);
249 }
250
251
252 //=======================================================================
253 //function : ConnexIntByArc
254 //purpose :
255 //=======================================================================
256
ConnexIntByArc(const TopTools_ListOfShape &,const TopoDS_Shape & ShapeInit,const BRepOffset_Analyse & Analyse,const BRepAlgo_Image & InitOffsetFace,const Message_ProgressRange & theRange)257 void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces*/,
258 const TopoDS_Shape& ShapeInit,
259 const BRepOffset_Analyse& Analyse,
260 const BRepAlgo_Image& InitOffsetFace,
261 const Message_ProgressRange& theRange)
262 {
263 ChFiDS_TypeOfConcavity OT = ChFiDS_Concave;
264 if (mySide == TopAbs_OUT) OT = ChFiDS_Convex;
265 TopExp_Explorer Exp(ShapeInit,TopAbs_EDGE);
266 TopTools_ListOfShape LInt1,LInt2;
267 TopoDS_Face F1,F2;
268 TopoDS_Edge NullEdge;
269 TopoDS_Face NullFace;
270 Message_ProgressScope aPSOuter(theRange, NULL, 2);
271 Message_ProgressScope aPSIntF(aPSOuter.Next(), "Intersecting offset faces", 1, Standard_True);
272 //---------------------------------------------------------------------
273 // etape 1 : Intersection of faces // corresponding to the initial faces
274 // separated by a concave edge if offset > 0, otherwise convex.
275 //---------------------------------------------------------------------
276 for (; Exp.More(); Exp.Next(), aPSIntF.Next()) {
277 if (!aPSIntF.More())
278 {
279 return;
280 }
281 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
282 const BRepOffset_ListOfInterval& L = Analyse.Type(E);
283 if (!L.IsEmpty() && L.First().Type() == OT) {
284 //-----------------------------------------------------------
285 // edge is of the proper type , return adjacent faces.
286 //-----------------------------------------------------------
287 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
288 if (Anc.Extent() == 2) {
289
290 const TopoDS_Face& InitF1 = TopoDS::Face(Anc.First());
291 const TopoDS_Face& InitF2 = TopoDS::Face(Anc.Last());
292 F1 = TopoDS::Face(InitOffsetFace.Image(InitF1).First());
293 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
294 if (!IsDone(F1,F2)) {
295 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,InitF1,InitF2);
296 Store (F1,F2,LInt1,LInt2);
297 }
298 }
299 }
300 }
301 //---------------------------------------------------------------------
302 // etape 2 : Intersections of tubes sharing a vertex without sphere with:
303 // - tubes on each other edge sharing the vertex
304 // - faces containing an edge connected to vertex that has no tubes.
305 //---------------------------------------------------------------------
306 TopoDS_Vertex V[2];
307 TopTools_ListIteratorOfListOfShape it;
308 Message_ProgressScope aPSIntT(aPSOuter.Next(), "Intersecting tubes", 1, Standard_True);
309 for (Exp.Init(ShapeInit,TopAbs_EDGE); Exp.More(); Exp.Next(), aPSIntT.Next()) {
310 if (!aPSIntT.More())
311 {
312 return;
313 }
314 const TopoDS_Edge& E1 = TopoDS::Edge(Exp.Current());
315 if (InitOffsetFace.HasImage(E1)) {
316 //---------------------------
317 // E1 generated a tube.
318 //---------------------------
319 F1 = TopoDS::Face(InitOffsetFace.Image(E1).First());
320 TopExp::Vertices(E1,V[0],V[1]);
321 const TopTools_ListOfShape& AncE1 = Analyse.Ancestors(E1);
322
323 for (Standard_Integer i = 0; i < 2; i++) {
324 if (!InitOffsetFace.HasImage(V[i])) {
325 //-----------------------------
326 // the vertex has no sphere.
327 //-----------------------------
328 const TopTools_ListOfShape& Anc = Analyse.Ancestors(V[i]);
329 TopTools_ListOfShape TangOnV;
330 Analyse.TangentEdges(E1,V[i],TangOnV);
331 TopTools_MapOfShape MTEV;
332 for (it.Initialize(TangOnV); it.More(); it.Next()) {
333 MTEV.Add(it.Value());
334 }
335 for (it.Initialize(Anc); it.More(); it.Next()) {
336 const TopoDS_Edge& E2 = TopoDS::Edge(it.Value());
337 // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 Begin
338 // if (E1.IsSame(E2) || MTEV.Contains(E2)) continue;
339 Standard_Boolean isToSkip = Standard_False;
340
341 if (!E1.IsSame(E2)) {
342 const BRepOffset_ListOfInterval& aL = Analyse.Type(E2);
343
344 isToSkip = (MTEV.Contains(E2) &&
345 (aL.IsEmpty() ||
346 (!aL.IsEmpty() && aL.First().Type() != OT)));
347 }
348
349 if (E1.IsSame(E2) || isToSkip)
350 continue;
351 // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 End
352 if (InitOffsetFace.HasImage(E2)) {
353 //-----------------------------
354 // E2 generated a tube.
355 //-----------------------------
356 F2 = TopoDS::Face(InitOffsetFace.Image(E2).First());
357 if (!IsDone(F1,F2)) {
358 //---------------------------------------------------------------------
359 // Intersection tube/tube if the edges are not tangent (AFINIR).
360 //----------------------------------------------------------------------
361 BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide);
362 Store (F1,F2,LInt1,LInt2);
363 }
364 }
365 else {
366 //-------------------------------------------------------
367 // Intersection of the tube of E1 with faces //
368 // to face containing E2 if they are not tangent
369 // to the tube or if E2 is not a tangent edge.
370 //-------------------------------------------------------
371 const BRepOffset_ListOfInterval& L = Analyse.Type(E2);
372 if (!L.IsEmpty() && L.First().Type() == ChFiDS_Tangential) {
373 continue;
374 }
375 const TopTools_ListOfShape& AncE2 = Analyse.Ancestors(E2);
376 Standard_Boolean TangentFaces = Standard_False;
377 if (AncE2.Extent() == 2) {
378 TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ());
379 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
380 InitF2.IsSame(AncE1.Last()));
381 if (!TangentFaces) {
382 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
383 if (!IsDone(F1,F2)) {
384 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
385 Store (F1,F2,LInt1,LInt2);
386 }
387 }
388 InitF2 = TopoDS::Face(AncE2.Last ());
389 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
390 InitF2.IsSame(AncE1.Last()));
391 if (!TangentFaces) {
392 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
393 if (!IsDone(F1,F2)) {
394 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
395 Store (F1,F2,LInt1,LInt2);
396 }
397 }
398 }
399 }
400 }
401 }
402 }
403 }
404 }
405 }
406
407
408 //=======================================================================
409 //function : ConnexIntByInt
410 //purpose :
411 //=======================================================================
412
ConnexIntByInt(const TopoDS_Shape & SI,const BRepOffset_DataMapOfShapeOffset & MapSF,const BRepOffset_Analyse & Analyse,TopTools_DataMapOfShapeShape & MES,TopTools_DataMapOfShapeShape & Build,TopTools_ListOfShape & Failed,const Message_ProgressRange & theRange,const Standard_Boolean bIsPlanar)413 void BRepOffset_Inter3d::ConnexIntByInt
414 (const TopoDS_Shape& SI,
415 const BRepOffset_DataMapOfShapeOffset& MapSF,
416 const BRepOffset_Analyse& Analyse,
417 TopTools_DataMapOfShapeShape& MES,
418 TopTools_DataMapOfShapeShape& Build,
419 TopTools_ListOfShape& Failed,
420 const Message_ProgressRange& theRange,
421 const Standard_Boolean bIsPlanar)
422 {
423 TopTools_IndexedMapOfShape VEmap;
424 TopoDS_Face F1,F2,OF1,OF2,NF1,NF2;
425 TopAbs_State CurSide = mySide;
426 BRep_Builder B;
427 Standard_Boolean bEdge;
428 Standard_Integer i, aNb = 0;
429 TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2;
430 //
431 TopExp::MapShapes (SI, TopAbs_EDGE, VEmap);
432 // Take the vertices for treatment
433 Message_ProgressScope aPSOuter(theRange, NULL, 10);
434 if (bIsPlanar)
435 {
436 aNb = VEmap.Extent();
437 for (i = 1; i <= aNb; ++i)
438 {
439 const TopoDS_Edge& aE = TopoDS::Edge (VEmap (i));
440 TopoDS_Shape aFGen = Analyse.Generated (aE);
441 if (!aFGen.IsNull())
442 TopExp::MapShapes (aFGen, TopAbs_EDGE, VEmap);
443 }
444
445 // Add vertices for treatment
446 TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap);
447
448 for (TopTools_ListOfShape::Iterator itNF (Analyse.NewFaces()); itNF.More(); itNF.Next())
449 TopExp::MapShapes (itNF.Value(), TopAbs_VERTEX, VEmap);
450 }
451 //
452 TopTools_DataMapOfShapeListOfShape aDMVLF1, aDMVLF2, aDMIntFF;
453 TopTools_IndexedDataMapOfShapeListOfShape aDMIntE;
454 //
455 if (bIsPlanar)
456 {
457 // Find internal edges in the faces to skip them while preparing faces
458 // for intersection through vertices
459 NCollection_DataMap<TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> aDMFEI;
460 {
461 for (TopExp_Explorer expF (SI, TopAbs_FACE); expF.More(); expF.Next())
462 {
463 const TopoDS_Shape& aFx = expF.Current();
464
465 TopTools_MapOfShape aMEI;
466 for (TopExp_Explorer expE (aFx, TopAbs_EDGE); expE.More(); expE.Next())
467 {
468 const TopoDS_Shape& aEx = expE.Current();
469 if (aEx.Orientation() != TopAbs_FORWARD &&
470 aEx.Orientation() != TopAbs_REVERSED)
471 aMEI.Add (aEx);
472 }
473 if (!aMEI.IsEmpty())
474 aDMFEI.Bind (aFx, aMEI);
475 }
476 }
477
478 // Analyze faces connected through vertices
479 for (i = aNb + 1, aNb = VEmap.Extent(); i <= aNb; ++i)
480 {
481 if (!aPSOuter.More())
482 {
483 return;
484 }
485 const TopoDS_Shape& aS = VEmap(i);
486 if (aS.ShapeType() != TopAbs_VERTEX)
487 continue;
488
489 // Find faces connected to the vertex
490 TopTools_ListOfShape aLF;
491 {
492 const TopTools_ListOfShape& aLE = Analyse.Ancestors (aS);
493 for (TopTools_ListOfShape::Iterator itLE (aLE); itLE.More(); itLE.Next())
494 {
495 const TopTools_ListOfShape& aLEA = Analyse.Ancestors (itLE.Value());
496 for (TopTools_ListOfShape::Iterator itLEA (aLEA); itLEA.More(); itLEA.Next())
497 {
498 if (!aLF.Contains (itLEA.Value()))
499 aLF.Append (itLEA.Value());
500 }
501 }
502 }
503
504 if (aLF.Extent() < 2)
505 continue;
506
507 // build lists of faces connected to the same vertex by looking for
508 // the pairs in which the vertex is alone (not connected to shared edges)
509 TopTools_ListOfShape aLF1, aLF2;
510
511 it.Initialize(aLF);
512 for (; it.More(); it.Next())
513 {
514 const TopoDS_Shape& aFV1 = it.Value();
515
516 // get edges of first face connected to current vertex
517 TopTools_MapOfShape aME;
518 const TopTools_MapOfShape *pF1Internal = aDMFEI.Seek (aFV1);
519 const TopTools_ListOfShape* pLE1 = Analyse.Descendants (aFV1);
520 if (!pLE1)
521 continue;
522 TopTools_ListOfShape::Iterator itLE1 (*pLE1);
523 for (; itLE1.More(); itLE1.Next())
524 {
525 const TopoDS_Shape& aE = itLE1.Value();
526 if (pF1Internal && pF1Internal->Contains (aE))
527 break;
528
529 for (TopoDS_Iterator aItV(aE); aItV.More(); aItV.Next())
530 {
531 if (aS.IsSame (aItV.Value()))
532 {
533 aME.Add(aE);
534 break;
535 }
536 }
537 }
538 if (itLE1.More())
539 continue;
540
541 // get to the next face in the list
542 it1 = it;
543 for (it1.Next(); it1.More(); it1.Next()) {
544 const TopoDS_Face& aFV2 = TopoDS::Face (it1.Value());
545
546 const TopTools_MapOfShape *pF2Internal = aDMFEI.Seek (aFV2);
547
548 const TopTools_ListOfShape* pLE2 = Analyse.Descendants (aFV2);
549 if (!pLE2)
550 continue;
551 TopTools_ListOfShape::Iterator itLE2 (*pLE2);
552 for (; itLE2.More(); itLE2.Next())
553 {
554 const TopoDS_Shape& aEV2 = itLE2.Value();
555 if (!aME.Contains (aEV2))
556 continue;
557
558 if (pF2Internal && pF2Internal->Contains (aEV2))
559 // Avoid intersection of faces connected by internal edge
560 break;
561
562 if (Analyse.HasAncestor (aEV2) &&
563 Analyse.Ancestors (aEV2).Extent() == 2)
564 // Faces will be intersected through the edge
565 break;
566 }
567
568 if (!itLE2.More())
569 {
570 aLF1.Append(aFV1);
571 aLF2.Append(aFV2);
572 }
573 }
574 }
575 //
576 if (aLF1.Extent()) {
577 aDMVLF1.Bind(aS, aLF1);
578 aDMVLF2.Bind(aS, aLF2);
579 }
580 }
581 }
582 //
583 aNb = VEmap.Extent();
584 Message_ProgressScope aPSInter(aPSOuter.Next(8), "Intersecting offset faces", aNb);
585 for (i = 1; i <= aNb; ++i, aPSInter.Next()) {
586 if (!aPSInter.More())
587 {
588 return;
589 }
590 const TopoDS_Shape& aS = VEmap(i);
591 //
592 TopoDS_Edge E;
593 TopTools_ListOfShape aLF1, aLF2;
594 //
595 bEdge = (aS.ShapeType() == TopAbs_EDGE);
596 if (bEdge) {
597 // faces connected by the edge
598 E = *(TopoDS_Edge*)&aS;
599 //
600 const BRepOffset_ListOfInterval& L = Analyse.Type(E);
601 if (L.IsEmpty()) {
602 continue;
603 }
604 //
605 ChFiDS_TypeOfConcavity OT = L.First().Type();
606 if (OT != ChFiDS_Convex && OT != ChFiDS_Concave) {
607 continue;
608 }
609 //
610 if (OT == ChFiDS_Concave) CurSide = TopAbs_IN;
611 else CurSide = TopAbs_OUT;
612 //-----------------------------------------------------------
613 // edge is of the proper type, return adjacent faces.
614 //-----------------------------------------------------------
615 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
616 if (Anc.Extent() != 2) {
617 continue;
618 }
619 //
620 F1 = TopoDS::Face(Anc.First());
621 F2 = TopoDS::Face(Anc.Last ());
622 //
623 aLF1.Append(F1);
624 aLF2.Append(F2);
625 }
626 else {
627 if (!aDMVLF1.IsBound(aS)) {
628 continue;
629 }
630 //
631 aLF1 = aDMVLF1.Find(aS);
632 aLF2 = aDMVLF2.Find(aS);
633 //
634 CurSide = mySide;
635 }
636 //
637 itF1.Initialize(aLF1);
638 itF2.Initialize(aLF2);
639 for (; itF1.More() && itF2.More(); itF1.Next(), itF2.Next()) {
640 F1 = TopoDS::Face(itF1.Value());
641 F2 = TopoDS::Face(itF2.Value());
642 //
643 OF1 = TopoDS::Face(MapSF(F1).Face());
644 OF2 = TopoDS::Face(MapSF(F2).Face());
645 if (!MES.IsBound(OF1)) {
646 Standard_Boolean enlargeU = Standard_True;
647 Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
648 BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
649 BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
650 MES.Bind(OF1,NF1);
651 }
652 else {
653 NF1 = TopoDS::Face(MES(OF1));
654 }
655 //
656 if (!MES.IsBound(OF2)) {
657 Standard_Boolean enlargeU = Standard_True;
658 Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
659 BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
660 BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
661 MES.Bind(OF2,NF2);
662 }
663 else {
664 NF2 = TopoDS::Face(MES(OF2));
665 }
666 //
667 if (!IsDone(NF1,NF2)) {
668 TopTools_ListOfShape LInt1,LInt2;
669 BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,F1,F2);
670 SetDone(NF1,NF2);
671 if (!LInt1.IsEmpty()) {
672 Store (NF1,NF2,LInt1,LInt2);
673 //
674 TopoDS_Compound C;
675 B.MakeCompound(C);
676 //
677 if (Build.IsBound(aS)) {
678 const TopoDS_Shape& aSE = Build(aS);
679 TopExp_Explorer aExp(aSE, TopAbs_EDGE);
680 for (; aExp.More(); aExp.Next()) {
681 const TopoDS_Shape& aNE = aExp.Current();
682 B.Add(C, aNE);
683 }
684 }
685 //
686 it.Initialize(LInt1);
687 for (; it.More(); it.Next()) {
688 const TopoDS_Shape& aNE = it.Value();
689 B.Add(C, aNE);
690 //
691 // keep connection from new edge to shape from which it was created
692 TopTools_ListOfShape *pLS = &aDMIntE(aDMIntE.Add(aNE, TopTools_ListOfShape()));
693 pLS->Append(aS);
694 // keep connection to faces created the edge as well
695 TopTools_ListOfShape* pLFF = aDMIntFF.Bound(aNE, TopTools_ListOfShape());
696 pLFF->Append(F1);
697 pLFF->Append(F2);
698 }
699 //
700 Build.Bind(aS,C);
701 }
702 else {
703 Failed.Append(aS);
704 }
705 } else { // IsDone(NF1,NF2)
706 // Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
707 const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
708 const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
709
710 if (!aLInt1.IsEmpty()) {
711 TopoDS_Compound C;
712 B.MakeCompound(C);
713 //
714 if (Build.IsBound(aS)) {
715 const TopoDS_Shape& aSE = Build(aS);
716 TopExp_Explorer aExp(aSE, TopAbs_EDGE);
717 for (; aExp.More(); aExp.Next()) {
718 const TopoDS_Shape& aNE = aExp.Current();
719 B.Add(C, aNE);
720 }
721 }
722 //
723 for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
724 const TopoDS_Shape &anE1 = it.Value();
725 //
726 for (it1.Initialize(aLInt2) ; it1.More(); it1.Next()) {
727 const TopoDS_Shape &anE2 = it1.Value();
728 if (anE1.IsSame(anE2)) {
729 B.Add(C, anE1);
730 //
731 TopTools_ListOfShape *pLS = aDMIntE.ChangeSeek(anE1);
732 if (pLS) {
733 pLS->Append(aS);
734 }
735 }
736 }
737 }
738 Build.Bind(aS,C);
739 }
740 else {
741 Failed.Append(aS);
742 }
743 }
744 }
745 // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
746 }
747 //
748 // create unique intersection for each localized shared part
749 aNb = aDMIntE.Extent();
750 Message_ProgressScope aPSPostTreat(aPSOuter.Next(2), "Creating unique intersection", aNb);
751 for (i = 1; i <= aNb; ++i, aPSPostTreat.Next()) {
752 if (!aPSPostTreat.More())
753 {
754 return;
755 }
756 const TopTools_ListOfShape& aLS = aDMIntE(i);
757 if (aLS.Extent() < 2) {
758 continue;
759 }
760 //
761 // intersection edge
762 const TopoDS_Edge& aE = TopoDS::Edge(aDMIntE.FindKey(i));
763 // faces created the edge
764 const TopTools_ListOfShape& aLFF = aDMIntFF.Find(aE);
765 const TopoDS_Shape& aF1 = aLFF.First();
766 const TopoDS_Shape& aF2 = aLFF.Last();
767
768 // Build really localized blocks from the original shapes in <aLS>:
769 // 1. Find edges from original faces connected to two or more shapes in <aLS>;
770 // 2. Make connexity blocks from edges in <aLS> and found connection edges;
771 // 3. Check if the vertices from <aLS> are not connected by these connection edges:
772 // a. If so - add these vertices to Connexity Block containing the corresponding
773 // connexity edge;
774 // b. If not - add this vertex to list of connexity blocks
775 // 4. Create unique intersection edge for each connexity block
776
777 // list of vertices
778 TopTools_ListOfShape aLV;
779 // compound of edges to build connexity blocks
780 TopoDS_Compound aCE;
781 B.MakeCompound(aCE);
782 TopTools_MapOfShape aMS;
783 TopTools_ListIteratorOfListOfShape aItLS(aLS);
784 for (; aItLS.More(); aItLS.Next()) {
785 const TopoDS_Shape& aS = aItLS.Value();
786 aMS.Add(aS);
787 if (aS.ShapeType() == TopAbs_EDGE) {
788 B.Add(aCE, aS);
789 }
790 else {
791 aLV.Append(aS);
792 }
793 }
794 //
795 // look for additional edges to connect the shared parts
796 TopTools_MapOfShape aMEConnection;
797 for (Standard_Integer j = 0; j < 2; ++j) {
798 const TopoDS_Shape& aF = !j ? aF1 : aF2;
799 //
800 TopExp_Explorer aExp(aF, TopAbs_EDGE);
801 for (; aExp.More(); aExp.Next()) {
802 const TopoDS_Shape& aEF = aExp.Current();
803 if (aMS.Contains(aEF) || aMEConnection.Contains(aEF)) {
804 continue;
805 }
806 //
807 TopoDS_Vertex aV1, aV2;
808 TopExp::Vertices(TopoDS::Edge(aEF), aV1, aV2);
809 //
810 // find parts to which the edge is connected
811 Standard_Integer iCounter = 0;
812 aItLS.Initialize(aLS);
813 for (; aItLS.More(); aItLS.Next()) {
814 const TopoDS_Shape& aS = aItLS.Value();
815 // iterator is not suitable here, because aS may be a vertex
816 TopExp_Explorer aExpV(aS, TopAbs_VERTEX);
817 for (; aExpV.More(); aExpV.Next()) {
818 const TopoDS_Shape& aV = aExpV.Current();
819 if (aV.IsSame(aV1) || aV.IsSame(aV2)) {
820 ++iCounter;
821 break;
822 }
823 }
824 }
825 //
826 if (iCounter >= 2) {
827 B.Add(aCE, aEF);
828 aMEConnection.Add(aEF);
829 }
830 }
831 }
832 //
833 TopTools_ListOfShape aLCBE;
834 BOPTools_AlgoTools::MakeConnexityBlocks(aCE, TopAbs_VERTEX, TopAbs_EDGE, aLCBE);
835 //
836 // create connexity blocks for alone vertices
837 TopTools_ListOfShape aLCBV;
838 TopTools_ListIteratorOfListOfShape aItLV(aLV);
839 for (; aItLV.More(); aItLV.Next()) {
840 const TopoDS_Shape& aV = aItLV.Value();
841 // check if this vertex is contained in some connexity block of edges
842 TopTools_ListIteratorOfListOfShape aItLCB(aLCBE);
843 for (; aItLCB.More(); aItLCB.Next()) {
844 TopoDS_Shape& aCB = aItLCB.ChangeValue();
845 TopExp_Explorer aExpV(aCB, TopAbs_VERTEX);
846 for (; aExpV.More(); aExpV.Next()) {
847 if (aV.IsSame(aExpV.Current())) {
848 B.Add(aCB, aV);
849 break;
850 }
851 }
852 if (aExpV.More()) {
853 break;
854 }
855 }
856 //
857 if (!aItLCB.More()) {
858 TopoDS_Compound aCV;
859 B.MakeCompound(aCV);
860 B.Add(aCV, aV);
861 aLCBV.Append(aCV);
862 }
863 }
864 //
865 aLCBE.Append(aLCBV);
866 //
867 if (aLCBE.Extent() == 1) {
868 continue;
869 }
870 //
871 const TopoDS_Shape& aNF1 = MES(MapSF(aF1).Face());
872 const TopoDS_Shape& aNF2 = MES(MapSF(aF2).Face());
873 //
874 TopTools_ListIteratorOfListOfShape aItLCB(aLCBE);
875 for (aItLCB.Next(); aItLCB.More(); aItLCB.Next()) {
876 // make new edge with different tedge instance
877 TopoDS_Edge aNewEdge;
878 TopoDS_Vertex aV1, aV2;
879 Standard_Real aT1, aT2;
880 //
881 TopExp::Vertices(aE, aV1, aV2);
882 BRep_Tool::Range(aE, aT1, aT2);
883 //
884 BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aNewEdge);
885 //
886 myAsDes->Add(aNF1, aNewEdge);
887 myAsDes->Add(aNF2, aNewEdge);
888 //
889 const TopoDS_Shape& aCB = aItLCB.Value();
890 TopoDS_Iterator aItCB(aCB);
891 for (; aItCB.More(); aItCB.Next()) {
892 const TopoDS_Shape& aS = aItCB.Value();
893 if (aMEConnection.Contains(aS)) {
894 continue;
895 }
896 TopoDS_Shape& aCI = Build.ChangeFind(aS);
897 //
898 TopoDS_Compound aNewCI;
899 B.MakeCompound(aNewCI);
900 TopExp_Explorer aExp(aCI, TopAbs_EDGE);
901 for (; aExp.More(); aExp.Next()) {
902 const TopoDS_Shape& aSx = aExp.Current();
903 if (!aSx.IsSame(aE)) {
904 B.Add(aNewCI, aSx);
905 }
906 }
907 B.Add(aNewCI, aNewEdge);
908 aCI = aNewCI;
909 }
910 }
911 }
912 }
913
914 //=======================================================================
915 //function : ContextIntByInt
916 //purpose :
917 //=======================================================================
918
ContextIntByInt(const TopTools_IndexedMapOfShape & ContextFaces,const Standard_Boolean ExtentContext,const BRepOffset_DataMapOfShapeOffset & MapSF,const BRepOffset_Analyse & Analyse,TopTools_DataMapOfShapeShape & MES,TopTools_DataMapOfShapeShape & Build,TopTools_ListOfShape & Failed,const Message_ProgressRange & theRange,const Standard_Boolean bIsPlanar)919 void BRepOffset_Inter3d::ContextIntByInt
920 (const TopTools_IndexedMapOfShape& ContextFaces,
921 const Standard_Boolean ExtentContext,
922 const BRepOffset_DataMapOfShapeOffset& MapSF,
923 const BRepOffset_Analyse& Analyse,
924 TopTools_DataMapOfShapeShape& MES,
925 TopTools_DataMapOfShapeShape& Build,
926 TopTools_ListOfShape& Failed,
927 const Message_ProgressRange& theRange,
928 const Standard_Boolean bIsPlanar)
929 {
930 TopTools_MapOfShape MV;
931 TopExp_Explorer exp;
932 TopoDS_Face OF,NF,WCF;
933 TopoDS_Edge OE;
934 TopoDS_Compound C;
935 BRep_Builder B;
936 TopTools_ListIteratorOfListOfShape it, itF;
937 Standard_Integer i, j, aNb, aNbVE;
938 Standard_Boolean bEdge;
939
940 aNb = ContextFaces.Extent();
941 for (i = 1; i <= aNb; i++) {
942 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
943 myTouched.Add(CF);
944 if (ExtentContext) {
945 BRepOffset_Tool::EnLargeFace(CF,NF,0,0);
946 MES.Bind(CF,NF);
947 }
948 }
949 TopAbs_State Side = TopAbs_OUT;
950
951 Message_ProgressScope aPS(theRange, "Intersecting with deepening faces", aNb);
952 for (i = 1; i <= aNb; i++, aPS.Next()) {
953 if (!aPS.More())
954 {
955 return;
956 }
957 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
958 if (ExtentContext) WCF = TopoDS::Face(MES(CF));
959 else WCF = CF;
960
961 TopTools_IndexedMapOfShape VEmap;
962 TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap);
963 //
964 if (bIsPlanar) {
965 TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
966 }
967 //
968 aNbVE = VEmap.Extent();
969 for (j = 1; j <= aNbVE; ++j) {
970 const TopoDS_Shape& aS = VEmap(j);
971 //
972 bEdge = (aS.ShapeType() == TopAbs_EDGE);
973 //
974 TopoDS_Edge E;
975 TopTools_ListOfShape Anc;
976 //
977 if (bEdge) {
978 // faces connected by the edge
979 //
980 E = *(TopoDS_Edge*)&aS;
981 if (!Analyse.HasAncestor(E)) {
982 //----------------------------------------------------------------
983 // the edges of faces of context that are not in the initial shape
984 // can appear in the result.
985 //----------------------------------------------------------------
986 if (!ExtentContext) {
987 myAsDes->Add(CF,E);
988 myNewEdges.Add(E);
989 }
990 else {
991 if (!MES.IsBound(E)) {
992 TopoDS_Edge NE;
993 Standard_Real f,l,Tol;
994 BRep_Tool::Range(E,f,l);
995 Tol = BRep_Tool::Tolerance(E);
996 ExtentEdge(CF,E,NE);
997 TopoDS_Vertex V1,V2;
998 TopExp::Vertices(E,V1,V2);
999 NE.Orientation(TopAbs_FORWARD);
1000 myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
1001 myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
1002 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
1003 B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
1004 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
1005 B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
1006 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
1007 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
1008 NE.Orientation(E.Orientation());
1009 myAsDes->Add(CF,NE);
1010 myNewEdges.Add(NE);
1011 MES.Bind(E,NE);
1012 }
1013 else {
1014 TopoDS_Shape NE = MES(E);
1015 TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation());
1016 myAsDes->Add(CF,aLocalShape);
1017 // myAsDes->Add(CF,NE.Oriented(E.Orientation()));
1018 }
1019 }
1020 continue;
1021 }
1022 Anc = Analyse.Ancestors(E);
1023 }
1024 else {
1025 // faces connected by the vertex
1026 //
1027 if (!Analyse.HasAncestor(aS)) {
1028 continue;
1029 }
1030 //
1031 const TopTools_ListOfShape& aLE = Analyse.Ancestors(aS);
1032 it.Initialize(aLE);
1033 for (; it.More(); it.Next()) {
1034 const TopoDS_Edge& aE = *(TopoDS_Edge*)&it.Value();
1035 //
1036 if (BRep_Tool::Degenerated(aE)) {
1037 continue;
1038 }
1039 //
1040 if (VEmap.Contains(aE)) {
1041 continue;
1042 }
1043 //
1044 const TopTools_ListOfShape& aLF = Analyse.Ancestors(aE);
1045 itF.Initialize(aLF);
1046 for (; itF.More(); itF.Next()) {
1047 const TopoDS_Shape& aF = itF.Value();
1048 Standard_Boolean bAdd = Standard_True;
1049 exp.Init(aF, TopAbs_EDGE);
1050 for (; exp.More() && bAdd; exp.Next()) {
1051 const TopoDS_Shape& aEF = exp.Current();
1052 bAdd = !VEmap.Contains(aEF);
1053 }
1054 if (bAdd) {
1055 Anc.Append(aF);
1056 }
1057 }
1058 }
1059 }
1060 //
1061 itF.Initialize(Anc);
1062 for (; itF.More(); itF.Next()) {
1063 const TopoDS_Face& F = TopoDS::Face(itF.Value());
1064 OF = TopoDS::Face(MapSF(F).Face());
1065 TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
1066 OE = TopoDS::Edge(aLocalShape);
1067 // OE = TopoDS::Edge(MapSF(F).Generated(E));
1068 if (!MES.IsBound(OF)) {
1069 BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
1070 MES.Bind(OF,NF);
1071 }
1072 else {
1073 NF = TopoDS::Face(MES(OF));
1074 }
1075 if (!IsDone(NF,CF)) {
1076 TopTools_ListOfShape LInt1,LInt2;
1077 TopTools_ListOfShape LOE;
1078 LOE.Append(OE);
1079 BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,CF,F);
1080 SetDone(NF,CF);
1081 if (!LInt1.IsEmpty()) {
1082 Store (CF,NF,LInt1,LInt2);
1083 if ((LInt1.Extent() == 1) && !Build.IsBound(aS)) {
1084 Build.Bind(aS,LInt1.First());
1085 }
1086 else {
1087 B.MakeCompound(C);
1088 if (Build.IsBound(aS)) {
1089 const TopoDS_Shape& aSE = Build(aS);
1090 exp.Init(aSE, TopAbs_EDGE);
1091 for (; exp.More(); exp.Next()) {
1092 const TopoDS_Shape& aNE = exp.Current();
1093 B.Add(C, aNE);
1094 }
1095 }
1096 //
1097 for (it.Initialize(LInt1) ; it.More(); it.Next()) {
1098 B.Add(C,it.Value());
1099 }
1100 Build.Bind(aS,C);
1101 }
1102 }
1103 else {
1104 Failed.Append(aS);
1105 }
1106 }
1107 }
1108 }
1109 }
1110 }
1111
1112 //=======================================================================
1113 //function : ContextIntByArc
1114 //purpose :
1115 //=======================================================================
ContextIntByArc(const TopTools_IndexedMapOfShape & ContextFaces,const Standard_Boolean InSide,const BRepOffset_Analyse & Analyse,const BRepAlgo_Image & InitOffsetFace,BRepAlgo_Image & InitOffsetEdge,const Message_ProgressRange & theRange)1116 void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& ContextFaces,
1117 const Standard_Boolean InSide,
1118 const BRepOffset_Analyse& Analyse,
1119 const BRepAlgo_Image& InitOffsetFace,
1120 BRepAlgo_Image& InitOffsetEdge,
1121 const Message_ProgressRange& theRange)
1122 {
1123 TopTools_ListOfShape LInt1,LInt2;
1124 TopTools_MapOfShape MV;
1125 TopExp_Explorer exp;
1126 TopoDS_Face OF1,OF2;
1127 TopoDS_Edge OE;
1128 BRep_Builder B;
1129 TopoDS_Edge NullEdge;
1130 TopoDS_Face NullFace;
1131 Standard_Integer j;
1132
1133 for (j = 1; j <= ContextFaces.Extent(); j++) {
1134 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
1135 myTouched.Add(CF);
1136 }
1137
1138 Message_ProgressScope aPS(theRange, "Intersecting with deepening faces", ContextFaces.Extent());
1139 for (j = 1; j <= ContextFaces.Extent(); j++, aPS.Next()) {
1140 if (!aPS.More())
1141 {
1142 return;
1143 }
1144 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
1145 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1146 exp.More(); exp.Next()) {
1147 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1148 if (!Analyse.HasAncestor(E)) {
1149 if (InSide)
1150 myAsDes->Add(CF,E);
1151 else {
1152 TopoDS_Edge NE;
1153 if (!InitOffsetEdge.HasImage(E)) {
1154 Standard_Real f,l,Tol;
1155 BRep_Tool::Range(E,f,l);
1156 Tol = BRep_Tool::Tolerance(E);
1157 ExtentEdge(CF,E,NE);
1158 TopoDS_Vertex V1,V2;
1159 TopExp::Vertices(E,V1,V2);
1160 NE.Orientation(TopAbs_FORWARD);
1161 myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
1162 myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
1163 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
1164 B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
1165 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
1166 B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
1167 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
1168 // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
1169 NE.Orientation(E.Orientation());
1170 myAsDes->Add(CF,NE);
1171 InitOffsetEdge.Bind(E,NE);
1172 }
1173 else {
1174 NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
1175 myAsDes->Add(CF,NE.Oriented(E.Orientation()));
1176 }
1177 }
1178 continue;
1179 }
1180 OE.Nullify();
1181 //---------------------------------------------------
1182 // OF1 parallel facee generated by the ancestor of E.
1183 //---------------------------------------------------
1184 const TopoDS_Shape SI = Analyse.Ancestors(E).First();
1185 OF1 = TopoDS::Face(InitOffsetFace.Image(SI).First());
1186 OE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
1187
1188 {
1189 //Check if OE has pcurve in CF
1190
1191 Standard_Real f,l;
1192
1193 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l);
1194 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l);
1195
1196 if(C1.IsNull() || C2.IsNull())
1197 {
1198 continue;
1199 }
1200 }
1201
1202 //--------------------------------------------------
1203 // MAJ of OE on cap CF.
1204 //--------------------------------------------------
1205 // TopTools_ListOfShape LOE; LOE.Append(OE);
1206 // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
1207 // LInt2.Clear();
1208 // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
1209 // LInt1,LInt2);
1210 LInt1.Clear(); LInt1.Append(OE);
1211 LInt2.Clear();
1212 TopAbs_Orientation anOri1, anOri2;
1213 BRepOffset_Tool::OrientSection(OE,CF,OF1, anOri1,anOri2);
1214 // if (mySide == TopAbs_OUT);
1215 anOri1 = TopAbs::Reverse(anOri1);
1216 LInt1.First().Orientation(anOri1);
1217 Store(CF,OF1,LInt1,LInt2);
1218
1219 //------------------------------------------------------
1220 // Processing of offsets on the ancestors of vertices.
1221 //------------------------------------------------------
1222 TopoDS_Vertex V[2];
1223 TopExp::Vertices (E,V[0],V[1]);
1224 for (Standard_Integer i = 0; i < 2; i++) {
1225 if (!MV.Add(V[i])) continue;
1226 OF1.Nullify();
1227 const TopTools_ListOfShape& LE = Analyse.Ancestors(V[i]);
1228 TopTools_ListIteratorOfListOfShape itLE(LE);
1229 for ( ; itLE.More(); itLE.Next()) {
1230 const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
1231 if (InitOffsetFace.HasImage(EV)) {
1232 //-------------------------------------------------
1233 // OF1 parallel face generated by an ancester edge of V[i].
1234 //-------------------------------------------------
1235 OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First());
1236 OE = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First());
1237
1238 {
1239 //Check if OE has pcurve in CF and OF1
1240
1241 Standard_Real f,l;
1242
1243 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l);
1244 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l);
1245
1246 if(C1.IsNull() || C2.IsNull())
1247 {
1248 continue;
1249 }
1250 }
1251
1252 //--------------------------------------------------
1253 // MAj of OE on cap CF.
1254 //--------------------------------------------------
1255 // LOE.Clear(); LOE.Append(OE);
1256 // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
1257 // LInt2.Clear();
1258 // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
1259 // LInt1,LInt2);
1260 LInt1.Clear(); LInt1.Append(OE);
1261 LInt2.Clear();
1262 TopAbs_Orientation O1,O2;
1263 BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);
1264 // if (mySide == TopAbs_OUT);
1265 O1 = TopAbs::Reverse(O1);
1266 LInt1.First().Orientation(O1);
1267 Store(CF,OF1,LInt1,LInt2);
1268 }
1269 }
1270 }
1271 }
1272
1273 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
1274 exp.More(); exp.Next()) {
1275 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
1276 if (!Analyse.HasAncestor(V)) {
1277 continue;
1278 }
1279 const TopTools_ListOfShape& LE = Analyse.Ancestors(V);
1280 TopTools_ListIteratorOfListOfShape itLE(LE);
1281 for (; itLE.More(); itLE.Next()) {
1282 const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
1283 const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
1284 TopTools_ListIteratorOfListOfShape itLF(LF);
1285 for ( ; itLF.More(); itLF.Next()) {
1286 const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
1287 //-------------------------------------------------
1288 // OF1 parallel face generated by uneFace ancestor of V[i].
1289 //-------------------------------------------------
1290 OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
1291 if (!IsDone(OF1,CF)) {
1292 //-------------------------------------------------------
1293 // Find if one of edges of OF1 has no trace in CF.
1294 //-------------------------------------------------------
1295 TopTools_ListOfShape LOE;
1296 TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1297 for ( ;exp2.More(); exp2.Next()) {
1298 LOE.Append(exp2.Current());
1299 }
1300 BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
1301 //-------------------------------------------------------
1302 // If no trace try intersection.
1303 //-------------------------------------------------------
1304 if (LInt1.IsEmpty()) {
1305 BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge,NullFace,NullFace);
1306 }
1307 Store (CF,OF1,LInt1,LInt2);
1308 }
1309 }
1310 }
1311 }
1312 }
1313 }
1314
1315 //=======================================================================
1316 //function : SetDone
1317 //purpose :
1318 //=======================================================================
SetDone(const TopoDS_Face & F1,const TopoDS_Face & F2)1319 void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1,
1320 const TopoDS_Face& F2)
1321 {
1322 if (!myDone.IsBound(F1)) {
1323 TopTools_ListOfShape empty;
1324 myDone.Bind(F1,empty);
1325 }
1326 myDone(F1).Append(F2);
1327 if (!myDone.IsBound(F2)) {
1328 TopTools_ListOfShape empty;
1329 myDone.Bind(F2,empty);
1330 }
1331 myDone(F2).Append(F1);
1332 }
1333
1334 //=======================================================================
1335 //function : IsDone
1336 //purpose :
1337 //=======================================================================
IsDone(const TopoDS_Face & F1,const TopoDS_Face & F2) const1338 Standard_Boolean BRepOffset_Inter3d::IsDone(const TopoDS_Face& F1,
1339 const TopoDS_Face& F2) const
1340 {
1341 if (myDone.IsBound(F1)) {
1342 TopTools_ListIteratorOfListOfShape it (myDone(F1));
1343 for (; it.More(); it.Next()) {
1344 if (it.Value().IsSame(F2)) return Standard_True;
1345 }
1346 }
1347 return Standard_False;
1348 }
1349
1350 //=======================================================================
1351 //function : Store
1352 //purpose :
1353 //=======================================================================
Store(const TopoDS_Face & F1,const TopoDS_Face & F2,const TopTools_ListOfShape & LInt1,const TopTools_ListOfShape & LInt2)1354 void BRepOffset_Inter3d::Store(const TopoDS_Face& F1,
1355 const TopoDS_Face& F2,
1356 const TopTools_ListOfShape& LInt1,
1357 const TopTools_ListOfShape& LInt2)
1358 {
1359 if (!LInt1.IsEmpty()) {
1360 myTouched.Add(F1);
1361 myTouched.Add(F2);
1362 myAsDes->Add( F1,LInt1);
1363 myAsDes->Add( F2,LInt2);
1364 TopTools_ListIteratorOfListOfShape it(LInt1);
1365 for (; it.More(); it.Next()) {
1366 myNewEdges.Add(it.Value());
1367 }
1368 }
1369 SetDone(F1,F2);
1370 }
1371