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