1 // Copyright (C) 2007-2010 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
20 #include <GEOMAlgo_ShapeInfoFiller.ixx>
22 #include <Precision.hxx>
28 #include <Geom_Curve.hxx>
29 #include <GeomAdaptor_Curve.hxx>
31 #include <TopoDS_Vertex.hxx>
33 #include <TopoDS_Edge.hxx>
35 #include <BRep_Tool.hxx>
38 #include <TopTools_IndexedMapOfShape.hxx>
39 #include <gp_Circ.hxx>
41 #include <gp_Elips.hxx>
42 #include <TopoDS_Iterator.hxx>
43 #include <TopoDS_Wire.hxx>
45 #include <Geom_Surface.hxx>
46 #include <TopoDS_Face.hxx>
47 #include <GeomAdaptor_Surface.hxx>
49 #include <gp_Sphere.hxx>
51 #include <BRepTools.hxx>
52 #include <gp_Cylinder.hxx>
53 #include <gp_Cone.hxx>
54 #include <gp_Torus.hxx>
55 #include <TopoDS_Solid.hxx>
61 Standard_Boolean IsAllowedType(const GeomAbs_CurveType aCT);
63 Standard_Boolean IsAllowedType(const GeomAbs_SurfaceType aST);
65 Standard_Integer NbWires(const TopoDS_Face& aF);
67 Standard_Integer NbShells(const TopoDS_Solid& aS);
69 //=======================================================================
72 //=======================================================================
73 GEOMAlgo_ShapeInfoFiller::GEOMAlgo_ShapeInfoFiller()
79 //=======================================================================
82 //=======================================================================
83 GEOMAlgo_ShapeInfoFiller::~GEOMAlgo_ShapeInfoFiller()
86 //=======================================================================
87 //function : SetTolerance
89 //=======================================================================
90 void GEOMAlgo_ShapeInfoFiller::SetTolerance(const Standard_Real aT)
94 //=======================================================================
95 //function : Tolerance
97 //=======================================================================
98 Standard_Real GEOMAlgo_ShapeInfoFiller::Tolerance()const
102 //=======================================================================
103 //function : SetShape
105 //=======================================================================
106 void GEOMAlgo_ShapeInfoFiller::SetShape(const TopoDS_Shape& aS)
110 //=======================================================================
113 //=======================================================================
114 const TopoDS_Shape& GEOMAlgo_ShapeInfoFiller::Shape() const
118 //=======================================================================
121 //=======================================================================
122 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info() const
124 return Info(myShape);
126 //=======================================================================
129 //=======================================================================
130 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info(const TopoDS_Shape& aS) const
133 if (myMapInfo.Contains(aS)) {
134 const GEOMAlgo_ShapeInfo& aInfo=myMapInfo.FindFromKey(aS);
141 //=======================================================================
142 //function : CheckData
144 //=======================================================================
145 void GEOMAlgo_ShapeInfoFiller::CheckData()
149 if (myShape.IsNull()) {
154 //=======================================================================
157 //=======================================================================
158 void GEOMAlgo_ShapeInfoFiller::Perform()
171 //=======================================================================
172 //function :FillShape
174 //=======================================================================
175 void GEOMAlgo_ShapeInfoFiller::FillShape(const TopoDS_Shape& aS)
177 TopAbs_ShapeEnum aType;
179 aType=aS.ShapeType();
200 case TopAbs_COMPSOLID:
201 case TopAbs_COMPOUND:
209 //=======================================================================
210 //function :FillSubShapes
212 //=======================================================================
213 void GEOMAlgo_ShapeInfoFiller::FillSubShapes(const TopoDS_Shape& aS)
218 for (; aIt.More(); aIt.Next()){
219 const TopoDS_Shape& aSx=aIt.Value();
223 //=======================================================================
224 //function : FillContainer
226 //=======================================================================
227 void GEOMAlgo_ShapeInfoFiller::FillContainer(const TopoDS_Shape& aS)
231 Standard_Boolean bIsClosed;
232 TopAbs_ShapeEnum aType;
233 GEOMAlgo_KindOfClosed aKC;
235 aType=aS.ShapeType();
236 //----------------------------------------------------
237 if (myMapInfo.Contains(aS)) {
241 GEOMAlgo_ShapeInfo aInfoX;
242 myMapInfo.Add(aS, aInfoX);
244 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
245 //----------------------------------------------------
246 aInfo.SetType(aType);
247 FillNbSubShapes(aS, aInfo);
249 if (aType==TopAbs_SHELL) {
250 bIsClosed=BRep_Tool::IsClosed(aS);
251 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
252 aInfo.SetKindOfClosed(aKC);
254 else if (aType==TopAbs_WIRE) {
256 TopoDS_Vertex aV1, aV2;
259 TopExp::Vertices(aW, aV1, aV2);
261 bIsClosed=aV1.IsSame(aV2);
262 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
263 aInfo.SetKindOfClosed(aKC);
268 //=======================================================================
269 //function : FillSolid
271 //=======================================================================
272 void GEOMAlgo_ShapeInfoFiller::FillSolid(const TopoDS_Shape& aS)
274 Standard_Integer aNbShells;
278 //----------------------------------------------------
279 if (myMapInfo.Contains(aS)) {
283 GEOMAlgo_ShapeInfo aInfoX;
284 myMapInfo.Add(aS, aInfoX);
286 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
287 //----------------------------------------------------
288 aInfo.SetType(TopAbs_SOLID);
289 FillNbSubShapes(aS, aInfo);
292 aSd=TopoDS::Solid(aS);
294 aNbShells=NbShells(aSd);
301 //=======================================================================
304 //=======================================================================
305 void GEOMAlgo_ShapeInfoFiller::FillFace(const TopoDS_Shape& aS)
309 Standard_Boolean bIsAllowedType;
310 Standard_Integer aNbWires;//, iRet
311 Standard_Boolean bInf, bInfU1, bInfU2, bInfV1, bInfV2;
312 Standard_Real aUMin, aUMax, aVMin, aVMax, aR1, aR2;
316 GeomAbs_SurfaceType aST;
317 Handle(Geom_Surface) aSurf;
319 //GEOMAlgo_KindOfName aKindOfName;
320 //----------------------------------------------------
321 if (myMapInfo.Contains(aS)) {
325 GEOMAlgo_ShapeInfo aInfoX;
326 myMapInfo.Add(aS, aInfoX);
328 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
329 //----------------------------------------------------
330 aInfo.SetType(TopAbs_FACE);
332 FillNbSubShapes(aS, aInfo);
338 aNbWires=NbWires(aF);
340 aSurf=BRep_Tool::Surface(aF);
341 GeomAdaptor_Surface aGAS(aSurf);
343 bIsAllowedType=IsAllowedType(aST);
344 if (!bIsAllowedType) {
349 if (aST==GeomAbs_Plane) {
354 aAx3=aPln.Position();
356 aInfo.SetKindOfShape(GEOMAlgo_KS_PLANE);
357 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
358 aInfo.SetLocation(aP0);
359 aInfo.SetPosition(aAx3);
361 if (aNbWires>1) return;
363 //aSurf->Bounds(aUMin, aUMax, aVMin, aVMax);
364 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
365 bInfU1=Precision::IsNegativeInfinite(aUMin);
366 bInfU2=Precision::IsPositiveInfinite(aUMax);
367 bInfV1=Precision::IsNegativeInfinite(aVMin);
368 bInfV2=Precision::IsPositiveInfinite(aVMax);
370 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
372 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
375 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
378 FillDetails(aF, aPln);
379 }// if (aCT==GeomAbs_Line) {
382 else if (aST==GeomAbs_Sphere) {
385 aSphere=aGAS.Sphere();
386 aP0=aSphere.Location();
387 aAx3=aSphere.Position();
388 aR1=aSphere.Radius();
390 aInfo.SetKindOfShape(GEOMAlgo_KS_SPHERE);
391 aInfo.SetLocation(aP0);
392 aInfo.SetPosition(aAx3);
393 aInfo.SetRadius1(aR1);
395 if (aNbWires>1) return;
397 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
398 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
400 FillDetails(aF, aSphere);
401 }// else if (aST==GeomAbs_Sphere) {
404 else if (aST==GeomAbs_Cylinder) {
407 aCyl=aGAS.Cylinder();
409 aAx3=aCyl.Position();
412 aInfo.SetKindOfShape(GEOMAlgo_KS_CYLINDER);
413 aInfo.SetLocation(aP0);
414 aInfo.SetPosition(aAx3);
415 aInfo.SetRadius1(aR1);
417 if (aNbWires>1) return;
419 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
420 bInfU1=Precision::IsNegativeInfinite(aUMin);
421 bInfU2=Precision::IsPositiveInfinite(aUMax);
422 bInfV1=Precision::IsNegativeInfinite(aVMin);
423 bInfV2=Precision::IsPositiveInfinite(aVMax);
425 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
427 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
430 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
432 FillDetails(aF, aCyl);
436 else if (aST==GeomAbs_Cone) {
440 aP0=aCone.Location();
441 aAx3=aCone.Position();
444 aInfo.SetKindOfShape(GEOMAlgo_KS_CONE);
445 aInfo.SetLocation(aP0);
446 aInfo.SetPosition(aAx3);
447 //aInfo.SetRadius1(aR1);
449 if (aNbWires>1) return;
451 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
452 bInfU1=Precision::IsNegativeInfinite(aUMin);
453 bInfU2=Precision::IsPositiveInfinite(aUMax);
454 bInfV1=Precision::IsNegativeInfinite(aVMin);
455 bInfV2=Precision::IsPositiveInfinite(aVMax);
457 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
459 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
462 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
464 FillDetails(aF, aCone);
468 else if (aST==GeomAbs_Torus) {
472 aP0=aTorus.Location();
473 aAx3=aTorus.Position();
474 aR1=aTorus.MajorRadius();
475 aR2=aTorus.MinorRadius();
477 aInfo.SetKindOfShape(GEOMAlgo_KS_TORUS);
478 aInfo.SetLocation(aP0);
479 aInfo.SetPosition(aAx3);
480 aInfo.SetRadius1(aR1);
481 aInfo.SetRadius2(aR2);
483 if (aNbWires>1) return;
485 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
487 FillDetails(aF, aTorus);
490 //=======================================================================
493 //=======================================================================
494 void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS)
498 Standard_Boolean bDegenerated, bIsAllowedType;
499 Standard_Integer aNbV;
500 Standard_Real aR1, aR2;
501 gp_Pnt aP, aP1, aP2, aPc;
504 Standard_Real aT1, aT2;
505 GeomAbs_CurveType aCT;
506 Handle(Geom_Curve) aC3D;
508 //----------------------------------------------------
509 if (myMapInfo.Contains(aS)) {
513 GEOMAlgo_ShapeInfo aInfoX;
514 myMapInfo.Add(aS, aInfoX);
516 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
517 //----------------------------------------------------
518 aInfo.SetType(TopAbs_EDGE);
520 FillNbSubShapes(aS, aInfo);
524 bDegenerated=BRep_Tool::Degenerated(aE);
526 aInfo.SetKindOfShape(GEOMAlgo_KS_DEGENERATED);
531 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
532 GeomAdaptor_Curve aGAC(aC3D);
534 bIsAllowedType=IsAllowedType(aCT);
535 if (!bIsAllowedType) {
540 if (aCT==GeomAbs_Line) {
541 Standard_Boolean bInf1, bInf2;
542 Standard_Real aLength;
544 gp_XYZ aXYZ1, aXYZ2, aXYZc;
550 aInfo.SetKindOfShape(GEOMAlgo_KS_LINE);
551 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
552 aInfo.SetLocation(aP);
553 aInfo.SetDirection(aD);
555 bInf1=Precision::IsNegativeInfinite(aT1);
556 bInf2=Precision::IsPositiveInfinite(aT2);
558 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
559 aInfo.SetKindOfName(GEOMAlgo_KN_LINE);
562 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
563 aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
569 aLength=aP1.Distance(aP2);
576 gp_Vec aVec(aPc, aP2);
579 aInfo.SetLocation(aPc);
580 aInfo.SetDirection(aDir);
581 aInfo.SetLength(aLength);
583 }// if (aCT==GeomAbs_Line) {
586 else if (aCT==GeomAbs_Circle) {
591 aAx2=aCirc.Position();
594 aInfo.SetKindOfShape(GEOMAlgo_KS_CIRCLE);
595 aInfo.SetLocation(aP);
596 aInfo.SetPosition(aAx2);
597 aInfo.SetRadius1(aR1);
599 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
601 myErrorStatus=11; // circle edge without vertices
604 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
611 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
612 aInfo.SetKindOfName(GEOMAlgo_KN_CIRCLE);
615 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
616 aInfo.SetKindOfName(GEOMAlgo_KN_ARCCIRCLE);
618 gp_Vec aVecX(aP, aP1);
620 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
621 aInfo.SetPosition(aAx2new);
623 }// else if (aCT==GeomAbs_Circle) {
626 else if (aCT==GeomAbs_Ellipse) {
629 aElips=aGAC.Ellipse();
630 aP=aElips.Location();
631 aAx2=aElips.Position();
632 aR1=aElips.MajorRadius();
633 aR2=aElips.MinorRadius();
635 aInfo.SetKindOfShape(GEOMAlgo_KS_ELLIPSE);
636 aInfo.SetLocation(aP);
637 aInfo.SetPosition(aAx2);
638 aInfo.SetRadius1(aR1);
639 aInfo.SetRadius2(aR2);
641 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
643 myErrorStatus=11; // ellipse edge without vertices
646 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
653 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
654 aInfo.SetKindOfName(GEOMAlgo_KN_ELLIPSE);
657 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
658 aInfo.SetKindOfName(GEOMAlgo_KN_ARCELLIPSE);
660 gp_Vec aVecX(aP, aP1);
662 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
663 aInfo.SetPosition(aAx2new);
665 }// else if (aCT==GeomAbs_Ellipse) {
669 //=======================================================================
670 //function :FillVertex
672 //=======================================================================
673 void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS)
680 if (myMapInfo.Contains(aS)) {
684 GEOMAlgo_ShapeInfo aInfoX;
685 myMapInfo.Add(aS, aInfoX);
687 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
689 aV=TopoDS::Vertex(aS);
690 aP=BRep_Tool::Pnt(aV);
692 aInfo.SetType(TopAbs_VERTEX);
693 aInfo.SetLocation(aP);
694 myMapInfo.Add(aS, aInfo);
696 //=======================================================================
697 //function : FillNbSubshapes
699 //=======================================================================
700 void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS,
701 GEOMAlgo_ShapeInfo& aInfo)
705 Standard_Integer i, aNb, aNbS;
706 TopTools_IndexedMapOfShape aM;
707 TopAbs_ShapeEnum aST;
708 TopAbs_ShapeEnum aTypes[]= {
709 //TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX
722 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
723 for (i=0; i<aNb; ++i) {
724 if (aTypes[i]==aST) {
728 TopExp::MapShapes(aS, aTypes[i], aM);
730 aInfo.SetNbSubShapes(aTypes[i], aNbS);
733 //=======================================================================
736 //=======================================================================
737 Standard_Integer NbShells(const TopoDS_Solid& aSd)
739 Standard_Integer iCnt;
745 for (; aIt.More(); aIt.Next()){
746 //const TopoDS_Shape& aSh=aIt.Value();
751 //=======================================================================
754 //=======================================================================
755 Standard_Integer NbWires(const TopoDS_Face& aF)
757 Standard_Integer iCnt;
763 for (; aIt.More(); aIt.Next()){
764 //const TopoDS_Shape& aW=aIt.Value();
769 //=======================================================================
770 //function : IsAllowedType
772 //=======================================================================
773 Standard_Boolean IsAllowedType(const GeomAbs_CurveType aCT)
775 Standard_Boolean bRet;
776 Standard_Integer i, aNb;
777 GeomAbs_CurveType aTypes[]={
778 GeomAbs_Line, GeomAbs_Circle, GeomAbs_Ellipse
782 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
783 for (i=0; i<aNb && !bRet; ++i) {
784 bRet=(aCT==aTypes[i]);
789 //=======================================================================
790 //function : IsAllowedType
792 //=======================================================================
793 Standard_Boolean IsAllowedType(const GeomAbs_SurfaceType aST)
795 Standard_Boolean bRet;
796 Standard_Integer i, aNb;
797 GeomAbs_SurfaceType aTypes[]={
798 GeomAbs_Plane, GeomAbs_Cylinder,
799 GeomAbs_Cone, GeomAbs_Sphere,
804 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
805 for (i=0; i<aNb && !bRet; ++i) {
806 bRet=(aST==aTypes[i]);
815 // 1 - The object is just initialized
818 // 11 - circle/ellipse edge without vertices