0024157: Parallelization of assembly part of BO
[occt.git] / src / BRepOffset / BRepOffset_Inter3d.cxx
CommitLineData
b311480e 1// Created on: 1996-09-03
2// Created by: Yves FRICAUD
3// Copyright (c) 1996-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22
23// Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455
24
25#include <BRepOffset_Inter3d.ixx>
26#include <BRepOffset_Tool.hxx>
27#include <BRepOffset_Interval.hxx>
28#include <BRepOffset_ListOfInterval.hxx>
29#include <BRepOffset_DataMapOfShapeOffset.hxx>
30#include <BRepOffset_Offset.hxx>
31#include <BRepAdaptor_Curve.hxx>
32#include <BRep_Builder.hxx>
33#include <BRep_Tool.hxx>
34#include <BRepLib_MakeVertex.hxx>
35
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_Vertex.hxx>
42#include <TopOpeBRepTool_BoxSort.hxx>
43#include <TopTools_ListIteratorOfListOfShape.hxx>
44#include <TopTools_MapIteratorOfMapOfShape.hxx>
45#include <TopTools_IndexedMapOfShape.hxx>
46#include <Extrema_ExtPC.hxx>
975ec82a 47#include <TopTools_MapOfShape.hxx>
1d47d8d0 48#include <Precision.hxx>
7fd59977 49
50
51
52//=======================================================================
53//function : BRepOffset_Inter3d
54//purpose :
55//=======================================================================
56
57BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes,
58 const TopAbs_State Side ,
59 const Standard_Real Tol)
60:myAsDes(AsDes),
61mySide(Side),
62myTol(Tol)
63{
64}
65
66
67//=======================================================================
68//function : ExtentEdge
69//purpose :
70//=======================================================================
71
35e08fe8 72static void ExtentEdge(const TopoDS_Face& /*F*/,
7fd59977 73 const TopoDS_Edge& E,
74 TopoDS_Edge& NE)
75{
76 TopoDS_Shape aLocalShape = E.EmptyCopied();
77 NE = TopoDS::Edge(aLocalShape);
78// NE = TopoDS::Edge(E.EmptyCopied());
79
80
0d969553
Y
81 // Enough for analytic edges, in general case reconstruct the
82 // geometry of the edge recalculating the intersection of surfaces.
7fd59977 83
84 NE.Orientation(TopAbs_FORWARD);
85 Standard_Real f,l;
86 BRep_Tool::Range(E,f,l);
87 Standard_Real length = l-f;
88 f -= 100*length;
89 l += 100*length;
90
91 BRep_Builder B;
92 B.Range(NE,f,l);
93 BRepAdaptor_Curve CE(E);
94 TopoDS_Vertex V1 = BRepLib_MakeVertex(CE.Value(f));
95 TopoDS_Vertex V2 = BRepLib_MakeVertex(CE.Value(l));
96 B.Add(NE,V1.Oriented(TopAbs_FORWARD));
97 B.Add(NE,V2.Oriented(TopAbs_REVERSED));
98 NE.Orientation(E.Orientation());
99
100}
101
102//=======================================================================
103//function : SelectEdge
104//purpose :
105//=======================================================================
106
35e08fe8 107static void SelectEdge (const TopoDS_Face& /*F*/,
108 const TopoDS_Face& /*EF*/,
7fd59977 109 const TopoDS_Edge& E,
110 TopTools_ListOfShape& LInt)
111{
112 //------------------------------------------------------------
0d969553 113 // Proofing on the intersections on periodical faces
7fd59977 114 //------------------------------------------------------------
115 TopTools_ListIteratorOfListOfShape it(LInt);
116// Modified by Sergey KHROMOV - Wed Jun 5 11:43:04 2002 Begin
117// Standard_Real dU = 1.0e100;
118 Standard_Real dU = RealLast();
119// Modified by Sergey KHROMOV - Wed Jun 5 11:43:05 2002 End
120 TopoDS_Edge GE;
121
122 Standard_Real Fst, Lst, tmp;
123 BRep_Tool::Range(E, Fst, Lst);
124 BRepAdaptor_Curve Ad1(E);
125
126 gp_Pnt PFirst = Ad1.Value( Fst );
127 gp_Pnt PLast = Ad1.Value( Lst );
128
129// Modified by Sergey KHROMOV - Wed Jun 5 11:23:10 2002 Begin
130 Extrema_ExtPC anExt;
131// Modified by Sergey KHROMOV - Wed Jun 5 11:23:11 2002 End
132 //----------------------------------------------------------------------
0d969553 133 // Selection of edge that coversmost of the domain of the initial edge.
7fd59977 134 //----------------------------------------------------------------------
135 for (; it.More(); it.Next()) {
136 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
137
138 BRep_Tool::Range(EI, Fst, Lst);
139 BRepAdaptor_Curve Ad2(EI);
140
141// Modified by Sergey KHROMOV - Wed Jun 5 11:25:03 2002 Begin
142 Standard_Integer i;
143 Standard_Real aTol = BRep_Tool::Tolerance(EI);
144 Standard_Boolean isMinFound = Standard_False;
1d47d8d0 145 Standard_Real aSqrDist1 = Precision::Infinite();
146 Standard_Real aSqrDist2 = Precision::Infinite();
7fd59977 147
148 anExt.Initialize(Ad2, Fst, Lst, aTol);
149
150// Seek for the min distance for PFirst:
151 anExt.Perform(PFirst);
152 if (anExt.IsDone()) {
153 for (i = 1; i <= anExt.NbExt(); i++) {
154 if (anExt.IsMin(i)) {
155 const gp_Pnt &aPMin = anExt.Point(i).Value();
156
157 aSqrDist1 = PFirst.SquareDistance(aPMin);
158 isMinFound = Standard_True;
159
160 break;
161 }
162 }
163 }
164 if (!isMinFound) {
165 gp_Pnt aP1 = Ad2.Value(Fst);
166 gp_Pnt aP2 = Ad2.Value(Lst);
167
168 aSqrDist1 = Min(aP1.SquareDistance(PFirst), aP2.SquareDistance(PFirst));
169 }
170
171// Seek for the min distance for PLast:
172 isMinFound = Standard_False;
173 anExt.Perform(PLast);
174 if (anExt.IsDone()) {
175 for (i = 1; i <= anExt.NbExt(); i++) {
176 if (anExt.IsMin(i)) {
177 const gp_Pnt &aPMin = anExt.Point(i).Value();
178
179 aSqrDist2 = PLast.SquareDistance(aPMin);
180 isMinFound = Standard_True;
181
182 break;
183 }
184 }
185 }
186 if (!isMinFound) {
187 gp_Pnt aP1 = Ad2.Value(Fst);
188 gp_Pnt aP2 = Ad2.Value(Lst);
189
190 aSqrDist2 = Min(aP1.SquareDistance(PLast), aP2.SquareDistance(PLast));
191 }
192
193 tmp = aSqrDist1 + aSqrDist2;
194// gp_Pnt P1 = Ad2.Value(Fst);
195// gp_Pnt P2 = Ad2.Value(Lst);
196
197// tmp = P1.Distance(PFirst) + P2.Distance(PLast);
198 if( tmp <= dU ) {
199 dU = tmp;
200 GE = EI;
201 }
202// Modified by Sergey KHROMOV - Wed Jun 5 11:24:54 2002 End
203
204 }
205 LInt.Clear();
206 LInt.Append(GE);
207}
208
209
210//=======================================================================
211//function : CompletInt
212//purpose :
213//=======================================================================
214
215void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces,
216 const BRepAlgo_Image& InitOffsetFace)
217{
218 //---------------------------------------------------------------
0d969553
Y
219 // Calculate the intersections of offset faces
220 // Distinction of intersection between faces // tangents.
7fd59977 221 //---------------------------------------------------------------
222 TopoDS_Face F1,F2;
223 TopTools_ListIteratorOfListOfShape it;
224
225 //---------------------------------------------------------------
0d969553 226 // Construction of bounding boxes
7fd59977 227 //---------------------------------------------------------------
228 TopOpeBRepTool_BoxSort BOS;
229 BRep_Builder B;
230 TopoDS_Compound CompOS;
231 B.MakeCompound(CompOS);
232
233 for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
234 const TopoDS_Shape& OS = it.Value();
235 B.Add(CompOS,OS);
236 }
237 BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE);
238
239 //---------------------------
0d969553 240 // Intersection of faces //
7fd59977 241 //---------------------------
242 for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
243 const TopoDS_Face& F1 = TopoDS::Face(it.Value());
244 TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1);
245 for (; itLI.More(); itLI.Next()) {
246 F2 = TopoDS::Face(BOS.TouchedShape(itLI));
247 FaceInter(F1,F2,InitOffsetFace);
248 }
249 }
250}
251
252
253//=======================================================================
254//function : CompletInt
255//purpose :
256//=======================================================================
257
258void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1,
259 const TopoDS_Face& F2,
260 const BRepAlgo_Image& InitOffsetFace)
261{
262 TopTools_ListOfShape LInt1, LInt2;
263 TopoDS_Edge NullEdge;
264
265 if (F1.IsSame(F2)) return;
266 if (IsDone(F1,F2)) return;
267 const TopoDS_Shape& InitF1 = InitOffsetFace.ImageFrom(F1);
268 const TopoDS_Shape& InitF2 = InitOffsetFace.ImageFrom(F2);
269 Standard_Boolean InterPipes = (InitF2.ShapeType() == TopAbs_EDGE &&
270 InitF1.ShapeType() == TopAbs_EDGE );
271 Standard_Boolean InterFaces = (InitF1.ShapeType() == TopAbs_FACE &&
272 InitF2.ShapeType() == TopAbs_FACE);
273 TopTools_ListOfShape LE,LV;
274 LInt1.Clear(); LInt2.Clear();
275 if (BRepOffset_Tool::HasCommonShapes(F1,F2,LE,LV) ||
276 myAsDes->HasCommonDescendant(F1,F2,LE)) {
277 //-------------------------------------------------
0d969553 278 // F1 and F2 share shapes.
7fd59977 279 //-------------------------------------------------
280 if ( LE.IsEmpty() && !LV.IsEmpty()) {
281 if (InterPipes) {
0d969553
Y
282 //----------------------
283 // tubes share a vertex.
284 //----------------------
7fd59977 285 const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1);
286 const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2);
287 TopoDS_Vertex VE1[2],VE2[2];
288 TopExp::Vertices(EE1,VE1[0],VE1[1]);
289 TopExp::Vertices(EE2,VE2[0],VE2[1]);
290 TopoDS_Vertex V;
291 for (Standard_Integer i = 0 ; i < 2; i++) {
292 for (Standard_Integer j = 0 ; j < 2; j++) {
293 if (VE1[i].IsSame(VE2[j])) {
294 V = VE1[i];
295 }
296 }
297 }
0d969553 298 if (!InitOffsetFace.HasImage(V)) { //no sphere
7fd59977 299 BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
300 }
301 }
302 else {
303 //--------------------------------------------------------
0d969553
Y
304 // Intersection having only common vertices
305 // and supports having common edges.
306 // UNSUFFICIENT, but a larger criterion shakes too
307 // many sections.
7fd59977 308 //--------------------------------------------------------
309 if (InterFaces &&
310 BRepOffset_Tool::HasCommonShapes(TopoDS::Face(InitF1),
311 TopoDS::Face(InitF2),LE,LV))
312 if (!LE.IsEmpty())
313 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
314 }
315 }
316 }
317 else {
318 if (InterPipes) {
319 BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide);
320 }
321 else {
322 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
323 }
324 }
325 Store (F1,F2,LInt1,LInt2);
326}
327
328
329//=======================================================================
330//function : ConnexIntByArc
331//purpose :
332//=======================================================================
333
35e08fe8 334void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces*/,
335 const TopoDS_Shape& ShapeInit,
336 const BRepOffset_Analyse& Analyse,
337 const BRepAlgo_Image& InitOffsetFace)
7fd59977 338{
339 BRepOffset_Type OT = BRepOffset_Concave;
340 if (mySide == TopAbs_OUT) OT = BRepOffset_Convex;
341 TopExp_Explorer Exp(ShapeInit,TopAbs_EDGE);
342 TopTools_ListOfShape LInt1,LInt2;
343 TopoDS_Face F1,F2;
344 TopoDS_Edge NullEdge;
345
346 //---------------------------------------------------------------------
0d969553
Y
347 // etape 1 : Intersection of faces // corresponding to the initial faces
348 // separated by a concave edge if offset > 0, otherwise convex.
7fd59977 349 //---------------------------------------------------------------------
350 for (; Exp.More(); Exp.Next()) {
351 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
352 const BRepOffset_ListOfInterval& L = Analyse.Type(E);
353 if (!L.IsEmpty() && L.First().Type() == OT) {
354 //-----------------------------------------------------------
0d969553 355 // edge is of the proper type , return adjacent faces.
7fd59977 356 //-----------------------------------------------------------
357 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
358 if (Anc.Extent() == 2) {
359 F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First());
360 F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First());
361 if (!IsDone(F1,F2)) {
362 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True);
363 Store (F1,F2,LInt1,LInt2);
364 }
365 }
366 }
367 }
368 //---------------------------------------------------------------------
0d969553
Y
369 // etape 2 : Intersections of tubes sharing a vertex without sphere with:
370 // - tubes on each other edge sharing the vertex
371 // - faces containing an edge connected to vertex that has no tubes.
7fd59977 372 //---------------------------------------------------------------------
373 TopoDS_Vertex V[2];
374 TopTools_ListIteratorOfListOfShape it;
375
376 for (Exp.Init(ShapeInit,TopAbs_EDGE); Exp.More(); Exp.Next()) {
377 const TopoDS_Edge& E1 = TopoDS::Edge(Exp.Current());
378 if (InitOffsetFace.HasImage(E1)) {
379 //---------------------------
0d969553 380 // E1 generated a tube.
7fd59977 381 //---------------------------
382 F1 = TopoDS::Face(InitOffsetFace.Image(E1).First());;
383 TopExp::Vertices(E1,V[0],V[1]);
384 const TopTools_ListOfShape& AncE1 = Analyse.Ancestors(E1);
385
386 for (Standard_Integer i = 0; i < 2; i++) {
387 if (!InitOffsetFace.HasImage(V[i])) {
388 //-----------------------------
0d969553 389 // the vertex has no sphere.
7fd59977 390 //-----------------------------
391 const TopTools_ListOfShape& Anc = Analyse.Ancestors(V[i]);
392 TopTools_ListOfShape TangOnV;
393 Analyse.TangentEdges(E1,V[i],TangOnV);
394 TopTools_MapOfShape MTEV;
395 for (it.Initialize(TangOnV); it.More(); it.Next()) {
396 MTEV.Add(it.Value());
397 }
398 for (it.Initialize(Anc); it.More(); it.Next()) {
399 const TopoDS_Edge& E2 = TopoDS::Edge(it.Value());
400// Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 Begin
401// if (E1.IsSame(E2) || MTEV.Contains(E2)) continue;
402 Standard_Boolean isToSkip = Standard_False;
403
404 if (!E1.IsSame(E2)) {
405 const BRepOffset_ListOfInterval& aL = Analyse.Type(E2);
406
407 isToSkip = (MTEV.Contains(E2) &&
408 (aL.IsEmpty() ||
409 (!aL.IsEmpty() && aL.First().Type() != OT)));
410 }
411
412 if (E1.IsSame(E2) || isToSkip)
413 continue;
414// Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 End
415 if (InitOffsetFace.HasImage(E2)) {
416 //-----------------------------
0d969553 417 // E2 generated a tube.
7fd59977 418 //-----------------------------
419 F2 = TopoDS::Face(InitOffsetFace.Image(E2).First());
420 if (!IsDone(F1,F2)) {
421 //---------------------------------------------------------------------
0d969553 422 // Intersection tube/tube if the edges are not tangent (AFINIR).
7fd59977 423 //----------------------------------------------------------------------
424 BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide);
425 Store (F1,F2,LInt1,LInt2);
426 }
427 }
428 else {
429 //-------------------------------------------------------
0d969553
Y
430 // Intersection of the tube of E1 with faces //
431 // to face containing E2 if they are not tangent
432 // to the tube or if E2 is not a tangent edge.
7fd59977 433 //-------------------------------------------------------
434 const BRepOffset_ListOfInterval& L = Analyse.Type(E2);
435 if (!L.IsEmpty() && L.First().Type() == BRepOffset_Tangent) {
436 continue;
437 }
438 const TopTools_ListOfShape& AncE2 = Analyse.Ancestors(E2);
439 Standard_Boolean TangentFaces = Standard_False;
440 if (AncE2.Extent() == 2) {
441 TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ());
442 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
443 InitF2.IsSame(AncE1.Last()));
444 if (!TangentFaces) {
445 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
446 if (!IsDone(F1,F2)) {
447 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
448 Store (F1,F2,LInt1,LInt2);
449 }
450 }
451 InitF2 = TopoDS::Face(AncE2.Last ());
452 TangentFaces = (InitF2.IsSame(AncE1.First()) ||
453 InitF2.IsSame(AncE1.Last()));
454 if (!TangentFaces) {
455 F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First());
456 if (!IsDone(F1,F2)) {
457 BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge);
458 Store (F1,F2,LInt1,LInt2);
459 }
460 }
461 }
462 }
463 }
464 }
465 }
466 }
467 }
468}
469
470
471//=======================================================================
472//function : ConnexIntByInt
473//purpose :
474//=======================================================================
475
476void BRepOffset_Inter3d::ConnexIntByInt
477(const TopoDS_Shape& SI,
478 const BRepOffset_DataMapOfShapeOffset& MapSF,
479 const BRepOffset_Analyse& Analyse,
480 TopTools_DataMapOfShapeShape& MES,
481 TopTools_DataMapOfShapeShape& Build,
482 TopTools_ListOfShape& Failed)
483{
484 //TopExp_Explorer Exp(SI,TopAbs_EDGE);
485 TopTools_IndexedMapOfShape Emap;
486 TopExp::MapShapes( SI, TopAbs_EDGE, Emap );
487 TopoDS_Face F1,F2,OF1,OF2,NF1,NF2;
488 TopAbs_State CurSide = mySide;
489 BRep_Builder B;
490 TopTools_ListIteratorOfListOfShape it;
491
492 //for (; Exp.More(); Exp.Next()) {
493 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
494 //const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
495 const TopoDS_Edge& E = TopoDS::Edge(Emap(i));
496 const BRepOffset_ListOfInterval& L = Analyse.Type(E);
497 if (!L.IsEmpty()) {
498 BRepOffset_Type OT = L.First().Type();
499 if (OT == BRepOffset_Convex || OT == BRepOffset_Concave) {
500 if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
501 else CurSide = TopAbs_OUT;
502 //-----------------------------------------------------------
0d969553 503 // edge is of the proper type, return adjacent faces.
7fd59977 504 //-----------------------------------------------------------
505 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
506 if (Anc.Extent() != 2) continue;
507 F1 = TopoDS::Face(Anc.First());
508 F2 = TopoDS::Face(Anc.Last ());
509 OF1 = TopoDS::Face(MapSF(F1).Face()); OF2 = TopoDS::Face(MapSF(F2).Face());
510 if (!MES.IsBound(OF1)) {
511 Standard_Boolean enlargeU = Standard_True;
512 Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
513 BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
514 BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
515 MES.Bind(OF1,NF1);
516 }
517 else {
518 NF1 = TopoDS::Face(MES(OF1));
519 }
520 if (!MES.IsBound(OF2)) {
521 Standard_Boolean enlargeU = Standard_True;
522 Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
523 BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
524 BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
525 MES.Bind(OF2,NF2);
526 }
527 else {
528 NF2 = TopoDS::Face(MES(OF2));
529 }
530 if (!IsDone(NF1,NF2)) {
531 TopTools_ListOfShape LInt1,LInt2;
532 BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,Standard_True);
533 if (LInt1.Extent() > 1)
534 {
0d969553 535 // intersection is in seceral edges (free sewing)
7fd59977 536 SelectEdge( NF1, NF2, E, LInt1 );
537 SelectEdge( NF1, NF2, E, LInt2 );
538 }
539 SetDone(NF1,NF2);
540 if (!LInt1.IsEmpty()) {
541 Store (NF1,NF2,LInt1,LInt2);
542 TopoDS_Compound C;
543 B.MakeCompound(C);
544 for (it.Initialize(LInt1) ; it.More(); it.Next()) {
545 B.Add(C,it.Value());
546 }
547 Build.Bind(E,C);
548 }
549 else {
550 Failed.Append(E);
551 }
552 } else { // IsDone(NF1,NF2)
553 // Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
554 const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
555 const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
556
557 if (!aLInt1.IsEmpty()) {
558 TopoDS_Compound C;
559 TopTools_ListIteratorOfListOfShape anIt2;
560
561 B.MakeCompound(C);
562
563 for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
564 const TopoDS_Shape &anE1 = it.Value();
565
566 for (anIt2.Initialize(aLInt2) ; anIt2.More(); anIt2.Next()) {
567 const TopoDS_Shape &anE2 = anIt2.Value();
568
569 if (anE1.IsSame(anE2))
570 B.Add(C, anE1);
571 }
572 }
573 Build.Bind(E,C);
574 }
575 else {
576 Failed.Append(E);
577 }
578 }
579 // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
580 }
581 }
582 }
583}
584
585//=======================================================================
586//function : ContextIntByInt
587//purpose :
588//=======================================================================
589
590void BRepOffset_Inter3d::ContextIntByInt
975ec82a
J
591(const TopTools_IndexedMapOfShape& ContextFaces,
592 const Standard_Boolean ExtentContext,
7fd59977 593 const BRepOffset_DataMapOfShapeOffset& MapSF,
594 const BRepOffset_Analyse& Analyse,
595 TopTools_DataMapOfShapeShape& MES,
596 TopTools_DataMapOfShapeShape& Build,
597 TopTools_ListOfShape& Failed)
598{
599 TopTools_ListOfShape LInt1,LInt2;
7fd59977 600 TopTools_MapOfShape MV;
601 TopExp_Explorer exp;
602 TopoDS_Face OF,NF,WCF;
603 TopoDS_Edge OE;
604 TopoDS_Compound C;
605 BRep_Builder B;
606 TopTools_ListIteratorOfListOfShape it;
975ec82a
J
607 Standard_Integer i;
608
609 for (i = 1; i <= ContextFaces.Extent(); i++) {
610 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
7fd59977 611 myTouched.Add(CF);
612 if (ExtentContext) {
613 BRepOffset_Tool::EnLargeFace(CF,NF,0,0);
614 MES.Bind(CF,NF);
615 }
616 }
617 TopAbs_State Side = TopAbs_OUT;
618
975ec82a
J
619 for (i = 1; i <= ContextFaces.Extent(); i++) {
620 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i));
7fd59977 621 if (ExtentContext) WCF = TopoDS::Face(MES(CF));
622 else WCF = CF;
623
624 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
625 exp.More(); exp.Next()) {
626 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
627 if (!Analyse.HasAncestor(E)) {
628 //----------------------------------------------------------------
0d969553
Y
629 // the edges of faces of context that are not in the initial shape
630 // can appear in the result.
7fd59977 631 //----------------------------------------------------------------
632 if (!ExtentContext) {
633 myAsDes->Add(CF,E);
634 myNewEdges.Add(E);
635 }
636 else {
637 if (!MES.IsBound(E)) {
638 TopoDS_Edge NE;
639 Standard_Real f,l,Tol;
640 BRep_Tool::Range(E,f,l);
641 Tol = BRep_Tool::Tolerance(E);
642 ExtentEdge(CF,E,NE);
643 TopoDS_Vertex V1,V2;
644 TopExp::Vertices(E,V1,V2);
645 NE.Orientation(TopAbs_FORWARD);
646 myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
647 myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
648 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
649 B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
650 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
651 B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
652// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
653// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
654 NE.Orientation(E.Orientation());
655 myAsDes->Add(CF,NE);
656 myNewEdges.Add(NE);
657 MES.Bind(E,NE);
658 }
659 else {
660 TopoDS_Shape NE = MES(E);
661 TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation());
662 myAsDes->Add(CF,aLocalShape);
663// myAsDes->Add(CF,NE.Oriented(E.Orientation()));
664 }
665 }
666 continue;
667 }
668 const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
669 const TopoDS_Face& F = TopoDS::Face(Anc.First());
670 OF = TopoDS::Face(MapSF(F).Face());
671 TopoDS_Shape aLocalShape = MapSF(F).Generated(E);
672 OE = TopoDS::Edge(aLocalShape);
673// OE = TopoDS::Edge(MapSF(F).Generated(E));
674 if (!MES.IsBound(OF)) {
675 BRepOffset_Tool::EnLargeFace(OF,NF,1,1);
676 MES.Bind(OF,NF);
677 }
678 else {
679 NF = TopoDS::Face(MES(OF));
680 }
681 if (!IsDone(NF,CF)) {
682 TopTools_ListOfShape LInt1,LInt2;
683 TopTools_ListOfShape LOE;
684 LOE.Append(OE);
685 BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,Standard_True);
686 SetDone(NF,CF);
687 if (!LInt1.IsEmpty()) {
688 Store (CF,NF,LInt1,LInt2);
689 if (LInt1.Extent() == 1) {
690 Build.Bind(E,LInt1.First());
691 }
692 else {
693 B.MakeCompound(C);
694 for (it.Initialize(LInt1) ; it.More(); it.Next()) {
695 B.Add(C,it.Value());
696 }
697 Build.Bind(E,C);
698 }
699 }
700 else {
701 Failed.Append(E);
702 }
703 }
704 }
705 }
706}
707
708//=======================================================================
709//function : ContextIntByArc
710//purpose :
711//=======================================================================
712
975ec82a
J
713void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& ContextFaces,
714 const Standard_Boolean InSide,
715 const BRepOffset_Analyse& Analyse,
716 const BRepAlgo_Image& InitOffsetFace,
717 BRepAlgo_Image& InitOffsetEdge)
7fd59977 718
719{
720 TopTools_ListOfShape LInt1,LInt2;
7fd59977 721 TopTools_MapOfShape MV;
722 TopExp_Explorer exp;
723 TopoDS_Face OF1,OF2;
724 TopoDS_Edge OE;
725 BRep_Builder B;
726 TopoDS_Edge NullEdge;
975ec82a 727 Standard_Integer j;
7fd59977 728
975ec82a
J
729 for (j = 1; j <= ContextFaces.Extent(); j++) {
730 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
7fd59977 731 myTouched.Add(CF);
732 }
733
975ec82a
J
734 for (j = 1; j <= ContextFaces.Extent(); j++) {
735 const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j));
7fd59977 736 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
737 exp.More(); exp.Next()) {
738 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
739 if (!Analyse.HasAncestor(E)) {
740 if (InSide)
741 myAsDes->Add(CF,E);
742 else {
743 TopoDS_Edge NE;
744 if (!InitOffsetEdge.HasImage(E)) {
745 Standard_Real f,l,Tol;
746 BRep_Tool::Range(E,f,l);
747 Tol = BRep_Tool::Tolerance(E);
748 ExtentEdge(CF,E,NE);
749 TopoDS_Vertex V1,V2;
750 TopExp::Vertices(E,V1,V2);
751 NE.Orientation(TopAbs_FORWARD);
752 myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED));
753 myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD));
754 TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL);
755 B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol);
756 aLocalShape = V2.Oriented(TopAbs_INTERNAL);
757 B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol);
758// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol);
759// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol);
760 NE.Orientation(E.Orientation());
761 myAsDes->Add(CF,NE);
762 InitOffsetEdge.Bind(E,NE);
763 }
764 else {
765 NE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
766 myAsDes->Add(CF,NE.Oriented(E.Orientation()));
767 }
768 }
769 continue;
770 }
771 OE.Nullify();
0d969553
Y
772 //---------------------------------------------------
773 // OF1 parallel facee generated by the ancestor of E.
774 //---------------------------------------------------
7fd59977 775 const TopoDS_Shape SI = Analyse.Ancestors(E).First();
776 OF1 = TopoDS::Face(InitOffsetFace.Image(SI).First());
777 OE = TopoDS::Edge(InitOffsetEdge.Image(E).First());
778 //--------------------------------------------------
0d969553 779 // MAJ of OE on cap CF.
7fd59977 780 //--------------------------------------------------
781// TopTools_ListOfShape LOE; LOE.Append(OE);
782// BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
783// LInt2.Clear();
784// StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
785// LInt1,LInt2);
786 LInt1.Clear(); LInt1.Append(OE);
787 LInt2.Clear();
788 TopAbs_Orientation O1,O2;
789 BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);
790// if (mySide == TopAbs_OUT) O1 = TopAbs::Reverse(O1);
791 O1 = TopAbs::Reverse(O1);
792 LInt1.First().Orientation(O1);
793 Store(CF,OF1,LInt1,LInt2);
794
795 //------------------------------------------------------
0d969553 796 // Processing of offsets on the ancestors of vertices.
7fd59977 797 //------------------------------------------------------
798 TopoDS_Vertex V[2];
799 TopExp::Vertices (E,V[0],V[1]);
800 for (Standard_Integer i = 0; i < 2; i++) {
801 if (!MV.Add(V[i])) continue;
802 OF1.Nullify();
803 const TopTools_ListOfShape& LE = Analyse.Ancestors(V[i]);
804 TopTools_ListIteratorOfListOfShape itLE(LE);
805 for ( ; itLE.More(); itLE.Next()) {
806 const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
807 if (InitOffsetFace.HasImage(EV)) {
808 //-------------------------------------------------
0d969553 809 // OF1 parallel face generated by an ancester edge of V[i].
7fd59977 810 //-------------------------------------------------
811 OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First());
812 OE = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First());
813 //--------------------------------------------------
0d969553 814 // MAj of OE on cap CF.
7fd59977 815 //--------------------------------------------------
816 // LOE.Clear(); LOE.Append(OE);
817 // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide);
818 // LInt2.Clear();
819 // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes,
820 // LInt1,LInt2);
821 LInt1.Clear(); LInt1.Append(OE);
822 LInt2.Clear();
823 TopAbs_Orientation O1,O2;
824 BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2);
825// if (mySide == TopAbs_OUT);
826 O1 = TopAbs::Reverse(O1);
827 LInt1.First().Orientation(O1);
828 Store(CF,OF1,LInt1,LInt2);
829 }
830 }
831 }
832 }
833
834 for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
835 exp.More(); exp.Next()) {
836 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
837 if (!Analyse.HasAncestor(V)) {
838 continue;
839 }
840 const TopTools_ListOfShape& LE = Analyse.Ancestors(V);
841 TopTools_ListIteratorOfListOfShape itLE(LE);
842 for (; itLE.More(); itLE.Next()) {
843 const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value());
844 const TopTools_ListOfShape& LF = Analyse.Ancestors(EV);
845 TopTools_ListIteratorOfListOfShape itLF(LF);
846 for ( ; itLF.More(); itLF.Next()) {
847 const TopoDS_Face& FEV = TopoDS::Face(itLF.Value());
848 //-------------------------------------------------
0d969553 849 // OF1 parallel face generated by uneFace ancestor of V[i].
7fd59977 850 //-------------------------------------------------
851 OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First());
852 if (!IsDone(OF1,CF)) {
853 //-------------------------------------------------------
0d969553 854 // Find if one of edges of OF1 has no trace in CF.
7fd59977 855 //-------------------------------------------------------
856 TopTools_ListOfShape LOE;
857 TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
858 for ( ;exp2.More(); exp2.Next()) {
859 LOE.Append(exp2.Current());
860 }
861 BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol);
862 //-------------------------------------------------------
0d969553 863 // If no trace try intersection.
7fd59977 864 //-------------------------------------------------------
865 if (LInt1.IsEmpty()) {
866 BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge);
867 }
868 Store (CF,OF1,LInt1,LInt2);
869 }
870 }
871 }
872 }
873 }
874}
875
876//=======================================================================
877//function : AddCommonEdges
878//purpose :
879//=======================================================================
880
35e08fe8 881void BRepOffset_Inter3d::AddCommonEdges(const TopTools_ListOfShape&)
7fd59977 882{
883}
884
885
886//=======================================================================
887//function : SetDone
888//purpose :
889//=======================================================================
890
891void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1,
892 const TopoDS_Face& F2)
893{
894 if (!myDone.IsBound(F1)) {
895 TopTools_ListOfShape empty;
896 myDone.Bind(F1,empty);
897 }
898 myDone(F1).Append(F2);
899 if (!myDone.IsBound(F2)) {
900 TopTools_ListOfShape empty;
901 myDone.Bind(F2,empty);
902 }
903 myDone(F2).Append(F1);
904}
905
906
907//=======================================================================
908//function : IsDone
909//purpose :
910//=======================================================================
911
912Standard_Boolean BRepOffset_Inter3d::IsDone(const TopoDS_Face& F1,
913 const TopoDS_Face& F2)
914const
915{
916 if (myDone.IsBound(F1)) {
917 TopTools_ListIteratorOfListOfShape it (myDone(F1));
918 for (; it.More(); it.Next()) {
919 if (it.Value().IsSame(F2)) return Standard_True;
920 }
921 }
922 return Standard_False;
923}
924
925
926//=======================================================================
927//function : TouchedFaces
928//purpose :
929//=======================================================================
930
975ec82a 931TopTools_IndexedMapOfShape& BRepOffset_Inter3d::TouchedFaces()
7fd59977 932{
933 return myTouched;
934}
935
936
937//=======================================================================
938//function : AsDes
939//purpose :
940//=======================================================================
941
942Handle(BRepAlgo_AsDes) BRepOffset_Inter3d::AsDes() const
943{
944 return myAsDes;
945}
946
947
948//=======================================================================
949//function : NewEdges
950//purpose :
951//=======================================================================
952
975ec82a 953TopTools_IndexedMapOfShape& BRepOffset_Inter3d::NewEdges()
7fd59977 954{
955 return myNewEdges;
956}
957
958
959
960//=======================================================================
961//function : Store
962//purpose :
963//=======================================================================
964
965void BRepOffset_Inter3d::Store(const TopoDS_Face& F1,
966 const TopoDS_Face& F2,
967 const TopTools_ListOfShape& LInt1,
968 const TopTools_ListOfShape& LInt2)
969{
970 if (!LInt1.IsEmpty()) {
971 myTouched.Add(F1);
972 myTouched.Add(F2);
973 myAsDes->Add( F1,LInt1);
974 myAsDes->Add( F2,LInt2);
975 TopTools_ListIteratorOfListOfShape it(LInt1);
976 for (; it.More(); it.Next()) {
977 myNewEdges.Add(it.Value());
978 }
979 }
980 SetDone(F1,F2);
981}
982
983
984