1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include <GEOMAlgo_ShapeInfoFiller.ixx>
24 #include <Precision.hxx>
30 #include <Geom_Curve.hxx>
31 #include <GeomAdaptor_Curve.hxx>
33 #include <TopoDS_Vertex.hxx>
35 #include <TopoDS_Edge.hxx>
37 #include <BRep_Tool.hxx>
40 #include <TopTools_IndexedMapOfShape.hxx>
41 #include <gp_Circ.hxx>
43 #include <gp_Elips.hxx>
44 #include <TopoDS_Iterator.hxx>
45 #include <TopoDS_Wire.hxx>
47 #include <Geom_Surface.hxx>
48 #include <TopoDS_Face.hxx>
49 #include <GeomAdaptor_Surface.hxx>
51 #include <gp_Sphere.hxx>
53 #include <BRepTools.hxx>
54 #include <gp_Cylinder.hxx>
55 #include <gp_Cone.hxx>
56 #include <gp_Torus.hxx>
57 #include <TopoDS_Solid.hxx>
63 Standard_Boolean IsAllowedType(const GeomAbs_CurveType aCT);
65 Standard_Boolean IsAllowedType(const GeomAbs_SurfaceType aST);
67 Standard_Integer NbWires(const TopoDS_Face& aF);
69 Standard_Integer NbShells(const TopoDS_Solid& aS);
71 //=======================================================================
74 //=======================================================================
75 GEOMAlgo_ShapeInfoFiller::GEOMAlgo_ShapeInfoFiller()
81 //=======================================================================
84 //=======================================================================
85 GEOMAlgo_ShapeInfoFiller::~GEOMAlgo_ShapeInfoFiller()
88 //=======================================================================
89 //function : SetTolerance
91 //=======================================================================
92 void GEOMAlgo_ShapeInfoFiller::SetTolerance(const Standard_Real aT)
96 //=======================================================================
97 //function : Tolerance
99 //=======================================================================
100 Standard_Real GEOMAlgo_ShapeInfoFiller::Tolerance()const
104 //=======================================================================
105 //function : SetShape
107 //=======================================================================
108 void GEOMAlgo_ShapeInfoFiller::SetShape(const TopoDS_Shape& aS)
112 //=======================================================================
115 //=======================================================================
116 const TopoDS_Shape& GEOMAlgo_ShapeInfoFiller::Shape() const
120 //=======================================================================
123 //=======================================================================
124 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info() const
126 return Info(myShape);
128 //=======================================================================
131 //=======================================================================
132 const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info(const TopoDS_Shape& aS) const
135 if (myMapInfo.Contains(aS)) {
136 const GEOMAlgo_ShapeInfo& aInfo=myMapInfo.FindFromKey(aS);
143 //=======================================================================
144 //function : CheckData
146 //=======================================================================
147 void GEOMAlgo_ShapeInfoFiller::CheckData()
151 if (myShape.IsNull()) {
156 //=======================================================================
159 //=======================================================================
160 void GEOMAlgo_ShapeInfoFiller::Perform()
173 //=======================================================================
174 //function :FillShape
176 //=======================================================================
177 void GEOMAlgo_ShapeInfoFiller::FillShape(const TopoDS_Shape& aS)
179 TopAbs_ShapeEnum aType;
181 aType=aS.ShapeType();
202 case TopAbs_COMPSOLID:
203 case TopAbs_COMPOUND:
211 //=======================================================================
212 //function :FillSubShapes
214 //=======================================================================
215 void GEOMAlgo_ShapeInfoFiller::FillSubShapes(const TopoDS_Shape& aS)
220 for (; aIt.More(); aIt.Next()){
221 const TopoDS_Shape& aSx=aIt.Value();
225 //=======================================================================
226 //function : FillContainer
228 //=======================================================================
229 void GEOMAlgo_ShapeInfoFiller::FillContainer(const TopoDS_Shape& aS)
233 Standard_Boolean bIsClosed;
234 TopAbs_ShapeEnum aType;
235 GEOMAlgo_KindOfClosed aKC;
237 aType=aS.ShapeType();
238 //----------------------------------------------------
239 if (myMapInfo.Contains(aS)) {
243 GEOMAlgo_ShapeInfo aInfoX;
244 myMapInfo.Add(aS, aInfoX);
246 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
247 //----------------------------------------------------
248 aInfo.SetType(aType);
249 FillNbSubShapes(aS, aInfo);
251 if (aType==TopAbs_SHELL) {
252 bIsClosed=BRep_Tool::IsClosed(aS);
253 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
254 aInfo.SetKindOfClosed(aKC);
256 else if (aType==TopAbs_WIRE) {
258 TopoDS_Vertex aV1, aV2;
261 TopExp::Vertices(aW, aV1, aV2);
263 bIsClosed=aV1.IsSame(aV2);
264 aKC=(bIsClosed) ? GEOMAlgo_KC_CLOSED :GEOMAlgo_KC_NOTCLOSED;
265 aInfo.SetKindOfClosed(aKC);
270 //=======================================================================
271 //function : FillSolid
273 //=======================================================================
274 void GEOMAlgo_ShapeInfoFiller::FillSolid(const TopoDS_Shape& aS)
276 Standard_Integer aNbShells;
280 //----------------------------------------------------
281 if (myMapInfo.Contains(aS)) {
285 GEOMAlgo_ShapeInfo aInfoX;
286 myMapInfo.Add(aS, aInfoX);
288 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
289 //----------------------------------------------------
290 aInfo.SetType(TopAbs_SOLID);
291 FillNbSubShapes(aS, aInfo);
294 aSd=TopoDS::Solid(aS);
296 aNbShells=NbShells(aSd);
303 //=======================================================================
306 //=======================================================================
307 void GEOMAlgo_ShapeInfoFiller::FillFace(const TopoDS_Shape& aS)
311 Standard_Boolean bIsAllowedType;
312 Standard_Integer aNbWires;//, iRet
313 Standard_Boolean bInf, bInfU1, bInfU2, bInfV1, bInfV2;
314 Standard_Real aUMin, aUMax, aVMin, aVMax, aR1, aR2;
318 GeomAbs_SurfaceType aST;
319 Handle(Geom_Surface) aSurf;
321 //GEOMAlgo_KindOfName aKindOfName;
322 //----------------------------------------------------
323 if (myMapInfo.Contains(aS)) {
327 GEOMAlgo_ShapeInfo aInfoX;
328 myMapInfo.Add(aS, aInfoX);
330 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
331 //----------------------------------------------------
332 aInfo.SetType(TopAbs_FACE);
334 FillNbSubShapes(aS, aInfo);
340 aNbWires=NbWires(aF);
342 aSurf=BRep_Tool::Surface(aF);
343 GeomAdaptor_Surface aGAS(aSurf);
345 bIsAllowedType=IsAllowedType(aST);
346 if (!bIsAllowedType) {
351 if (aST==GeomAbs_Plane) {
356 aAx3=aPln.Position();
358 aInfo.SetKindOfShape(GEOMAlgo_KS_PLANE);
359 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
360 aInfo.SetLocation(aP0);
361 aInfo.SetPosition(aAx3);
363 if (aNbWires>1) return;
365 //aSurf->Bounds(aUMin, aUMax, aVMin, aVMax);
366 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
367 bInfU1=Precision::IsNegativeInfinite(aUMin);
368 bInfU2=Precision::IsPositiveInfinite(aUMax);
369 bInfV1=Precision::IsNegativeInfinite(aVMin);
370 bInfV2=Precision::IsPositiveInfinite(aVMax);
372 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
374 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
377 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
380 FillDetails(aF, aPln);
381 }// if (aCT==GeomAbs_Line) {
384 else if (aST==GeomAbs_Sphere) {
387 aSphere=aGAS.Sphere();
388 aP0=aSphere.Location();
389 aAx3=aSphere.Position();
390 aR1=aSphere.Radius();
392 aInfo.SetKindOfShape(GEOMAlgo_KS_SPHERE);
393 aInfo.SetLocation(aP0);
394 aInfo.SetPosition(aAx3);
395 aInfo.SetRadius1(aR1);
397 if (aNbWires>1) return;
399 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
400 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
402 FillDetails(aF, aSphere);
403 }// else if (aST==GeomAbs_Sphere) {
406 else if (aST==GeomAbs_Cylinder) {
409 aCyl=aGAS.Cylinder();
411 aAx3=aCyl.Position();
414 aInfo.SetKindOfShape(GEOMAlgo_KS_CYLINDER);
415 aInfo.SetLocation(aP0);
416 aInfo.SetPosition(aAx3);
417 aInfo.SetRadius1(aR1);
419 if (aNbWires>1) return;
421 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
422 bInfU1=Precision::IsNegativeInfinite(aUMin);
423 bInfU2=Precision::IsPositiveInfinite(aUMax);
424 bInfV1=Precision::IsNegativeInfinite(aVMin);
425 bInfV2=Precision::IsPositiveInfinite(aVMax);
427 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
429 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
432 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
434 FillDetails(aF, aCyl);
438 else if (aST==GeomAbs_Cone) {
442 aP0=aCone.Location();
443 aAx3=aCone.Position();
446 aInfo.SetKindOfShape(GEOMAlgo_KS_CONE);
447 aInfo.SetLocation(aP0);
448 aInfo.SetPosition(aAx3);
449 //aInfo.SetRadius1(aR1);
451 if (aNbWires>1) return;
453 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
454 bInfU1=Precision::IsNegativeInfinite(aUMin);
455 bInfU2=Precision::IsPositiveInfinite(aUMax);
456 bInfV1=Precision::IsNegativeInfinite(aVMin);
457 bInfV2=Precision::IsPositiveInfinite(aVMax);
459 bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2);
461 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
464 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
466 FillDetails(aF, aCone);
470 else if (aST==GeomAbs_Torus) {
474 aP0=aTorus.Location();
475 aAx3=aTorus.Position();
476 aR1=aTorus.MajorRadius();
477 aR2=aTorus.MinorRadius();
479 aInfo.SetKindOfShape(GEOMAlgo_KS_TORUS);
480 aInfo.SetLocation(aP0);
481 aInfo.SetPosition(aAx3);
482 aInfo.SetRadius1(aR1);
483 aInfo.SetRadius2(aR2);
485 if (aNbWires>1) return;
487 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
489 FillDetails(aF, aTorus);
492 //=======================================================================
495 //=======================================================================
496 void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS)
500 Standard_Boolean bDegenerated, bIsAllowedType;
501 Standard_Integer aNbV;
502 Standard_Real aR1, aR2;
503 gp_Pnt aP, aP1, aP2, aPc;
506 Standard_Real aT1, aT2;
507 GeomAbs_CurveType aCT;
508 Handle(Geom_Curve) aC3D;
510 //----------------------------------------------------
511 if (myMapInfo.Contains(aS)) {
515 GEOMAlgo_ShapeInfo aInfoX;
516 myMapInfo.Add(aS, aInfoX);
518 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
519 //----------------------------------------------------
520 aInfo.SetType(TopAbs_EDGE);
522 FillNbSubShapes(aS, aInfo);
526 bDegenerated=BRep_Tool::Degenerated(aE);
528 aInfo.SetKindOfShape(GEOMAlgo_KS_DEGENERATED);
533 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
534 GeomAdaptor_Curve aGAC(aC3D);
536 bIsAllowedType=IsAllowedType(aCT);
537 if (!bIsAllowedType) {
542 if (aCT==GeomAbs_Line) {
543 Standard_Boolean bInf1, bInf2;
544 Standard_Real aLength;
546 gp_XYZ aXYZ1, aXYZ2, aXYZc;
552 aInfo.SetKindOfShape(GEOMAlgo_KS_LINE);
553 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
554 aInfo.SetLocation(aP);
555 aInfo.SetDirection(aD);
557 bInf1=Precision::IsNegativeInfinite(aT1);
558 bInf2=Precision::IsPositiveInfinite(aT2);
560 aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE);
561 aInfo.SetKindOfName(GEOMAlgo_KN_LINE);
564 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
565 aInfo.SetKindOfName(GEOMAlgo_KN_SEGMENT);
571 aLength=aP1.Distance(aP2);
578 gp_Vec aVec(aPc, aP2);
581 aInfo.SetLocation(aPc);
582 aInfo.SetDirection(aDir);
583 aInfo.SetLength(aLength);
585 }// if (aCT==GeomAbs_Line) {
588 else if (aCT==GeomAbs_Circle) {
593 aAx2=aCirc.Position();
596 aInfo.SetKindOfShape(GEOMAlgo_KS_CIRCLE);
597 aInfo.SetLocation(aP);
598 aInfo.SetPosition(aAx2);
599 aInfo.SetRadius1(aR1);
601 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
603 myErrorStatus=11; // circle edge without vertices
606 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
613 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
614 aInfo.SetKindOfName(GEOMAlgo_KN_CIRCLE);
617 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
618 aInfo.SetKindOfName(GEOMAlgo_KN_ARCCIRCLE);
620 gp_Vec aVecX(aP, aP1);
622 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
623 aInfo.SetPosition(aAx2new);
625 }// else if (aCT==GeomAbs_Circle) {
628 else if (aCT==GeomAbs_Ellipse) {
631 aElips=aGAC.Ellipse();
632 aP=aElips.Location();
633 aAx2=aElips.Position();
634 aR1=aElips.MajorRadius();
635 aR2=aElips.MinorRadius();
637 aInfo.SetKindOfShape(GEOMAlgo_KS_ELLIPSE);
638 aInfo.SetLocation(aP);
639 aInfo.SetPosition(aAx2);
640 aInfo.SetRadius1(aR1);
641 aInfo.SetRadius2(aR2);
643 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
645 myErrorStatus=11; // ellipse edge without vertices
648 aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED);
655 aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED);
656 aInfo.SetKindOfName(GEOMAlgo_KN_ELLIPSE);
659 aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED);
660 aInfo.SetKindOfName(GEOMAlgo_KN_ARCELLIPSE);
662 gp_Vec aVecX(aP, aP1);
664 gp_Ax2 aAx2new(aP, aAx2.Direction(), aDirX);
665 aInfo.SetPosition(aAx2new);
667 }// else if (aCT==GeomAbs_Ellipse) {
671 //=======================================================================
672 //function :FillVertex
674 //=======================================================================
675 void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS)
682 if (myMapInfo.Contains(aS)) {
686 GEOMAlgo_ShapeInfo aInfoX;
687 myMapInfo.Add(aS, aInfoX);
689 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS);
691 aV=TopoDS::Vertex(aS);
692 aP=BRep_Tool::Pnt(aV);
694 aInfo.SetType(TopAbs_VERTEX);
695 aInfo.SetLocation(aP);
696 myMapInfo.Add(aS, aInfo);
698 //=======================================================================
699 //function : FillNbSubshapes
701 //=======================================================================
702 void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS,
703 GEOMAlgo_ShapeInfo& aInfo)
707 Standard_Integer i, aNb, aNbS;
708 TopTools_IndexedMapOfShape aM;
709 TopAbs_ShapeEnum aST;
710 TopAbs_ShapeEnum aTypes[]= {
711 //TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX
724 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
725 for (i=0; i<aNb; ++i) {
726 if (aTypes[i]==aST) {
730 TopExp::MapShapes(aS, aTypes[i], aM);
732 aInfo.SetNbSubShapes(aTypes[i], aNbS);
735 //=======================================================================
738 //=======================================================================
739 Standard_Integer NbShells(const TopoDS_Solid& aSd)
741 Standard_Integer iCnt;
747 for (; aIt.More(); aIt.Next()){
748 //const TopoDS_Shape& aSh=aIt.Value();
753 //=======================================================================
756 //=======================================================================
757 Standard_Integer NbWires(const TopoDS_Face& aF)
759 Standard_Integer iCnt;
765 for (; aIt.More(); aIt.Next()){
766 //const TopoDS_Shape& aW=aIt.Value();
771 //=======================================================================
772 //function : IsAllowedType
774 //=======================================================================
775 Standard_Boolean IsAllowedType(const GeomAbs_CurveType aCT)
777 Standard_Boolean bRet;
778 Standard_Integer i, aNb;
779 GeomAbs_CurveType aTypes[]={
780 GeomAbs_Line, GeomAbs_Circle, GeomAbs_Ellipse
784 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
785 for (i=0; i<aNb && !bRet; ++i) {
786 bRet=(aCT==aTypes[i]);
791 //=======================================================================
792 //function : IsAllowedType
794 //=======================================================================
795 Standard_Boolean IsAllowedType(const GeomAbs_SurfaceType aST)
797 Standard_Boolean bRet;
798 Standard_Integer i, aNb;
799 GeomAbs_SurfaceType aTypes[]={
800 GeomAbs_Plane, GeomAbs_Cylinder,
801 GeomAbs_Cone, GeomAbs_Sphere,
806 aNb=sizeof(aTypes)/sizeof(aTypes[0]);
807 for (i=0; i<aNb && !bRet; ++i) {
808 bRet=(aST==aTypes[i]);
817 // 1 - The object is just initialized
820 // 11 - circle/ellipse edge without vertices