1 // Copyright (C) 2007-2012 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.
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
19 #include <GEOMAlgo_ShapeInfoFiller.hxx>
21 #include <Precision.hxx>
26 #include <gp_Circ.hxx>
28 #include <gp_Elips.hxx>
29 #include <gp_Sphere.hxx>
31 #include <gp_Cylinder.hxx>
32 #include <gp_Cone.hxx>
33 #include <gp_Torus.hxx>
36 #include <Geom_Curve.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_BSplineCurve.hxx>
40 #include <GeomAdaptor_Curve.hxx>
41 #include <GeomAdaptor_Surface.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Solid.hxx>
46 #include <TopoDS_Vertex.hxx>
47 #include <TopoDS_Iterator.hxx>
48 #include <TopoDS_Wire.hxx>
49 #include <TopoDS_Face.hxx>
51 #include <BRep_Tool.hxx>
53 #include <BRepTools.hxx>
55 #include <TopTools_IndexedMapOfShape.hxx>
57 //=======================================================================
60 //=======================================================================
61 GEOMAlgo_ShapeInfoFiller::GEOMAlgo_ShapeInfoFiller()
67 //=======================================================================
70 //=======================================================================
71 GEOMAlgo_ShapeInfoFiller::~GEOMAlgo_ShapeInfoFiller()
74 //=======================================================================
75 //function : SetTolerance
77 //=======================================================================
78 void GEOMAlgo_ShapeInfoFiller::SetTolerance(const Standard_Real aT)
82 //=======================================================================
83 //function : Tolerance
85 //=======================================================================
86 Standard_Real GEOMAlgo_ShapeInfoFiller::Tolerance()const
90 //=======================================================================
93 //=======================================================================
94 void GEOMAlgo_ShapeInfoFiller::SetShape(const TopoDS_Shape& aS)
98 //=======================================================================
101 //=======================================================================
102 const TopoDS_Shape& GEOMAlgo_ShapeInfoFiller::Shape() const
106 //=======================================================================
109 //=======================================================================
110 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info() const
112 return Info(myShape);
114 //=======================================================================
117 //=======================================================================
118 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info(const TopoDS_Shape& aS) const
121 if (myMapInfo.Contains(aS)) {
122 const GEOMAlgo_ShapeInfo& aInfo=myMapInfo.FindFromKey(aS);
129 //=======================================================================
130 //function : CheckData
132 //=======================================================================
133 void GEOMAlgo_ShapeInfoFiller::CheckData()
137 if (myShape.IsNull()) {
142 //=======================================================================
145 //=======================================================================
146 void GEOMAlgo_ShapeInfoFiller::Perform()
159 //=======================================================================
160 //function :FillShape
162 //=======================================================================
163 void GEOMAlgo_ShapeInfoFiller::FillShape(const TopoDS_Shape& aS)
165 TopAbs_ShapeEnum aType;
167 aType=aS.ShapeType();
188 case TopAbs_COMPSOLID:
189 case TopAbs_COMPOUND:
197 //=======================================================================
198 //function :FillSubShapes
200 //=======================================================================
201 void GEOMAlgo_ShapeInfoFiller::FillSubShapes(const TopoDS_Shape& aS)
206 for (; aIt.More(); aIt.Next()) {
207 const TopoDS_Shape& aSx=aIt.Value();
211 //=======================================================================
212 //function : FillContainer
214 //=======================================================================
215 void GEOMAlgo_ShapeInfoFiller::FillContainer(const TopoDS_Shape& aS)
219 Standard_Boolean bIsClosed;
220 TopAbs_ShapeEnum aType;
221 GEOMAlgo_KindOfClosed aKC;
223 aType=aS.ShapeType();
224 //----------------------------------------------------
225 if (myMapInfo.Contains(aS)) {
229 GEOMAlgo_ShapeInfo aInfoX;
230 myMapInfo.Add(aS, aInfoX);
232 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
233 //----------------------------------------------------
234 aInfo.SetType(aType);
235 FillNbSubShapes(aS, aInfo);
237 if (aType==TopAbs_SHELL) {
238 bIsClosed=BRep_Tool::IsClosed(aS);
239 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
240 aInfo.SetKindOfClosed(aKC);
242 else if (aType==TopAbs_WIRE) {
244 TopoDS_Vertex aV1, aV2;
247 TopExp::Vertices(aW, aV1, aV2);
249 bIsClosed=aV1.IsSame(aV2);
250 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
251 aInfo.SetKindOfClosed(aKC);
256 //=======================================================================
257 //function : FillSolid
259 //=======================================================================
260 void GEOMAlgo_ShapeInfoFiller::FillSolid(const TopoDS_Shape& aS)
262 Standard_Integer aNbShells;
266 //----------------------------------------------------
267 if (myMapInfo.Contains(aS)) {
271 GEOMAlgo_ShapeInfo aInfoX;
272 myMapInfo.Add(aS, aInfoX);
274 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
275 //----------------------------------------------------
276 aInfo.SetType(TopAbs_SOLID);
277 FillNbSubShapes(aS, aInfo);
280 aSd=TopoDS::Solid(aS);
282 aNbShells=GEOMAlgo_ShapeInfoFiller::NbShells(aSd);
289 //=======================================================================
292 //=======================================================================
293 void GEOMAlgo_ShapeInfoFiller::FillFace(const TopoDS_Shape& aS)
297 Standard_Boolean bIsAllowedType;
298 Standard_Integer aNbWires;//, iRet
299 Standard_Boolean bInf, bInfU1, bInfU2, bInfV1, bInfV2;
300 Standard_Real aUMin, aUMax, aVMin, aVMax, aR1, aR2;
304 GeomAbs_SurfaceType aST;
305 Handle(Geom_Surface) aSurf;
307 //GEOMAlgo_KindOfName aKindOfName;
308 //----------------------------------------------------
309 if (myMapInfo.Contains(aS)) {
313 GEOMAlgo_ShapeInfo aInfoX;
314 myMapInfo.Add(aS, aInfoX);
316 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
317 //----------------------------------------------------
318 aInfo.SetType(TopAbs_FACE);
320 FillNbSubShapes(aS, aInfo);
326 aNbWires=GEOMAlgo_ShapeInfoFiller::NbWires(aF);
328 aSurf=BRep_Tool::Surface(aF);
329 GeomAdaptor_Surface aGAS(aSurf);
331 bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aST);
332 if (!bIsAllowedType) {
337 if (aST==GeomAbs_Plane) {
342 aAx3=aPln.Position();
344 aInfo.SetKindOfShape(GEOMAlgo_KS_PLANE);
345 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
346 aInfo.SetLocation(aP0);
347 aInfo.SetPosition(aAx3);
353 //aSurf->Bounds(aUMin, aUMax, aVMin, aVMax);
354 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
355 bInfU1=Precision::IsNegativeInfinite(aUMin);
356 bInfU2=Precision::IsPositiveInfinite(aUMax);
357 bInfV1=Precision::IsNegativeInfinite(aVMin);
358 bInfV2=Precision::IsPositiveInfinite(aVMax);
360 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
362 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
365 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
368 FillDetails(aF, aPln);
369 }// if (aCT==GeomAbs_Line) {
372 else if (aST==GeomAbs_Sphere) {
375 aSphere=aGAS.Sphere();
376 aP0=aSphere.Location();
377 aAx3=aSphere.Position();
378 aR1=aSphere.Radius();
380 aInfo.SetKindOfShape(GEOMAlgo_KS_SPHERE);
381 aInfo.SetLocation(aP0);
382 aInfo.SetPosition(aAx3);
383 aInfo.SetRadius1(aR1);
389 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
390 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
392 FillDetails(aF, aSphere);
393 }// else if (aST==GeomAbs_Sphere) {
396 else if (aST==GeomAbs_Cylinder) {
399 aCyl=aGAS.Cylinder();
401 aAx3=aCyl.Position();
404 aInfo.SetKindOfShape(GEOMAlgo_KS_CYLINDER);
405 aInfo.SetLocation(aP0);
406 aInfo.SetPosition(aAx3);
407 aInfo.SetRadius1(aR1);
413 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
414 bInfU1=Precision::IsNegativeInfinite(aUMin);
415 bInfU2=Precision::IsPositiveInfinite(aUMax);
416 bInfV1=Precision::IsNegativeInfinite(aVMin);
417 bInfV2=Precision::IsPositiveInfinite(aVMax);
419 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
421 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
424 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
426 FillDetails(aF, aCyl);
430 else if (aST==GeomAbs_Cone) {
434 aP0=aCone.Location();
435 aAx3=aCone.Position();
438 aInfo.SetKindOfShape(GEOMAlgo_KS_CONE);
439 aInfo.SetLocation(aP0);
440 aInfo.SetPosition(aAx3);
441 //aInfo.SetRadius1(aR1);
447 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
448 bInfU1=Precision::IsNegativeInfinite(aUMin);
449 bInfU2=Precision::IsPositiveInfinite(aUMax);
450 bInfV1=Precision::IsNegativeInfinite(aVMin);
451 bInfV2=Precision::IsPositiveInfinite(aVMax);
453 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
455 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
458 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
460 FillDetails(aF, aCone);
464 else if (aST==GeomAbs_Torus) {
468 aP0=aTorus.Location();
469 aAx3=aTorus.Position();
470 aR1=aTorus.MajorRadius();
471 aR2=aTorus.MinorRadius();
473 aInfo.SetKindOfShape(GEOMAlgo_KS_TORUS);
474 aInfo.SetLocation(aP0);
475 aInfo.SetPosition(aAx3);
476 aInfo.SetRadius1(aR1);
477 aInfo.SetRadius2(aR2);
483 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
485 FillDetails(aF, aTorus);
488 //=======================================================================
491 //=======================================================================
492 void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS)
496 Standard_Boolean bDegenerated, bIsAllowedType;
497 Standard_Integer aNbV;
498 Standard_Real aR1, aR2;
499 gp_Pnt aP, aP1, aP2, aPc;
502 Standard_Real aT1, aT2;
503 GeomAbs_CurveType aCT;
504 Handle(Geom_Curve) aC3D;
506 //----------------------------------------------------
507 if (myMapInfo.Contains(aS)) {
511 GEOMAlgo_ShapeInfo aInfoX;
512 myMapInfo.Add(aS, aInfoX);
514 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
515 //----------------------------------------------------
516 aInfo.SetType(TopAbs_EDGE);
518 FillNbSubShapes(aS, aInfo);
522 bDegenerated=BRep_Tool::Degenerated(aE);
524 aInfo.SetKindOfShape(GEOMAlgo_KS_DEGENERATED);
529 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
530 GeomAdaptor_Curve aGAC(aC3D);
532 bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aCT);
533 if (!bIsAllowedType) {
537 //modified by NIZNHY-PKV Tue Jul 03 10:19:03 2012f
539 if (aCT==GeomAbs_BSplineCurve) {
540 Standard_Integer aNbKnots, aNbPoles, aDegree;
541 Standard_Real aLength;
542 gp_XYZ aXYZ1, aXYZ2, aXYZc;
543 Handle(Geom_BSplineCurve) aBSp;
546 aNbKnots=aBSp->NbKnots();
547 aNbPoles=aBSp->NbPoles();
548 aDegree =aBSp->Degree();
549 if (!(aDegree==1 && aNbKnots==2 && aNbPoles==2)) {
550 return; // unallowed B-Spline curve
553 aInfo.SetKindOfShape(GEOMAlgo_KS_BSPLINE);
554 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
556 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
557 aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
563 aLength=aP1.Distance(aP2);
564 aInfo.SetLength(aLength);
571 aInfo.SetLocation(aPc);
573 gp_Vec aVec(aPc, aP2);
575 aInfo.SetDirection(aDir);
577 //modified by NIZNHY-PKV Tue Jul 03 10:19:06 2012t
579 else if (aCT==GeomAbs_Line) {
580 Standard_Boolean bInf1, bInf2;
581 Standard_Real aLength;
583 gp_XYZ aXYZ1, aXYZ2, aXYZc;
589 aInfo.SetKindOfShape(GEOMAlgo_KS_LINE);
590 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
591 aInfo.SetLocation(aP);
592 aInfo.SetDirection(aD);
594 bInf1=Precision::IsNegativeInfinite(aT1);
595 bInf2=Precision::IsPositiveInfinite(aT2);
597 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
598 aInfo.SetKindOfName(GEOMAlgo_KN_LINE);
601 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
602 aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
608 aLength=aP1.Distance(aP2);
615 gp_Vec aVec(aPc, aP2);
618 aInfo.SetLocation(aPc);
619 aInfo.SetDirection(aDir);
620 aInfo.SetLength(aLength);
622 }// if (aCT==GeomAbs_Line) {
625 else if (aCT==GeomAbs_Circle) {
630 aAx2=aCirc.Position();
633 aInfo.SetKindOfShape(GEOMAlgo_KS_CIRCLE);
634 aInfo.SetLocation(aP);
635 aInfo.SetPosition(aAx2);
636 aInfo.SetRadius1(aR1);
638 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
640 myErrorStatus=11; // circle edge without vertices
643 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
650 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
651 aInfo.SetKindOfName(GEOMAlgo_KN_CIRCLE);
654 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
655 aInfo.SetKindOfName(GEOMAlgo_KN_ARCCIRCLE);
657 gp_Vec aVecX(aP, aP1);
659 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
660 aInfo.SetPosition(aAx2new);
662 }// else if (aCT==GeomAbs_Circle) {
665 else if (aCT==GeomAbs_Ellipse) {
668 aElips=aGAC.Ellipse();
669 aP=aElips.Location();
670 aAx2=aElips.Position();
671 aR1=aElips.MajorRadius();
672 aR2=aElips.MinorRadius();
674 aInfo.SetKindOfShape(GEOMAlgo_KS_ELLIPSE);
675 aInfo.SetLocation(aP);
676 aInfo.SetPosition(aAx2);
677 aInfo.SetRadius1(aR1);
678 aInfo.SetRadius2(aR2);
680 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
682 myErrorStatus=11; // ellipse edge without vertices
685 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
692 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
693 aInfo.SetKindOfName(GEOMAlgo_KN_ELLIPSE);
696 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
697 aInfo.SetKindOfName(GEOMAlgo_KN_ARCELLIPSE);
699 gp_Vec aVecX(aP, aP1);
701 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
702 aInfo.SetPosition(aAx2new);
704 }// else if (aCT==GeomAbs_Ellipse) {
708 //=======================================================================
709 //function :FillVertex
711 //=======================================================================
712 void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS)
719 if (myMapInfo.Contains(aS)) {
723 GEOMAlgo_ShapeInfo aInfoX;
724 myMapInfo.Add(aS, aInfoX);
726 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
728 aV=TopoDS::Vertex(aS);
729 aP=BRep_Tool::Pnt(aV);
731 aInfo.SetType(TopAbs_VERTEX);
732 aInfo.SetLocation(aP);
733 myMapInfo.Add(aS, aInfo);
735 //=======================================================================
736 //function : FillNbSubshapes
738 //=======================================================================
739 void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS,
740 GEOMAlgo_ShapeInfo& aInfo)
744 Standard_Integer i, aNb, aNbS;
745 TopTools_IndexedMapOfShape aM;
746 TopAbs_ShapeEnum aST;
747 TopAbs_ShapeEnum aTypes[]= {
748 //TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX
761 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
762 for (i=0; i<aNb; ++i) {
763 if (aTypes[i]==aST) {
767 TopExp::MapShapes(aS, aTypes[i], aM);
769 aInfo.SetNbSubShapes(aTypes[i], aNbS);
772 //=======================================================================
775 //=======================================================================
776 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbShells(const TopoDS_Solid& aSd)
778 Standard_Integer iCnt;
784 for (; aIt.More(); aIt.Next()) {
785 //const TopoDS_Shape& aSh=aIt.Value();
790 //=======================================================================
793 //=======================================================================
794 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbWires(const TopoDS_Face& aF)
796 Standard_Integer iCnt;
802 for (; aIt.More(); aIt.Next()) {
803 //const TopoDS_Shape& aW=aIt.Value();
808 //=======================================================================
809 //function : IsAllowedType
811 //=======================================================================
812 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType(const GeomAbs_CurveType aCT)
814 Standard_Boolean bRet;
815 Standard_Integer i, aNb;
816 GeomAbs_CurveType aTypes[]={
820 GeomAbs_BSplineCurve //modified by NIZNHY-PKV Tue Jul 03 10:18:01 2012ft
824 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
825 for (i=0; i<aNb && !bRet; ++i) {
826 bRet=(aCT==aTypes[i]);
830 //=======================================================================
831 //function : IsAllowedType
833 //=======================================================================
834 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType(const GeomAbs_SurfaceType aST)
836 Standard_Boolean bRet;
837 Standard_Integer i, aNb;
838 GeomAbs_SurfaceType aTypes[]={
839 GeomAbs_Plane, GeomAbs_Cylinder,
840 GeomAbs_Cone, GeomAbs_Sphere,
845 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
846 for (i=0; i<aNb && !bRet; ++i) {
847 bRet=(aST==aTypes[i]);
856 // 1 - The object is just initialized
859 // 11 - circle/ellipse edge without vertices