1 #include <GEOMAlgo_ShapeInfoFiller.ixx>
3 #include <Precision.hxx>
16 #include <TopoDS_Vertex.hxx>
17 #include <TopoDS_Edge.hxx>
18 #include <TopoDS_Wire.hxx>
19 #include <TopoDS_Face.hxx>
20 #include <TopoDS_Iterator.hxx>
22 #include <BRep_Tool.hxx>
25 #include <TopExp_Explorer.hxx>
27 #include <TopTools_MapOfShape.hxx>
28 #include <TopTools_IndexedMapOfShape.hxx>
29 #include <BRepTools_WireExplorer.hxx>
31 #include <GEOMAlgo_ShapeInfo.hxx>
32 #include <TColStd_MapOfInteger.hxx>
33 #include <TColStd_IndexedMapOfInteger.hxx>
35 //=======================================================================
36 //function : FillDetails
38 //=======================================================================
39 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd)
41 Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX;
42 TopoDS_Shape aFCyl, aFCon;
43 TopTools_IndexedMapOfShape aMF;
44 GEOMAlgo_KindOfName aKNF;
46 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
47 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
49 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
57 const TopoDS_Shape& aF=aMF(1);
58 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
59 aKNF=aInfoF.KindOfName(); // mb: sphere, torus
60 if (aKNF==GEOMAlgo_KN_SPHERE ||
61 aKNF==GEOMAlgo_KN_TORUS) {
62 aInfo.SetKindOfName(aKNF);
63 aInfo.SetLocation(aInfoF.Location());
64 aInfo.SetPosition(aInfoF.Position());
65 aInfo.SetRadius1(aInfoF.Radius1());
66 if(aKNF==GEOMAlgo_KN_TORUS) {
67 aInfo.SetRadius2(aInfoF.Radius2());
78 for (i=1; i<=aNbF; ++i) {
79 const TopoDS_Shape& aF=aMF(i);
80 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
81 aKNF=aInfoF.KindOfName();
82 if (aKNF==GEOMAlgo_KN_CYLINDER) {
86 else if (aKNF==GEOMAlgo_KN_CONE) {
90 else if (aKNF==GEOMAlgo_KN_DISKCIRCLE) {
93 else if (aKNF==GEOMAlgo_KN_POLYGON ||
94 aKNF==GEOMAlgo_KN_TRIANGLE ||
95 aKNF==GEOMAlgo_KN_QUADRANGLE) {
99 else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
106 if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
107 // cylinder (as they understand it)
108 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
109 aKNF=aInfoF.KindOfName();
110 aInfo.SetKindOfName(aKNF);
111 aInfo.SetLocation(aInfoF.Location());
112 aInfo.SetPosition(aInfoF.Position());
113 aInfo.SetRadius1(aInfoF.Radius1());
114 aInfo.SetHeight(aInfoF.Height());
119 if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
121 GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
122 aKNF=aInfoF.KindOfName();
123 aInfo.SetKindOfName(aKNF);
124 aInfo.SetLocation(aInfoF.Location());
125 aInfo.SetPosition(aInfoF.Position());
126 aInfo.SetRadius1(aInfoF.Radius1());
127 aInfo.SetRadius2(aInfoF.Radius2());
128 aInfo.SetHeight(aInfoF.Height());
133 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
136 if (aNbPgn!=aNbRct) {
137 aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
140 //===================================================
143 Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
144 Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
145 Standard_Real aDistMin, aDistMax;
149 TColStd_IndexedMapOfInteger aMp;
150 TopTools_IndexedMapOfShape aMV, aMFi;
153 TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
159 aXYZc.SetCoord(0.,0.,0.);
160 for (i=1; i<=aNbV; ++i) {
161 const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
162 aPi=BRep_Tool::Pnt(aVi);
163 const gp_XYZ& aXYZ=aPi.XYZ();
171 for (i=1; i<=aNbF; ++i) {
172 if (aMp.Contains(i)) {
176 const TopoDS_Shape& aFi=aMF(i);
177 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
178 const gp_Dir& aDNi=aIFi.Position().Direction();
180 for (j=i+1; j<=aNbF; ++j) {
181 if (aMp.Contains(j)) {
185 const TopoDS_Shape& aFj=aMF(j);
186 const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
187 const gp_Dir& aDNj=aIFj.Position().Direction();
190 if (fabs(1.-aDot)<0.0001) {
206 for (i=0; i<aNbFi; ++i) {
207 const TopoDS_Shape& aFi=aMFi(i+1);
208 const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
210 aDist[i]=aPc.Distance(aPi);
211 if (aDist[i]>aDistMax) {
215 if (aDist[i]<aDistMin) {
219 gp_Vec aVi(aPc, aPi);
230 aLength=2.*aDist[iMax];
231 aWidth=2.*aDist[iMid];
232 aHeight=2.*aDist[iMin];
234 gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
237 aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
238 aInfo.SetLocation(aPc);
239 aInfo.SetLength(aLength);
240 aInfo.SetWidth(aWidth);
241 aInfo.SetHeight(aHeight);
242 aInfo.SetPosition(aAx3);
244 //=======================================================================
245 //function : FillDetails
247 //=======================================================================
248 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
251 Standard_Integer aNbV, aNbE, i, j;
252 Standard_Real aDot, aD0, aD1, aLength, aWidth;
254 gp_Pnt aPx[4], aP, aPc;
256 TopExp_Explorer aExp;
261 TopTools_IndexedMapOfShape aMV;
262 BRepTools_WireExplorer aWExp;
263 GEOMAlgo_KindOfName aKN, aKNE;
264 GEOMAlgo_KindOfShape aKS;
266 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
267 aKN=GEOMAlgo_KN_UNKNOWN;
268 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
270 aKS=aInfo.KindOfShape();
271 if (aKS!=GEOMAlgo_KS_PLANE) {
275 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
276 aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
280 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
281 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
283 // 1. may be it is circle/ellipse
284 if (aNbV==1 && aNbE==1) {
285 aExp.Init(aF, TopAbs_EDGE);
286 for (; aExp.More(); aExp.Next()) {
291 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
292 aKNE=aInfoE.KindOfName();
293 if (aKNE==GEOMAlgo_KN_CIRCLE) {
294 aKN=GEOMAlgo_KN_DISKCIRCLE;
295 aInfo.SetKindOfName(aKN);
296 aInfo.SetRadius1(aInfoE.Radius1());
297 aInfo.SetLocation(aInfoE.Location());
298 aInfo.SetPosition(aInfoE.Position());
300 if (aKNE==GEOMAlgo_KN_ELLIPSE) {
301 aKN=GEOMAlgo_KN_DISKELLIPSE;
302 aInfo.SetKindOfName(aKN);
303 aInfo.SetRadius1(aInfoE.Radius1());
304 aInfo.SetRadius2(aInfoE.Radius2());
305 aInfo.SetLocation(aInfoE.Location());
306 aInfo.SetPosition(aInfoE.Position());
310 // 2. may be it is rectangle
312 aExp.Init(aF, TopAbs_EDGE);
313 for (; aExp.More(); aExp.Next()) {
315 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
316 aKNE=aInfoE.KindOfName();
317 if (aKNE!=GEOMAlgo_KN_SEGMENT) {
322 aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
324 if (aNbV==3 && aNbE==3) {
325 aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
327 aXYZc.SetCoord(0.,0.,0.);
328 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
329 for (i=1; i<=aNbV; ++i) {
330 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
331 aP=BRep_Tool::Pnt(aV);
332 const gp_XYZ& aXYZ=aP.XYZ();
339 gp_Vec aVX(aPc, aPx[0]);
341 aDX.SetXYZ(aVX.XYZ());
342 const gp_Dir& aDZ=aPln.Axis().Direction();
344 gp_Ax2 aAx2(aPc, aDZ, aDX);
347 aInfo.SetLocation(aPc);
348 aInfo.SetPosition(aAx3);
353 if (!(aNbV==4 && aNbE==4)) {
357 // aNbV==4 && aNbE==4 and all edges are segments
359 for (; aIt.More(); aIt.Next()){
360 aW=TopoDS::Wire(aIt.Value());
365 for (i=0; aWExp.More(); aWExp.Next(), ++i) {
367 const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
368 aDx[i]=aInfoEx.Direction();
369 aPx[i]=aInfoEx.Location();
372 for (i=0; i<4; ++i) {
375 if (fabs (aDot) > myTolerance) {
376 aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
382 aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
384 // shift location to the center and calc. sizes
385 aXYZc.SetCoord(0.,0.,0.);
386 TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
387 for (i=1; i<=aNbV; ++i) {
388 const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
389 aP=BRep_Tool::Pnt(aV);
390 const gp_XYZ& aXYZ=aP.XYZ();
394 // Location : aPc in center of rectangle
395 // Position : 0z is plane normal
396 // 0x is along length
401 gp_Lin aL0(aPx[0], aDx[0]);
402 gp_Lin aL1(aPx[1], aDx[1]);
404 aD0=aL0.Distance(aPc);
405 aD1=aL1.Distance(aPc);
419 aInfo.SetLocation(aPc);
420 aInfo.SetLength(aLength);
421 aInfo.SetWidth(aWidth);
423 const gp_Dir& aDZ=aPln.Axis().Direction();
424 gp_Ax2 aAx2(aPc, aDZ, aDX);
426 aInfo.SetPosition(aAx3);
431 //=======================================================================
432 //function : FillDetails
434 //=======================================================================
435 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
438 Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
440 TopExp_Explorer aExp;
441 TopTools_MapOfShape aM;
442 GEOMAlgo_KindOfShape aKS, aKSE;
444 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
445 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
447 aKS=aInfo.KindOfShape();
448 if (aKS!=GEOMAlgo_KS_SPHERE) {
452 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
453 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
454 if (!(aNbV==2 && aNbE==3)) {
460 aExp.Init(aF, TopAbs_EDGE);
461 for (; aExp.More(); aExp.Next()) {
462 aE=TopoDS::Edge(aExp.Current());
464 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
465 aKSE=aInfoE.KindOfShape();
467 if (BRep_Tool::IsClosed(aE, aF)) {
470 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
476 if (!(aNbSE==1 && aNbDE==2)) {
479 aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
481 //=======================================================================
482 //function : FillDetails
484 //=======================================================================
485 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
486 const gp_Cone& )//aCone)
488 Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
489 Standard_Real aR[3], aHeight;
490 gp_Pnt aPC[3], aPD, aPc, aPX[3];
494 TopExp_Explorer aExp;
495 TopTools_MapOfShape aM;
496 GEOMAlgo_KindOfShape aKS, aKSE;
497 GEOMAlgo_KindOfName aKN, aKNE;
498 GEOMAlgo_KindOfClosed aKCE;
500 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
501 aKN=GEOMAlgo_KN_UNKNOWN;
502 aInfo.SetKindOfName(aKN);
504 aKS=aInfo.KindOfShape();
505 if (aKS!=GEOMAlgo_KS_CONE) {
509 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
513 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
514 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
515 if (!(aNbV==2 && aNbE==3)) {
523 aExp.Init(aF, TopAbs_EDGE);
524 for (; aExp.More(); aExp.Next()) {
525 aE=TopoDS::Edge(aExp.Current());
527 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
528 aKNE=aInfoE.KindOfName();
529 aKCE=aInfoE.KindOfClosed();
530 aKSE=aInfoE.KindOfShape();
531 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
532 aPC[i]=aInfoE.Location();
533 aR[i]=aInfoE.Radius1();
536 for (; aIt.More(); aIt.Next()) {
537 aVD=TopoDS::Vertex(aIt.Value());
540 aPX[i]=BRep_Tool::Pnt(aVD);
545 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
546 if (BRep_Tool::IsClosed(aE, aF)) {
550 else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
552 for (; aIt.More(); aIt.Next()) {
553 aVD=TopoDS::Vertex(aIt.Value());
557 aPD=BRep_Tool::Pnt(aVD);
564 if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
573 aHeight=aPC[0].Distance(aPC[1]);
575 Standard_Real aRmin, aRmax;
582 gp_Vec aVz(aPC[0], aPC[1]);
583 gp_Vec aVx(aPC[0], aPX[0]);
586 gp_Ax2 aAx2(aPc, aDz, aDx);
593 gp_Vec aVz(aPC[1], aPC[0]);
594 gp_Vec aVx(aPC[1], aPX[1]);
597 gp_Ax2 aAx2(aPc, aDz, aDx);
601 gp_Ax3 aAx3(aAx2new);
602 aInfo.SetLocation(aPc);
603 aInfo.SetPosition(aAx3);
604 aInfo.SetRadius1(aRmax);
605 aInfo.SetRadius2(aRmin);
606 aInfo.SetHeight(aHeight);
608 aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
610 //=======================================================================
611 //function : FillDetails
613 //=======================================================================
614 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
615 const gp_Cylinder& aCyl)
617 Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
618 Standard_Real aT0, aT1, aHeight;
621 TopExp_Explorer aExp;
622 TopTools_MapOfShape aM;
623 GEOMAlgo_KindOfShape aKS;
624 GEOMAlgo_KindOfName aKN, aKNE;
625 GEOMAlgo_KindOfClosed aKCE;
627 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
628 aKN=GEOMAlgo_KN_UNKNOWN;
629 aInfo.SetKindOfName(aKN);
631 aKS=aInfo.KindOfShape();
632 if (aKS!=GEOMAlgo_KS_CYLINDER) {
636 if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
640 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
641 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
642 if (!(aNbV==2 && aNbE==3)) {
649 aExp.Init(aF, TopAbs_EDGE);
650 for (; aExp.More(); aExp.Next()) {
651 aE=TopoDS::Edge(aExp.Current());
653 const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
654 aKNE=aInfoE.KindOfName();
655 aKCE=aInfoE.KindOfClosed();
656 if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
657 aPC[aNbCE]=aInfoE.Location();
660 else if (aKNE==GEOMAlgo_KN_SEGMENT) {
661 if (BRep_Tool::IsClosed(aE, aF)) {
668 if (!(aNbCE==2 && aNbSE==1)) {
672 const gp_Ax1& aAx1=aCyl.Axis();
673 const gp_Dir& aDir=aAx1.Direction();
674 const gp_Pnt& aPLoc=aAx1.Location();
675 gp_Lin aLin(aPLoc, aDir);
677 aT0=ElCLib::Parameter(aLin, aPC[0]);
678 aT1=ElCLib::Parameter(aLin, aPC[1]);
684 aHeight=aPC[0].Distance(aPC[1]);
686 gp_Ax3 aAx3=aCyl.Position();
687 aAx3.SetLocation(aPc);
689 aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
690 aInfo.SetPosition(aAx3);
691 aInfo.SetLocation(aPc);
692 aInfo.SetHeight(aHeight);
695 //=======================================================================
696 //function : FillDetails
698 //=======================================================================
699 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
702 Standard_Integer aNbV, aNbE, aNbSE;
704 TopExp_Explorer aExp;
705 TopTools_MapOfShape aM;
706 GEOMAlgo_KindOfShape aKS;
708 GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
709 aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
711 aKS=aInfo.KindOfShape();
712 if (aKS!=GEOMAlgo_KS_TORUS) {
716 aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
717 aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
718 if (!(aNbV==1 && aNbE==2)) {
723 aExp.Init(aF, TopAbs_EDGE);
724 for (; aExp.More(); aExp.Next()) {
725 aE=TopoDS::Edge(aExp.Current());
727 //const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
728 if (BRep_Tool::IsClosed(aE, aF)) {
737 aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);