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>
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) {
118 else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
125 if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
126 // cylinder (as they understand it)
127 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
128 aKNF=aInfoF.KindOfName();
129 aInfo.SetKindOfName(aKNF);
130 aInfo.SetLocation(aInfoF.Location());
131 aInfo.SetPosition(aInfoF.Position());
132 aInfo.SetRadius1(aInfoF.Radius1());
133 aInfo.SetHeight(aInfoF.Height());
138 if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
140 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
141 aKNF=aInfoF.KindOfName();
142 aInfo.SetKindOfName(aKNF);
143 aInfo.SetLocation(aInfoF.Location());
144 aInfo.SetPosition(aInfoF.Position());
145 aInfo.SetRadius1(aInfoF.Radius1());
146 aInfo.SetRadius2(aInfoF.Radius2());
147 aInfo.SetHeight(aInfoF.Height());
152 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
155 if (aNbPgn!=aNbRct) {
156 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
159 //===================================================
162 Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
163 Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
164 Standard_Real aDistMin, aDistMax;
168 TColStd_IndexedMapOfInteger aMp;
169 TopTools_IndexedMapOfShape aMV, aMFi;
172 TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
178 aXYZc.SetCoord(0.,0.,0.);
179 for (i=1; i<=aNbV; ++i) {
180 const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
181 aPi=BRep_Tool::Pnt(aVi);
182 const gp_XYZ& aXYZ=aPi.XYZ();
190 for (i=1; i<=aNbF; ++i) {
191 if (aMp.Contains(i)) {
195 const TopoDS_Shape& aFi=aMF(i);
196 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
197 const gp_Dir& aDNi=aIFi.Position().Direction();
199 for (j=i+1; j<=aNbF; ++j) {
200 if (aMp.Contains(j)) {
204 const TopoDS_Shape& aFj=aMF(j);
205 const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
206 const gp_Dir& aDNj=aIFj.Position().Direction();
209 if (fabs(1.-aDot)<0.0001) {
225 for (i=0; i<aNbFi; ++i) {
226 const TopoDS_Shape& aFi=aMFi(i+1);
227 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
229 aDist[i]=aPc.Distance(aPi);
230 if (aDist[i]>aDistMax) {
234 if (aDist[i]<aDistMin) {
238 gp_Vec aVi(aPc, aPi);
249 aLength=2.*aDist[iMax];
250 aWidth=2.*aDist[iMid];
251 aHeight=2.*aDist[iMin];
253 gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
256 aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
257 aInfo.SetLocation(aPc);
258 aInfo.SetLength(aLength);
259 aInfo.SetWidth(aWidth);
260 aInfo.SetHeight(aHeight);
261 aInfo.SetPosition(aAx3);
263 //=======================================================================
264 //function : FillDetails
266 //=======================================================================
267 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
270 Standard_Integer aNbV, aNbE, i, j;
271 Standard_Real aDot, aD0, aD1, aLength, aWidth;
273 gp_Pnt aPx[4], aP, aPc;
275 TopExp_Explorer aExp;
280 TopTools_IndexedMapOfShape aMV;
281 BRepTools_WireExplorer aWExp;
282 GEOMAlgo_KindOfName aKN, aKNE;
283 GEOMAlgo_KindOfShape aKS;
285 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
286 aKN=GEOMAlgo_KN_UNKNOWN;
287 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
289 aKS=aInfo.KindOfShape();
290 if (aKS!=GEOMAlgo_KS_PLANE) {
294 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
295 aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
299 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
300 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
302 // 1. may be it is circle/ellipse
303 if (aNbV==1 && aNbE==1) {
304 aExp.Init(aF, TopAbs_EDGE);
305 for (; aExp.More(); aExp.Next()) {
310 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
311 aKNE=aInfoE.KindOfName();
312 if (aKNE==GEOMAlgo_KN_CIRCLE) {
313 aKN=GEOMAlgo_KN_DISKCIRCLE;
314 aInfo.SetKindOfName(aKN);
315 aInfo.SetRadius1(aInfoE.Radius1());
316 aInfo.SetLocation(aInfoE.Location());
317 aInfo.SetPosition(aInfoE.Position());
319 if (aKNE==GEOMAlgo_KN_ELLIPSE) {
320 aKN=GEOMAlgo_KN_DISKELLIPSE;
321 aInfo.SetKindOfName(aKN);
322 aInfo.SetRadius1(aInfoE.Radius1());
323 aInfo.SetRadius2(aInfoE.Radius2());
324 aInfo.SetLocation(aInfoE.Location());
325 aInfo.SetPosition(aInfoE.Position());
329 // 2. may be it is rectangle
331 aExp.Init(aF, TopAbs_EDGE);
332 for (; aExp.More(); aExp.Next()) {
334 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
335 aKNE=aInfoE.KindOfName();
336 if (aKNE!=GEOMAlgo_KN_SEGMENT) {
341 aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
343 if (aNbV==3 && aNbE==3) {
344 aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
346 aXYZc.SetCoord(0.,0.,0.);
347 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
348 for (i=1; i<=aNbV; ++i) {
349 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
350 aP=BRep_Tool::Pnt(aV);
351 const gp_XYZ& aXYZ=aP.XYZ();
358 gp_Vec aVX(aPc, aPx[0]);
360 aDX.SetXYZ(aVX.XYZ());
361 const gp_Dir& aDZ=aPln.Axis().Direction();
363 gp_Ax2 aAx2(aPc, aDZ, aDX);
366 aInfo.SetLocation(aPc);
367 aInfo.SetPosition(aAx3);
372 if (!(aNbV==4 && aNbE==4)) {
376 // aNbV==4 && aNbE==4 and all edges are segments
378 for (; aIt.More(); aIt.Next()){
379 aW=TopoDS::Wire(aIt.Value());
384 for (i=0; aWExp.More(); aWExp.Next(), ++i) {
386 const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
387 aDx[i]=aInfoEx.Direction();
388 aPx[i]=aInfoEx.Location();
391 for (i=0; i<4; ++i) {
394 if (fabs (aDot) > myTolerance) {
395 aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
401 aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
403 // shift location to the center and calc. sizes
404 aXYZc.SetCoord(0.,0.,0.);
405 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
406 for (i=1; i<=aNbV; ++i) {
407 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
408 aP=BRep_Tool::Pnt(aV);
409 const gp_XYZ& aXYZ=aP.XYZ();
413 // Location : aPc in center of rectangle
414 // Position : 0z is plane normal
415 // 0x is along length
420 gp_Lin aL0(aPx[0], aDx[0]);
421 gp_Lin aL1(aPx[1], aDx[1]);
423 aD0=aL0.Distance(aPc);
424 aD1=aL1.Distance(aPc);
438 aInfo.SetLocation(aPc);
439 aInfo.SetLength(aLength);
440 aInfo.SetWidth(aWidth);
442 const gp_Dir& aDZ=aPln.Axis().Direction();
443 gp_Ax2 aAx2(aPc, aDZ, aDX);
445 aInfo.SetPosition(aAx3);
450 //=======================================================================
451 //function : FillDetails
453 //=======================================================================
454 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
457 Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
459 TopExp_Explorer aExp;
460 TopTools_MapOfShape aM;
461 GEOMAlgo_KindOfShape aKS, aKSE;
463 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
464 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
466 aKS=aInfo.KindOfShape();
467 if (aKS!=GEOMAlgo_KS_SPHERE) {
471 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
472 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
473 if (!(aNbV==2 && aNbE==3)) {
479 aExp.Init(aF, TopAbs_EDGE);
480 for (; aExp.More(); aExp.Next()) {
481 aE=TopoDS::Edge(aExp.Current());
483 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
484 aKSE=aInfoE.KindOfShape();
486 if (BRep_Tool::IsClosed(aE, aF)) {
489 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
495 if (!(aNbSE==1 && aNbDE==2)) {
498 aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
500 //=======================================================================
501 //function : FillDetails
503 //=======================================================================
504 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
505 const gp_Cone& )//aCone)
507 Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
508 Standard_Real aR[3], aHeight;
509 gp_Pnt aPC[3], aPD, aPc, aPX[3];
513 TopExp_Explorer aExp;
514 TopTools_MapOfShape aM;
515 GEOMAlgo_KindOfShape aKS, aKSE;
516 GEOMAlgo_KindOfName aKN, aKNE;
517 GEOMAlgo_KindOfClosed aKCE;
519 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
520 aKN=GEOMAlgo_KN_UNKNOWN;
521 aInfo.SetKindOfName(aKN);
523 aKS=aInfo.KindOfShape();
524 if (aKS!=GEOMAlgo_KS_CONE) {
528 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
532 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
533 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
534 if (!(aNbV==2 && aNbE==3)) {
542 aExp.Init(aF, TopAbs_EDGE);
543 for (; aExp.More(); aExp.Next()) {
544 aE=TopoDS::Edge(aExp.Current());
546 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
547 aKNE=aInfoE.KindOfName();
548 aKCE=aInfoE.KindOfClosed();
549 aKSE=aInfoE.KindOfShape();
550 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
551 aPC[i]=aInfoE.Location();
552 aR[i]=aInfoE.Radius1();
555 for (; aIt.More(); aIt.Next()) {
556 aVD=TopoDS::Vertex(aIt.Value());
559 aPX[i]=BRep_Tool::Pnt(aVD);
564 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
565 if (BRep_Tool::IsClosed(aE, aF)) {
569 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
571 for (; aIt.More(); aIt.Next()) {
572 aVD=TopoDS::Vertex(aIt.Value());
576 aPD=BRep_Tool::Pnt(aVD);
583 if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
592 aHeight=aPC[0].Distance(aPC[1]);
594 Standard_Real aRmin, aRmax;
601 gp_Vec aVz(aPC[0], aPC[1]);
602 gp_Vec aVx(aPC[0], aPX[0]);
605 gp_Ax2 aAx2(aPc, aDz, aDx);
612 gp_Vec aVz(aPC[1], aPC[0]);
613 gp_Vec aVx(aPC[1], aPX[1]);
616 gp_Ax2 aAx2(aPc, aDz, aDx);
620 gp_Ax3 aAx3(aAx2new);
621 aInfo.SetLocation(aPc);
622 aInfo.SetPosition(aAx3);
623 aInfo.SetRadius1(aRmax);
624 aInfo.SetRadius2(aRmin);
625 aInfo.SetHeight(aHeight);
627 aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
629 //=======================================================================
630 //function : FillDetails
632 //=======================================================================
633 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
634 const gp_Cylinder& aCyl)
636 Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
637 Standard_Real aT0, aT1, aHeight;
640 TopExp_Explorer aExp;
641 TopTools_MapOfShape aM;
642 GEOMAlgo_KindOfShape aKS;
643 GEOMAlgo_KindOfName aKN, aKNE;
644 GEOMAlgo_KindOfClosed aKCE;
646 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
647 aKN=GEOMAlgo_KN_UNKNOWN;
648 aInfo.SetKindOfName(aKN);
650 aKS=aInfo.KindOfShape();
651 if (aKS!=GEOMAlgo_KS_CYLINDER) {
655 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
659 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
660 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
661 if (!(aNbV==2 && aNbE==3)) {
668 aExp.Init(aF, TopAbs_EDGE);
669 for (; aExp.More(); aExp.Next()) {
670 aE=TopoDS::Edge(aExp.Current());
672 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
673 aKNE=aInfoE.KindOfName();
674 aKCE=aInfoE.KindOfClosed();
675 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
676 aPC[aNbCE]=aInfoE.Location();
679 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
680 if (BRep_Tool::IsClosed(aE, aF)) {
687 if (!(aNbCE==2 && aNbSE==1)) {
691 const gp_Ax1& aAx1=aCyl.Axis();
692 const gp_Dir& aDir=aAx1.Direction();
693 const gp_Pnt& aPLoc=aAx1.Location();
694 gp_Lin aLin(aPLoc, aDir);
696 aT0=ElCLib::Parameter(aLin, aPC[0]);
697 aT1=ElCLib::Parameter(aLin, aPC[1]);
703 aHeight=aPC[0].Distance(aPC[1]);
705 gp_Ax3 aAx3=aCyl.Position();
706 aAx3.SetLocation(aPc);
708 aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
709 aInfo.SetPosition(aAx3);
710 aInfo.SetLocation(aPc);
711 aInfo.SetHeight(aHeight);
714 //=======================================================================
715 //function : FillDetails
717 //=======================================================================
718 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
721 Standard_Integer aNbV, aNbE, aNbSE;
723 TopExp_Explorer aExp;
724 TopTools_MapOfShape aM;
725 GEOMAlgo_KindOfShape aKS;
727 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
728 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
730 aKS=aInfo.KindOfShape();
731 if (aKS!=GEOMAlgo_KS_TORUS) {
735 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
736 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
737 if (!(aNbV==1 && aNbE==2)) {
742 aExp.Init(aF, TopAbs_EDGE);
743 for (; aExp.More(); aExp.Next()) {
744 aE=TopoDS::Edge(aExp.Current());
746 //const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
747 if (BRep_Tool::IsClosed(aE, aF)) {
756 aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);