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>
37 #include <TopoDS_Vertex.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS_Iterator.hxx>
43 #include <BRep_Tool.hxx>
46 #include <TopExp_Explorer.hxx>
48 #include <TopTools_MapOfShape.hxx>
49 #include <TopTools_IndexedMapOfShape.hxx>
50 #include <BRepTools_WireExplorer.hxx>
52 #include <GEOMAlgo_ShapeInfo.hxx>
53 #include <TColStd_MapOfInteger.hxx>
54 #include <TColStd_IndexedMapOfInteger.hxx>
56 //=======================================================================
57 //function : FillDetails
59 //=======================================================================
60 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd)
62 Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX;
63 TopoDS_Shape aFCyl, aFCon;
64 TopTools_IndexedMapOfShape aMF;
65 GEOMAlgo_KindOfName aKNF;
67 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
68 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
70 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
78 const TopoDS_Shape& aF=aMF(1);
79 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
80 aKNF=aInfoF.KindOfName(); // mb: sphere, torus
81 if (aKNF==GEOMAlgo_KN_SPHERE ||
82 aKNF==GEOMAlgo_KN_TORUS) {
83 aInfo.SetKindOfName(aKNF);
84 aInfo.SetLocation(aInfoF.Location());
85 aInfo.SetPosition(aInfoF.Position());
86 aInfo.SetRadius1(aInfoF.Radius1());
87 if(aKNF==GEOMAlgo_KN_TORUS) {
88 aInfo.SetRadius2(aInfoF.Radius2());
99 for (i=1; i<=aNbF; ++i) {
100 const TopoDS_Shape& aF=aMF(i);
101 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
102 aKNF=aInfoF.KindOfName();
103 if (aKNF==GEOMAlgo_KN_CYLINDER) {
107 else if (aKNF==GEOMAlgo_KN_CONE) {
111 else if (aKNF==GEOMAlgo_KN_DISKCIRCLE) {
114 else if (aKNF==GEOMAlgo_KN_POLYGON ||
115 aKNF==GEOMAlgo_KN_TRIANGLE ||
116 aKNF==GEOMAlgo_KN_QUADRANGLE) {
120 else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
127 if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
128 // cylinder (as they understand it)
129 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
130 aKNF=aInfoF.KindOfName();
131 aInfo.SetKindOfName(aKNF);
132 aInfo.SetLocation(aInfoF.Location());
133 aInfo.SetPosition(aInfoF.Position());
134 aInfo.SetRadius1(aInfoF.Radius1());
135 aInfo.SetHeight(aInfoF.Height());
140 if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
142 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
143 aKNF=aInfoF.KindOfName();
144 aInfo.SetKindOfName(aKNF);
145 aInfo.SetLocation(aInfoF.Location());
146 aInfo.SetPosition(aInfoF.Position());
147 aInfo.SetRadius1(aInfoF.Radius1());
148 aInfo.SetRadius2(aInfoF.Radius2());
149 aInfo.SetHeight(aInfoF.Height());
154 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
157 if (aNbPgn!=aNbRct) {
158 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
161 //===================================================
164 Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
165 Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
166 Standard_Real aDistMin, aDistMax;
170 TColStd_IndexedMapOfInteger aMp;
171 TopTools_IndexedMapOfShape aMV, aMFi;
174 TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
180 aXYZc.SetCoord(0.,0.,0.);
181 for (i=1; i<=aNbV; ++i) {
182 const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
183 aPi=BRep_Tool::Pnt(aVi);
184 const gp_XYZ& aXYZ=aPi.XYZ();
192 for (i=1; i<=aNbF; ++i) {
193 if (aMp.Contains(i)) {
197 const TopoDS_Shape& aFi=aMF(i);
198 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
199 const gp_Dir& aDNi=aIFi.Position().Direction();
201 for (j=i+1; j<=aNbF; ++j) {
202 if (aMp.Contains(j)) {
206 const TopoDS_Shape& aFj=aMF(j);
207 const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
208 const gp_Dir& aDNj=aIFj.Position().Direction();
211 if (fabs(1.-aDot)<0.0001) {
227 for (i=0; i<aNbFi; ++i) {
228 const TopoDS_Shape& aFi=aMFi(i+1);
229 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
231 aDist[i]=aPc.Distance(aPi);
232 if (aDist[i]>aDistMax) {
236 if (aDist[i]<aDistMin) {
240 gp_Vec aVi(aPc, aPi);
251 aLength=2.*aDist[iMax];
252 aWidth=2.*aDist[iMid];
253 aHeight=2.*aDist[iMin];
255 gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
258 aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
259 aInfo.SetLocation(aPc);
260 aInfo.SetLength(aLength);
261 aInfo.SetWidth(aWidth);
262 aInfo.SetHeight(aHeight);
263 aInfo.SetPosition(aAx3);
265 //=======================================================================
266 //function : FillDetails
268 //=======================================================================
269 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
272 Standard_Integer aNbV, aNbE, i, j;
273 Standard_Real aDot, aD0, aD1, aLength, aWidth;
275 gp_Pnt aPx[4], aP, aPc;
277 TopExp_Explorer aExp;
282 TopTools_IndexedMapOfShape aMV;
283 BRepTools_WireExplorer aWExp;
284 GEOMAlgo_KindOfName aKN, aKNE;
285 GEOMAlgo_KindOfShape aKS;
287 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
288 aKN=GEOMAlgo_KN_UNKNOWN;
289 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
291 aKS=aInfo.KindOfShape();
292 if (aKS!=GEOMAlgo_KS_PLANE) {
296 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
297 aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
301 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
302 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
304 // 1. may be it is circle/ellipse
305 if (aNbV==1 && aNbE==1) {
306 aExp.Init(aF, TopAbs_EDGE);
307 for (; aExp.More(); aExp.Next()) {
312 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
313 aKNE=aInfoE.KindOfName();
314 if (aKNE==GEOMAlgo_KN_CIRCLE) {
315 aKN=GEOMAlgo_KN_DISKCIRCLE;
316 aInfo.SetKindOfName(aKN);
317 aInfo.SetRadius1(aInfoE.Radius1());
318 aInfo.SetLocation(aInfoE.Location());
319 aInfo.SetPosition(aInfoE.Position());
321 if (aKNE==GEOMAlgo_KN_ELLIPSE) {
322 aKN=GEOMAlgo_KN_DISKELLIPSE;
323 aInfo.SetKindOfName(aKN);
324 aInfo.SetRadius1(aInfoE.Radius1());
325 aInfo.SetRadius2(aInfoE.Radius2());
326 aInfo.SetLocation(aInfoE.Location());
327 aInfo.SetPosition(aInfoE.Position());
331 // 2. may be it is rectangle
333 aExp.Init(aF, TopAbs_EDGE);
334 for (; aExp.More(); aExp.Next()) {
336 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
337 aKNE=aInfoE.KindOfName();
338 if (aKNE!=GEOMAlgo_KN_SEGMENT) {
343 aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
345 if (aNbV==3 && aNbE==3) {
346 aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
348 aXYZc.SetCoord(0.,0.,0.);
349 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
350 for (i=1; i<=aNbV; ++i) {
351 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
352 aP=BRep_Tool::Pnt(aV);
353 const gp_XYZ& aXYZ=aP.XYZ();
360 gp_Vec aVX(aPc, aPx[0]);
362 aDX.SetXYZ(aVX.XYZ());
363 const gp_Dir& aDZ=aPln.Axis().Direction();
365 gp_Ax2 aAx2(aPc, aDZ, aDX);
368 aInfo.SetLocation(aPc);
369 aInfo.SetPosition(aAx3);
374 if (!(aNbV==4 && aNbE==4)) {
378 // aNbV==4 && aNbE==4 and all edges are segments
380 for (; aIt.More(); aIt.Next()){
381 aW=TopoDS::Wire(aIt.Value());
386 for (i=0; aWExp.More(); aWExp.Next(), ++i) {
388 const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
389 aDx[i]=aInfoEx.Direction();
390 aPx[i]=aInfoEx.Location();
393 for (i=0; i<4; ++i) {
396 if (fabs (aDot) > myTolerance) {
397 aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
403 aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
405 // shift location to the center and calc. sizes
406 aXYZc.SetCoord(0.,0.,0.);
407 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
408 for (i=1; i<=aNbV; ++i) {
409 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
410 aP=BRep_Tool::Pnt(aV);
411 const gp_XYZ& aXYZ=aP.XYZ();
415 // Location : aPc in center of rectangle
416 // Position : 0z is plane normal
417 // 0x is along length
422 gp_Lin aL0(aPx[0], aDx[0]);
423 gp_Lin aL1(aPx[1], aDx[1]);
425 aD0=aL0.Distance(aPc);
426 aD1=aL1.Distance(aPc);
440 aInfo.SetLocation(aPc);
441 aInfo.SetLength(aLength);
442 aInfo.SetWidth(aWidth);
444 const gp_Dir& aDZ=aPln.Axis().Direction();
445 gp_Ax2 aAx2(aPc, aDZ, aDX);
447 aInfo.SetPosition(aAx3);
452 //=======================================================================
453 //function : FillDetails
455 //=======================================================================
456 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
459 Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
461 TopExp_Explorer aExp;
462 TopTools_MapOfShape aM;
463 GEOMAlgo_KindOfShape aKS, aKSE;
465 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
466 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
468 aKS=aInfo.KindOfShape();
469 if (aKS!=GEOMAlgo_KS_SPHERE) {
473 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
474 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
475 if (!(aNbV==2 && aNbE==3)) {
481 aExp.Init(aF, TopAbs_EDGE);
482 for (; aExp.More(); aExp.Next()) {
483 aE=TopoDS::Edge(aExp.Current());
485 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
486 aKSE=aInfoE.KindOfShape();
488 if (BRep_Tool::IsClosed(aE, aF)) {
491 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
497 if (!(aNbSE==1 && aNbDE==2)) {
500 aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
502 //=======================================================================
503 //function : FillDetails
505 //=======================================================================
506 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
507 const gp_Cone& )//aCone)
509 Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
510 Standard_Real aR[3], aHeight;
511 gp_Pnt aPC[3], aPD, aPc, aPX[3];
515 TopExp_Explorer aExp;
516 TopTools_MapOfShape aM;
517 GEOMAlgo_KindOfShape aKS, aKSE;
518 GEOMAlgo_KindOfName aKN, aKNE;
519 GEOMAlgo_KindOfClosed aKCE;
521 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
522 aKN=GEOMAlgo_KN_UNKNOWN;
523 aInfo.SetKindOfName(aKN);
525 aKS=aInfo.KindOfShape();
526 if (aKS!=GEOMAlgo_KS_CONE) {
530 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
534 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
535 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
536 if (!(aNbV==2 && aNbE==3)) {
544 aExp.Init(aF, TopAbs_EDGE);
545 for (; aExp.More(); aExp.Next()) {
546 aE=TopoDS::Edge(aExp.Current());
548 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
549 aKNE=aInfoE.KindOfName();
550 aKCE=aInfoE.KindOfClosed();
551 aKSE=aInfoE.KindOfShape();
552 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
553 aPC[i]=aInfoE.Location();
554 aR[i]=aInfoE.Radius1();
557 for (; aIt.More(); aIt.Next()) {
558 aVD=TopoDS::Vertex(aIt.Value());
561 aPX[i]=BRep_Tool::Pnt(aVD);
566 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
567 if (BRep_Tool::IsClosed(aE, aF)) {
571 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
573 for (; aIt.More(); aIt.Next()) {
574 aVD=TopoDS::Vertex(aIt.Value());
578 aPD=BRep_Tool::Pnt(aVD);
585 if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
594 aHeight=aPC[0].Distance(aPC[1]);
596 Standard_Real aRmin, aRmax;
603 gp_Vec aVz(aPC[0], aPC[1]);
604 gp_Vec aVx(aPC[0], aPX[0]);
607 gp_Ax2 aAx2(aPc, aDz, aDx);
614 gp_Vec aVz(aPC[1], aPC[0]);
615 gp_Vec aVx(aPC[1], aPX[1]);
618 gp_Ax2 aAx2(aPc, aDz, aDx);
622 gp_Ax3 aAx3(aAx2new);
623 aInfo.SetLocation(aPc);
624 aInfo.SetPosition(aAx3);
625 aInfo.SetRadius1(aRmax);
626 aInfo.SetRadius2(aRmin);
627 aInfo.SetHeight(aHeight);
629 aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
631 //=======================================================================
632 //function : FillDetails
634 //=======================================================================
635 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
636 const gp_Cylinder& aCyl)
638 Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
639 Standard_Real aT0, aT1, aHeight;
642 TopExp_Explorer aExp;
643 TopTools_MapOfShape aM;
644 GEOMAlgo_KindOfShape aKS;
645 GEOMAlgo_KindOfName aKN, aKNE;
646 GEOMAlgo_KindOfClosed aKCE;
648 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
649 aKN=GEOMAlgo_KN_UNKNOWN;
650 aInfo.SetKindOfName(aKN);
652 aKS=aInfo.KindOfShape();
653 if (aKS!=GEOMAlgo_KS_CYLINDER) {
657 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
661 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
662 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
663 if (!(aNbV==2 && aNbE==3)) {
670 aExp.Init(aF, TopAbs_EDGE);
671 for (; aExp.More(); aExp.Next()) {
672 aE=TopoDS::Edge(aExp.Current());
674 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
675 aKNE=aInfoE.KindOfName();
676 aKCE=aInfoE.KindOfClosed();
677 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
678 aPC[aNbCE]=aInfoE.Location();
681 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
682 if (BRep_Tool::IsClosed(aE, aF)) {
689 if (!(aNbCE==2 && aNbSE==1)) {
693 const gp_Ax1& aAx1=aCyl.Axis();
694 const gp_Dir& aDir=aAx1.Direction();
695 const gp_Pnt& aPLoc=aAx1.Location();
696 gp_Lin aLin(aPLoc, aDir);
698 aT0=ElCLib::Parameter(aLin, aPC[0]);
699 aT1=ElCLib::Parameter(aLin, aPC[1]);
705 aHeight=aPC[0].Distance(aPC[1]);
707 gp_Ax3 aAx3=aCyl.Position();
708 aAx3.SetLocation(aPc);
710 aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
711 aInfo.SetPosition(aAx3);
712 aInfo.SetLocation(aPc);
713 aInfo.SetHeight(aHeight);
716 //=======================================================================
717 //function : FillDetails
719 //=======================================================================
720 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
723 Standard_Integer aNbV, aNbE, aNbSE;
725 TopExp_Explorer aExp;
726 TopTools_MapOfShape aM;
727 GEOMAlgo_KindOfShape aKS;
729 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
730 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
732 aKS=aInfo.KindOfShape();
733 if (aKS!=GEOMAlgo_KS_TORUS) {
737 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
738 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
739 if (!(aNbV==1 && aNbE==2)) {
744 aExp.Init(aF, TopAbs_EDGE);
745 for (; aExp.More(); aExp.Next()) {
746 aE=TopoDS::Edge(aExp.Current());
748 //const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
749 if (BRep_Tool::IsClosed(aE, aF)) {
758 aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);