1 // Copyright (C) 2007-2011 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.ixx>
21 #include <Precision.hxx>
34 #include <TopoDS_Vertex.hxx>
35 #include <TopoDS_Edge.hxx>
36 #include <TopoDS_Wire.hxx>
37 #include <TopoDS_Face.hxx>
38 #include <TopoDS_Iterator.hxx>
40 #include <BRep_Tool.hxx>
43 #include <TopExp_Explorer.hxx>
45 #include <TopTools_MapOfShape.hxx>
46 #include <TopTools_IndexedMapOfShape.hxx>
47 #include <BRepTools_WireExplorer.hxx>
49 #include <GEOMAlgo_ShapeInfo.hxx>
50 #include <TColStd_MapOfInteger.hxx>
51 #include <TColStd_IndexedMapOfInteger.hxx>
53 //=======================================================================
54 //function : FillDetails
56 //=======================================================================
57 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd)
59 Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX;
60 TopoDS_Shape aFCyl, aFCon;
61 TopTools_IndexedMapOfShape aMF;
62 GEOMAlgo_KindOfName aKNF;
64 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
65 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
67 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
75 const TopoDS_Shape& aF=aMF(1);
76 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
77 aKNF=aInfoF.KindOfName(); // mb: sphere, torus
78 if (aKNF==GEOMAlgo_KN_SPHERE ||
79 aKNF==GEOMAlgo_KN_TORUS) {
80 aInfo.SetKindOfName(aKNF);
81 aInfo.SetLocation(aInfoF.Location());
82 aInfo.SetPosition(aInfoF.Position());
83 aInfo.SetRadius1(aInfoF.Radius1());
84 if(aKNF==GEOMAlgo_KN_TORUS) {
85 aInfo.SetRadius2(aInfoF.Radius2());
96 for (i=1; i<=aNbF; ++i) {
97 const TopoDS_Shape& aF=aMF(i);
98 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
99 aKNF=aInfoF.KindOfName();
100 if (aKNF==GEOMAlgo_KN_CYLINDER) {
104 else if (aKNF==GEOMAlgo_KN_CONE) {
108 else if (aKNF==GEOMAlgo_KN_DISKCIRCLE) {
111 else if (aKNF==GEOMAlgo_KN_POLYGON ||
112 aKNF==GEOMAlgo_KN_TRIANGLE ||
113 aKNF==GEOMAlgo_KN_QUADRANGLE) {
116 else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
123 if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
124 // cylinder (as they understand it)
125 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
126 aKNF=aInfoF.KindOfName();
127 aInfo.SetKindOfName(aKNF);
128 aInfo.SetLocation(aInfoF.Location());
129 aInfo.SetPosition(aInfoF.Position());
130 aInfo.SetRadius1(aInfoF.Radius1());
131 aInfo.SetHeight(aInfoF.Height());
136 if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
138 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
139 aKNF=aInfoF.KindOfName();
140 aInfo.SetKindOfName(aKNF);
141 aInfo.SetLocation(aInfoF.Location());
142 aInfo.SetPosition(aInfoF.Position());
143 aInfo.SetRadius1(aInfoF.Radius1());
144 aInfo.SetRadius2(aInfoF.Radius2());
145 aInfo.SetHeight(aInfoF.Height());
149 //modified by NIZNHY-PKV Wed Jan 11 11:04:31 2012f
151 return;// -> GEOMAlgo_KN_UNKNOWN
153 //modified by NIZNHY-PKV Wed Jan 11 11:04:37 2012t
155 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
159 if (aNbPgn!=aNbRct) {
160 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
163 //===================================================
166 Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
167 Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
168 Standard_Real aDistMin, aDistMax;
172 TColStd_IndexedMapOfInteger aMp;
173 TopTools_IndexedMapOfShape aMV, aMFi;
176 TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
182 aXYZc.SetCoord(0.,0.,0.);
183 for (i=1; i<=aNbV; ++i) {
184 const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
185 aPi=BRep_Tool::Pnt(aVi);
186 const gp_XYZ& aXYZ=aPi.XYZ();
194 for (i=1; i<=aNbF; ++i) {
195 if (aMp.Contains(i)) {
199 const TopoDS_Shape& aFi=aMF(i);
200 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
201 const gp_Dir& aDNi=aIFi.Position().Direction();
203 for (j=i+1; j<=aNbF; ++j) {
204 if (aMp.Contains(j)) {
208 const TopoDS_Shape& aFj=aMF(j);
209 const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
210 const gp_Dir& aDNj=aIFj.Position().Direction();
213 if (fabs(1.-aDot)<0.0001) {
229 for (i=0; i<aNbFi; ++i) {
230 const TopoDS_Shape& aFi=aMFi(i+1);
231 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
233 aDist[i]=aPc.Distance(aPi);
234 if (aDist[i]>aDistMax) {
238 if (aDist[i]<aDistMin) {
242 gp_Vec aVi(aPc, aPi);
253 aLength=2.*aDist[iMax];
254 aWidth=2.*aDist[iMid];
255 aHeight=2.*aDist[iMin];
257 gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
260 aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
261 aInfo.SetLocation(aPc);
262 aInfo.SetLength(aLength);
263 aInfo.SetWidth(aWidth);
264 aInfo.SetHeight(aHeight);
265 aInfo.SetPosition(aAx3);
267 //=======================================================================
268 //function : FillDetails
270 //=======================================================================
271 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
274 Standard_Integer aNbV, aNbE, i, j;
275 Standard_Real aDot, aD0, aD1, aLength, aWidth;
277 gp_Pnt aPx[4], aP, aPc;
279 TopExp_Explorer aExp;
284 TopTools_IndexedMapOfShape aMV;
285 BRepTools_WireExplorer aWExp;
286 GEOMAlgo_KindOfName aKN, aKNE;
287 GEOMAlgo_KindOfShape aKS;
289 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
290 aKN=GEOMAlgo_KN_UNKNOWN;
291 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
293 aKS=aInfo.KindOfShape();
294 if (aKS!=GEOMAlgo_KS_PLANE) {
298 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
299 aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
303 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
304 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
306 // 1. may be it is circle/ellipse
307 if (aNbV==1 && aNbE==1) {
308 aExp.Init(aF, TopAbs_EDGE);
309 for (; aExp.More(); aExp.Next()) {
314 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
315 aKNE=aInfoE.KindOfName();
316 if (aKNE==GEOMAlgo_KN_CIRCLE) {
317 aKN=GEOMAlgo_KN_DISKCIRCLE;
318 aInfo.SetKindOfName(aKN);
319 aInfo.SetRadius1(aInfoE.Radius1());
320 aInfo.SetLocation(aInfoE.Location());
321 aInfo.SetPosition(aInfoE.Position());
323 if (aKNE==GEOMAlgo_KN_ELLIPSE) {
324 aKN=GEOMAlgo_KN_DISKELLIPSE;
325 aInfo.SetKindOfName(aKN);
326 aInfo.SetRadius1(aInfoE.Radius1());
327 aInfo.SetRadius2(aInfoE.Radius2());
328 aInfo.SetLocation(aInfoE.Location());
329 aInfo.SetPosition(aInfoE.Position());
333 // 2. may be it is rectangle
335 aExp.Init(aF, TopAbs_EDGE);
336 for (; aExp.More(); aExp.Next()) {
338 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
339 aKNE=aInfoE.KindOfName();
340 if (aKNE!=GEOMAlgo_KN_SEGMENT) {
345 aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
347 if (aNbV==3 && aNbE==3) {
348 aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
350 aXYZc.SetCoord(0.,0.,0.);
351 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
352 for (i=1; i<=aNbV; ++i) {
353 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
354 aP=BRep_Tool::Pnt(aV);
355 const gp_XYZ& aXYZ=aP.XYZ();
362 gp_Vec aVX(aPc, aPx[0]);
364 aDX.SetXYZ(aVX.XYZ());
365 const gp_Dir& aDZ=aPln.Axis().Direction();
367 gp_Ax2 aAx2(aPc, aDZ, aDX);
370 aInfo.SetLocation(aPc);
371 aInfo.SetPosition(aAx3);
376 if (!(aNbV==4 && aNbE==4)) {
380 // aNbV==4 && aNbE==4 and all edges are segments
382 for (; aIt.More(); aIt.Next()){
383 aW=TopoDS::Wire(aIt.Value());
388 for (i=0; aWExp.More(); aWExp.Next(), ++i) {
390 const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
391 aDx[i]=aInfoEx.Direction();
392 aPx[i]=aInfoEx.Location();
395 for (i=0; i<4; ++i) {
398 if (fabs (aDot) > myTolerance) {
399 aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
405 aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
407 // shift location to the center and calc. sizes
408 aXYZc.SetCoord(0.,0.,0.);
409 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
410 for (i=1; i<=aNbV; ++i) {
411 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
412 aP=BRep_Tool::Pnt(aV);
413 const gp_XYZ& aXYZ=aP.XYZ();
417 // Location : aPc in center of rectangle
418 // Position : 0z is plane normal
419 // 0x is along length
424 gp_Lin aL0(aPx[0], aDx[0]);
425 gp_Lin aL1(aPx[1], aDx[1]);
427 aD0=aL0.Distance(aPc);
428 aD1=aL1.Distance(aPc);
442 aInfo.SetLocation(aPc);
443 aInfo.SetLength(aLength);
444 aInfo.SetWidth(aWidth);
446 const gp_Dir& aDZ=aPln.Axis().Direction();
447 gp_Ax2 aAx2(aPc, aDZ, aDX);
449 aInfo.SetPosition(aAx3);
454 //=======================================================================
455 //function : FillDetails
457 //=======================================================================
458 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
461 Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
463 TopExp_Explorer aExp;
464 TopTools_MapOfShape aM;
465 GEOMAlgo_KindOfShape aKS, aKSE;
467 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
468 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
470 aKS=aInfo.KindOfShape();
471 if (aKS!=GEOMAlgo_KS_SPHERE) {
475 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
476 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
477 if (!(aNbV==2 && aNbE==3)) {
483 aExp.Init(aF, TopAbs_EDGE);
484 for (; aExp.More(); aExp.Next()) {
485 aE=TopoDS::Edge(aExp.Current());
487 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
488 aKSE=aInfoE.KindOfShape();
490 if (BRep_Tool::IsClosed(aE, aF)) {
493 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
499 if (!(aNbSE==1 && aNbDE==2)) {
502 aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
504 //=======================================================================
505 //function : FillDetails
507 //=======================================================================
508 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
509 const gp_Cone& )//aCone)
511 Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
512 Standard_Real aR[3], aHeight;
513 gp_Pnt aPC[3], aPD, aPc, aPX[3];
517 TopExp_Explorer aExp;
518 TopTools_MapOfShape aM;
519 GEOMAlgo_KindOfShape aKS, aKSE;
520 GEOMAlgo_KindOfName aKN, aKNE;
521 GEOMAlgo_KindOfClosed aKCE;
523 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
524 aKN=GEOMAlgo_KN_UNKNOWN;
525 aInfo.SetKindOfName(aKN);
527 aKS=aInfo.KindOfShape();
528 if (aKS!=GEOMAlgo_KS_CONE) {
532 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
536 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
537 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
538 if (!(aNbV==2 && aNbE==3)) {
546 aExp.Init(aF, TopAbs_EDGE);
547 for (; aExp.More(); aExp.Next()) {
548 aE=TopoDS::Edge(aExp.Current());
550 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
551 aKNE=aInfoE.KindOfName();
552 aKCE=aInfoE.KindOfClosed();
553 aKSE=aInfoE.KindOfShape();
554 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
555 aPC[i]=aInfoE.Location();
556 aR[i]=aInfoE.Radius1();
559 for (; aIt.More(); aIt.Next()) {
560 aVD=TopoDS::Vertex(aIt.Value());
563 aPX[i]=BRep_Tool::Pnt(aVD);
568 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
569 if (BRep_Tool::IsClosed(aE, aF)) {
573 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
575 for (; aIt.More(); aIt.Next()) {
576 aVD=TopoDS::Vertex(aIt.Value());
580 aPD=BRep_Tool::Pnt(aVD);
587 if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
596 aHeight=aPC[0].Distance(aPC[1]);
598 Standard_Real aRmin, aRmax;
605 gp_Vec aVz(aPC[0], aPC[1]);
606 gp_Vec aVx(aPC[0], aPX[0]);
609 gp_Ax2 aAx2(aPc, aDz, aDx);
616 gp_Vec aVz(aPC[1], aPC[0]);
617 gp_Vec aVx(aPC[1], aPX[1]);
620 gp_Ax2 aAx2(aPc, aDz, aDx);
624 gp_Ax3 aAx3(aAx2new);
625 aInfo.SetLocation(aPc);
626 aInfo.SetPosition(aAx3);
627 aInfo.SetRadius1(aRmax);
628 aInfo.SetRadius2(aRmin);
629 aInfo.SetHeight(aHeight);
631 aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
633 //=======================================================================
634 //function : FillDetails
636 //=======================================================================
637 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
638 const gp_Cylinder& aCyl)
640 Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
641 Standard_Real aT0, aT1, aHeight;
644 TopExp_Explorer aExp;
645 TopTools_MapOfShape aM;
646 GEOMAlgo_KindOfShape aKS;
647 GEOMAlgo_KindOfName aKN, aKNE;
648 GEOMAlgo_KindOfClosed aKCE;
650 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
651 aKN=GEOMAlgo_KN_UNKNOWN;
652 aInfo.SetKindOfName(aKN);
654 aKS=aInfo.KindOfShape();
655 if (aKS!=GEOMAlgo_KS_CYLINDER) {
659 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
663 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
664 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
665 if (!(aNbV==2 && aNbE==3)) {
672 aExp.Init(aF, TopAbs_EDGE);
673 for (; aExp.More(); aExp.Next()) {
674 aE=TopoDS::Edge(aExp.Current());
676 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
677 aKNE=aInfoE.KindOfName();
678 aKCE=aInfoE.KindOfClosed();
679 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
680 aPC[aNbCE]=aInfoE.Location();
683 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
684 if (BRep_Tool::IsClosed(aE, aF)) {
691 if (!(aNbCE==2 && aNbSE==1)) {
695 const gp_Ax1& aAx1=aCyl.Axis();
696 const gp_Dir& aDir=aAx1.Direction();
697 const gp_Pnt& aPLoc=aAx1.Location();
698 gp_Lin aLin(aPLoc, aDir);
700 aT0=ElCLib::Parameter(aLin, aPC[0]);
701 aT1=ElCLib::Parameter(aLin, aPC[1]);
707 aHeight=aPC[0].Distance(aPC[1]);
709 gp_Ax3 aAx3=aCyl.Position();
710 aAx3.SetLocation(aPc);
712 aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
713 aInfo.SetPosition(aAx3);
714 aInfo.SetLocation(aPc);
715 aInfo.SetHeight(aHeight);
718 //=======================================================================
719 //function : FillDetails
721 //=======================================================================
722 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
725 Standard_Integer aNbV, aNbE, aNbSE;
727 TopExp_Explorer aExp;
728 TopTools_MapOfShape aM;
729 GEOMAlgo_KindOfShape aKS;
731 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
732 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
734 aKS=aInfo.KindOfShape();
735 if (aKS!=GEOMAlgo_KS_TORUS) {
739 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
740 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
741 if (!(aNbV==1 && aNbE==2)) {
746 aExp.Init(aF, TopAbs_EDGE);
747 for (; aExp.More(); aExp.Next()) {
748 aE=TopoDS::Edge(aExp.Current());
750 //const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
751 if (BRep_Tool::IsClosed(aE, aF)) {
760 aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);