1 // Copyright (C) 2007-2016 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
120 (const TopoDS_Shape& aS) const
123 if (myMapInfo.Contains(aS)) {
124 const GEOMAlgo_ShapeInfo& aInfo=myMapInfo.FindFromKey(aS);
131 //=======================================================================
132 //function : CheckData
134 //=======================================================================
135 void GEOMAlgo_ShapeInfoFiller::CheckData()
139 if (myShape.IsNull()) {
144 //=======================================================================
147 //=======================================================================
148 void GEOMAlgo_ShapeInfoFiller::Perform()
161 //=======================================================================
162 //function :FillShape
164 //=======================================================================
165 void GEOMAlgo_ShapeInfoFiller::FillShape(const TopoDS_Shape& aS)
167 TopAbs_ShapeEnum aType;
169 aType=aS.ShapeType();
190 case TopAbs_COMPSOLID:
191 case TopAbs_COMPOUND:
199 //=======================================================================
200 //function :FillSubShapes
202 //=======================================================================
203 void GEOMAlgo_ShapeInfoFiller::FillSubShapes(const TopoDS_Shape& aS)
208 for (; aIt.More(); aIt.Next()) {
209 const TopoDS_Shape& aSx=aIt.Value();
213 //=======================================================================
214 //function : FillContainer
216 //=======================================================================
217 void GEOMAlgo_ShapeInfoFiller::FillContainer(const TopoDS_Shape& aS)
221 Standard_Boolean bIsClosed;
222 TopAbs_ShapeEnum aType;
223 GEOMAlgo_KindOfClosed aKC;
225 aType=aS.ShapeType();
226 //----------------------------------------------------
227 if (myMapInfo.Contains(aS)) {
231 GEOMAlgo_ShapeInfo aInfoX;
232 myMapInfo.Add(aS, aInfoX);
234 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
235 //----------------------------------------------------
236 aInfo.SetType(aType);
237 FillNbSubShapes(aS, aInfo);
239 if (aType==TopAbs_SHELL) {
240 bIsClosed=BRep_Tool::IsClosed(aS);
241 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
242 aInfo.SetKindOfClosed(aKC);
244 else if (aType==TopAbs_WIRE) {
246 TopoDS_Vertex aV1, aV2;
249 TopExp::Vertices(aW, aV1, aV2);
251 bIsClosed=aV1.IsSame(aV2);
252 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
253 aInfo.SetKindOfClosed(aKC);
258 //=======================================================================
259 //function : FillSolid
261 //=======================================================================
262 void GEOMAlgo_ShapeInfoFiller::FillSolid(const TopoDS_Shape& aS)
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);
285 //=======================================================================
288 //=======================================================================
289 void GEOMAlgo_ShapeInfoFiller::FillFace(const TopoDS_Shape& aS)
292 if (myMapInfo.Contains(aS)) {
296 Standard_Boolean bIsAllowedType;
297 Standard_Boolean bInf, bInfU1, bInfU2, bInfV1, bInfV2;
298 Standard_Real aUMin, aUMax, aVMin, aVMax, aR1, aR2, dV;
302 GeomAbs_SurfaceType aST;
303 Handle(Geom_Surface) aSurf;
305 //----------------------------------------------------
306 GEOMAlgo_ShapeInfo aInfoX;
307 myMapInfo.Add(aS, aInfoX);
309 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
310 //----------------------------------------------------
311 aInfo.SetType(TopAbs_FACE);
313 FillNbSubShapes(aS, aInfo);
319 aSurf=BRep_Tool::Surface(aF);
320 GeomAdaptor_Surface aGAS(aSurf);
322 bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aST);
323 if (!bIsAllowedType) {
327 //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
329 if (aST==GeomAbs_Plane) {
334 aAx3=aPln.Position();
336 aInfo.SetKindOfShape(GEOMAlgo_KS_PLANE);
337 aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
338 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
339 aInfo.SetLocation(aP0);
340 aInfo.SetPosition(aAx3);
342 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
343 bInfU1=Precision::IsNegativeInfinite(aUMin);
344 bInfU2=Precision::IsPositiveInfinite(aUMax);
345 bInfV1=Precision::IsNegativeInfinite(aVMin);
346 bInfV2=Precision::IsPositiveInfinite(aVMax);
348 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
350 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
354 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
356 FillDetails(aF, aPln);
357 }// if (aCT==GeomAbs_Line) {
359 //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
361 else if (aST==GeomAbs_Sphere) {
364 aSphere=aGAS.Sphere();
365 aP0=aSphere.Location();
366 aAx3=aSphere.Position();
367 aR1=aSphere.Radius();
369 aInfo.SetKindOfShape(GEOMAlgo_KS_SPHERE);
370 aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
371 aInfo.SetLocation(aP0);
372 aInfo.SetPosition(aAx3);
373 aInfo.SetRadius1(aR1);
375 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
376 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
378 FillDetails(aF, aSphere);
379 }// else if (aST==GeomAbs_Sphere) {
381 //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
383 else if (aST==GeomAbs_Cylinder) {
386 aCyl=aGAS.Cylinder();
388 aAx3=aCyl.Position();
391 aInfo.SetKindOfShape(GEOMAlgo_KS_CYLINDER);
392 aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
393 aInfo.SetLocation(aP0);
394 aInfo.SetPosition(aAx3);
395 aInfo.SetRadius1(aR1);
397 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
398 bInfU1=Precision::IsNegativeInfinite(aUMin);
399 bInfU2=Precision::IsPositiveInfinite(aUMax);
400 bInfV1=Precision::IsNegativeInfinite(aVMin);
401 bInfV2=Precision::IsPositiveInfinite(aVMax);
403 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
405 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
409 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
414 FillDetails(aF, aCyl);
417 //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
419 else if (aST==GeomAbs_Cone) {
420 Standard_Real aSemiAngle;
424 aP0=aCone.Location();
425 aAx3=aCone.Position();
427 aInfo.SetKindOfShape(GEOMAlgo_KS_CONE);
428 aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
429 aInfo.SetLocation(aP0);
430 aInfo.SetPosition(aAx3);
432 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
433 bInfU1=Precision::IsNegativeInfinite(aUMin);
434 bInfU2=Precision::IsPositiveInfinite(aUMax);
435 bInfV1=Precision::IsNegativeInfinite(aVMin);
436 bInfV2=Precision::IsPositiveInfinite(aVMax);
438 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
440 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
444 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
446 aSemiAngle=fabs(aCone.SemiAngle());
447 dV=(aVMax-aVMin)*cos(aSemiAngle);
451 FillDetails(aF, aCone);
454 //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
456 else if (aST==GeomAbs_Torus) {
460 aP0=aTorus.Location();
461 aAx3=aTorus.Position();
462 aR1=aTorus.MajorRadius();
463 aR2=aTorus.MinorRadius();
465 aInfo.SetKindOfShape(GEOMAlgo_KS_TORUS);
466 aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);
467 aInfo.SetLocation(aP0);
468 aInfo.SetPosition(aAx3);
469 aInfo.SetRadius1(aR1);
470 aInfo.SetRadius2(aR2);
472 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
474 FillDetails(aF, aTorus);
477 //=======================================================================
480 //=======================================================================
481 void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS)
485 Standard_Boolean bDegenerated, bIsAllowedType;
486 Standard_Integer aNbV;
487 Standard_Real aR1, aR2;
488 gp_Pnt aP, aP1, aP2, aPc;
491 Standard_Real aT1, aT2;
492 GeomAbs_CurveType aCT;
493 Handle(Geom_Curve) aC3D;
495 //----------------------------------------------------
496 if (myMapInfo.Contains(aS)) {
500 GEOMAlgo_ShapeInfo aInfoX;
501 myMapInfo.Add(aS, aInfoX);
503 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
504 //----------------------------------------------------
505 aInfo.SetType(TopAbs_EDGE);
507 FillNbSubShapes(aS, aInfo);
511 bDegenerated=BRep_Tool::Degenerated(aE);
513 aInfo.SetKindOfShape(GEOMAlgo_KS_DEGENERATED);
518 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
519 GeomAdaptor_Curve aGAC(aC3D);
521 bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aCT);
522 if (!bIsAllowedType) {
527 if (aCT==GeomAbs_BSplineCurve) {
528 Standard_Integer aNbKnots, aNbPoles, aDegree;
529 Standard_Real aLength;
530 gp_XYZ aXYZ1, aXYZ2, aXYZc;
531 Handle(Geom_BSplineCurve) aBSp;
534 aNbKnots=aBSp->NbKnots();
535 aNbPoles=aBSp->NbPoles();
536 aDegree =aBSp->Degree();
537 if (!(aDegree==1 && aNbKnots==2 && aNbPoles==2)) {
538 return; // unallowed B-Spline curve
541 aInfo.SetKindOfShape(GEOMAlgo_KS_BSPLINE);
542 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
544 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
545 aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
551 aLength=aP1.Distance(aP2);
552 aInfo.SetLength(aLength);
559 aInfo.SetLocation(aPc);
561 if ( aLength >= gp::Resolution() ) {
562 gp_Vec aVec(aPc, aP2);
564 aInfo.SetDirection(aDir);
568 else if (aCT==GeomAbs_Line) {
569 Standard_Boolean bInf1, bInf2;
570 Standard_Real aLength;
572 gp_XYZ aXYZ1, aXYZ2, aXYZc;
578 aInfo.SetKindOfShape(GEOMAlgo_KS_LINE);
579 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
580 aInfo.SetLocation(aP);
581 aInfo.SetDirection(aD);
583 bInf1=Precision::IsNegativeInfinite(aT1);
584 bInf2=Precision::IsPositiveInfinite(aT2);
586 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
587 aInfo.SetKindOfName(GEOMAlgo_KN_LINE);
590 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
591 aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
597 aLength=aP1.Distance(aP2);
604 gp_Vec aVec(aPc, aP2);
607 aInfo.SetLocation(aPc);
608 aInfo.SetDirection(aDir);
609 aInfo.SetLength(aLength);
611 }// if (aCT==GeomAbs_Line) {
614 else if (aCT==GeomAbs_Circle) {
619 aAx2=aCirc.Position();
622 aInfo.SetKindOfShape(GEOMAlgo_KS_CIRCLE);
623 aInfo.SetLocation(aP);
624 aInfo.SetPosition(aAx2);
625 aInfo.SetRadius1(aR1);
627 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
629 myErrorStatus=11; // circle edge without vertices
632 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
639 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
640 aInfo.SetKindOfName(GEOMAlgo_KN_CIRCLE);
643 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
644 aInfo.SetKindOfName(GEOMAlgo_KN_ARCCIRCLE);
646 gp_Vec aVecX(aP, aP1);
648 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
649 aInfo.SetPosition(aAx2new);
651 }// else if (aCT==GeomAbs_Circle) {
654 else if (aCT==GeomAbs_Ellipse) {
657 aElips=aGAC.Ellipse();
658 aP=aElips.Location();
659 aAx2=aElips.Position();
660 aR1=aElips.MajorRadius();
661 aR2=aElips.MinorRadius();
663 aInfo.SetKindOfShape(GEOMAlgo_KS_ELLIPSE);
664 aInfo.SetLocation(aP);
665 aInfo.SetPosition(aAx2);
666 aInfo.SetRadius1(aR1);
667 aInfo.SetRadius2(aR2);
669 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
671 myErrorStatus=11; // ellipse edge without vertices
674 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
681 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
682 aInfo.SetKindOfName(GEOMAlgo_KN_ELLIPSE);
685 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
686 aInfo.SetKindOfName(GEOMAlgo_KN_ARCELLIPSE);
688 gp_Vec aVecX(aP, aP1);
690 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
691 aInfo.SetPosition(aAx2new);
693 }// else if (aCT==GeomAbs_Ellipse) {
697 //=======================================================================
698 //function :FillVertex
700 //=======================================================================
701 void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS)
708 if (myMapInfo.Contains(aS)) {
712 GEOMAlgo_ShapeInfo aInfoX;
713 myMapInfo.Add(aS, aInfoX);
715 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
717 aV=TopoDS::Vertex(aS);
718 aP=BRep_Tool::Pnt(aV);
720 aInfo.SetType(TopAbs_VERTEX);
721 aInfo.SetLocation(aP);
722 myMapInfo.Add(aS, aInfo);
724 //=======================================================================
725 //function : FillNbSubshapes
727 //=======================================================================
728 void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS,
729 GEOMAlgo_ShapeInfo& aInfo)
733 Standard_Integer i, aNb, aNbS;
734 TopTools_IndexedMapOfShape aM;
735 TopAbs_ShapeEnum aST;
736 TopAbs_ShapeEnum aTypes[]= {
737 //TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX
750 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
751 for (i=0; i<aNb; ++i) {
752 if (aTypes[i]==aST) {
756 TopExp::MapShapes(aS, aTypes[i], aM);
758 aInfo.SetNbSubShapes(aTypes[i], aNbS);
761 //=======================================================================
764 //=======================================================================
765 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbShells
766 (const TopoDS_Solid& aSd)
768 Standard_Integer iCnt;
774 for (; aIt.More(); aIt.Next()) {
779 //=======================================================================
782 //=======================================================================
783 Standard_Integer GEOMAlgo_ShapeInfoFiller::NbWires
784 (const TopoDS_Face& aF)
786 Standard_Integer iCnt;
792 for (; aIt.More(); aIt.Next()) {
797 //=======================================================================
798 //function : IsAllowedType
800 //=======================================================================
801 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType
802 (const GeomAbs_CurveType aCT)
804 Standard_Boolean bRet;
805 Standard_Integer i, aNb;
806 GeomAbs_CurveType aTypes[]={
814 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
815 for (i=0; i<aNb && !bRet; ++i) {
816 bRet=(aCT==aTypes[i]);
820 //=======================================================================
821 //function : IsAllowedType
823 //=======================================================================
824 Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType
825 (const GeomAbs_SurfaceType aST)
827 Standard_Boolean bRet;
828 Standard_Integer i, aNb;
829 GeomAbs_SurfaceType aTypes[]={
830 GeomAbs_Plane, GeomAbs_Cylinder,
831 GeomAbs_Cone, GeomAbs_Sphere,
836 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
837 for (i=0; i<aNb && !bRet; ++i) {
838 bRet=(aST==aTypes[i]);
847 // 1 - The object is just initialized
850 // 11 - circle/ellipse edge without vertices