0023429: BRepFeat_SplitShape algorithm misses some section edges while building resul...
[occt.git] / src / BRepFeat / BRepFeat_MakePipe.cxx
1 // Created on: 1996-09-03
2 // Created by: Jacques GOUSSARD
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
21
22
23 #include <BRepFeat_MakePipe.ixx>
24
25 #include <BRepFeat.hxx>
26 #include <LocOpe.hxx>
27
28 //modified by NIZNHY-PKV Thu Mar 21 17:54:27 2002 f
29 //#include <BRepAlgo_Fuse.hxx>
30 //#include <BRepAlgo_Cut.hxx> 
31 #include <BRepAlgoAPI_Fuse.hxx>
32 #include <BRepAlgoAPI_Cut.hxx> 
33 //modified by NIZNHY-PKV Thu Mar 21 17:54:30 2002 t
34
35 #include <gp_Vec.hxx>
36 #include <gp_Pnt.hxx>
37 #include <gp_Pnt2d.hxx>
38 #include <TColgp_SequenceOfPnt.hxx>
39 #include <Geom_Curve.hxx>
40 #include <Geom_Line.hxx>
41
42 #include <LocOpe_Pipe.hxx>
43
44 #include <BRep_Tool.hxx>
45 #include <TopExp_Explorer.hxx>
46 #include <TopTools_MapOfShape.hxx>
47 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
48 #include <TopTools_ListIteratorOfListOfShape.hxx>
49 #include <TopTools_MapIteratorOfMapOfShape.hxx>
50 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
51
52 #include <Bnd_Box.hxx>
53 #include <TopoDS_Face.hxx>
54 #include <TopoDS_Shape.hxx>
55 #include <TopoDS.hxx>
56
57 #include <Standard_ConstructionError.hxx>
58
59 #include <TopExp.hxx>
60 #include <BRepBndLib.hxx>
61
62 #ifdef DEB
63 Standard_IMPORT Standard_Boolean BRepFeat_GettraceFEAT();
64 #endif
65
66 static void MajMap(const TopoDS_Shape&, // base
67                    LocOpe_Pipe&,
68                    TopTools_DataMapOfShapeListOfShape&, // myMap
69                    TopoDS_Shape&,  // myFShape
70                    TopoDS_Shape&); // myLShape
71
72
73 static void SetGluedFaces(const TopoDS_Face& theSkface,
74                           const TopoDS_Shape& theSbase,
75                           const TopoDS_Shape& thePbase,
76                           const TopTools_DataMapOfShapeListOfShape& 
77                                 theSlmap,
78                           LocOpe_Pipe&,
79                           TopTools_DataMapOfShapeShape&);
80
81
82 //=======================================================================
83 //function : Init
84 //purpose  : 
85 //=======================================================================
86
87 void BRepFeat_MakePipe::Init(const TopoDS_Shape& Sbase,
88                              const TopoDS_Shape& Pbase,
89                              const TopoDS_Face& Skface,
90                              const TopoDS_Wire& Spine,
91                              const Standard_Integer Mode,
92                              const Standard_Boolean Modify)
93 {
94 #ifdef DEB
95   Standard_Boolean trc = BRepFeat_GettraceFEAT();
96   if (trc) cout << "BRepFeat_MakePipe::Init" << endl;
97 #endif
98   mySbase  = Sbase;
99   BasisShapeValid();
100   mySkface = Skface;
101   SketchFaceValid();
102   myPbase  = Pbase;
103   mySlface.Clear();
104   mySpine   = Spine;
105   if(Mode == 0) {
106     myFuse   = Standard_False;
107     myJustFeat = Standard_False;
108   }
109   else if(Mode == 1) {
110     myFuse   = Standard_True;
111     myJustFeat = Standard_False;
112   }
113   else if(Mode == 2) {
114     myFuse   = Standard_True;
115     myJustFeat = Standard_True;
116   }
117   else {    
118   }
119   myModify = Modify;
120   myJustGluer = Standard_False;
121
122
123   //-------------- ifv
124   //mySkface.Nullify();
125   //-------------- ifv
126
127   myShape.Nullify();
128   myMap.Clear();
129   myFShape.Nullify();
130   myLShape.Nullify();
131   TopExp_Explorer exp;
132   for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
133     TopTools_ListOfShape thelist;
134     myMap.Bind(exp.Current(), thelist);
135     myMap(exp.Current()).Append(exp.Current());
136   }
137 #ifdef DEB
138   if (trc) {
139     if (myJustFeat)  cout << " Just Feature" << endl;
140     if (myFuse)  cout << " Fuse" << endl;
141     if (!myFuse)  cout << " Cut" << endl;
142     if (!myModify) cout << " Modify = 0" << endl;
143   }
144 #endif 
145 }
146
147
148 //=======================================================================
149 //function : Add
150 //purpose  : add faces of gluing
151 //=======================================================================
152
153 void BRepFeat_MakePipe::Add(const TopoDS_Edge& E,
154                              const TopoDS_Face& F)
155 {
156 #ifdef DEB
157   Standard_Boolean trc = BRepFeat_GettraceFEAT();
158   if (trc) cout << "BRepFeat_MakePipe::Add(Edge,face)" << endl;
159 #endif
160   TopExp_Explorer exp;
161   for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
162     if (exp.Current().IsSame(F)) {
163       break;
164     }
165   }
166   if (!exp.More()) {
167     Standard_ConstructionError::Raise();
168   }
169
170   for (exp.Init(myPbase,TopAbs_EDGE);exp.More();exp.Next()) {
171     if (exp.Current().IsSame(E)) {
172       break;
173     }
174   }
175   if (!exp.More()) {
176     Standard_ConstructionError::Raise();
177   }
178
179   if (!mySlface.IsBound(F)) {
180     TopTools_ListOfShape thelist1;
181     mySlface.Bind(F,thelist1);
182   }
183   TopTools_ListIteratorOfListOfShape itl(mySlface(F));
184   for (; itl.More();itl.Next()) {
185     if (itl.Value().IsSame(E)) {
186       break;
187     }
188   }
189   if (!itl.More()) {
190     mySlface(F).Append(E);
191   }
192 }
193
194
195 //=======================================================================
196 //function : Perform
197 //purpose  : 
198 //=======================================================================
199
200 void BRepFeat_MakePipe::Perform()
201 {
202 #ifdef DEB
203   Standard_Boolean trc = BRepFeat_GettraceFEAT();
204   if (trc) cout << "BRepFeat_MakePipe::Perform()" << endl;
205 #endif
206   mySFrom.Nullify();
207   ShapeFromValid();
208   mySUntil.Nullify();
209   ShapeUntilValid();
210   myGluedF.Clear();
211   myPerfSelection = BRepFeat_NoSelection;
212   PerfSelectionValid();
213   TopoDS_Shape theBase = myPbase;
214   LocOpe_Pipe thePipe(mySpine,theBase);
215   TopoDS_Shape VraiPipe = thePipe.Shape();
216   MajMap(myPbase,thePipe,myMap,myFShape,myLShape);
217   myGShape = VraiPipe;
218   GeneratedShapeValid();
219
220   //SetGluedFaces(mySkface, mySbase, myPbase, mySlface, thePipe, myGluedF);
221   GluedFacesValid();
222
223   if(myGluedF.IsEmpty()) {
224     if(myFuse == 1) {
225       //modified by NIZNHY-PKV Thu Mar 21 17:53:05 2002 f
226       //BRepAlgo_Fuse f(mySbase, myGShape);
227       //myShape = f.Shape();
228       //UpdateDescendants(f.Builder(), myShape, Standard_False);
229       BRepAlgoAPI_Fuse f(mySbase, myGShape);
230       myShape = f.Shape();
231       UpdateDescendants(f, myShape, Standard_False);
232       //modified by NIZNHY-PKV Thu Mar 21 17:53:10 2002 t
233       Done();
234     }
235     else if(myFuse == 0) {
236       //modified by NIZNHY-PKV Thu Mar 21 17:53:37 2002 f
237       //BRepAlgo_Cut c(mySbase, myGShape);
238       //myShape = c.Shape();
239       //UpdateDescendants(c.Builder(), myShape, Standard_False);
240       BRepAlgoAPI_Cut c(mySbase, myGShape);
241       myShape = c.Shape();
242       UpdateDescendants(c, myShape, Standard_False);
243       //modified by NIZNHY-PKV Thu Mar 21 17:53:50 2002 t
244       Done();
245     }
246     else {
247       myShape = myGShape;
248       Done();
249     }
250   }
251   else {
252     myFShape = thePipe.FirstShape();
253     TColgp_SequenceOfPnt spt;
254     LocOpe::SampleEdges(myFShape,spt); 
255     myCurves = thePipe.Curves(spt);
256     myBCurve = thePipe.BarycCurve();
257     GlobalPerform();
258   }
259 }
260
261
262 //=======================================================================
263 //function : Perform
264 //purpose  : till shape Until
265 //=======================================================================
266
267 void BRepFeat_MakePipe::Perform(const TopoDS_Shape& Until)
268 {
269 #ifdef DEB
270   Standard_Boolean trc = BRepFeat_GettraceFEAT();
271   if (trc) cout << "BRepFeat_MakePipe::Perform(Until)" << endl;
272 #endif
273   if (Until.IsNull()) {
274     Standard_ConstructionError::Raise();
275   }
276   TopExp_Explorer exp(Until, TopAbs_FACE);
277   if (!exp.More()) {
278     Standard_ConstructionError::Raise();
279   }
280   myGluedF.Clear();
281   myPerfSelection = BRepFeat_SelectionU;
282   PerfSelectionValid();
283   mySFrom.Nullify();
284   ShapeFromValid();
285   mySUntil = Until;
286   TransformShapeFU(1);
287   ShapeUntilValid();
288   LocOpe_Pipe thePipe(mySpine,myPbase);
289   TopoDS_Shape VraiTuyau = thePipe.Shape();
290   MajMap(myPbase,thePipe,myMap,myFShape,myLShape);
291   myGShape = VraiTuyau;
292   GeneratedShapeValid();
293
294   //SetGluedFaces(mySkface, mySbase, myPbase, mySlface, thePipe, myGluedF);
295   GluedFacesValid();
296
297   myFShape = thePipe.FirstShape();
298   TColgp_SequenceOfPnt spt;
299   LocOpe::SampleEdges(myFShape,spt); 
300   myCurves = thePipe.Curves(spt);
301   myBCurve = thePipe.BarycCurve();
302   GlobalPerform();
303 }
304
305
306 //=======================================================================
307 //function : Perform
308 //purpose  : between From and Until
309 //=======================================================================
310
311 void BRepFeat_MakePipe::Perform(const TopoDS_Shape& From,
312                                 const TopoDS_Shape& Until)
313 {
314 #ifdef DEB
315   Standard_Boolean trc = BRepFeat_GettraceFEAT();
316   if (trc) cout << "BRepFeat_MakePipe::Perform(From,Until)" << endl;
317 #endif
318   if (From.IsNull() || Until.IsNull()) {
319     Standard_ConstructionError::Raise();
320   }
321   if (!mySkface.IsNull()) {
322     if (From.IsSame(mySkface)) {
323       Perform(Until);
324       return;
325     }
326     else if (Until.IsSame(mySkface)) {
327       Perform(From);
328       return;
329     }
330   }
331   myGluedF.Clear();
332   myPerfSelection = BRepFeat_SelectionFU;
333   PerfSelectionValid();
334   TopExp_Explorer exp(From, TopAbs_FACE);
335   if (!exp.More()) {
336     Standard_ConstructionError::Raise();
337   }
338   exp.Init(Until, TopAbs_FACE);
339   if (!exp.More()) {
340     Standard_ConstructionError::Raise();
341   }
342   mySFrom = From;
343   TransformShapeFU(0);
344   ShapeFromValid();
345   mySUntil = Until;
346   TransformShapeFU(1);
347   ShapeUntilValid();  
348   LocOpe_Pipe thePipe(mySpine,myPbase);
349   TopoDS_Shape VraiTuyau = thePipe.Shape();
350   MajMap(myPbase,thePipe,myMap,myFShape,myLShape);
351   myGShape = VraiTuyau;
352   GeneratedShapeValid();
353
354   //SetGluedFaces(TopoDS_Face(), // on ne veut pas binder mySkface
355         //      mySbase, myPbase, mySlface, thePipe, myGluedF);
356   GluedFacesValid();
357
358   myFShape = thePipe.FirstShape();
359   TColgp_SequenceOfPnt spt;
360   LocOpe::SampleEdges(myFShape,spt); 
361   myCurves = thePipe.Curves(spt);
362   myBCurve = thePipe.BarycCurve();
363   GlobalPerform();
364 }
365
366
367 //=======================================================================
368 //function : Curves
369 //purpose  : curves parallel to the generating wire of the pipe
370 //=======================================================================
371
372 void BRepFeat_MakePipe::Curves(TColGeom_SequenceOfCurve& scur)
373 {
374   scur = myCurves;
375 }
376
377 //=======================================================================
378 //function : BarycCurve
379 //purpose  : pass through the center of mass
380 //=======================================================================
381
382 Handle(Geom_Curve) BRepFeat_MakePipe::BarycCurve()
383 {
384   return myBCurve;
385 }
386
387
388 //=======================================================================
389 //function : SetGluedFaces
390 //purpose  : management of faces of gluing and sliding  
391 //=======================================================================
392
393 static void SetGluedFaces(const TopoDS_Face& theSkface,
394                           const TopoDS_Shape& theSbase,
395                           const TopoDS_Shape& thePbase,
396                           const TopTools_DataMapOfShapeListOfShape& theSlmap,
397                           LocOpe_Pipe& thePipe,
398                           TopTools_DataMapOfShapeShape& theMap)
399 {
400   TopExp_Explorer exp;
401   if (!theSkface.IsNull() && thePbase.ShapeType() == TopAbs_FACE) {
402     for (exp.Init(theSbase,TopAbs_FACE); exp.More(); exp.Next()) {
403       if (exp.Current().IsSame(theSkface)) {
404         theMap.Bind(thePbase,theSkface);
405         break;
406       }
407     }
408   }
409   else {
410     TopExp_Explorer exp2;
411     for (exp.Init(thePbase,TopAbs_FACE);exp.More();exp.Next()) {
412       const TopoDS_Face& fac = TopoDS::Face(exp.Current());
413       for (exp2.Init(theSbase,TopAbs_FACE);exp2.More();exp2.Next()) {
414         if (exp2.Current().IsSame(fac)) {
415           theMap.Bind(fac,fac);
416           break;
417         }
418       }
419     }
420   }
421
422   // Sliding
423   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(theSlmap);
424   if(!theSlmap.IsEmpty()) {
425     for (; itm.More(); itm.Next()) {
426       const TopoDS_Face& fac = TopoDS::Face(itm.Key());
427       const TopTools_ListOfShape& ledg = itm.Value();
428       TopTools_ListIteratorOfListOfShape it;
429       for (it.Initialize(ledg); it.More(); it.Next()) {
430         const TopTools_ListOfShape& gfac = thePipe.Shapes(it.Value());
431         if (gfac.Extent() != 1) {
432 #ifdef DEB
433           Standard_Boolean trc = BRepFeat_GettraceFEAT();
434           if (trc) cout << " BRepFeat_MakeDPipe : Pb SetGluedFace" << endl;
435 #endif
436         }
437         theMap.Bind(gfac.First(),fac);
438       }
439     }
440   }
441 }
442
443
444 //=======================================================================
445 //function : MajMap
446 //purpose  : management of descendants
447 //=======================================================================
448
449 static void MajMap(const TopoDS_Shape& theB,
450                    LocOpe_Pipe& theP,
451                    TopTools_DataMapOfShapeListOfShape& theMap, // myMap
452                    TopoDS_Shape& theFShape,  // myFShape
453                    TopoDS_Shape& theLShape) // myLShape
454 {
455   TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
456   if (exp.More()) {
457     theFShape = exp.Current();
458     TopTools_ListOfShape thelist2;
459     theMap.Bind(theFShape, thelist2);
460     for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
461       theMap(theFShape).Append(exp.Current());
462     }
463   }
464   
465   exp.Init(theP.LastShape(),TopAbs_WIRE);
466   if (exp.More()) {
467     theLShape = exp.Current();
468     TopTools_ListOfShape thelist3;
469     theMap.Bind(theLShape, thelist3);
470     for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
471       theMap(theLShape).Append(exp.Current());
472     }
473   }
474
475   for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
476     if (!theMap.IsBound(exp.Current())) {
477       TopTools_ListOfShape thelist4;
478       theMap.Bind(exp.Current(), thelist4);
479       theMap(exp.Current()) = theP.Shapes(exp.Current());
480     }
481   }
482 }
483
484
485
486
487
488
489
490
491
492
493
494
495
496