Salome HOME
[bos #41409][FORUM] (2024) kindOfShape() bug for CONE2D
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_ShapeInfoFiller.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, 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 #include <gp_Hypr.hxx>
37 #include <gp_Parab.hxx>
38
39 #include <Geom_Curve.hxx>
40 #include <Geom_Surface.hxx>
41 #include <Geom_BSplineCurve.hxx>
42 #include <Geom_BezierCurve.hxx>
43
44 #include <GeomAdaptor_Curve.hxx>
45 #include <GeomAdaptor_Surface.hxx>
46
47 #include <TopoDS.hxx>
48 #include <TopoDS_Edge.hxx>
49 #include <TopoDS_Solid.hxx>
50 #include <TopoDS_Vertex.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopoDS_Wire.hxx>
53 #include <TopoDS_Face.hxx>
54
55 #include <BRep_Tool.hxx>
56 #include <TopExp.hxx>
57 #include <BRepTools.hxx>
58
59 #include <TopTools_IndexedMapOfShape.hxx>
60
61 //=======================================================================
62 //function :
63 //purpose  :
64 //=======================================================================
65 GEOMAlgo_ShapeInfoFiller::GEOMAlgo_ShapeInfoFiller()
66 :
67   GEOMAlgo_Algo()
68 {
69   myTolerance=0.0001;
70 }
71 //=======================================================================
72 //function : ~
73 //purpose  :
74 //=======================================================================
75 GEOMAlgo_ShapeInfoFiller::~GEOMAlgo_ShapeInfoFiller()
76 {
77 }
78 //=======================================================================
79 //function : SetTolerance
80 //purpose  :
81 //=======================================================================
82 void GEOMAlgo_ShapeInfoFiller::SetTolerance(const Standard_Real aT)
83 {
84   myTolerance=aT;
85 }
86 //=======================================================================
87 //function : Tolerance
88 //purpose  :
89 //=======================================================================
90 Standard_Real GEOMAlgo_ShapeInfoFiller::Tolerance()const
91 {
92   return myTolerance;
93 }
94 //=======================================================================
95 //function : SetShape
96 //purpose  :
97 //=======================================================================
98 void GEOMAlgo_ShapeInfoFiller::SetShape(const TopoDS_Shape& aS)
99 {
100   myShape=aS;
101 }
102 //=======================================================================
103 //function : Shape
104 //purpose  :
105 //=======================================================================
106 const TopoDS_Shape& GEOMAlgo_ShapeInfoFiller::Shape() const
107 {
108   return myShape;
109 }
110 //=======================================================================
111 //function : Info
112 //purpose  :
113 //=======================================================================
114 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info() const
115 {
116   return Info(myShape);
117 }
118 //=======================================================================
119 //function : Info
120 //purpose  :
121 //=======================================================================
122 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info
123   (const TopoDS_Shape& aS) const
124 {
125   if (!aS.IsNull()) {
126     if (myMapInfo.Contains(aS)) {
127       const GEOMAlgo_ShapeInfo& aInfo=myMapInfo.FindFromKey(aS);
128       return aInfo;
129     }
130   }
131   return myEmptyInfo;
132 }
133
134 //=======================================================================
135 //function : CheckData
136 //purpose  :
137 //=======================================================================
138 void GEOMAlgo_ShapeInfoFiller::CheckData()
139 {
140   myErrorStatus=0;
141   //
142   if (myShape.IsNull()) {
143     myErrorStatus=10;
144     return;
145   }
146 }
147 //=======================================================================
148 //function : Perform
149 //purpose  :
150 //=======================================================================
151 void GEOMAlgo_ShapeInfoFiller::Perform()
152 {
153   myErrorStatus=0;
154   //
155   myMapInfo.Clear();
156   //
157   CheckData();
158   if (myErrorStatus) {
159     return;
160   }
161   //
162   FillShape(myShape);
163 }
164 //=======================================================================
165 //function :FillShape
166 //purpose  :
167 //=======================================================================
168 void GEOMAlgo_ShapeInfoFiller::FillShape(const TopoDS_Shape& aS)
169 {
170   TopAbs_ShapeEnum aType;
171   //
172   aType=aS.ShapeType();
173   switch(aType) {
174     //
175     case TopAbs_VERTEX:
176       FillVertex(aS);
177       break;
178     //
179     case TopAbs_EDGE:
180       FillEdge(aS);
181       break;
182     //
183     case TopAbs_FACE:
184       FillFace(aS);
185       break;
186     //
187     case TopAbs_SOLID:
188       FillSolid(aS);
189       break;
190     //
191     case TopAbs_WIRE:
192     case TopAbs_SHELL:
193     case TopAbs_COMPSOLID:
194     case TopAbs_COMPOUND:
195       FillContainer(aS);
196       break;
197     //
198     default:
199       break;
200   }
201 }
202 //=======================================================================
203 //function :FillSubShapes
204 //purpose  :
205 //=======================================================================
206 void GEOMAlgo_ShapeInfoFiller::FillSubShapes(const TopoDS_Shape& aS)
207 {
208   TopoDS_Iterator aIt;
209   //
210   aIt.Initialize(aS);
211   for (; aIt.More(); aIt.Next()) {
212     const TopoDS_Shape& aSx=aIt.Value();
213     FillShape(aSx);
214   }
215 }
216 //=======================================================================
217 //function : FillContainer
218 //purpose  :
219 //=======================================================================
220 void GEOMAlgo_ShapeInfoFiller::FillContainer(const TopoDS_Shape& aS)
221 {
222   myErrorStatus=0;
223   //
224   Standard_Boolean bIsClosed;
225   TopAbs_ShapeEnum aType;
226   GEOMAlgo_KindOfClosed aKC;
227   //
228   aType=aS.ShapeType();
229   //----------------------------------------------------
230   if (myMapInfo.Contains(aS)) {
231     return;
232   }
233   else {
234     GEOMAlgo_ShapeInfo aInfoX;
235     myMapInfo.Add(aS, aInfoX);
236   }
237   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
238   //----------------------------------------------------
239   aInfo.SetType(aType);
240   FillNbSubShapes(aS, aInfo);
241   //
242   if (aType==TopAbs_SHELL) {
243     bIsClosed=BRep_Tool::IsClosed(aS);
244     aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
245     aInfo.SetKindOfClosed(aKC);
246   }
247   else if (aType==TopAbs_WIRE) {
248     TopoDS_Wire aW;
249     TopoDS_Vertex aV1, aV2;
250     //
251     aW=TopoDS::Wire(aS);
252     TopExp::Vertices(aW, aV1, aV2);
253     //
254     bIsClosed=aV1.IsSame(aV2);
255     aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
256     aInfo.SetKindOfClosed(aKC);
257   }
258   //
259   FillSubShapes(aS);
260 }
261 //=======================================================================
262 //function : FillSolid
263 //purpose  :
264 //=======================================================================
265 void GEOMAlgo_ShapeInfoFiller::FillSolid(const TopoDS_Shape& aS)
266 {
267   TopoDS_Solid aSd;
268   //
269   myErrorStatus=0;
270   //----------------------------------------------------
271   if (myMapInfo.Contains(aS)) {
272     return;
273   }
274   else {
275     GEOMAlgo_ShapeInfo aInfoX;
276     myMapInfo.Add(aS, aInfoX);
277   }
278   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
279   //----------------------------------------------------
280   aInfo.SetType(TopAbs_SOLID);
281   FillNbSubShapes(aS, aInfo);
282   FillSubShapes(aS);
283   //
284   aSd=TopoDS::Solid(aS);
285   //
286   FillDetails(aSd);
287 }
288 //=======================================================================
289 //function :FillFace
290 //purpose  :
291 //=======================================================================
292 void GEOMAlgo_ShapeInfoFiller::FillFace(const TopoDS_Shape& aS)
293 {
294   myErrorStatus=0;
295   if (myMapInfo.Contains(aS)) {
296     return;
297   }
298   //
299   Standard_Boolean bIsAllowedType;
300   Standard_Boolean bInf, bInfU1, bInfU2, bInfV1, bInfV2;
301   Standard_Real aUMin, aUMax, aVMin, aVMax, aR1, aR2, dV;
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   //----------------------------------------------------
309   GEOMAlgo_ShapeInfo aInfoX;
310   myMapInfo.Add(aS, aInfoX);
311   //
312   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
313   //----------------------------------------------------
314   aInfo.SetType(TopAbs_FACE);
315   //
316   FillNbSubShapes(aS, aInfo);
317   //
318   FillSubShapes(aS);
319   //
320   aF=TopoDS::Face(aS);
321   //
322   aSurf=BRep_Tool::Surface(aF);
323   GeomAdaptor_Surface aGAS(aSurf);
324   aST=aGAS.GetType();
325   bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aST);
326   if (!bIsAllowedType) {
327     return;
328   }
329   //
330   //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
331   // 1. Plane
332   if (aST==GeomAbs_Plane) {
333     gp_Pln aPln;
334     //
335     aPln=aGAS.Plane();
336     aP0=aPln.Location();
337     aAx3=aPln.Position();
338     //
339     aInfo.SetKindOfShape(GEOMAlgo_KS_PLANE);
340     aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
341     aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
342     aInfo.SetLocation(aP0);
343     aInfo.SetPosition(aAx3);
344     //
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       return;
355     }
356     //
357     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
358     //
359     FillDetails(aF, aPln);
360   }// if (aCT==GeomAbs_Line) {
361   //
362   //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
363   // 2. Sphere
364   else if (aST==GeomAbs_Sphere) {
365     gp_Sphere aSphere;
366     //
367     aSphere=aGAS.Sphere();
368     aP0=aSphere.Location();
369     aAx3=aSphere.Position();
370     aR1=aSphere.Radius();
371     //
372     aInfo.SetKindOfShape(GEOMAlgo_KS_SPHERE);
373     aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
374     aInfo.SetLocation(aP0);
375     aInfo.SetPosition(aAx3);
376     aInfo.SetRadius1(aR1);
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   //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
385   // 3. Cylinder
386   else if (aST==GeomAbs_Cylinder) {
387     gp_Cylinder aCyl;
388     //
389     aCyl=aGAS.Cylinder();
390     aP0=aCyl.Location();
391     aAx3=aCyl.Position();
392     aR1=aCyl.Radius();
393     //
394     aInfo.SetKindOfShape(GEOMAlgo_KS_CYLINDER);
395     aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
396     aInfo.SetLocation(aP0);
397     aInfo.SetPosition(aAx3);
398     aInfo.SetRadius1(aR1);
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       return;
410     }
411     //
412     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
413     //
414     dV=aVMax-aVMin;
415     aInfo.SetHeight(dV);
416     //
417     FillDetails(aF, aCyl);
418   }
419   //
420   //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
421   // 4. Cone
422   else if (aST==GeomAbs_Cone) {
423     const gp_Cone aCone=aGAS.Cone();
424     //
425     aInfo.SetKindOfShape(GEOMAlgo_KS_CONE);
426     aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
427     //
428     BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
429
430     bInfU1=Precision::IsNegativeInfinite(aUMin);
431     bInfU2=Precision::IsPositiveInfinite(aUMax);
432     bInfV1=Precision::IsNegativeInfinite(aVMin);
433     bInfV2=Precision::IsPositiveInfinite(aVMax);
434     //
435     bInf=bInfV1 || bInfV2;
436     if (bInf) {
437       aP0=aAx3.Location();
438       aAx3=aCone.Position();
439       aInfo.SetLocation(aP0);
440       aInfo.SetPosition(aAx3);
441       aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
442       return;
443     }
444     //
445     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
446     //
447     const Standard_Real aSemiAngle = aCone.SemiAngle();
448
449     dV = aVMax - aVMin;
450     Standard_Real H = dV * std::cos(aSemiAngle);
451
452     aAx3 = aCone.Position();
453     Standard_Real aShiftAlongAxisLength = aVMin * std::cos(aSemiAngle); // Required, because R1 does not equal to gp_Cone.RefRadius() in general case, and gp_Cone.Location() corresponds to the latter one.
454     auto aShiftAlongAxis = gp_Vec(aAx3.Direction().XYZ());
455     aShiftAlongAxis *= aShiftAlongAxisLength;
456     aAx3.Translate(aShiftAlongAxis);
457
458     aP0=aAx3.Location();
459     aInfo.SetLocation(aP0);
460     aInfo.SetPosition(aAx3);
461
462     aR1 = aCone.RefRadius() + aVMin * std::sin(aSemiAngle);
463     aR2 = aCone.RefRadius() + aVMax * std::sin(aSemiAngle);
464
465     aInfo.SetRadius1(aR1);
466     aInfo.SetRadius2(aR2);
467     aInfo.SetHeight(H);
468     aInfo.SetKindOfDef(GEOMAlgo_KD_SPECIFIED);
469   }
470   //
471   //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
472   // 5. Torus
473   else if (aST==GeomAbs_Torus) {
474     gp_Torus aTorus;
475     //
476     aTorus=aGAS.Torus();
477     aP0=aTorus.Location();
478     aAx3=aTorus.Position();
479     aR1=aTorus.MajorRadius();
480     aR2=aTorus.MinorRadius();
481     //
482     aInfo.SetKindOfShape(GEOMAlgo_KS_TORUS);
483     aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);
484     aInfo.SetLocation(aP0);
485     aInfo.SetPosition(aAx3);
486     aInfo.SetRadius1(aR1);
487     aInfo.SetRadius2(aR2);
488     //
489     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
490     //
491     FillDetails(aF, aTorus);
492   }
493 }
494 //=======================================================================
495 //function :FillEdge
496 //purpose  :
497 //=======================================================================
498 void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS)
499 {
500   myErrorStatus=0;
501   //
502   Standard_Boolean bDegenerated, bIsAllowedType;
503   Standard_Integer aNbV;
504   Standard_Real aR1, aR2;
505   gp_Pnt aP, aP1, aP2, aPc;
506   gp_Dir aD;
507   gp_Ax2 aAx2;
508   Standard_Real aT1, aT2;
509   GeomAbs_CurveType aCT;
510   Handle(Geom_Curve) aC3D;
511   TopoDS_Edge aE;
512   //----------------------------------------------------
513   if (myMapInfo.Contains(aS)) {
514     return;
515   }
516   else {
517     GEOMAlgo_ShapeInfo aInfoX;
518     myMapInfo.Add(aS, aInfoX);
519   }
520   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
521   //----------------------------------------------------
522   aInfo.SetType(TopAbs_EDGE);
523   //
524   FillNbSubShapes(aS, aInfo);
525   //
526   aE=TopoDS::Edge(aS);
527   //
528   bDegenerated=BRep_Tool::Degenerated(aE);
529   if (bDegenerated) {
530     aInfo.SetKindOfShape(GEOMAlgo_KS_DEGENERATED);
531     FillSubShapes(aS);
532     return;
533   }
534   //
535   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
536   GeomAdaptor_Curve aGAC(aC3D);
537   aCT=aGAC.GetType();
538   bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aCT);
539   if (!bIsAllowedType) {
540     FillSubShapes(aS);
541     return;
542   }
543   // BSplineCurve
544   if (aCT==GeomAbs_BSplineCurve) {
545     Standard_Integer aNbKnots, aNbPoles, aNbWeights, aNbMultiplicities, aDegree, i;
546     Standard_Real aLength;
547     gp_XYZ aXYZ1, aXYZ2, aXYZc;
548     Handle(Geom_BSplineCurve) aBSp;
549     //
550     aBSp=aGAC.BSpline();
551     aDegree = aBSp->Degree();
552     aNbPoles = aBSp->NbPoles();
553     aNbKnots = aBSp->NbKnots();
554     aNbWeights = (aBSp->IsRational() ? aNbPoles : 0);
555     aNbMultiplicities = (aBSp->KnotDistribution() == GeomAbs_Uniform ? 0 : aNbKnots);
556     if (aDegree==1 && aNbKnots==2 && aNbPoles==2) {
557       // This is a single line segment
558       aInfo.SetKindOfShape(GEOMAlgo_KS_BSPLINE);
559       aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
560       //
561       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
562       aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
563       aGAC.D0(aT1, aP1);
564       aGAC.D0(aT2, aP2);
565       aInfo.SetPnt1(aP1);
566       aInfo.SetPnt2(aP2);
567       //
568       aLength=aP1.Distance(aP2);
569       aInfo.SetLength(aLength);
570       //
571       aXYZ1=aP1.XYZ();
572       aXYZ2=aP2.XYZ();
573       aXYZc=aXYZ1+aXYZ2;
574       aXYZc.Multiply(0.5);
575       aPc.SetXYZ(aXYZc);
576       aInfo.SetLocation(aPc);
577       //
578       if ( aLength >= gp::Resolution() ) {
579         gp_Vec aVec(aPc, aP2);
580         gp_Dir aDir(aVec);
581         aInfo.SetDirection(aDir);
582       }
583     }
584     else {
585       // We have a higher degree B-Spline curve
586       aInfo.SetKindOfShape(GEOMAlgo_KS_BSPLINE);
587       aInfo.SetKindOfName(GEOMAlgo_KN_CURVEBSPLINE);
588       aInfo.SetKindOfPeriod(aBSp->IsPeriodic() ? GEOMAlgo_KP_PERIODIC : GEOMAlgo_KP_NONPERIODIC);
589       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
590       aInfo.SetKindOfClosed(aBSp->IsClosed() ? GEOMAlgo_KC_CLOSED : GEOMAlgo_KC_NOTCLOSED);
591       aGAC.D0(aT1, aP1);
592       aGAC.D0(aT2, aP2);
593       aInfo.SetPnt1(aP1);
594       aInfo.SetPnt2(aP2);
595       //
596       aInfo.SetDegree(aDegree);
597       aInfo.SetNbKnots(aNbKnots);
598       aInfo.SetNbPoles(aNbPoles);
599       aInfo.SetNbWeights(aNbWeights);
600       aInfo.SetNbMultiplicities(aNbMultiplicities);
601       // Fill the poles
602       Handle(TColgp_HArray1OfPnt) poles = new TColgp_HArray1OfPnt(1, aNbPoles);
603       for (i=1; i<=aNbPoles; i++)
604         poles->SetValue(i, aBSp->Pole(i));
605       aInfo.SetPoles(poles);
606       // Fill the knots
607       Handle(TColStd_HArray1OfReal) knots = new TColStd_HArray1OfReal(1, aNbKnots);
608       for (i=1; i<=aNbKnots; i++)
609         knots->SetValue(i, aBSp->Knot(i));
610       aInfo.SetKnots(knots);
611       // Fill the weights
612       if (aNbWeights > 0) {
613         Handle(TColStd_HArray1OfReal) weights = new TColStd_HArray1OfReal(1, aNbWeights);
614         for (i=1; i<=aNbWeights; i++)
615           weights->SetValue(i, aBSp->Weight(i));
616         aInfo.SetWeights(weights);
617       }
618       // Fill the multiplicities
619       if (aNbMultiplicities > 0) {
620         Handle(TColStd_HArray1OfInteger) mults = new TColStd_HArray1OfInteger(1, aNbMultiplicities);
621         for (i=1; i<=aNbMultiplicities; i++)
622           mults->SetValue(i, aBSp->Multiplicity(i));
623         aInfo.SetMultiplicities(mults);
624       }
625     }
626   }//if (aCT==GeomAbs_BSplineCurve) {
627   // Bezier
628   else if (aCT==GeomAbs_BezierCurve) {
629     Standard_Integer aNbPoles, aNbWeights, aDegree, i;
630     Handle(Geom_BezierCurve) aBC;
631     aBC=aGAC.Bezier();
632     aNbPoles = aBC->NbPoles();
633     aNbWeights = (aBC->IsRational() ? aNbPoles : 0);
634     aDegree = aBC->Degree();
635     aInfo.SetKindOfShape(GEOMAlgo_KS_BEZIER);
636     aInfo.SetKindOfName(GEOMAlgo_KN_CURVEBEZIER);
637     aInfo.SetKindOfPeriod(aBC->IsPeriodic() ? GEOMAlgo_KP_PERIODIC : GEOMAlgo_KP_NONPERIODIC);
638     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
639     aInfo.SetKindOfClosed(aBC->IsClosed() ? GEOMAlgo_KC_CLOSED : GEOMAlgo_KC_NOTCLOSED);
640     aGAC.D0(aT1, aP1);
641     aGAC.D0(aT2, aP2);
642     aInfo.SetPnt1(aP1);
643     aInfo.SetPnt2(aP2);
644     //
645     aInfo.SetDegree(aDegree);
646     aInfo.SetNbPoles(aNbPoles);
647     aInfo.SetNbWeights(aNbWeights);
648     // Fill the poles
649     Handle(TColgp_HArray1OfPnt) poles = new TColgp_HArray1OfPnt(1, aNbPoles);
650     for (i=1; i<=aNbPoles; i++)
651       poles->SetValue(i, aBC->Pole(i));
652     aInfo.SetPoles(poles);
653     // Fill the weights
654     if (aNbWeights > 0) {
655       Handle(TColStd_HArray1OfReal) weights = new TColStd_HArray1OfReal(1, aNbWeights);
656       for (i=1; i<=aNbWeights; i++)
657         weights->SetValue(i, aBC->Weight(i));
658       aInfo.SetWeights(weights);
659     }
660   }// if (aCT==GeomAbs_BezierCurve) {
661   // Line
662   else if (aCT==GeomAbs_Line) {
663     Standard_Boolean bInf1, bInf2;
664     Standard_Real aLength;
665     gp_Lin aLin;
666     gp_XYZ aXYZ1, aXYZ2, aXYZc;
667     //
668     aLin=aGAC.Line();
669     aP=aLin.Location();
670     aD=aLin.Direction();
671     //
672     aInfo.SetKindOfShape(GEOMAlgo_KS_LINE);
673     aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
674     aInfo.SetLocation(aP);
675     aInfo.SetDirection(aD);
676     //
677     bInf1=Precision::IsNegativeInfinite(aT1);
678     bInf2=Precision::IsPositiveInfinite(aT2);
679     if (bInf1||bInf2) {
680       aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
681       aInfo.SetKindOfName(GEOMAlgo_KN_LINE);
682     }
683     else {
684       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
685       aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
686       aGAC.D0(aT1, aP1);
687       aGAC.D0(aT2, aP2);
688       aInfo.SetPnt1(aP1);
689       aInfo.SetPnt2(aP2);
690       //
691       aLength=aP1.Distance(aP2);
692       aXYZ1=aP1.XYZ();
693       aXYZ2=aP2.XYZ();
694       aXYZc=aXYZ1+aXYZ2;
695       aXYZc.Multiply(0.5);
696       //
697       aPc.SetXYZ(aXYZc);
698       gp_Vec aVec(aPc, aP2);
699       gp_Dir aDir(aVec);
700       //
701       aInfo.SetLocation(aPc);
702       aInfo.SetDirection(aDir);
703       aInfo.SetLength(aLength);
704     }
705   }// if (aCT==GeomAbs_Line) {
706   //
707   // Circle
708   else if (aCT==GeomAbs_Circle) {
709     gp_Circ aCirc;
710     //
711     aCirc=aGAC.Circle();
712     aP=aCirc.Location();
713     aAx2=aCirc.Position();
714     aR1=aCirc.Radius();
715     //
716     aInfo.SetKindOfShape(GEOMAlgo_KS_CIRCLE);
717     aInfo.SetLocation(aP);
718     aInfo.SetPosition(aAx2);
719     aInfo.SetRadius1(aR1);
720     //
721     aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
722     if (!aNbV) {
723       myErrorStatus=11; // circle edge without vertices
724       return;
725     }
726     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
727     aGAC.D0(aT1, aP1);
728     aGAC.D0(aT2, aP2);
729     aInfo.SetPnt1(aP1);
730     aInfo.SetPnt2(aP2);
731     //
732     if (aNbV==1) {
733       aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
734       aInfo.SetKindOfName(GEOMAlgo_KN_CIRCLE);
735     }
736     else {
737       aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
738       aInfo.SetKindOfName(GEOMAlgo_KN_ARCCIRCLE);
739       //
740       gp_Vec aVecX(aP, aP1);
741       gp_Dir aDirX(aVecX);
742       gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
743       aInfo.SetPosition(aAx2new);
744     }
745   }// else if (aCT==GeomAbs_Circle) {
746   //
747   // Ellipse
748   else if (aCT==GeomAbs_Ellipse) {
749     gp_Elips aElips;
750     //
751     aElips=aGAC.Ellipse();
752     aP=aElips.Location();
753     aAx2=aElips.Position();
754     aR1=aElips.MajorRadius();
755     aR2=aElips.MinorRadius();
756     //
757     aInfo.SetKindOfShape(GEOMAlgo_KS_ELLIPSE);
758     aInfo.SetLocation(aP);
759     aInfo.SetPosition(aAx2);
760     aInfo.SetRadius1(aR1);
761     aInfo.SetRadius2(aR2);
762     //
763     aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
764     if (!aNbV) {
765       myErrorStatus=11; // ellipse edge without vertices
766       return;
767     }
768     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
769     aGAC.D0(aT1, aP1);
770     aGAC.D0(aT2, aP2);
771     aInfo.SetPnt1(aP1);
772     aInfo.SetPnt2(aP2);
773     //
774     if (aNbV==1) {
775       aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
776       aInfo.SetKindOfName(GEOMAlgo_KN_ELLIPSE);
777     }
778     else {
779       aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
780       aInfo.SetKindOfName(GEOMAlgo_KN_ARCELLIPSE);
781     }
782   }// else if (aCT==GeomAbs_Ellipse) {
783   // Hyperbola
784   else if (aCT==GeomAbs_Hyperbola) {
785     gp_Hypr aHyp;
786     aHyp=aGAC.Hyperbola();
787     aP=aHyp.Location();
788     aAx2=aHyp.Position();
789     aR1=aHyp.MajorRadius();
790     aR2=aHyp.MinorRadius();
791     aInfo.SetKindOfShape(GEOMAlgo_KS_HYPERBOLA);
792     aInfo.SetKindOfName(GEOMAlgo_KN_HYPERBOLA);
793     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
794     aInfo.SetLocation(aP);
795     aInfo.SetPosition(aAx2);
796     aInfo.SetRadius1(aR1);
797     aInfo.SetRadius2(aR2);
798     //
799     aGAC.D0(aT1, aP1);
800     aGAC.D0(aT2, aP2);
801     aInfo.SetPnt1(aP1);
802     aInfo.SetPnt2(aP2);
803     //
804   }// if (aCT==GeomAbs_Hyperbola) {
805   // Parabola
806   else if (aCT==GeomAbs_Parabola) {
807     gp_Parab aPara;
808     aPara=aGAC.Parabola();
809     aP=aPara.Location();
810     aAx2=aPara.Position();
811     aR1=aPara.Focal();
812     aInfo.SetKindOfShape(GEOMAlgo_KS_PARABOLA);
813     aInfo.SetKindOfName(GEOMAlgo_KN_PARABOLA);
814     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
815     aInfo.SetLocation(aP);
816     aInfo.SetPosition(aAx2);
817     aInfo.SetRadius1(aR1);
818     //
819     aGAC.D0(aT1, aP1);
820     aGAC.D0(aT2, aP2);
821     aInfo.SetPnt1(aP1);
822     aInfo.SetPnt2(aP2);
823     //
824   }// if (aCT==GeomAbs_Parabola) {
825   //
826   FillSubShapes(aS);
827 }
828 //=======================================================================
829 //function :FillVertex
830 //purpose  :
831 //=======================================================================
832 void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS)
833 {
834   myErrorStatus=0;
835   //
836   gp_Pnt aP;
837   TopoDS_Vertex aV;
838   //
839   if (myMapInfo.Contains(aS)) {
840     return;
841   }
842   else {
843     GEOMAlgo_ShapeInfo aInfoX;
844     myMapInfo.Add(aS, aInfoX);
845   }
846   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
847   //
848   aV=TopoDS::Vertex(aS);
849   aP=BRep_Tool::Pnt(aV);
850   //
851   aInfo.SetType(TopAbs_VERTEX);
852   aInfo.SetLocation(aP);
853   myMapInfo.Add(aS, aInfo);
854 }
855 //=======================================================================
856 //function : FillNbSubshapes
857 //purpose  :
858 //=======================================================================
859 void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS,
860                                                GEOMAlgo_ShapeInfo& aInfo)
861 {
862   myErrorStatus=0;
863   //
864   Standard_Integer i, aNb, aNbS;
865   TopTools_IndexedMapOfShape aM;
866   TopAbs_ShapeEnum aST;
867   TopAbs_ShapeEnum aTypes[]= {
868     //TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX
869     TopAbs_COMPOUND,
870     TopAbs_COMPSOLID,
871     TopAbs_SOLID,
872     TopAbs_SHELL,
873     TopAbs_FACE,
874     TopAbs_WIRE,
875     TopAbs_EDGE,
876     TopAbs_VERTEX
877   };
878
879   //
880   aST=aS.ShapeType();
881   aNb=sizeof(aTypes)/sizeof(aTypes[0]);
882   for (i=0; i<aNb; ++i) {
883     if (aTypes[i]==aST) {
884       continue;
885     }
886     aM.Clear();
887     TopExp::MapShapes(aS, aTypes[i], aM);
888     aNbS=aM.Extent();
889     aInfo.SetNbSubShapes(aTypes[i], aNbS);
890   }
891 }
892 //=======================================================================
893 //function :NbShells
894 //purpose  :
895 //=======================================================================
896 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbShells
897   (const TopoDS_Solid& aSd)
898 {
899   Standard_Integer iCnt;
900   TopoDS_Iterator aIt;
901   //
902   iCnt=0;
903   //
904   aIt.Initialize(aSd);
905   for (; aIt.More(); aIt.Next()) {
906     ++iCnt;
907   }
908   return iCnt;
909 }
910 //=======================================================================
911 //function : NbWires
912 //purpose  :
913 //=======================================================================
914 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbWires
915   (const TopoDS_Face& aF)
916 {
917   Standard_Integer iCnt;
918   TopoDS_Iterator aIt;
919   //
920   iCnt=0;
921   //
922   aIt.Initialize(aF);
923   for (; aIt.More(); aIt.Next()) {
924     ++iCnt;
925   }
926   return iCnt;
927 }
928 //=======================================================================
929 //function : IsAllowedType
930 //purpose  :
931 //=======================================================================
932 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType
933   (const GeomAbs_CurveType aCT)
934 {
935   Standard_Boolean bRet;
936   Standard_Integer i, aNb;
937   GeomAbs_CurveType aTypes[]={
938     GeomAbs_Line,
939     GeomAbs_Circle,
940     GeomAbs_Ellipse,
941     GeomAbs_BSplineCurve,
942     GeomAbs_BezierCurve,
943     GeomAbs_Hyperbola,
944     GeomAbs_Parabola
945   };
946   //
947   bRet=Standard_False;
948   aNb=sizeof(aTypes)/sizeof(aTypes[0]);
949   for (i=0; i<aNb && !bRet; ++i) {
950     bRet=(aCT==aTypes[i]);
951   }
952   return bRet;
953 }
954 //=======================================================================
955 //function : IsAllowedType
956 //purpose  :
957 //=======================================================================
958 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType
959   (const GeomAbs_SurfaceType aST)
960 {
961   Standard_Boolean bRet;
962   Standard_Integer i, aNb;
963   GeomAbs_SurfaceType aTypes[]={
964     GeomAbs_Plane, GeomAbs_Cylinder,
965     GeomAbs_Cone,  GeomAbs_Sphere,
966     GeomAbs_Torus
967   };
968   //
969   bRet=Standard_False;
970   aNb=sizeof(aTypes)/sizeof(aTypes[0]);
971   for (i=0; i<aNb && !bRet; ++i) {
972     bRet=(aST==aTypes[i]);
973   }
974   //
975   return bRet;
976 }
977 //
978 // myErrorStatus
979 //
980 // 0  - Ok
981 // 1  - The object is just initialized
982 //
983 // 10 - Null shape
984 // 11 - circle/ellipse edge without vertices