Salome HOME
Merge from BR_Dev_For_4_0 branch (from tag mergeto_BR_QT4_Dev_17Jan08)
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_ShapeInfoFiller.cxx
1 #include <GEOMAlgo_ShapeInfoFiller.ixx>
2
3 #include <Precision.hxx>
4
5 #include <gp_Lin.hxx>
6 #include <gp_Pnt.hxx>
7 #include <gp_Dir.hxx>
8
9 #include <Geom_Curve.hxx>
10 #include <GeomAdaptor_Curve.hxx>
11
12 #include <TopoDS_Vertex.hxx>
13 #include <TopoDS.hxx>
14 #include <TopoDS_Edge.hxx>
15
16 #include <BRep_Tool.hxx>
17 #include <TopExp.hxx>
18
19 #include <TopTools_IndexedMapOfShape.hxx>
20 #include <gp_Circ.hxx>
21 #include <gp_Ax2.hxx>
22 #include <gp_Elips.hxx>
23 #include <TopoDS_Iterator.hxx>
24 #include <TopoDS_Wire.hxx>
25 #include <TopExp.hxx>
26 #include <Geom_Surface.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <GeomAdaptor_Surface.hxx>
29 #include <gp_Pln.hxx>
30 #include <gp_Sphere.hxx>
31 #include <gp_Ax3.hxx>
32 #include <BRepTools.hxx>
33 #include <gp_Cylinder.hxx>
34 #include <gp_Cone.hxx>
35 #include <gp_Torus.hxx>
36 #include <TopoDS_Solid.hxx>
37
38
39
40
41 static 
42   Standard_Boolean IsAllowedType(const GeomAbs_CurveType aCT);
43 static
44   Standard_Boolean IsAllowedType(const GeomAbs_SurfaceType aST);
45 static
46   Standard_Integer NbWires(const TopoDS_Face& aF);
47 static
48   Standard_Integer NbShells(const TopoDS_Solid& aS);
49
50 //=======================================================================
51 //function : 
52 //purpose  : 
53 //=======================================================================
54   GEOMAlgo_ShapeInfoFiller::GEOMAlgo_ShapeInfoFiller()
55 :
56   GEOMAlgo_Algo()
57 {
58   myTolerance=0.0001;
59 }
60 //=======================================================================
61 //function : ~
62 //purpose  : 
63 //=======================================================================
64   GEOMAlgo_ShapeInfoFiller::~GEOMAlgo_ShapeInfoFiller()
65 {
66 }
67 //=======================================================================
68 //function : SetTolerance
69 //purpose  : 
70 //=======================================================================
71   void GEOMAlgo_ShapeInfoFiller::SetTolerance(const Standard_Real aT)
72 {
73   myTolerance=aT;
74 }
75 //=======================================================================
76 //function : Tolerance
77 //purpose  : 
78 //=======================================================================
79   Standard_Real GEOMAlgo_ShapeInfoFiller::Tolerance()const
80 {
81   return myTolerance;
82 }
83 //=======================================================================
84 //function : SetShape
85 //purpose  : 
86 //=======================================================================
87   void GEOMAlgo_ShapeInfoFiller::SetShape(const TopoDS_Shape& aS) 
88 {
89   myShape=aS;
90 }
91 //=======================================================================
92 //function : Shape
93 //purpose  : 
94 //=======================================================================
95   const TopoDS_Shape& GEOMAlgo_ShapeInfoFiller::Shape() const
96 {
97   return myShape;
98 }
99 //=======================================================================
100 //function : Info
101 //purpose  : 
102 //=======================================================================
103   const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info() const
104 {
105   return Info(myShape); 
106 }
107 //=======================================================================
108 //function : Info
109 //purpose  : 
110 //=======================================================================
111   const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info(const TopoDS_Shape& aS) const
112 {
113   if (!aS.IsNull()) {
114     if (myMapInfo.Contains(aS)) {
115       const GEOMAlgo_ShapeInfo& aInfo=myMapInfo.FindFromKey(aS);
116       return aInfo;
117     }
118   }
119   return myEmptyInfo; 
120 }
121
122 //=======================================================================
123 //function : CheckData
124 //purpose  : 
125 //=======================================================================
126   void GEOMAlgo_ShapeInfoFiller::CheckData()
127 {
128   myErrorStatus=0;
129   //
130   if (myShape.IsNull()) {
131     myErrorStatus=10;
132     return;
133   }
134 }
135 //=======================================================================
136 //function : Perform
137 //purpose  : 
138 //=======================================================================
139   void GEOMAlgo_ShapeInfoFiller::Perform() 
140 {
141   myErrorStatus=0;
142   //
143   myMapInfo.Clear();
144   //
145   CheckData();
146   if (myErrorStatus) {
147     return;
148   }
149   //
150   FillShape(myShape);
151 }
152 //=======================================================================
153 //function :FillShape 
154 //purpose  : 
155 //=======================================================================
156   void GEOMAlgo_ShapeInfoFiller::FillShape(const TopoDS_Shape& aS)
157 {
158   TopAbs_ShapeEnum aType;
159   //
160   aType=aS.ShapeType();
161   switch(aType) {
162     //
163     case TopAbs_VERTEX:
164       FillVertex(aS);
165       break;
166     //  
167     case TopAbs_EDGE:
168       FillEdge(aS);
169       break;
170     //
171     case TopAbs_FACE:
172       FillFace(aS);
173       break;
174     //
175     case TopAbs_SOLID:
176       FillSolid(aS);
177       break;
178     //
179     case TopAbs_WIRE:
180     case TopAbs_SHELL:
181     case TopAbs_COMPSOLID:
182     case TopAbs_COMPOUND:
183       FillContainer(aS);
184       break;
185     // 
186     default:
187       break;
188   }
189 }
190 //=======================================================================
191 //function :FillSubShapes 
192 //purpose  : 
193 //=======================================================================
194   void GEOMAlgo_ShapeInfoFiller::FillSubShapes(const TopoDS_Shape& aS)
195 {
196   TopoDS_Iterator aIt;
197   //
198   aIt.Initialize(aS);
199   for (; aIt.More(); aIt.Next()){
200     const TopoDS_Shape& aSx=aIt.Value();
201     FillShape(aSx);
202   }
203 }
204 //=======================================================================
205 //function : FillContainer
206 //purpose  : 
207 //=======================================================================
208   void GEOMAlgo_ShapeInfoFiller::FillContainer(const TopoDS_Shape& aS) 
209 {
210   myErrorStatus=0;
211   //
212   Standard_Boolean bIsClosed;
213   TopAbs_ShapeEnum aType;
214   GEOMAlgo_KindOfClosed aKC;
215   //
216   aType=aS.ShapeType();
217   //----------------------------------------------------
218   if (myMapInfo.Contains(aS)) {
219     return;
220   }
221   else {
222     GEOMAlgo_ShapeInfo aInfoX;
223     myMapInfo.Add(aS, aInfoX);
224   }
225   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
226   //----------------------------------------------------
227   aInfo.SetType(aType);
228   FillNbSubShapes(aS, aInfo);
229   //
230   if (aType==TopAbs_SHELL) {
231     bIsClosed=BRep_Tool::IsClosed(aS);
232     aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
233     aInfo.SetKindOfClosed(aKC);
234   }
235   else if (aType==TopAbs_WIRE) {
236     TopoDS_Wire aW;
237     TopoDS_Vertex aV1, aV2;
238     //
239     aW=TopoDS::Wire(aS);
240     TopExp::Vertices(aW, aV1, aV2);
241     //
242     bIsClosed=aV1.IsSame(aV2);
243     aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
244     aInfo.SetKindOfClosed(aKC);
245   }
246   //
247   FillSubShapes(aS);
248 }
249 //=======================================================================
250 //function : FillSolid
251 //purpose  : 
252 //=======================================================================
253   void GEOMAlgo_ShapeInfoFiller::FillSolid(const TopoDS_Shape& aS) 
254 {
255   Standard_Integer aNbShells;
256   TopoDS_Solid aSd;
257   //
258   myErrorStatus=0;
259   //----------------------------------------------------
260   if (myMapInfo.Contains(aS)) {
261     return;
262   }
263   else {
264     GEOMAlgo_ShapeInfo aInfoX;
265     myMapInfo.Add(aS, aInfoX);
266   }
267   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
268   //----------------------------------------------------
269   aInfo.SetType(TopAbs_SOLID);
270   FillNbSubShapes(aS, aInfo);
271   FillSubShapes(aS);
272   //
273   aSd=TopoDS::Solid(aS);
274   //
275   aNbShells=NbShells(aSd);
276   if (aNbShells>1) {
277     return;
278   }
279   //
280   FillDetails(aSd);
281 }
282 //=======================================================================
283 //function :FillFace 
284 //purpose  : 
285 //=======================================================================
286   void GEOMAlgo_ShapeInfoFiller::FillFace(const TopoDS_Shape& aS) 
287 {
288   myErrorStatus=0;
289   //
290   Standard_Boolean bIsAllowedType;
291   Standard_Integer aNbWires;//, iRet 
292   Standard_Boolean bInf, bInfU1, bInfU2, bInfV1, bInfV2;
293   Standard_Real aUMin, aUMax, aVMin, aVMax, aR1, aR2;
294   gp_Pnt aP0; 
295   gp_Dir aDN;
296   gp_Ax3 aAx3;
297   GeomAbs_SurfaceType aST;
298   Handle(Geom_Surface) aSurf;
299   TopoDS_Face aF;
300   //GEOMAlgo_KindOfName aKindOfName;
301   //----------------------------------------------------
302   if (myMapInfo.Contains(aS)) {
303     return;
304   }
305   else {
306     GEOMAlgo_ShapeInfo aInfoX;
307     myMapInfo.Add(aS, aInfoX);
308   }
309   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
310   //----------------------------------------------------
311   aInfo.SetType(TopAbs_FACE);
312   //
313   FillNbSubShapes(aS, aInfo);
314   //
315   FillSubShapes(aS);
316   //
317   aF=TopoDS::Face(aS);
318   //
319   aNbWires=NbWires(aF);
320   //
321   aSurf=BRep_Tool::Surface(aF);
322   GeomAdaptor_Surface aGAS(aSurf);
323   aST=aGAS.GetType();
324   bIsAllowedType=IsAllowedType(aST);
325   if (!bIsAllowedType) {
326     return;
327   }
328   //
329   // 1. Plane
330   if (aST==GeomAbs_Plane) {
331     gp_Pln aPln;
332     //
333     aPln=aGAS.Plane();
334     aP0=aPln.Location();
335     aAx3=aPln.Position();
336     //
337     aInfo.SetKindOfShape(GEOMAlgo_KS_PLANE);
338     aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
339     aInfo.SetLocation(aP0);
340     aInfo.SetPosition(aAx3);
341     //
342     if (aNbWires>1) return;
343     //
344     //aSurf->Bounds(aUMin, aUMax, aVMin, aVMax);
345     BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
346     bInfU1=Precision::IsNegativeInfinite(aUMin);
347     bInfU2=Precision::IsPositiveInfinite(aUMax);
348     bInfV1=Precision::IsNegativeInfinite(aVMin);
349     bInfV2=Precision::IsPositiveInfinite(aVMax);
350     //
351     bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
352     if (bInf) {
353       aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
354     }
355     else {
356       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
357     }
358     //
359     FillDetails(aF, aPln);
360   }// if (aCT==GeomAbs_Line) {
361   //
362   // 2. Sphere
363   else if (aST==GeomAbs_Sphere) {
364     gp_Sphere aSphere;
365     //
366     aSphere=aGAS.Sphere();
367     aP0=aSphere.Location();
368     aAx3=aSphere.Position();
369     aR1=aSphere.Radius();
370     //
371     aInfo.SetKindOfShape(GEOMAlgo_KS_SPHERE);
372     aInfo.SetLocation(aP0);
373     aInfo.SetPosition(aAx3);
374     aInfo.SetRadius1(aR1);
375     //
376     if (aNbWires>1) return;
377     //
378     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
379     aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
380     //
381     FillDetails(aF, aSphere);
382   }// else if (aST==GeomAbs_Sphere) {
383   // 
384   // 3. Cylinder
385   else if (aST==GeomAbs_Cylinder) {
386     gp_Cylinder aCyl;
387     //
388     aCyl=aGAS.Cylinder();
389     aP0=aCyl.Location();
390     aAx3=aCyl.Position();
391     aR1=aCyl.Radius();
392     //
393     aInfo.SetKindOfShape(GEOMAlgo_KS_CYLINDER);
394     aInfo.SetLocation(aP0);
395     aInfo.SetPosition(aAx3);
396     aInfo.SetRadius1(aR1);
397     //
398     if (aNbWires>1) return;
399     //
400     BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
401     bInfU1=Precision::IsNegativeInfinite(aUMin);
402     bInfU2=Precision::IsPositiveInfinite(aUMax);
403     bInfV1=Precision::IsNegativeInfinite(aVMin);
404     bInfV2=Precision::IsPositiveInfinite(aVMax);
405     //
406     bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
407     if (bInf) {
408       aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
409     }
410     else {
411       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
412     }
413     FillDetails(aF, aCyl);
414   }
415   // 
416   // 4. Cone
417   else if (aST==GeomAbs_Cone) {
418     gp_Cone aCone;
419     //
420     aCone=aGAS.Cone();
421     aP0=aCone.Location();
422     aAx3=aCone.Position();
423     //aR1=aCyl.Radius();
424     //
425     aInfo.SetKindOfShape(GEOMAlgo_KS_CONE);
426     aInfo.SetLocation(aP0);
427     aInfo.SetPosition(aAx3);
428     //aInfo.SetRadius1(aR1);
429     //
430     if (aNbWires>1) return;
431     //
432     BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
433     bInfU1=Precision::IsNegativeInfinite(aUMin);
434     bInfU2=Precision::IsPositiveInfinite(aUMax);
435     bInfV1=Precision::IsNegativeInfinite(aVMin);
436     bInfV2=Precision::IsPositiveInfinite(aVMax);
437     //
438     bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
439     if (bInf) {
440       aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
441     }
442     else {
443       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
444     }
445     FillDetails(aF, aCone);
446   }
447   // 
448   // 5. Torus
449   else if (aST==GeomAbs_Torus) {
450     gp_Torus aTorus;
451     //
452     aTorus=aGAS.Torus();
453     aP0=aTorus.Location();
454     aAx3=aTorus.Position();
455     aR1=aTorus.MajorRadius();
456     aR2=aTorus.MinorRadius();
457     //
458     aInfo.SetKindOfShape(GEOMAlgo_KS_TORUS);
459     aInfo.SetLocation(aP0);
460     aInfo.SetPosition(aAx3);
461     aInfo.SetRadius1(aR1);
462     aInfo.SetRadius2(aR2);
463     //
464     if (aNbWires>1) return;
465     //
466     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
467     //
468     FillDetails(aF, aTorus);
469   }
470 }
471 //=======================================================================
472 //function :FillEdge 
473 //purpose  : 
474 //=======================================================================
475   void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS) 
476 {
477   myErrorStatus=0;
478   //
479   Standard_Boolean bDegenerated, bIsAllowedType;
480   Standard_Integer aNbV;
481   Standard_Real aR1, aR2;
482   gp_Pnt aP, aP1, aP2, aPc;
483   gp_Dir aD;
484   gp_Ax2 aAx2;
485   Standard_Real aT1, aT2;
486   GeomAbs_CurveType aCT;
487   Handle(Geom_Curve) aC3D;
488   TopoDS_Edge aE;
489   //----------------------------------------------------
490   if (myMapInfo.Contains(aS)) {
491     return;
492   }
493   else {
494     GEOMAlgo_ShapeInfo aInfoX;
495     myMapInfo.Add(aS, aInfoX);
496   }
497   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
498   //----------------------------------------------------
499   aInfo.SetType(TopAbs_EDGE);
500   //
501   FillNbSubShapes(aS, aInfo);
502   //
503   aE=TopoDS::Edge(aS);
504   //
505   bDegenerated=BRep_Tool::Degenerated(aE);
506   if (bDegenerated) {
507     aInfo.SetKindOfShape(GEOMAlgo_KS_DEGENERATED);
508     FillSubShapes(aS);
509     return;
510   }
511   //
512   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
513   GeomAdaptor_Curve aGAC(aC3D);
514   aCT=aGAC.GetType();
515   bIsAllowedType=IsAllowedType(aCT);
516   if (!bIsAllowedType) {
517     FillSubShapes(aS);
518     return;
519   }
520   // Line
521   if (aCT==GeomAbs_Line) {
522     Standard_Boolean bInf1, bInf2;
523     Standard_Real aLength;
524     gp_Lin aLin;
525     gp_XYZ aXYZ1, aXYZ2, aXYZc;
526     //
527     aLin=aGAC.Line();
528     aP=aLin.Location();
529     aD=aLin.Direction();
530     //
531     aInfo.SetKindOfShape(GEOMAlgo_KS_LINE);
532     aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
533     aInfo.SetLocation(aP);
534     aInfo.SetDirection(aD);
535     //
536     bInf1=Precision::IsNegativeInfinite(aT1);
537     bInf2=Precision::IsPositiveInfinite(aT2);
538     if (bInf1||bInf2) {
539       aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
540       aInfo.SetKindOfName(GEOMAlgo_KN_LINE);
541     }
542     else {
543       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
544       aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
545       aGAC.D0(aT1, aP1);
546       aGAC.D0(aT2, aP2);
547       aInfo.SetPnt1(aP1);
548       aInfo.SetPnt2(aP2);
549       //
550       aLength=aP1.Distance(aP2);
551       aXYZ1=aP1.XYZ();
552       aXYZ2=aP2.XYZ();
553       aXYZc=aXYZ1+aXYZ2;
554       aXYZc.Multiply(0.5);
555       //
556       aPc.SetXYZ(aXYZc);
557       gp_Vec aVec(aPc, aP2);
558       gp_Dir aDir(aVec);
559       //
560       aInfo.SetLocation(aPc);
561       aInfo.SetDirection(aDir);
562       aInfo.SetLength(aLength);
563     }
564   }// if (aCT==GeomAbs_Line) {
565   //
566   // Circle
567   else if (aCT==GeomAbs_Circle) {
568     gp_Circ aCirc;
569     //
570     aCirc=aGAC.Circle();
571     aP=aCirc.Location();
572     aAx2=aCirc.Position();
573     aR1=aCirc.Radius();
574     //
575     aInfo.SetKindOfShape(GEOMAlgo_KS_CIRCLE);
576     aInfo.SetLocation(aP);
577     aInfo.SetPosition(aAx2);
578     aInfo.SetRadius1(aR1);
579     //
580     aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
581     if (!aNbV) {
582       myErrorStatus=11; // circle edge without vertices
583       return;
584     }
585     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
586     aGAC.D0(aT1, aP1);
587     aGAC.D0(aT2, aP2);
588     aInfo.SetPnt1(aP1);
589     aInfo.SetPnt2(aP2);
590     //
591     if (aNbV==1) {
592       aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
593       aInfo.SetKindOfName(GEOMAlgo_KN_CIRCLE);
594     }
595     else {
596       aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
597       aInfo.SetKindOfName(GEOMAlgo_KN_ARCCIRCLE);
598       //
599       gp_Vec aVecX(aP, aP1);
600       gp_Dir aDirX(aVecX); 
601       gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
602       aInfo.SetPosition(aAx2new);
603     }
604   }// else if (aCT==GeomAbs_Circle) {
605   //
606   // Ellipse
607   else if (aCT==GeomAbs_Ellipse) {
608     gp_Elips aElips;
609     //
610     aElips=aGAC.Ellipse();
611     aP=aElips.Location();
612     aAx2=aElips.Position();
613     aR1=aElips.MajorRadius();
614     aR2=aElips.MinorRadius();
615     //
616     aInfo.SetKindOfShape(GEOMAlgo_KS_ELLIPSE);
617     aInfo.SetLocation(aP);
618     aInfo.SetPosition(aAx2);
619     aInfo.SetRadius1(aR1);
620     aInfo.SetRadius2(aR2);
621     //
622     aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
623     if (!aNbV) {
624       myErrorStatus=11; // ellipse edge without vertices
625       return;
626     }
627     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
628     aGAC.D0(aT1, aP1);
629     aGAC.D0(aT2, aP2);
630     aInfo.SetPnt1(aP1);
631     aInfo.SetPnt2(aP2);
632     //
633     if (aNbV==1) {
634       aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
635       aInfo.SetKindOfName(GEOMAlgo_KN_ELLIPSE);
636     }
637     else {
638       aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
639       aInfo.SetKindOfName(GEOMAlgo_KN_ARCELLIPSE);
640       //
641       gp_Vec aVecX(aP, aP1);
642       gp_Dir aDirX(aVecX); 
643       gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
644       aInfo.SetPosition(aAx2new);
645     }
646   }// else if (aCT==GeomAbs_Ellipse) {
647   //
648   FillSubShapes(aS);
649 }
650 //=======================================================================
651 //function :FillVertex 
652 //purpose  : 
653 //=======================================================================
654   void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS) 
655 {
656   myErrorStatus=0;
657   //
658   gp_Pnt aP;
659   TopoDS_Vertex aV;
660   //
661   if (myMapInfo.Contains(aS)) {
662     return;
663   }
664   else {
665     GEOMAlgo_ShapeInfo aInfoX;
666     myMapInfo.Add(aS, aInfoX);
667   }
668   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
669   //
670   aV=TopoDS::Vertex(aS);
671   aP=BRep_Tool::Pnt(aV);
672   //
673   aInfo.SetType(TopAbs_VERTEX);
674   aInfo.SetLocation(aP);
675   myMapInfo.Add(aS, aInfo);
676 }
677 //=======================================================================
678 //function : FillNbSubshapes
679 //purpose  : 
680 //=======================================================================
681   void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS,
682                                                  GEOMAlgo_ShapeInfo& aInfo)
683 {
684   myErrorStatus=0;
685   //
686   Standard_Integer i, aNb, aNbS;
687   TopTools_IndexedMapOfShape aM;
688   TopAbs_ShapeEnum aST; 
689   TopAbs_ShapeEnum aTypes[]= {
690     //TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX
691     TopAbs_COMPOUND,
692     TopAbs_COMPSOLID,
693     TopAbs_SOLID,
694     TopAbs_SHELL,
695     TopAbs_FACE,
696     TopAbs_WIRE,
697     TopAbs_EDGE,
698     TopAbs_VERTEX
699   };
700   
701   //
702   aST=aS.ShapeType();
703   aNb=sizeof(aTypes)/sizeof(aTypes[0]);
704   for (i=0; i<aNb; ++i) {
705     if (aTypes[i]==aST) {
706       continue;
707     }
708     aM.Clear();
709     TopExp::MapShapes(aS, aTypes[i], aM);
710     aNbS=aM.Extent();
711     aInfo.SetNbSubShapes(aTypes[i], aNbS);
712   }
713 }
714 //=======================================================================
715 //function :NbShells 
716 //purpose  : 
717 //=======================================================================
718 Standard_Integer NbShells(const TopoDS_Solid& aSd)
719 {
720   Standard_Integer iCnt;
721   TopoDS_Iterator aIt;
722   //
723   iCnt=0;
724   //
725   aIt.Initialize(aSd);
726   for (; aIt.More(); aIt.Next()){
727     //const TopoDS_Shape& aSh=aIt.Value();
728     ++iCnt;
729   }
730   return iCnt;
731 }
732 //=======================================================================
733 //function : NbWires
734 //purpose  : 
735 //=======================================================================
736 Standard_Integer NbWires(const TopoDS_Face& aF)
737 {
738   Standard_Integer iCnt;
739   TopoDS_Iterator aIt;
740   //
741   iCnt=0;
742   //
743   aIt.Initialize(aF);
744   for (; aIt.More(); aIt.Next()){
745     //const TopoDS_Shape& aW=aIt.Value();
746     ++iCnt;
747   }
748   return iCnt;
749 }
750 //=======================================================================
751 //function : IsAllowedType
752 //purpose  : 
753 //=======================================================================
754 Standard_Boolean IsAllowedType(const GeomAbs_CurveType aCT)
755 {
756   Standard_Boolean bRet;
757   Standard_Integer i, aNb;
758   GeomAbs_CurveType aTypes[]={
759     GeomAbs_Line, GeomAbs_Circle, GeomAbs_Ellipse
760   };
761   //
762   bRet=Standard_False;
763   aNb=sizeof(aTypes)/sizeof(aTypes[0]);
764   for (i=0; i<aNb && !bRet; ++i) {
765     bRet=(aCT==aTypes[i]);
766   }
767   //
768   return bRet;
769 }
770 //=======================================================================
771 //function : IsAllowedType
772 //purpose  : 
773 //=======================================================================
774 Standard_Boolean IsAllowedType(const GeomAbs_SurfaceType aST)
775 {
776   Standard_Boolean bRet;
777   Standard_Integer i, aNb;
778   GeomAbs_SurfaceType aTypes[]={
779     GeomAbs_Plane, GeomAbs_Cylinder, 
780     GeomAbs_Cone,  GeomAbs_Sphere,
781     GeomAbs_Torus
782   };
783   //
784   bRet=Standard_False;
785   aNb=sizeof(aTypes)/sizeof(aTypes[0]);
786   for (i=0; i<aNb && !bRet; ++i) {
787     bRet=(aST==aTypes[i]);
788   }
789   //
790   return bRet;
791 }
792 //
793 // myErrorStatus
794 // 
795 // 0  - Ok
796 // 1  - The object is just initialized
797 //
798 // 10 - Null shape 
799 // 11 - circle/ellipse edge without vertices