1 // Copyright (C) 2007-2012 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.hxx>
22 #include <Precision.hxx>
35 #include <TopoDS_Vertex.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS_Wire.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <TopoDS_Iterator.hxx>
41 #include <BRep_Tool.hxx>
44 #include <TopExp_Explorer.hxx>
46 #include <TopTools_MapOfShape.hxx>
47 #include <TopTools_IndexedMapOfShape.hxx>
48 #include <BRepTools_WireExplorer.hxx>
50 #include <GEOMAlgo_ShapeInfo.hxx>
51 #include <TColStd_MapOfInteger.hxx>
52 #include <TColStd_IndexedMapOfInteger.hxx>
54 //=======================================================================
55 //function : FillDetails
57 //=======================================================================
58 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd)
60 Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX;
61 TopoDS_Shape aFCyl, aFCon;
62 TopTools_IndexedMapOfShape aMF;
63 GEOMAlgo_KindOfName aKNF;
65 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
66 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
68 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
76 const TopoDS_Shape& aF=aMF(1);
77 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
78 aKNF=aInfoF.KindOfName(); // mb: sphere, torus
79 if (aKNF==GEOMAlgo_KN_SPHERE ||
80 aKNF==GEOMAlgo_KN_TORUS) {
81 aInfo.SetKindOfName(aKNF);
82 aInfo.SetLocation(aInfoF.Location());
83 aInfo.SetPosition(aInfoF.Position());
84 aInfo.SetRadius1(aInfoF.Radius1());
85 if(aKNF==GEOMAlgo_KN_TORUS) {
86 aInfo.SetRadius2(aInfoF.Radius2());
97 for (i=1; i<=aNbF; ++i) {
98 const TopoDS_Shape& aF=aMF(i);
99 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
100 aKNF=aInfoF.KindOfName();
101 if (aKNF==GEOMAlgo_KN_CYLINDER) {
105 else if (aKNF==GEOMAlgo_KN_CONE) {
109 else if (aKNF==GEOMAlgo_KN_DISKCIRCLE) {
112 else if (aKNF==GEOMAlgo_KN_POLYGON ||
113 aKNF==GEOMAlgo_KN_TRIANGLE ||
114 aKNF==GEOMAlgo_KN_QUADRANGLE) {
117 else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
124 if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
125 // cylinder (as they understand it)
126 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
127 aKNF=aInfoF.KindOfName();
128 aInfo.SetKindOfName(aKNF);
129 aInfo.SetLocation(aInfoF.Location());
130 aInfo.SetPosition(aInfoF.Position());
131 aInfo.SetRadius1(aInfoF.Radius1());
132 aInfo.SetHeight(aInfoF.Height());
137 if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
139 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
140 aKNF=aInfoF.KindOfName();
141 aInfo.SetKindOfName(aKNF);
142 aInfo.SetLocation(aInfoF.Location());
143 aInfo.SetPosition(aInfoF.Position());
144 aInfo.SetRadius1(aInfoF.Radius1());
145 aInfo.SetRadius2(aInfoF.Radius2());
146 aInfo.SetHeight(aInfoF.Height());
150 //modified by NIZNHY-PKV Wed Jan 11 11:04:31 2012f
152 return;// -> GEOMAlgo_KN_UNKNOWN
154 //modified by NIZNHY-PKV Wed Jan 11 11:04:37 2012t
156 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
160 if (aNbPgn!=aNbRct) {
161 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
164 //===================================================
167 Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
168 Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
169 Standard_Real aDistMin, aDistMax;
173 TColStd_IndexedMapOfInteger aMp;
174 TopTools_IndexedMapOfShape aMV, aMFi;
177 TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
183 aXYZc.SetCoord(0.,0.,0.);
184 for (i=1; i<=aNbV; ++i) {
185 const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
186 aPi=BRep_Tool::Pnt(aVi);
187 const gp_XYZ& aXYZ=aPi.XYZ();
195 for (i=1; i<=aNbF; ++i) {
196 if (aMp.Contains(i)) {
200 const TopoDS_Shape& aFi=aMF(i);
201 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
202 const gp_Dir& aDNi=aIFi.Position().Direction();
204 for (j=i+1; j<=aNbF; ++j) {
205 if (aMp.Contains(j)) {
209 const TopoDS_Shape& aFj=aMF(j);
210 const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
211 const gp_Dir& aDNj=aIFj.Position().Direction();
214 if (fabs(1.-aDot)<0.0001) {
230 for (i=0; i<aNbFi; ++i) {
231 const TopoDS_Shape& aFi=aMFi(i+1);
232 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
234 aDist[i]=aPc.Distance(aPi);
235 if (aDist[i]>aDistMax) {
239 if (aDist[i]<aDistMin) {
243 gp_Vec aVi(aPc, aPi);
254 aLength=2.*aDist[iMax];
255 aWidth=2.*aDist[iMid];
256 aHeight=2.*aDist[iMin];
258 gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
261 aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
262 aInfo.SetLocation(aPc);
263 aInfo.SetLength(aLength);
264 aInfo.SetWidth(aWidth);
265 aInfo.SetHeight(aHeight);
266 aInfo.SetPosition(aAx3);
268 //=======================================================================
269 //function : FillDetails
271 //=======================================================================
272 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
275 Standard_Integer aNbV, aNbE, i, j;
276 Standard_Real aDot, aD0, aD1, aLength, aWidth;
278 gp_Pnt aPx[4], aP, aPc;
280 TopExp_Explorer aExp;
285 TopTools_IndexedMapOfShape aMV;
286 BRepTools_WireExplorer aWExp;
287 GEOMAlgo_KindOfName aKN, aKNE;
288 GEOMAlgo_KindOfShape aKS;
290 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
291 aKN=GEOMAlgo_KN_UNKNOWN;
292 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
294 aKS=aInfo.KindOfShape();
295 if (aKS!=GEOMAlgo_KS_PLANE) {
299 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
300 aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
304 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
305 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
307 // 1. may be it is circle/ellipse
308 if (aNbV==1 && aNbE==1) {
309 aExp.Init(aF, TopAbs_EDGE);
310 for (; aExp.More(); aExp.Next()) {
315 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
316 aKNE=aInfoE.KindOfName();
317 if (aKNE==GEOMAlgo_KN_CIRCLE) {
318 aKN=GEOMAlgo_KN_DISKCIRCLE;
319 aInfo.SetKindOfName(aKN);
320 aInfo.SetRadius1(aInfoE.Radius1());
321 aInfo.SetLocation(aInfoE.Location());
322 aInfo.SetPosition(aInfoE.Position());
324 if (aKNE==GEOMAlgo_KN_ELLIPSE) {
325 aKN=GEOMAlgo_KN_DISKELLIPSE;
326 aInfo.SetKindOfName(aKN);
327 aInfo.SetRadius1(aInfoE.Radius1());
328 aInfo.SetRadius2(aInfoE.Radius2());
329 aInfo.SetLocation(aInfoE.Location());
330 aInfo.SetPosition(aInfoE.Position());
334 // 2. may be it is rectangle
336 aExp.Init(aF, TopAbs_EDGE);
337 for (; aExp.More(); aExp.Next()) {
339 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
340 aKNE=aInfoE.KindOfName();
341 if (aKNE!=GEOMAlgo_KN_SEGMENT) {
346 aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
348 if (aNbV==3 && aNbE==3) {
349 aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
351 aXYZc.SetCoord(0.,0.,0.);
352 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
353 for (i=1; i<=aNbV; ++i) {
354 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
355 aP=BRep_Tool::Pnt(aV);
356 const gp_XYZ& aXYZ=aP.XYZ();
363 gp_Vec aVX(aPc, aPx[0]);
365 aDX.SetXYZ(aVX.XYZ());
366 const gp_Dir& aDZ=aPln.Axis().Direction();
368 gp_Ax2 aAx2(aPc, aDZ, aDX);
371 aInfo.SetLocation(aPc);
372 aInfo.SetPosition(aAx3);
377 if (!(aNbV==4 && aNbE==4)) {
381 // aNbV==4 && aNbE==4 and all edges are segments
383 for (; aIt.More(); aIt.Next()){
384 aW=TopoDS::Wire(aIt.Value());
389 for (i=0; aWExp.More(); aWExp.Next(), ++i) {
391 const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
392 aDx[i]=aInfoEx.Direction();
393 aPx[i]=aInfoEx.Location();
396 for (i=0; i<4; ++i) {
399 if (fabs (aDot) > myTolerance) {
400 aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
406 aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
408 // shift location to the center and calc. sizes
409 aXYZc.SetCoord(0.,0.,0.);
410 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
411 for (i=1; i<=aNbV; ++i) {
412 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
413 aP=BRep_Tool::Pnt(aV);
414 const gp_XYZ& aXYZ=aP.XYZ();
418 // Location : aPc in center of rectangle
419 // Position : 0z is plane normal
420 // 0x is along length
425 gp_Lin aL0(aPx[0], aDx[0]);
426 gp_Lin aL1(aPx[1], aDx[1]);
428 aD0=aL0.Distance(aPc);
429 aD1=aL1.Distance(aPc);
443 aInfo.SetLocation(aPc);
444 aInfo.SetLength(aLength);
445 aInfo.SetWidth(aWidth);
447 const gp_Dir& aDZ=aPln.Axis().Direction();
448 gp_Ax2 aAx2(aPc, aDZ, aDX);
450 aInfo.SetPosition(aAx3);
455 //=======================================================================
456 //function : FillDetails
458 //=======================================================================
459 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
462 Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
464 TopExp_Explorer aExp;
465 TopTools_MapOfShape aM;
466 GEOMAlgo_KindOfShape aKS, aKSE;
468 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
469 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
471 aKS=aInfo.KindOfShape();
472 if (aKS!=GEOMAlgo_KS_SPHERE) {
476 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
477 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
478 if (!(aNbV==2 && aNbE==3)) {
484 aExp.Init(aF, TopAbs_EDGE);
485 for (; aExp.More(); aExp.Next()) {
486 aE=TopoDS::Edge(aExp.Current());
488 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
489 aKSE=aInfoE.KindOfShape();
491 if (BRep_Tool::IsClosed(aE, aF)) {
494 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
500 if (!(aNbSE==1 && aNbDE==2)) {
503 aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
505 //=======================================================================
506 //function : FillDetails
508 //=======================================================================
509 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
510 const gp_Cone& )//aCone)
512 Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
513 Standard_Real aR[3], aHeight;
514 gp_Pnt aPC[3], aPD, aPc, aPX[3];
518 TopExp_Explorer aExp;
519 TopTools_MapOfShape aM;
520 GEOMAlgo_KindOfShape aKS, aKSE;
521 GEOMAlgo_KindOfName aKN, aKNE;
522 GEOMAlgo_KindOfClosed aKCE;
524 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
525 aKN=GEOMAlgo_KN_UNKNOWN;
526 aInfo.SetKindOfName(aKN);
528 aKS=aInfo.KindOfShape();
529 if (aKS!=GEOMAlgo_KS_CONE) {
533 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
537 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
538 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
539 if (!(aNbV==2 && aNbE==3)) {
547 aExp.Init(aF, TopAbs_EDGE);
548 for (; aExp.More(); aExp.Next()) {
549 aE=TopoDS::Edge(aExp.Current());
551 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
552 aKNE=aInfoE.KindOfName();
553 aKCE=aInfoE.KindOfClosed();
554 aKSE=aInfoE.KindOfShape();
555 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
556 aPC[i]=aInfoE.Location();
557 aR[i]=aInfoE.Radius1();
560 for (; aIt.More(); aIt.Next()) {
561 aVD=TopoDS::Vertex(aIt.Value());
564 aPX[i]=BRep_Tool::Pnt(aVD);
569 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
570 if (BRep_Tool::IsClosed(aE, aF)) {
574 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
576 for (; aIt.More(); aIt.Next()) {
577 aVD=TopoDS::Vertex(aIt.Value());
581 aPD=BRep_Tool::Pnt(aVD);
588 if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
597 aHeight=aPC[0].Distance(aPC[1]);
599 Standard_Real aRmin, aRmax;
606 gp_Vec aVz(aPC[0], aPC[1]);
607 gp_Vec aVx(aPC[0], aPX[0]);
610 gp_Ax2 aAx2(aPc, aDz, aDx);
617 gp_Vec aVz(aPC[1], aPC[0]);
618 gp_Vec aVx(aPC[1], aPX[1]);
621 gp_Ax2 aAx2(aPc, aDz, aDx);
625 gp_Ax3 aAx3(aAx2new);
626 aInfo.SetLocation(aPc);
627 aInfo.SetPosition(aAx3);
628 aInfo.SetRadius1(aRmax);
629 aInfo.SetRadius2(aRmin);
630 aInfo.SetHeight(aHeight);
632 aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
634 //=======================================================================
635 //function : FillDetails
637 //=======================================================================
638 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
639 const gp_Cylinder& aCyl)
641 Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
642 Standard_Real aT0, aT1, aHeight;
645 TopExp_Explorer aExp;
646 TopTools_MapOfShape aM;
647 GEOMAlgo_KindOfShape aKS;
648 GEOMAlgo_KindOfName aKN, aKNE;
649 GEOMAlgo_KindOfClosed aKCE;
651 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
652 aKN=GEOMAlgo_KN_UNKNOWN;
653 aInfo.SetKindOfName(aKN);
655 aKS=aInfo.KindOfShape();
656 if (aKS!=GEOMAlgo_KS_CYLINDER) {
660 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
664 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
665 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
666 if (!(aNbV==2 && aNbE==3)) {
673 aExp.Init(aF, TopAbs_EDGE);
674 for (; aExp.More(); aExp.Next()) {
675 aE=TopoDS::Edge(aExp.Current());
677 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
678 aKNE=aInfoE.KindOfName();
679 aKCE=aInfoE.KindOfClosed();
680 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
681 aPC[aNbCE]=aInfoE.Location();
684 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
685 if (BRep_Tool::IsClosed(aE, aF)) {
692 if (!(aNbCE==2 && aNbSE==1)) {
696 const gp_Ax1& aAx1=aCyl.Axis();
697 const gp_Dir& aDir=aAx1.Direction();
698 const gp_Pnt& aPLoc=aAx1.Location();
699 gp_Lin aLin(aPLoc, aDir);
701 aT0=ElCLib::Parameter(aLin, aPC[0]);
702 aT1=ElCLib::Parameter(aLin, aPC[1]);
708 aHeight=aPC[0].Distance(aPC[1]);
710 gp_Ax3 aAx3=aCyl.Position();
711 aAx3.SetLocation(aPc);
713 aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
714 aInfo.SetPosition(aAx3);
715 aInfo.SetLocation(aPc);
716 aInfo.SetHeight(aHeight);
719 //=======================================================================
720 //function : FillDetails
722 //=======================================================================
723 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
726 Standard_Integer aNbV, aNbE, aNbSE;
728 TopExp_Explorer aExp;
729 TopTools_MapOfShape aM;
730 GEOMAlgo_KindOfShape aKS;
732 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
733 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
735 aKS=aInfo.KindOfShape();
736 if (aKS!=GEOMAlgo_KS_TORUS) {
740 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
741 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
742 if (!(aNbV==1 && aNbE==2)) {
747 aExp.Init(aF, TopAbs_EDGE);
748 for (; aExp.More(); aExp.Next()) {
749 aE=TopoDS::Edge(aExp.Current());
751 //const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
752 if (BRep_Tool::IsClosed(aE, aF)) {
761 aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);