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