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