1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <GEOMAlgo_ShapeInfoFiller.hxx>
22 #include <Precision.hxx>
27 #include <gp_Circ.hxx>
29 #include <gp_Elips.hxx>
30 #include <gp_Sphere.hxx>
32 #include <gp_Cylinder.hxx>
33 #include <gp_Cone.hxx>
34 #include <gp_Torus.hxx>
37 #include <Geom_Curve.hxx>
38 #include <Geom_Surface.hxx>
39 #include <Geom_BSplineCurve.hxx>
41 #include <GeomAdaptor_Curve.hxx>
42 #include <GeomAdaptor_Surface.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>
52 #include <BRep_Tool.hxx>
54 #include <BRepTools.hxx>
56 #include <TopTools_IndexedMapOfShape.hxx>
58 //=======================================================================
61 //=======================================================================
62 GEOMAlgo_ShapeInfoFiller::GEOMAlgo_ShapeInfoFiller()
68 //=======================================================================
71 //=======================================================================
72 GEOMAlgo_ShapeInfoFiller::~GEOMAlgo_ShapeInfoFiller()
75 //=======================================================================
76 //function : SetTolerance
78 //=======================================================================
79 void GEOMAlgo_ShapeInfoFiller::SetTolerance(const Standard_Real aT)
83 //=======================================================================
84 //function : Tolerance
86 //=======================================================================
87 Standard_Real GEOMAlgo_ShapeInfoFiller::Tolerance()const
91 //=======================================================================
94 //=======================================================================
95 void GEOMAlgo_ShapeInfoFiller::SetShape(const TopoDS_Shape& aS)
99 //=======================================================================
102 //=======================================================================
103 const TopoDS_Shape& GEOMAlgo_ShapeInfoFiller::Shape() const
107 //=======================================================================
110 //=======================================================================
111 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info() const
113 return Info(myShape);
115 //=======================================================================
118 //=======================================================================
119 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info(const TopoDS_Shape& aS) const
122 if (myMapInfo.Contains(aS)) {
123 const GEOMAlgo_ShapeInfo& aInfo=myMapInfo.FindFromKey(aS);
130 //=======================================================================
131 //function : CheckData
133 //=======================================================================
134 void GEOMAlgo_ShapeInfoFiller::CheckData()
138 if (myShape.IsNull()) {
143 //=======================================================================
146 //=======================================================================
147 void GEOMAlgo_ShapeInfoFiller::Perform()
160 //=======================================================================
161 //function :FillShape
163 //=======================================================================
164 void GEOMAlgo_ShapeInfoFiller::FillShape(const TopoDS_Shape& aS)
166 TopAbs_ShapeEnum aType;
168 aType=aS.ShapeType();
189 case TopAbs_COMPSOLID:
190 case TopAbs_COMPOUND:
198 //=======================================================================
199 //function :FillSubShapes
201 //=======================================================================
202 void GEOMAlgo_ShapeInfoFiller::FillSubShapes(const TopoDS_Shape& aS)
207 for (; aIt.More(); aIt.Next()) {
208 const TopoDS_Shape& aSx=aIt.Value();
212 //=======================================================================
213 //function : FillContainer
215 //=======================================================================
216 void GEOMAlgo_ShapeInfoFiller::FillContainer(const TopoDS_Shape& aS)
220 Standard_Boolean bIsClosed;
221 TopAbs_ShapeEnum aType;
222 GEOMAlgo_KindOfClosed aKC;
224 aType=aS.ShapeType();
225 //----------------------------------------------------
226 if (myMapInfo.Contains(aS)) {
230 GEOMAlgo_ShapeInfo aInfoX;
231 myMapInfo.Add(aS, aInfoX);
233 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
234 //----------------------------------------------------
235 aInfo.SetType(aType);
236 FillNbSubShapes(aS, aInfo);
238 if (aType==TopAbs_SHELL) {
239 bIsClosed=BRep_Tool::IsClosed(aS);
240 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
241 aInfo.SetKindOfClosed(aKC);
243 else if (aType==TopAbs_WIRE) {
245 TopoDS_Vertex aV1, aV2;
248 TopExp::Vertices(aW, aV1, aV2);
250 bIsClosed=aV1.IsSame(aV2);
251 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
252 aInfo.SetKindOfClosed(aKC);
257 //=======================================================================
258 //function : FillSolid
260 //=======================================================================
261 void GEOMAlgo_ShapeInfoFiller::FillSolid(const TopoDS_Shape& aS)
263 Standard_Integer aNbShells;
267 //----------------------------------------------------
268 if (myMapInfo.Contains(aS)) {
272 GEOMAlgo_ShapeInfo aInfoX;
273 myMapInfo.Add(aS, aInfoX);
275 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
276 //----------------------------------------------------
277 aInfo.SetType(TopAbs_SOLID);
278 FillNbSubShapes(aS, aInfo);
281 aSd=TopoDS::Solid(aS);
283 aNbShells=GEOMAlgo_ShapeInfoFiller::NbShells(aSd);
290 //=======================================================================
293 //=======================================================================
294 void GEOMAlgo_ShapeInfoFiller::FillFace(const TopoDS_Shape& aS)
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;
305 GeomAbs_SurfaceType aST;
306 Handle(Geom_Surface) aSurf;
308 //GEOMAlgo_KindOfName aKindOfName;
309 //----------------------------------------------------
310 if (myMapInfo.Contains(aS)) {
314 GEOMAlgo_ShapeInfo aInfoX;
315 myMapInfo.Add(aS, aInfoX);
317 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
318 //----------------------------------------------------
319 aInfo.SetType(TopAbs_FACE);
321 FillNbSubShapes(aS, aInfo);
327 aNbWires=GEOMAlgo_ShapeInfoFiller::NbWires(aF);
329 aSurf=BRep_Tool::Surface(aF);
330 GeomAdaptor_Surface aGAS(aSurf);
332 bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aST);
333 if (!bIsAllowedType) {
338 if (aST==GeomAbs_Plane) {
343 aAx3=aPln.Position();
345 aInfo.SetKindOfShape(GEOMAlgo_KS_PLANE);
346 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
347 aInfo.SetLocation(aP0);
348 aInfo.SetPosition(aAx3);
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);
361 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
363 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
366 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
369 FillDetails(aF, aPln);
370 }// if (aCT==GeomAbs_Line) {
373 else if (aST==GeomAbs_Sphere) {
376 aSphere=aGAS.Sphere();
377 aP0=aSphere.Location();
378 aAx3=aSphere.Position();
379 aR1=aSphere.Radius();
381 aInfo.SetKindOfShape(GEOMAlgo_KS_SPHERE);
382 aInfo.SetLocation(aP0);
383 aInfo.SetPosition(aAx3);
384 aInfo.SetRadius1(aR1);
390 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
391 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
393 FillDetails(aF, aSphere);
394 }// else if (aST==GeomAbs_Sphere) {
397 else if (aST==GeomAbs_Cylinder) {
400 aCyl=aGAS.Cylinder();
402 aAx3=aCyl.Position();
405 aInfo.SetKindOfShape(GEOMAlgo_KS_CYLINDER);
406 aInfo.SetLocation(aP0);
407 aInfo.SetPosition(aAx3);
408 aInfo.SetRadius1(aR1);
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);
420 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
422 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
425 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
427 FillDetails(aF, aCyl);
431 else if (aST==GeomAbs_Cone) {
435 aP0=aCone.Location();
436 aAx3=aCone.Position();
439 aInfo.SetKindOfShape(GEOMAlgo_KS_CONE);
440 aInfo.SetLocation(aP0);
441 aInfo.SetPosition(aAx3);
442 //aInfo.SetRadius1(aR1);
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);
454 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
456 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
459 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
461 FillDetails(aF, aCone);
465 else if (aST==GeomAbs_Torus) {
469 aP0=aTorus.Location();
470 aAx3=aTorus.Position();
471 aR1=aTorus.MajorRadius();
472 aR2=aTorus.MinorRadius();
474 aInfo.SetKindOfShape(GEOMAlgo_KS_TORUS);
475 aInfo.SetLocation(aP0);
476 aInfo.SetPosition(aAx3);
477 aInfo.SetRadius1(aR1);
478 aInfo.SetRadius2(aR2);
484 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
486 FillDetails(aF, aTorus);
489 //=======================================================================
492 //=======================================================================
493 void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS)
497 Standard_Boolean bDegenerated, bIsAllowedType;
498 Standard_Integer aNbV;
499 Standard_Real aR1, aR2;
500 gp_Pnt aP, aP1, aP2, aPc;
503 Standard_Real aT1, aT2;
504 GeomAbs_CurveType aCT;
505 Handle(Geom_Curve) aC3D;
507 //----------------------------------------------------
508 if (myMapInfo.Contains(aS)) {
512 GEOMAlgo_ShapeInfo aInfoX;
513 myMapInfo.Add(aS, aInfoX);
515 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
516 //----------------------------------------------------
517 aInfo.SetType(TopAbs_EDGE);
519 FillNbSubShapes(aS, aInfo);
523 bDegenerated=BRep_Tool::Degenerated(aE);
525 aInfo.SetKindOfShape(GEOMAlgo_KS_DEGENERATED);
530 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
531 GeomAdaptor_Curve aGAC(aC3D);
533 bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aCT);
534 if (!bIsAllowedType) {
538 //modified by NIZNHY-PKV Tue Jul 03 10:19:03 2012f
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;
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
554 aInfo.SetKindOfShape(GEOMAlgo_KS_BSPLINE);
555 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
557 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
558 aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
564 aLength=aP1.Distance(aP2);
565 aInfo.SetLength(aLength);
572 aInfo.SetLocation(aPc);
574 if ( aLength >= gp::Resolution() ) {
575 gp_Vec aVec(aPc, aP2);
577 aInfo.SetDirection(aDir);
580 //modified by NIZNHY-PKV Tue Jul 03 10:19:06 2012t
582 else if (aCT==GeomAbs_Line) {
583 Standard_Boolean bInf1, bInf2;
584 Standard_Real aLength;
586 gp_XYZ aXYZ1, aXYZ2, aXYZc;
592 aInfo.SetKindOfShape(GEOMAlgo_KS_LINE);
593 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
594 aInfo.SetLocation(aP);
595 aInfo.SetDirection(aD);
597 bInf1=Precision::IsNegativeInfinite(aT1);
598 bInf2=Precision::IsPositiveInfinite(aT2);
600 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
601 aInfo.SetKindOfName(GEOMAlgo_KN_LINE);
604 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
605 aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
611 aLength=aP1.Distance(aP2);
618 gp_Vec aVec(aPc, aP2);
621 aInfo.SetLocation(aPc);
622 aInfo.SetDirection(aDir);
623 aInfo.SetLength(aLength);
625 }// if (aCT==GeomAbs_Line) {
628 else if (aCT==GeomAbs_Circle) {
633 aAx2=aCirc.Position();
636 aInfo.SetKindOfShape(GEOMAlgo_KS_CIRCLE);
637 aInfo.SetLocation(aP);
638 aInfo.SetPosition(aAx2);
639 aInfo.SetRadius1(aR1);
641 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
643 myErrorStatus=11; // circle edge without vertices
646 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
653 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
654 aInfo.SetKindOfName(GEOMAlgo_KN_CIRCLE);
657 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
658 aInfo.SetKindOfName(GEOMAlgo_KN_ARCCIRCLE);
660 gp_Vec aVecX(aP, aP1);
662 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
663 aInfo.SetPosition(aAx2new);
665 }// else if (aCT==GeomAbs_Circle) {
668 else if (aCT==GeomAbs_Ellipse) {
671 aElips=aGAC.Ellipse();
672 aP=aElips.Location();
673 aAx2=aElips.Position();
674 aR1=aElips.MajorRadius();
675 aR2=aElips.MinorRadius();
677 aInfo.SetKindOfShape(GEOMAlgo_KS_ELLIPSE);
678 aInfo.SetLocation(aP);
679 aInfo.SetPosition(aAx2);
680 aInfo.SetRadius1(aR1);
681 aInfo.SetRadius2(aR2);
683 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
685 myErrorStatus=11; // ellipse edge without vertices
688 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
695 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
696 aInfo.SetKindOfName(GEOMAlgo_KN_ELLIPSE);
699 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
700 aInfo.SetKindOfName(GEOMAlgo_KN_ARCELLIPSE);
702 gp_Vec aVecX(aP, aP1);
704 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
705 aInfo.SetPosition(aAx2new);
707 }// else if (aCT==GeomAbs_Ellipse) {
711 //=======================================================================
712 //function :FillVertex
714 //=======================================================================
715 void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS)
722 if (myMapInfo.Contains(aS)) {
726 GEOMAlgo_ShapeInfo aInfoX;
727 myMapInfo.Add(aS, aInfoX);
729 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
731 aV=TopoDS::Vertex(aS);
732 aP=BRep_Tool::Pnt(aV);
734 aInfo.SetType(TopAbs_VERTEX);
735 aInfo.SetLocation(aP);
736 myMapInfo.Add(aS, aInfo);
738 //=======================================================================
739 //function : FillNbSubshapes
741 //=======================================================================
742 void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS,
743 GEOMAlgo_ShapeInfo& aInfo)
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
764 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
765 for (i=0; i<aNb; ++i) {
766 if (aTypes[i]==aST) {
770 TopExp::MapShapes(aS, aTypes[i], aM);
772 aInfo.SetNbSubShapes(aTypes[i], aNbS);
775 //=======================================================================
778 //=======================================================================
779 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbShells(const TopoDS_Solid& aSd)
781 Standard_Integer iCnt;
787 for (; aIt.More(); aIt.Next()) {
788 //const TopoDS_Shape& aSh=aIt.Value();
793 //=======================================================================
796 //=======================================================================
797 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbWires(const TopoDS_Face& aF)
799 Standard_Integer iCnt;
805 for (; aIt.More(); aIt.Next()) {
806 //const TopoDS_Shape& aW=aIt.Value();
811 //=======================================================================
812 //function : IsAllowedType
814 //=======================================================================
815 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType(const GeomAbs_CurveType aCT)
817 Standard_Boolean bRet;
818 Standard_Integer i, aNb;
819 GeomAbs_CurveType aTypes[]={
823 GeomAbs_BSplineCurve //modified by NIZNHY-PKV Tue Jul 03 10:18:01 2012ft
827 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
828 for (i=0; i<aNb && !bRet; ++i) {
829 bRet=(aCT==aTypes[i]);
833 //=======================================================================
834 //function : IsAllowedType
836 //=======================================================================
837 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType(const GeomAbs_SurfaceType aST)
839 Standard_Boolean bRet;
840 Standard_Integer i, aNb;
841 GeomAbs_SurfaceType aTypes[]={
842 GeomAbs_Plane, GeomAbs_Cylinder,
843 GeomAbs_Cone, GeomAbs_Sphere,
848 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
849 for (i=0; i<aNb && !bRet; ++i) {
850 bRet=(aST==aTypes[i]);
859 // 1 - The object is just initialized
862 // 11 - circle/ellipse edge without vertices