Salome HOME
849b5a0c20091b00d381c7107a31f3cff571bf0b
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_ShapeInfoFiller.cxx
1 // Copyright (C) 2007-2023  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     Standard_Real aSemiAngle;
424     gp_Cone aCone;
425     //
426     aCone=aGAS.Cone();
427     aP0=aCone.Location();
428     aAx3=aCone.Position();
429     //
430     aInfo.SetKindOfShape(GEOMAlgo_KS_CONE);
431     aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
432     aInfo.SetLocation(aP0);
433     aInfo.SetPosition(aAx3);
434     //
435     BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
436     bInfU1=Precision::IsNegativeInfinite(aUMin);
437     bInfU2=Precision::IsPositiveInfinite(aUMax);
438     bInfV1=Precision::IsNegativeInfinite(aVMin);
439     bInfV2=Precision::IsPositiveInfinite(aVMax);
440     //
441     bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
442     if (bInf) {
443       aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
444       return;
445     }
446     //
447     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
448     //
449     aSemiAngle=fabs(aCone.SemiAngle());
450     dV=(aVMax-aVMin)*cos(aSemiAngle);
451     
452     aInfo.SetHeight(dV);
453     //
454     FillDetails(aF, aCone);
455   }
456   //
457   //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
458   // 5. Torus
459   else if (aST==GeomAbs_Torus) {
460     gp_Torus aTorus;
461     //
462     aTorus=aGAS.Torus();
463     aP0=aTorus.Location();
464     aAx3=aTorus.Position();
465     aR1=aTorus.MajorRadius();
466     aR2=aTorus.MinorRadius();
467     //
468     aInfo.SetKindOfShape(GEOMAlgo_KS_TORUS);
469     aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);
470     aInfo.SetLocation(aP0);
471     aInfo.SetPosition(aAx3);
472     aInfo.SetRadius1(aR1);
473     aInfo.SetRadius2(aR2);
474     //
475     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
476     //
477     FillDetails(aF, aTorus);
478   }
479 }
480 //=======================================================================
481 //function :FillEdge
482 //purpose  :
483 //=======================================================================
484 void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS)
485 {
486   myErrorStatus=0;
487   //
488   Standard_Boolean bDegenerated, bIsAllowedType;
489   Standard_Integer aNbV;
490   Standard_Real aR1, aR2;
491   gp_Pnt aP, aP1, aP2, aPc;
492   gp_Dir aD;
493   gp_Ax2 aAx2;
494   Standard_Real aT1, aT2;
495   GeomAbs_CurveType aCT;
496   Handle(Geom_Curve) aC3D;
497   TopoDS_Edge aE;
498   //----------------------------------------------------
499   if (myMapInfo.Contains(aS)) {
500     return;
501   }
502   else {
503     GEOMAlgo_ShapeInfo aInfoX;
504     myMapInfo.Add(aS, aInfoX);
505   }
506   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
507   //----------------------------------------------------
508   aInfo.SetType(TopAbs_EDGE);
509   //
510   FillNbSubShapes(aS, aInfo);
511   //
512   aE=TopoDS::Edge(aS);
513   //
514   bDegenerated=BRep_Tool::Degenerated(aE);
515   if (bDegenerated) {
516     aInfo.SetKindOfShape(GEOMAlgo_KS_DEGENERATED);
517     FillSubShapes(aS);
518     return;
519   }
520   //
521   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
522   GeomAdaptor_Curve aGAC(aC3D);
523   aCT=aGAC.GetType();
524   bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aCT);
525   if (!bIsAllowedType) {
526     FillSubShapes(aS);
527     return;
528   }
529   // BSplineCurve
530   if (aCT==GeomAbs_BSplineCurve) {
531     Standard_Integer aNbKnots, aNbPoles, aNbWeights, aNbMultiplicities, aDegree, i;
532     Standard_Real aLength;
533     gp_XYZ aXYZ1, aXYZ2, aXYZc;
534     Handle(Geom_BSplineCurve) aBSp;
535     //
536     aBSp=aGAC.BSpline();
537     aDegree = aBSp->Degree();
538     aNbPoles = aBSp->NbPoles();
539     aNbKnots = aBSp->NbKnots();
540     aNbWeights = (aBSp->IsRational() ? aNbPoles : 0);
541     aNbMultiplicities = (aBSp->KnotDistribution() == GeomAbs_Uniform ? 0 : aNbKnots);
542     if (aDegree==1 && aNbKnots==2 && aNbPoles==2) {
543       // This is a single line segment
544       aInfo.SetKindOfShape(GEOMAlgo_KS_BSPLINE);
545       aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
546       //
547       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
548       aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
549       aGAC.D0(aT1, aP1);
550       aGAC.D0(aT2, aP2);
551       aInfo.SetPnt1(aP1);
552       aInfo.SetPnt2(aP2);
553       //
554       aLength=aP1.Distance(aP2);
555       aInfo.SetLength(aLength);
556       //
557       aXYZ1=aP1.XYZ();
558       aXYZ2=aP2.XYZ();
559       aXYZc=aXYZ1+aXYZ2;
560       aXYZc.Multiply(0.5);
561       aPc.SetXYZ(aXYZc);
562       aInfo.SetLocation(aPc);
563       //
564       if ( aLength >= gp::Resolution() ) {
565         gp_Vec aVec(aPc, aP2);
566         gp_Dir aDir(aVec);
567         aInfo.SetDirection(aDir);
568       }
569     }
570     else {
571       // We have a higher degree B-Spline curve
572       aInfo.SetKindOfShape(GEOMAlgo_KS_BSPLINE);
573       aInfo.SetKindOfName(GEOMAlgo_KN_CURVEBSPLINE);
574       aInfo.SetKindOfPeriod(aBSp->IsPeriodic() ? GEOMAlgo_KP_PERIODIC : GEOMAlgo_KP_NONPERIODIC);
575       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
576       aInfo.SetKindOfClosed(aBSp->IsClosed() ? GEOMAlgo_KC_CLOSED : GEOMAlgo_KC_NOTCLOSED);
577       aGAC.D0(aT1, aP1);
578       aGAC.D0(aT2, aP2);
579       aInfo.SetPnt1(aP1);
580       aInfo.SetPnt2(aP2);
581       //
582       aInfo.SetDegree(aDegree);
583       aInfo.SetNbKnots(aNbKnots);
584       aInfo.SetNbPoles(aNbPoles);
585       aInfo.SetNbWeights(aNbWeights);
586       aInfo.SetNbMultiplicities(aNbMultiplicities);
587       // Fill the poles
588       Handle(TColgp_HArray1OfPnt) poles = new TColgp_HArray1OfPnt(1, aNbPoles);
589       for (i=1; i<=aNbPoles; i++)
590         poles->SetValue(i, aBSp->Pole(i));
591       aInfo.SetPoles(poles);
592       // Fill the knots
593       Handle(TColStd_HArray1OfReal) knots = new TColStd_HArray1OfReal(1, aNbKnots);
594       for (i=1; i<=aNbKnots; i++)
595         knots->SetValue(i, aBSp->Knot(i));
596       aInfo.SetKnots(knots);
597       // Fill the weights
598       if (aNbWeights > 0) {
599         Handle(TColStd_HArray1OfReal) weights = new TColStd_HArray1OfReal(1, aNbWeights);
600         for (i=1; i<=aNbWeights; i++)
601           weights->SetValue(i, aBSp->Weight(i));
602         aInfo.SetWeights(weights);
603       }
604       // Fill the multiplicities
605       if (aNbMultiplicities > 0) {
606         Handle(TColStd_HArray1OfInteger) mults = new TColStd_HArray1OfInteger(1, aNbMultiplicities);
607         for (i=1; i<=aNbMultiplicities; i++)
608           mults->SetValue(i, aBSp->Multiplicity(i));
609         aInfo.SetMultiplicities(mults);
610       }
611     }
612   }//if (aCT==GeomAbs_BSplineCurve) {
613   // Bezier
614   else if (aCT==GeomAbs_BezierCurve) {
615     Standard_Integer aNbPoles, aNbWeights, aDegree, i;
616     Handle(Geom_BezierCurve) aBC;
617     aBC=aGAC.Bezier();
618     aNbPoles = aBC->NbPoles();
619     aNbWeights = (aBC->IsRational() ? aNbPoles : 0);
620     aDegree = aBC->Degree();
621     aInfo.SetKindOfShape(GEOMAlgo_KS_BEZIER);
622     aInfo.SetKindOfName(GEOMAlgo_KN_CURVEBEZIER);
623     aInfo.SetKindOfPeriod(aBC->IsPeriodic() ? GEOMAlgo_KP_PERIODIC : GEOMAlgo_KP_NONPERIODIC);
624     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
625     aInfo.SetKindOfClosed(aBC->IsClosed() ? GEOMAlgo_KC_CLOSED : GEOMAlgo_KC_NOTCLOSED);
626     aGAC.D0(aT1, aP1);
627     aGAC.D0(aT2, aP2);
628     aInfo.SetPnt1(aP1);
629     aInfo.SetPnt2(aP2);
630     //
631     aInfo.SetDegree(aDegree);
632     aInfo.SetNbPoles(aNbPoles);
633     aInfo.SetNbWeights(aNbWeights);
634     // Fill the poles
635     Handle(TColgp_HArray1OfPnt) poles = new TColgp_HArray1OfPnt(1, aNbPoles);
636     for (i=1; i<=aNbPoles; i++)
637       poles->SetValue(i, aBC->Pole(i));
638     aInfo.SetPoles(poles);
639     // Fill the weights
640     if (aNbWeights > 0) {
641       Handle(TColStd_HArray1OfReal) weights = new TColStd_HArray1OfReal(1, aNbWeights);
642       for (i=1; i<=aNbWeights; i++)
643         weights->SetValue(i, aBC->Weight(i));
644       aInfo.SetWeights(weights);
645     }
646   }// if (aCT==GeomAbs_BezierCurve) {
647   // Line
648   else if (aCT==GeomAbs_Line) {
649     Standard_Boolean bInf1, bInf2;
650     Standard_Real aLength;
651     gp_Lin aLin;
652     gp_XYZ aXYZ1, aXYZ2, aXYZc;
653     //
654     aLin=aGAC.Line();
655     aP=aLin.Location();
656     aD=aLin.Direction();
657     //
658     aInfo.SetKindOfShape(GEOMAlgo_KS_LINE);
659     aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
660     aInfo.SetLocation(aP);
661     aInfo.SetDirection(aD);
662     //
663     bInf1=Precision::IsNegativeInfinite(aT1);
664     bInf2=Precision::IsPositiveInfinite(aT2);
665     if (bInf1||bInf2) {
666       aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
667       aInfo.SetKindOfName(GEOMAlgo_KN_LINE);
668     }
669     else {
670       aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
671       aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
672       aGAC.D0(aT1, aP1);
673       aGAC.D0(aT2, aP2);
674       aInfo.SetPnt1(aP1);
675       aInfo.SetPnt2(aP2);
676       //
677       aLength=aP1.Distance(aP2);
678       aXYZ1=aP1.XYZ();
679       aXYZ2=aP2.XYZ();
680       aXYZc=aXYZ1+aXYZ2;
681       aXYZc.Multiply(0.5);
682       //
683       aPc.SetXYZ(aXYZc);
684       gp_Vec aVec(aPc, aP2);
685       gp_Dir aDir(aVec);
686       //
687       aInfo.SetLocation(aPc);
688       aInfo.SetDirection(aDir);
689       aInfo.SetLength(aLength);
690     }
691   }// if (aCT==GeomAbs_Line) {
692   //
693   // Circle
694   else if (aCT==GeomAbs_Circle) {
695     gp_Circ aCirc;
696     //
697     aCirc=aGAC.Circle();
698     aP=aCirc.Location();
699     aAx2=aCirc.Position();
700     aR1=aCirc.Radius();
701     //
702     aInfo.SetKindOfShape(GEOMAlgo_KS_CIRCLE);
703     aInfo.SetLocation(aP);
704     aInfo.SetPosition(aAx2);
705     aInfo.SetRadius1(aR1);
706     //
707     aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
708     if (!aNbV) {
709       myErrorStatus=11; // circle edge without vertices
710       return;
711     }
712     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
713     aGAC.D0(aT1, aP1);
714     aGAC.D0(aT2, aP2);
715     aInfo.SetPnt1(aP1);
716     aInfo.SetPnt2(aP2);
717     //
718     if (aNbV==1) {
719       aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
720       aInfo.SetKindOfName(GEOMAlgo_KN_CIRCLE);
721     }
722     else {
723       aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
724       aInfo.SetKindOfName(GEOMAlgo_KN_ARCCIRCLE);
725       //
726       gp_Vec aVecX(aP, aP1);
727       gp_Dir aDirX(aVecX);
728       gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
729       aInfo.SetPosition(aAx2new);
730     }
731   }// else if (aCT==GeomAbs_Circle) {
732   //
733   // Ellipse
734   else if (aCT==GeomAbs_Ellipse) {
735     gp_Elips aElips;
736     //
737     aElips=aGAC.Ellipse();
738     aP=aElips.Location();
739     aAx2=aElips.Position();
740     aR1=aElips.MajorRadius();
741     aR2=aElips.MinorRadius();
742     //
743     aInfo.SetKindOfShape(GEOMAlgo_KS_ELLIPSE);
744     aInfo.SetLocation(aP);
745     aInfo.SetPosition(aAx2);
746     aInfo.SetRadius1(aR1);
747     aInfo.SetRadius2(aR2);
748     //
749     aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
750     if (!aNbV) {
751       myErrorStatus=11; // ellipse edge without vertices
752       return;
753     }
754     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
755     aGAC.D0(aT1, aP1);
756     aGAC.D0(aT2, aP2);
757     aInfo.SetPnt1(aP1);
758     aInfo.SetPnt2(aP2);
759     //
760     if (aNbV==1) {
761       aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
762       aInfo.SetKindOfName(GEOMAlgo_KN_ELLIPSE);
763     }
764     else {
765       aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
766       aInfo.SetKindOfName(GEOMAlgo_KN_ARCELLIPSE);
767     }
768   }// else if (aCT==GeomAbs_Ellipse) {
769   // Hyperbola
770   else if (aCT==GeomAbs_Hyperbola) {
771     gp_Hypr aHyp;
772     aHyp=aGAC.Hyperbola();
773     aP=aHyp.Location();
774     aAx2=aHyp.Position();
775     aR1=aHyp.MajorRadius();
776     aR2=aHyp.MinorRadius();
777     aInfo.SetKindOfShape(GEOMAlgo_KS_HYPERBOLA);
778     aInfo.SetKindOfName(GEOMAlgo_KN_HYPERBOLA);
779     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
780     aInfo.SetLocation(aP);
781     aInfo.SetPosition(aAx2);
782     aInfo.SetRadius1(aR1);
783     aInfo.SetRadius2(aR2);
784     //
785     aGAC.D0(aT1, aP1);
786     aGAC.D0(aT2, aP2);
787     aInfo.SetPnt1(aP1);
788     aInfo.SetPnt2(aP2);
789     //
790   }// if (aCT==GeomAbs_Hyperbola) {
791   // Parabola
792   else if (aCT==GeomAbs_Parabola) {
793     gp_Parab aPara;
794     aPara=aGAC.Parabola();
795     aP=aPara.Location();
796     aAx2=aPara.Position();
797     aR1=aPara.Focal();
798     aInfo.SetKindOfShape(GEOMAlgo_KS_PARABOLA);
799     aInfo.SetKindOfName(GEOMAlgo_KN_PARABOLA);
800     aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
801     aInfo.SetLocation(aP);
802     aInfo.SetPosition(aAx2);
803     aInfo.SetRadius1(aR1);
804     //
805     aGAC.D0(aT1, aP1);
806     aGAC.D0(aT2, aP2);
807     aInfo.SetPnt1(aP1);
808     aInfo.SetPnt2(aP2);
809     //
810   }// if (aCT==GeomAbs_Parabola) {
811   //
812   FillSubShapes(aS);
813 }
814 //=======================================================================
815 //function :FillVertex
816 //purpose  :
817 //=======================================================================
818 void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS)
819 {
820   myErrorStatus=0;
821   //
822   gp_Pnt aP;
823   TopoDS_Vertex aV;
824   //
825   if (myMapInfo.Contains(aS)) {
826     return;
827   }
828   else {
829     GEOMAlgo_ShapeInfo aInfoX;
830     myMapInfo.Add(aS, aInfoX);
831   }
832   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
833   //
834   aV=TopoDS::Vertex(aS);
835   aP=BRep_Tool::Pnt(aV);
836   //
837   aInfo.SetType(TopAbs_VERTEX);
838   aInfo.SetLocation(aP);
839   myMapInfo.Add(aS, aInfo);
840 }
841 //=======================================================================
842 //function : FillNbSubshapes
843 //purpose  :
844 //=======================================================================
845 void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS,
846                                                GEOMAlgo_ShapeInfo& aInfo)
847 {
848   myErrorStatus=0;
849   //
850   Standard_Integer i, aNb, aNbS;
851   TopTools_IndexedMapOfShape aM;
852   TopAbs_ShapeEnum aST;
853   TopAbs_ShapeEnum aTypes[]= {
854     //TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX
855     TopAbs_COMPOUND,
856     TopAbs_COMPSOLID,
857     TopAbs_SOLID,
858     TopAbs_SHELL,
859     TopAbs_FACE,
860     TopAbs_WIRE,
861     TopAbs_EDGE,
862     TopAbs_VERTEX
863   };
864
865   //
866   aST=aS.ShapeType();
867   aNb=sizeof(aTypes)/sizeof(aTypes[0]);
868   for (i=0; i<aNb; ++i) {
869     if (aTypes[i]==aST) {
870       continue;
871     }
872     aM.Clear();
873     TopExp::MapShapes(aS, aTypes[i], aM);
874     aNbS=aM.Extent();
875     aInfo.SetNbSubShapes(aTypes[i], aNbS);
876   }
877 }
878 //=======================================================================
879 //function :NbShells
880 //purpose  :
881 //=======================================================================
882 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbShells
883   (const TopoDS_Solid& aSd)
884 {
885   Standard_Integer iCnt;
886   TopoDS_Iterator aIt;
887   //
888   iCnt=0;
889   //
890   aIt.Initialize(aSd);
891   for (; aIt.More(); aIt.Next()) {
892     ++iCnt;
893   }
894   return iCnt;
895 }
896 //=======================================================================
897 //function : NbWires
898 //purpose  :
899 //=======================================================================
900 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbWires
901   (const TopoDS_Face& aF)
902 {
903   Standard_Integer iCnt;
904   TopoDS_Iterator aIt;
905   //
906   iCnt=0;
907   //
908   aIt.Initialize(aF);
909   for (; aIt.More(); aIt.Next()) {
910     ++iCnt;
911   }
912   return iCnt;
913 }
914 //=======================================================================
915 //function : IsAllowedType
916 //purpose  :
917 //=======================================================================
918 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType
919   (const GeomAbs_CurveType aCT)
920 {
921   Standard_Boolean bRet;
922   Standard_Integer i, aNb;
923   GeomAbs_CurveType aTypes[]={
924     GeomAbs_Line,
925     GeomAbs_Circle,
926     GeomAbs_Ellipse,
927     GeomAbs_BSplineCurve,
928     GeomAbs_BezierCurve,
929     GeomAbs_Hyperbola,
930     GeomAbs_Parabola
931   };
932   //
933   bRet=Standard_False;
934   aNb=sizeof(aTypes)/sizeof(aTypes[0]);
935   for (i=0; i<aNb && !bRet; ++i) {
936     bRet=(aCT==aTypes[i]);
937   }
938   return bRet;
939 }
940 //=======================================================================
941 //function : IsAllowedType
942 //purpose  :
943 //=======================================================================
944 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType
945   (const GeomAbs_SurfaceType aST)
946 {
947   Standard_Boolean bRet;
948   Standard_Integer i, aNb;
949   GeomAbs_SurfaceType aTypes[]={
950     GeomAbs_Plane, GeomAbs_Cylinder,
951     GeomAbs_Cone,  GeomAbs_Sphere,
952     GeomAbs_Torus
953   };
954   //
955   bRet=Standard_False;
956   aNb=sizeof(aTypes)/sizeof(aTypes[0]);
957   for (i=0; i<aNb && !bRet; ++i) {
958     bRet=(aST==aTypes[i]);
959   }
960   //
961   return bRet;
962 }
963 //
964 // myErrorStatus
965 //
966 // 0  - Ok
967 // 1  - The object is just initialized
968 //
969 // 10 - Null shape
970 // 11 - circle/ellipse edge without vertices