Salome HOME
Update copyright
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_ShapeInfoFiller_1.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <GEOMAlgo_ShapeInfoFiller.ixx>
21
22 #include <Precision.hxx>
23
24 #include <gp_Lin.hxx>
25 #include <gp_XYZ.hxx>
26 #include <gp_Ax1.hxx>
27 #include <gp_Dir.hxx>
28 #include <gp_Vec.hxx>
29 #include <gp_Ax2.hxx>
30 #include <gp_Ax3.hxx>
31
32 #include <ElCLib.hxx>
33
34 #include <TopoDS.hxx>
35 #include <TopoDS_Vertex.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS_Wire.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <TopoDS_Iterator.hxx>
40
41 #include <BRep_Tool.hxx>
42
43 #include <TopExp.hxx>
44 #include <TopExp_Explorer.hxx>
45
46 #include <TopTools_MapOfShape.hxx>
47 #include <TopTools_IndexedMapOfShape.hxx>
48 #include <BRepTools_WireExplorer.hxx>
49
50 #include <GEOMAlgo_ShapeInfo.hxx>
51 #include <TColStd_MapOfInteger.hxx>
52 #include <TColStd_IndexedMapOfInteger.hxx>
53
54 //=======================================================================
55 //function : FillDetails
56 //purpose  : 
57 //=======================================================================
58   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd)
59 {
60   Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX;
61   TopoDS_Shape aFCyl, aFCon;
62   TopTools_IndexedMapOfShape aMF;
63   GEOMAlgo_KindOfName aKNF;
64   //
65   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
66   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
67   //
68   TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
69   //
70   aNbF=aMF.Extent();
71   if (!aNbF) {
72     return;
73   }
74   //
75   if (aNbF==1) {
76     const TopoDS_Shape& aF=aMF(1);
77     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
78     aKNF=aInfoF.KindOfName(); // mb: sphere, torus
79     if (aKNF==GEOMAlgo_KN_SPHERE ||
80         aKNF==GEOMAlgo_KN_TORUS) {
81       aInfo.SetKindOfName(aKNF);
82       aInfo.SetLocation(aInfoF.Location());
83       aInfo.SetPosition(aInfoF.Position());
84       aInfo.SetRadius1(aInfoF.Radius1());
85       if(aKNF==GEOMAlgo_KN_TORUS) {
86         aInfo.SetRadius2(aInfoF.Radius2());
87       }
88       return;
89     }
90   }
91   //
92   aNbCyl=0;
93   aNbCon=0;
94   aNbPgn=0;
95   aNbRct=0;
96   aNbCrc=0;
97   for (i=1; i<=aNbF; ++i) {
98     const TopoDS_Shape& aF=aMF(i);
99     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
100     aKNF=aInfoF.KindOfName(); 
101     if (aKNF==GEOMAlgo_KN_CYLINDER) {
102       aFCyl=aF;
103       ++aNbCyl;
104     }
105     else if (aKNF==GEOMAlgo_KN_CONE) {
106       aFCon=aF;
107       ++aNbCon;
108     }
109     else if (aKNF==GEOMAlgo_KN_DISKCIRCLE) {
110       ++aNbCrc;
111     }
112     else if (aKNF==GEOMAlgo_KN_POLYGON ||
113             aKNF==GEOMAlgo_KN_TRIANGLE ||
114             aKNF==GEOMAlgo_KN_QUADRANGLE) {
115       ++aNbPgn;
116       
117     } 
118     else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
119       ++aNbPgn;
120       ++aNbRct;
121     }
122   }
123   //
124   aNbX=aNbCyl+aNbCrc;
125   if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
126     // cylinder (as they understand it)
127     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
128     aKNF=aInfoF.KindOfName(); 
129     aInfo.SetKindOfName(aKNF);
130     aInfo.SetLocation(aInfoF.Location());
131     aInfo.SetPosition(aInfoF.Position());
132     aInfo.SetRadius1(aInfoF.Radius1());
133     aInfo.SetHeight(aInfoF.Height());
134     return;
135   }
136   //
137   aNbX=aNbCon+aNbCrc;
138   if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
139     // cone
140     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
141     aKNF=aInfoF.KindOfName(); 
142     aInfo.SetKindOfName(aKNF);
143     aInfo.SetLocation(aInfoF.Location());
144     aInfo.SetPosition(aInfoF.Position());
145     aInfo.SetRadius1(aInfoF.Radius1());
146     aInfo.SetRadius2(aInfoF.Radius2());
147     aInfo.SetHeight(aInfoF.Height());
148     return;
149   }
150   //
151   if (aNbPgn!=6) {
152     aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
153     return;
154   }
155   if (aNbPgn!=aNbRct) {
156     aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
157     return;
158   }
159   //===================================================
160   // aNbRct=6;
161   // box
162   Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
163   Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
164   Standard_Real aDistMin, aDistMax;
165   gp_Pnt aPi, aPc;
166   gp_Dir aDir[3];
167   gp_XYZ aXYZc;
168   TColStd_IndexedMapOfInteger aMp;
169   TopTools_IndexedMapOfShape aMV, aMFi;
170   //
171   // barycenter aPc
172   TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
173   aNbV=aMV.Extent();
174   if (aNbV!=8) {
175     return;
176   }
177   //
178   aXYZc.SetCoord(0.,0.,0.);
179   for (i=1; i<=aNbV; ++i) {
180     const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
181     aPi=BRep_Tool::Pnt(aVi);
182     const gp_XYZ& aXYZ=aPi.XYZ();
183     aXYZc=aXYZc+aXYZ;
184   }
185   //
186   aXYZc.Divide(aNbV);
187   aPc.SetXYZ(aXYZc);
188   //
189   // 3 faces
190   for (i=1; i<=aNbF; ++i) {
191     if (aMp.Contains(i)) {
192       continue;
193     }
194     //
195     const TopoDS_Shape& aFi=aMF(i);
196     const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
197     const gp_Dir& aDNi=aIFi.Position().Direction();
198     //
199     for (j=i+1; j<=aNbF; ++j) {
200       if (aMp.Contains(j)) {
201         continue;
202       }
203       //
204       const TopoDS_Shape& aFj=aMF(j);
205       const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
206       const gp_Dir& aDNj=aIFj.Position().Direction();
207       //
208       aDot=aDNi*aDNj;
209       if (fabs(1.-aDot)<0.0001) {
210         aMp.Add(i);
211         aMp.Add(j);
212         aMFi.Add(aFi);
213         break;
214       }
215       //
216     }
217   }
218   aNbFi=aMFi.Extent();
219   if (aNbFi!=3) {
220     return;
221   }
222   //
223   aDistMin=1.e15;
224   aDistMax=-aDistMin;
225   for (i=0; i<aNbFi; ++i) {
226     const TopoDS_Shape& aFi=aMFi(i+1);
227     const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
228     aPi=aIFi.Location();
229     aDist[i]=aPc.Distance(aPi);
230     if (aDist[i]>aDistMax) {
231       aDistMax=aDist[i];
232       iMax=i;
233     }
234     if (aDist[i]<aDistMin) {
235       aDistMin=aDist[i];
236       iMin=i;
237     }
238     gp_Vec aVi(aPc, aPi);
239     gp_Dir aDi(aVi);
240     aDir[i]=aDi;
241   }
242   //
243   if (iMax==iMin) {
244     iMax=0;
245     iMin=1;
246   }
247   iMid=3-iMax-iMin;
248   //
249   aLength=2.*aDist[iMax];
250   aWidth=2.*aDist[iMid];
251   aHeight=2.*aDist[iMin];
252   //
253   gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
254   gp_Ax3 aAx3(aAx2);
255   //
256   aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
257   aInfo.SetLocation(aPc);
258   aInfo.SetLength(aLength);
259   aInfo.SetWidth(aWidth);
260   aInfo.SetHeight(aHeight);
261   aInfo.SetPosition(aAx3);
262 }
263 //=======================================================================
264 //function : FillDetails
265 //purpose  : 
266 //=======================================================================
267   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
268                                              const gp_Pln& aPln)
269 {
270   Standard_Integer aNbV, aNbE, i, j;
271   Standard_Real aDot, aD0, aD1, aLength, aWidth;
272   gp_Dir aDx[4], aDX;
273   gp_Pnt aPx[4], aP, aPc;
274   gp_XYZ aXYZc;
275   TopExp_Explorer aExp;
276   TopoDS_Shape aE;
277   TopoDS_Wire aW;
278   TopoDS_Edge aEx;
279   TopoDS_Iterator aIt;
280   TopTools_IndexedMapOfShape aMV;
281   BRepTools_WireExplorer aWExp;
282   GEOMAlgo_KindOfName aKN, aKNE;
283   GEOMAlgo_KindOfShape aKS;
284   //
285   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
286   aKN=GEOMAlgo_KN_UNKNOWN;
287   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
288   //
289   aKS=aInfo.KindOfShape();
290   if (aKS!=GEOMAlgo_KS_PLANE) {
291     return;
292   }
293   //
294   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
295     aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
296     return;
297   }
298   //
299   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
300   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
301   //
302   // 1. may be it is circle/ellipse
303   if (aNbV==1 && aNbE==1) {
304     aExp.Init(aF, TopAbs_EDGE);
305     for (; aExp.More(); aExp.Next()) {
306       aE=aExp.Current();
307       break;
308     }
309     //
310     const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
311     aKNE=aInfoE.KindOfName();
312     if (aKNE==GEOMAlgo_KN_CIRCLE) {
313       aKN=GEOMAlgo_KN_DISKCIRCLE;
314       aInfo.SetKindOfName(aKN);
315       aInfo.SetRadius1(aInfoE.Radius1());
316       aInfo.SetLocation(aInfoE.Location());
317       aInfo.SetPosition(aInfoE.Position());
318     }
319     if (aKNE==GEOMAlgo_KN_ELLIPSE) {
320       aKN=GEOMAlgo_KN_DISKELLIPSE;
321       aInfo.SetKindOfName(aKN);
322       aInfo.SetRadius1(aInfoE.Radius1());
323       aInfo.SetRadius2(aInfoE.Radius2());
324       aInfo.SetLocation(aInfoE.Location());
325       aInfo.SetPosition(aInfoE.Position());
326     }
327   }
328   //
329   // 2. may be it is rectangle
330   else  {
331     aExp.Init(aF, TopAbs_EDGE);
332     for (; aExp.More(); aExp.Next()) {
333       aE=aExp.Current();
334       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
335       aKNE=aInfoE.KindOfName();
336       if (aKNE!=GEOMAlgo_KN_SEGMENT) {
337         return;
338       }
339     }
340     //
341     aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
342     //
343     if (aNbV==3 && aNbE==3) {
344       aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
345       //
346       aXYZc.SetCoord(0.,0.,0.);
347       TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
348       for (i=1; i<=aNbV; ++i) {
349         const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
350         aP=BRep_Tool::Pnt(aV);
351         const gp_XYZ& aXYZ=aP.XYZ();
352         aXYZc=aXYZc+aXYZ;
353         aPx[i-1]=aP;
354       }
355       aXYZc.Divide(3.);
356       //
357       aPc.SetXYZ(aXYZc);
358       gp_Vec aVX(aPc, aPx[0]);
359       aVX.Normalize();
360       aDX.SetXYZ(aVX.XYZ());
361       const gp_Dir& aDZ=aPln.Axis().Direction();
362       //
363       gp_Ax2 aAx2(aPc, aDZ, aDX);
364       gp_Ax3 aAx3(aAx2);
365       //
366       aInfo.SetLocation(aPc);
367       aInfo.SetPosition(aAx3);
368       //
369       return;
370     }
371     //
372     if (!(aNbV==4 && aNbE==4)) {
373       return;
374     }
375     //
376     // aNbV==4 && aNbE==4 and all edges are segments
377     aIt.Initialize(aF);
378     for (; aIt.More(); aIt.Next()){
379       aW=TopoDS::Wire(aIt.Value());
380       break;
381     }
382     //
383     aWExp.Init(aW, aF);
384     for (i=0; aWExp.More(); aWExp.Next(), ++i) {
385       aEx=aWExp.Current();
386       const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
387       aDx[i]=aInfoEx.Direction();
388       aPx[i]=aInfoEx.Location();
389     }
390     //
391     for (i=0; i<4; ++i) {
392       j=(i==3) ? 0 : i+1;
393       aDot=aDx[i]*aDx[j];
394       if (fabs (aDot) > myTolerance) {
395         aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
396         return;
397       }
398     }
399     //
400     // rectangle 
401     aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
402     //
403     // shift location to the center and calc. sizes
404     aXYZc.SetCoord(0.,0.,0.);
405     TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
406     for (i=1; i<=aNbV; ++i) {
407       const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
408       aP=BRep_Tool::Pnt(aV);
409       const gp_XYZ& aXYZ=aP.XYZ();
410       aXYZc=aXYZc+aXYZ;
411     }
412     //
413     // Location : aPc in center of rectangle
414     // Position : 0z is plane normal
415     //            0x is along length
416     //
417     aXYZc.Divide(4.);
418     aPc.SetXYZ(aXYZc);
419     //
420     gp_Lin aL0(aPx[0], aDx[0]);
421     gp_Lin aL1(aPx[1], aDx[1]);
422     //
423     aD0=aL0.Distance(aPc);
424     aD1=aL1.Distance(aPc);
425     //
426     aLength=aD0;
427     aWidth =aD1;
428     aDX=aL1.Direction();
429     if (aD0<aD1) {
430       aLength=aD1;
431       aWidth =aD0;
432       aDX=aL0.Direction();
433     }
434     //
435     aLength=2.*aLength;
436     aWidth =2.*aWidth;
437     //
438     aInfo.SetLocation(aPc);
439     aInfo.SetLength(aLength);
440     aInfo.SetWidth(aWidth);
441     //
442     const gp_Dir& aDZ=aPln.Axis().Direction();
443     gp_Ax2 aAx2(aPc, aDZ, aDX);
444     gp_Ax3 aAx3(aAx2);
445     aInfo.SetPosition(aAx3);
446   }
447   
448   return;
449 }
450 //=======================================================================
451 //function : FillDetails
452 //purpose  : 
453 //=======================================================================
454   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
455                                              const gp_Sphere& )
456 {
457   Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
458   TopoDS_Edge aE; 
459   TopExp_Explorer aExp;
460   TopTools_MapOfShape aM; 
461   GEOMAlgo_KindOfShape aKS, aKSE;
462   //
463   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
464   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
465   //
466   aKS=aInfo.KindOfShape();
467   if (aKS!=GEOMAlgo_KS_SPHERE) {
468     return;
469   }
470   //
471   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
472   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
473   if (!(aNbV==2 && aNbE==3)) {
474     return;
475   }
476   //
477   aNbSE=0;
478   aNbDE=0;
479   aExp.Init(aF, TopAbs_EDGE);
480   for (; aExp.More(); aExp.Next()) {
481     aE=TopoDS::Edge(aExp.Current());
482     if(aM.Add(aE)) {
483       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
484       aKSE=aInfoE.KindOfShape();
485       //
486       if (BRep_Tool::IsClosed(aE, aF)) {
487         ++aNbSE;
488       }
489       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
490         ++aNbDE;
491       }
492     }
493   }
494   //
495   if (!(aNbSE==1 && aNbDE==2)) {
496     return;
497   }
498   aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
499 }
500 //=======================================================================
501 //function : FillDetails
502 //purpose  : 
503 //=======================================================================
504   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
505                                              const gp_Cone& )//aCone)
506 {
507   Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
508   Standard_Real aR[3], aHeight;
509   gp_Pnt aPC[3], aPD, aPc, aPX[3];
510   TopoDS_Vertex aVD;
511   TopoDS_Edge aE;
512   TopoDS_Iterator aIt;
513   TopExp_Explorer aExp;
514   TopTools_MapOfShape aM;
515   GEOMAlgo_KindOfShape aKS, aKSE;
516   GEOMAlgo_KindOfName aKN, aKNE;
517   GEOMAlgo_KindOfClosed aKCE;
518   //
519   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
520   aKN=GEOMAlgo_KN_UNKNOWN;
521   aInfo.SetKindOfName(aKN);
522   //
523   aKS=aInfo.KindOfShape();
524   if (aKS!=GEOMAlgo_KS_CONE) {
525     return;
526   }
527   //
528   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
529     return;
530   }
531   //
532   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
533   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
534   if (!(aNbV==2 && aNbE==3)) {
535     return;
536   }
537   //
538   i=0;
539   aNbCE=0;
540   aNbSE=0;
541   aNbDE=0;
542   aExp.Init(aF, TopAbs_EDGE);
543   for (; aExp.More(); aExp.Next()) {
544     aE=TopoDS::Edge(aExp.Current());
545     if(aM.Add(aE)) {
546       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
547       aKNE=aInfoE.KindOfName();
548       aKCE=aInfoE.KindOfClosed();
549       aKSE=aInfoE.KindOfShape();
550       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
551         aPC[i]=aInfoE.Location();
552         aR[i]=aInfoE.Radius1();
553         //
554         aIt.Initialize(aE);
555         for (; aIt.More(); aIt.Next()) {
556           aVD=TopoDS::Vertex(aIt.Value());
557           break;
558         }
559         aPX[i]=BRep_Tool::Pnt(aVD);
560         //
561         ++i;
562         ++aNbCE;
563       }
564       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
565         if (BRep_Tool::IsClosed(aE, aF)) {
566           ++aNbSE;
567         }
568       }
569       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
570         aIt.Initialize(aE);
571         for (; aIt.More(); aIt.Next()) {
572           aVD=TopoDS::Vertex(aIt.Value());
573           break;
574         }
575         //
576         aPD=BRep_Tool::Pnt(aVD);
577         //
578         ++aNbDE;
579       }
580     }
581   }
582   //
583   if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
584     return;
585   }
586   //
587   if (aNbDE==1) {
588     aPC[1]=aPD;
589     aR[1]=0.;
590   }
591   //
592   aHeight=aPC[0].Distance(aPC[1]);
593   //
594   Standard_Real aRmin, aRmax;
595   gp_Ax2 aAx2new;
596   //
597   if (aR[0]>aR[1]) {
598     aRmin=aR[1];
599     aRmax=aR[0];
600     aPc=aPC[0];
601     gp_Vec aVz(aPC[0], aPC[1]);
602     gp_Vec aVx(aPC[0], aPX[0]);
603     gp_Dir aDz(aVz);
604     gp_Dir aDx(aVx);
605     gp_Ax2 aAx2(aPc, aDz, aDx);
606     aAx2new=aAx2;
607   }
608   else {
609     aRmin=aR[0];
610     aRmax=aR[1];
611     aPc=aPC[1];
612     gp_Vec aVz(aPC[1], aPC[0]);
613     gp_Vec aVx(aPC[1], aPX[1]);
614     gp_Dir aDz(aVz);
615     gp_Dir aDx(aVx);
616     gp_Ax2 aAx2(aPc, aDz, aDx);
617     aAx2new=aAx2;
618   }
619   //
620   gp_Ax3 aAx3(aAx2new);
621   aInfo.SetLocation(aPc);
622   aInfo.SetPosition(aAx3);
623   aInfo.SetRadius1(aRmax);
624   aInfo.SetRadius2(aRmin);
625   aInfo.SetHeight(aHeight);
626   //
627   aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
628 }
629 //=======================================================================
630 //function : FillDetails
631 //purpose  : 
632 //=======================================================================
633   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
634                                              const gp_Cylinder& aCyl)
635 {
636   Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
637   Standard_Real aT0, aT1, aHeight;
638   gp_Pnt aPC[3], aPc;
639   TopoDS_Edge aE;
640   TopExp_Explorer aExp;
641   TopTools_MapOfShape aM;
642   GEOMAlgo_KindOfShape aKS;
643   GEOMAlgo_KindOfName aKN, aKNE;
644   GEOMAlgo_KindOfClosed aKCE;
645   // 
646   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
647   aKN=GEOMAlgo_KN_UNKNOWN;
648   aInfo.SetKindOfName(aKN);
649   //
650   aKS=aInfo.KindOfShape();
651   if (aKS!=GEOMAlgo_KS_CYLINDER) {
652     return;
653   }
654   //
655   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
656     return;
657   }
658   //
659   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
660   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
661   if (!(aNbV==2 && aNbE==3)) {
662     return;
663   }
664   //
665   i=0;
666   aNbCE=0;
667   aNbSE=0;
668   aExp.Init(aF, TopAbs_EDGE);
669   for (; aExp.More(); aExp.Next()) {
670     aE=TopoDS::Edge(aExp.Current());
671     if(aM.Add(aE)) {
672       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
673       aKNE=aInfoE.KindOfName();
674       aKCE=aInfoE.KindOfClosed();
675       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
676         aPC[aNbCE]=aInfoE.Location();
677         ++aNbCE;
678       }
679       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
680         if (BRep_Tool::IsClosed(aE, aF)) {
681           ++aNbSE;
682         }
683       }
684     }
685   }
686   //
687   if (!(aNbCE==2 && aNbSE==1)) {
688     return;
689   }
690   //
691   const gp_Ax1& aAx1=aCyl.Axis();
692   const gp_Dir& aDir=aAx1.Direction();
693   const gp_Pnt& aPLoc=aAx1.Location();
694   gp_Lin aLin(aPLoc, aDir);
695   //
696   aT0=ElCLib::Parameter(aLin, aPC[0]);
697   aT1=ElCLib::Parameter(aLin, aPC[1]);
698   //
699   aPc=aPC[0];;
700   if (aT0>aT1) {
701     aPc=aPC[1];
702   }
703   aHeight=aPC[0].Distance(aPC[1]);
704   //
705   gp_Ax3 aAx3=aCyl.Position();
706   aAx3.SetLocation(aPc);
707   //
708   aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
709   aInfo.SetPosition(aAx3);
710   aInfo.SetLocation(aPc);
711   aInfo.SetHeight(aHeight);
712 }
713
714 //=======================================================================
715 //function : FillDetails
716 //purpose  : 
717 //=======================================================================
718   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
719                                              const gp_Torus& )
720 {
721   Standard_Integer aNbV, aNbE, aNbSE;
722   TopoDS_Edge aE; 
723   TopExp_Explorer aExp;
724   TopTools_MapOfShape aM; 
725   GEOMAlgo_KindOfShape aKS;
726   //
727   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
728   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
729   //
730   aKS=aInfo.KindOfShape();
731   if (aKS!=GEOMAlgo_KS_TORUS) {
732     return;
733   }
734   //
735   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
736   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
737   if (!(aNbV==1 && aNbE==2)) {
738     return;
739   }
740   //
741   aNbSE=0;
742   aExp.Init(aF, TopAbs_EDGE);
743   for (; aExp.More(); aExp.Next()) {
744     aE=TopoDS::Edge(aExp.Current());
745     if (aM.Add(aE)) {
746       //const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
747       if (BRep_Tool::IsClosed(aE, aF)) {
748         ++aNbSE;
749       }
750     }
751   }
752   //
753   if (aNbSE!=2) {
754     return;
755   }
756   aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);
757 }