0024096: Eliminate compiler warning C4505 in MSVC++ with warning level 4
[occt.git] / src / LocOpe / LocOpe_Pipe.cxx
1 // Created on: 1996-09-04
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 <LocOpe_Pipe.ixx>
24
25 #include <LocOpe.hxx>
26
27 #include <LocOpe_BuildShape.hxx>
28
29 #include <BRep_Builder.hxx>
30 #include <BRep_Tool.hxx>
31
32 #include <TopTools_MapOfShape.hxx>
33 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
34 #include <TopTools_MapIteratorOfMapOfShape.hxx>
35 #include <TopTools_DataMapOfShapeListOfShape.hxx>
36 #include <TopTools_ListIteratorOfListOfShape.hxx>
37 #include <TopExp_Explorer.hxx>
38
39 #include <TopoDS_Face.hxx>
40 #include <TopoDS_Edge.hxx>
41
42 #include <TColStd_Array1OfReal.hxx>
43 #include <TColStd_Array1OfInteger.hxx>
44 #include <TColgp_Array1OfPnt.hxx>
45
46 #include <Geom_Surface.hxx>
47 #include <Geom_RectangularTrimmedSurface.hxx>
48 #include <Geom_Plane.hxx>
49 #include <Geom_Curve.hxx>
50 #include <Geom_BSplineCurve.hxx>
51
52 #include <gp_Pln.hxx>
53
54 #include <TopoDS.hxx>
55 #include <TopExp.hxx>
56 #include <Precision.hxx>
57 #include <BSplCLib.hxx>
58
59 #include <GeomConvert.hxx>
60
61 static TopAbs_Orientation Orientation(const TopoDS_Shape&,
62                                       const TopoDS_Shape&);
63
64
65 //=======================================================================
66 //function : LocOpe_Pipe
67 //purpose  : 
68 //=======================================================================
69
70 LocOpe_Pipe::LocOpe_Pipe(const TopoDS_Wire& Spine,
71                          const TopoDS_Shape& Profile) : 
72            myPipe(Spine,Profile)
73 {
74
75   TopoDS_Shape Result = myPipe.Shape();
76
77   // On enleve les faces generees par les edges de connexite du profile,
78   // et on fusionne les plans si possible
79
80   TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
81   TopExp::MapShapesAndAncestors(Profile,TopAbs_EDGE,TopAbs_FACE,theEFMap);
82   TopExp_Explorer exp;
83   TopTools_ListOfShape Empty;
84   TopTools_ListIteratorOfListOfShape it;
85
86   TopTools_ListOfShape goodfaces;
87
88   for (Standard_Integer i=1; i<=theEFMap.Extent(); i++) { 
89     const TopoDS_Edge& edgpr = TopoDS::Edge(theEFMap.FindKey(i));
90     myMap.Bind(edgpr,Empty);
91     if (theEFMap(i).Extent() >= 2) {
92       // on ne prend pas les faces generees
93     }
94     else {
95       TopTools_MapOfShape MapFac; // on mappe les plans generes par cet edge
96       for (exp.Init(Spine,TopAbs_EDGE); exp.More(); exp.Next()) {
97         const TopoDS_Edge& edgsp = TopoDS::Edge(exp.Current());
98         TopoDS_Face resfac = myPipe.Face(edgsp,edgpr);
99         if (!resfac.IsNull()) {
100           Handle(Geom_Surface) P = BRep_Tool::Surface(resfac);
101           if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
102             P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
103           }
104           if (P->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
105             MapFac.Add(resfac);
106           }
107           else {
108             myMap(edgpr).Append(resfac);
109             goodfaces.Append(resfac);
110           }
111         }
112       }
113       
114       // Chercher les composantes connexes sur cet ensemble de faces., avec meme
115       // support geometrique
116
117       TopTools_MapIteratorOfMapOfShape itm(MapFac);
118       if (MapFac.Extent() <= 1) { // un seul plan. Rien a faire
119         if (MapFac.Extent() == 1) {
120           myMap(edgpr).Append(itm.Key());
121           goodfaces.Append(itm.Key());
122         }
123         continue;
124       }
125       
126       while (MapFac.Extent() >= 2) {
127         itm.Reset();
128         TopTools_ListOfShape FacFuse;
129         TopoDS_Face FaceRef = TopoDS::Face(itm.Key());
130         FacFuse.Append(FaceRef);
131         Handle(Geom_Surface) P = BRep_Tool::Surface(FaceRef);
132         if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
133           P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
134         }
135         gp_Pln Plref = Handle(Geom_Plane)::DownCast(P)->Pln();
136         
137         for (itm.Next(); itm.More(); itm.Next()) {
138           P = BRep_Tool::Surface(TopoDS::Face(itm.Key()));
139           if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
140             P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
141           }
142           gp_Pln Pl = Handle(Geom_Plane)::DownCast(P)->Pln();
143           if (Pl.Axis().IsParallel(Plref.Axis(),Precision::Angular()) &&
144               Plref.Contains(Pl.Location(),Precision::Confusion())) {
145             FacFuse.Append(itm.Key());
146           }
147         }
148         
149         // FacFuse contient des faces de meme support. Il faut en faire 
150         // des composantes connexes
151         
152         while (FacFuse.Extent() >= 2) {
153           FaceRef = TopoDS::Face(FacFuse.First());
154           // Recuperer l'orientation
155           TopAbs_Orientation orref = Orientation(FaceRef,Result);
156           P = BRep_Tool::Surface(FaceRef);
157           if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
158             P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
159           }
160           Plref = Handle(Geom_Plane)::DownCast(P)->Pln();
161           gp_Dir Dirref(Plref.Axis().Direction());
162           if (Plref.Direct() && orref == TopAbs_REVERSED ||
163               !Plref.Direct() && orref == TopAbs_FORWARD) {
164             Dirref.Reverse();
165           }
166           
167           TopTools_MapOfShape MapEd;
168           for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
169                exp.More(); exp.Next()) {
170             MapEd.Add(exp.Current());
171           }
172           
173           MapFac.Remove(FaceRef);
174           FacFuse.RemoveFirst(); // on enleve FaceRef
175           Standard_Boolean FaceToFuse = Standard_False;
176           Standard_Boolean MoreFound;
177           
178           
179           do {
180             MoreFound = Standard_False;
181             for (it.Initialize(FacFuse); it.More(); it.Next()) {
182               for (exp.Init(it.Value(),TopAbs_EDGE);
183                    exp.More(); exp.Next()) {
184                 if (MapEd.Contains(exp.Current())) {
185                   FaceToFuse = Standard_True;
186                   MoreFound = Standard_True;
187                   break;
188                 }
189               }
190               if (exp.More()) {
191                 break;
192               }
193             }
194             if (MoreFound) {
195               const TopoDS_Face& fac = TopoDS::Face(it.Value());
196               TopAbs_Orientation orrelat = Orientation(fac,Result);
197               Handle(Geom_Surface) OtherP = BRep_Tool::Surface(fac);
198               if (OtherP->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
199                 OtherP = Handle(Geom_RectangularTrimmedSurface)::
200                 DownCast(OtherP)->BasisSurface();
201               }
202               gp_Pln Pl = Handle(Geom_Plane)::DownCast(OtherP)->Pln();
203               gp_Dir Dirpl(Pl.Axis().Direction());
204               if (Pl.Direct() && orrelat == TopAbs_REVERSED ||
205                   !Plref.Direct() && orrelat == TopAbs_FORWARD) {
206                 Dirpl.Reverse();
207               }
208               if (Dirpl.Dot(Dirref) > 0) {
209                 orrelat = TopAbs_FORWARD;
210               }
211               else {
212                 orrelat = TopAbs_REVERSED;
213               }
214               for (exp.Init(fac.Oriented(orrelat),TopAbs_EDGE);
215                    exp.More(); exp.Next()) {
216                 if (!MapEd.Add(exp.Current())) {
217                   MapEd.Remove(exp.Current());
218                 }
219               }     
220               MapFac.Remove(fac);
221               FacFuse.Remove(it);
222             }
223           } while (MoreFound);
224           
225           if (FaceToFuse) {
226             TopoDS_Face NewFace;
227             BRep_Builder B;
228             B.MakeFace(NewFace,P,BRep_Tool::Tolerance(FaceRef));
229             TopoDS_Wire NewWire;
230             B.MakeWire(NewWire);
231             for (TopTools_MapIteratorOfMapOfShape itm2(MapEd);
232                  itm2.More(); itm2.Next()) {
233               B.Add(NewWire,itm2.Key());
234             }
235             exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
236             NewWire.Orientation(exp.Current().Orientation());
237             B.Add(NewFace,NewWire);
238             myMap(edgpr).Append(NewFace);
239             goodfaces.Append(NewFace);
240           }
241         }
242         if (FacFuse.Extent() == 1) {
243           MapFac.Remove(FacFuse.First());
244           myMap(edgpr).Append(FacFuse.First());
245           goodfaces.Append(FacFuse.First());
246         }
247       }
248     }
249   }
250
251   for (exp.Init(myPipe.FirstShape(),TopAbs_FACE); exp.More(); exp.Next()) {
252     goodfaces.Append(exp.Current());
253   }
254   for (exp.Init(myPipe.LastShape(),TopAbs_FACE); exp.More(); exp.Next()) {
255     goodfaces.Append(exp.Current());
256   }
257
258   LocOpe_BuildShape BS(goodfaces);
259   myRes = BS.Shape();
260 }
261
262
263 //=======================================================================
264 //function : Shape
265 //purpose  : 
266 //=======================================================================
267
268 const TopoDS_Shape& LocOpe_Pipe::Shape () const
269 {
270   return myRes;
271 }
272
273
274 //=======================================================================
275 //function : Shapes
276 //purpose  : 
277 //=======================================================================
278
279 const TopTools_ListOfShape& LocOpe_Pipe::Shapes (const TopoDS_Shape& S)
280 {
281   TopAbs_ShapeEnum typS = S.ShapeType();
282   if (typS != TopAbs_EDGE && typS != TopAbs_VERTEX) {
283     Standard_DomainError::Raise();
284   }
285 //  for (TopExp_Explorer exp(myPipe.Profile(),typS); exp.More(); exp.Next()) {
286   TopExp_Explorer exp(myPipe.Profile(),typS) ;
287   for ( ; exp.More(); exp.Next()) {
288     if (exp.Current().IsSame(S)) {
289       break;
290     }
291   }
292   if (!exp.More()) {
293     Standard_NoSuchObject::Raise();
294   }
295
296   myGShap.Clear();
297   if (typS == TopAbs_VERTEX) {
298     const TopoDS_Vertex& VProfile = TopoDS::Vertex(S);
299     for (exp.Init(myPipe.Spine(),TopAbs_EDGE); exp.More(); exp.Next()) {
300       const TopoDS_Edge& edsp = TopoDS::Edge(exp.Current());
301       TopoDS_Edge resed = myPipe.Edge(edsp,VProfile);
302       if (!resed.IsNull()) {
303         myGShap.Append(resed);
304       }
305     }
306     return myGShap;
307   }
308   // TopAbs_EDGE
309   const TopoDS_Edge& EProfile = TopoDS::Edge(S);
310   return myMap(EProfile);
311 }
312
313
314 //=======================================================================
315 //function : GetCurves
316 //purpose  : 
317 //=======================================================================
318
319 const TColGeom_SequenceOfCurve& 
320     LocOpe_Pipe::Curves(const TColgp_SequenceOfPnt& Spt) 
321 {
322
323   myCrvs.Clear();
324   TopTools_MapOfShape Map;
325
326   Standard_Integer i , j , k , Nbpnt = Spt.Length();
327   Standard_Real p1,p2;
328 //  gp_Pnt ptbid;
329
330   for ( i = 1; i <= Nbpnt; i++) {
331     gp_Pnt P1 = Spt(i);
332     Standard_Integer MaxDeg = 0;
333     TColGeom_SequenceOfCurve seq;
334     TopoDS_Wire W = myPipe.PipeLine(P1);
335     
336     TopExp_Explorer ex(W, TopAbs_EDGE);
337     for (; ex.More(); ex.Next()) {
338       Handle(Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(ex.Current()), p1, p2);
339       Handle(Geom_BSplineCurve) C = GeomConvert::CurveToBSplineCurve (C1);
340       if (C.IsNull()) {
341         continue;
342       }
343       MaxDeg = Max(MaxDeg,C->Degree());
344       P1 = C->Value(p2);
345       if (p1 != C->FirstParameter() || p2 != C->LastParameter()) {
346         C->Segment(p1,p2);
347       }
348       Standard_Integer Nbkn = C->NbKnots();
349       TColStd_Array1OfReal Tkn(1,Nbkn);
350       C->Knots(Tkn);
351       BSplCLib::Reparametrize(seq.Length(),seq.Length()+1,Tkn);
352       C->SetKnots(Tkn);
353       seq.Append(C);
354     }
355
356     Handle(Geom_Curve) newC;
357     Standard_Integer Nbkn=0 ,Nbp=0;
358     Standard_Integer Nbcurv = seq.Length();
359     if (Nbcurv == 0) {
360       myCrvs.Append(newC);
361       continue;
362     }
363
364     Handle(Geom_BSplineCurve) Bsp;
365     for (j=1; j<=Nbcurv; j++) {
366       Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
367       Bsp->IncreaseDegree(MaxDeg);
368       Nbp += Bsp->NbPoles();
369       Nbkn += Bsp->NbKnots();
370     }
371     Nbp  -= Nbcurv-1;
372     Nbkn -= Nbcurv-1;
373     TColStd_Array1OfReal Tkn(1,Nbkn);
374     TColStd_Array1OfInteger Tmu(1,Nbkn);
375     TColgp_Array1OfPnt Tpol(1,Nbp);
376     Standard_Integer Ik=0,Ip=0;
377
378     Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(1));
379     for ( k = 1; k<= Bsp->NbPoles(); k++) {
380       Ip++;
381       Tpol(Ip) = Bsp->Pole(k);
382     }
383     for (k = 1; k<= Bsp->NbKnots(); k++) {
384       Ik++;
385       Tkn(Ik) = Bsp->Knot(k);
386       Tmu(Ik) = Bsp->Multiplicity(k);
387     }
388     Tmu(Ik)--;
389     
390     for (j=2; j<=Nbcurv; j++) {
391       Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
392       for (k = 2; k<= Bsp->NbPoles(); k++) {
393         Ip++;
394         Tpol(Ip) = Bsp->Pole(k);
395       }
396       for (k = 2; k<= Bsp->NbKnots(); k++) {
397         Ik++;
398         Tkn(Ik) = Bsp->Knot(k);
399         Tmu(Ik) = Bsp->Multiplicity(k);
400       }
401       Tmu(Ik)--;
402     }
403     Tmu(Ik)++;
404     newC = new Geom_BSplineCurve(Tpol,Tkn,Tmu,MaxDeg);
405     myCrvs.Append(newC);
406   }
407
408   return myCrvs;
409 }
410
411
412 //=======================================================================
413 //function : Orientation
414 //purpose  : static, not member
415 //=======================================================================
416
417 static TopAbs_Orientation Orientation(const TopoDS_Shape& Sub,
418                                      const TopoDS_Shape& S)
419 {
420   TopExp_Explorer exp;
421   for (exp.Init(S,Sub.ShapeType()); exp.More(); exp.Next()) {
422     if (exp.Current().IsSame(Sub)) {
423       return exp.Current().Orientation();
424     }
425   }
426   Standard_NoSuchObject::Raise();
427   return TopAbs_INTERNAL;
428 }
429
430
431 //=======================================================================
432 //function : BarycCurve
433 //purpose  : 
434 //=======================================================================
435
436 Handle(Geom_Curve) LocOpe_Pipe::BarycCurve() 
437 {
438   Standard_Integer j , k ;
439
440   gp_Pnt bar(0., 0., 0.);
441   TColgp_SequenceOfPnt spt;
442   TopoDS_Shape Base = FirstShape();
443   LocOpe::SampleEdges(Base, spt);
444   for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
445     const gp_Pnt& pvt = spt(jj);
446     bar.ChangeCoord() += pvt.XYZ();
447   }
448   bar.ChangeCoord().Divide(spt.Length());
449
450   Standard_Real p1,p2;
451 //  gp_Pnt ptbid;
452   gp_Pnt P1 = bar;
453
454   Standard_Integer MaxDeg = 0;
455   TColGeom_SequenceOfCurve seq;  
456   TopoDS_Wire W = myPipe.PipeLine(P1);
457   
458   TopExp_Explorer ex(W, TopAbs_EDGE);
459   for (; ex.More(); ex.Next()) {
460     Handle(Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(ex.Current()), p1, p2);
461     Handle(Geom_BSplineCurve) C = GeomConvert::CurveToBSplineCurve (C1);
462
463     if (C.IsNull()) {
464       continue;
465     }
466     MaxDeg = Max(MaxDeg,C->Degree());
467     P1 = C->Value(p2);
468     if (p1 != C->FirstParameter() || p2 != C->LastParameter()) {
469       C->Segment(p1,p2);
470     }
471     Standard_Integer Nbkn = C->NbKnots();
472     TColStd_Array1OfReal Tkn(1,Nbkn);
473     C->Knots(Tkn);
474     BSplCLib::Reparametrize(seq.Length(),seq.Length()+1,Tkn);
475       C->SetKnots(Tkn);
476     seq.Append(C);
477   }
478   Handle(Geom_Curve) newC;
479   Standard_Integer Nbkn=0 ,Nbp=0;
480   Standard_Integer Nbcurv = seq.Length();
481   if (Nbcurv == 0) {
482     myCrvs.Append(newC);
483   }
484   Handle(Geom_BSplineCurve) Bsp;
485   for ( j=1; j<=Nbcurv; j++) {
486     Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
487     Bsp->IncreaseDegree(MaxDeg);
488     Nbp += Bsp->NbPoles();
489     Nbkn += Bsp->NbKnots();
490   }
491   Nbp  -= Nbcurv-1;
492   Nbkn -= Nbcurv-1;
493   TColStd_Array1OfReal Tkn(1,Nbkn);
494   TColStd_Array1OfInteger Tmu(1,Nbkn);
495   TColgp_Array1OfPnt Tpol(1,Nbp);
496   Standard_Integer Ik=0,Ip=0;
497
498   Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(1));
499   for ( k = 1; k<= Bsp->NbPoles(); k++) {
500     Ip++;
501     Tpol(Ip) = Bsp->Pole(k);
502   }
503   for (k = 1; k<= Bsp->NbKnots(); k++) {
504     Ik++;
505     Tkn(Ik) = Bsp->Knot(k);
506     Tmu(Ik) = Bsp->Multiplicity(k);
507   }
508   Tmu(Ik)--;
509   
510   for (j=2; j<=Nbcurv; j++) {
511     Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
512     for (k = 2; k<= Bsp->NbPoles(); k++) {
513       Ip++;
514         Tpol(Ip) = Bsp->Pole(k);
515     }
516       for (k = 2; k<= Bsp->NbKnots(); k++) {
517         Ik++;
518         Tkn(Ik) = Bsp->Knot(k);
519         Tmu(Ik) = Bsp->Multiplicity(k);
520       }
521     Tmu(Ik)--;
522   }
523   Tmu(Ik)++;
524   newC = new Geom_BSplineCurve(Tpol,Tkn,Tmu,MaxDeg);
525
526   return newC;
527 }
528
529