geom/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx
2012-08-09 07:58:02 +00:00

902 lines
22 KiB
C++

// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#include <GEOMAlgo_ShapeInfoFiller.hxx>
#include <Precision.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
#include <gp_Lin.hxx>
#include <gp_XYZ.hxx>
#include <gp_Ax1.hxx>
#include <gp_Dir.hxx>
#include <gp_Vec.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <ElCLib.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <BRep_Tool.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <BRepGProp.hxx>
#include <GProp_GProps.hxx>
#include <GEOMAlgo_ShapeInfo.hxx>
static
Standard_Boolean IsEqual(const gp_Sphere& aSp1,
const gp_Sphere& aSp2,
const Standard_Real aTolDst);
//=======================================================================
//function : FillDetails
//purpose :
//=======================================================================
void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd)
{
Standard_Boolean bIsStepSphere;
Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX;
TopoDS_Shape aFCyl, aFCon;
TopTools_IndexedMapOfShape aMF;
GEOMAlgo_KindOfName aKNF;
//
GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
//
TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
//
aNbF=aMF.Extent();
if (!aNbF) {
return;
}
//
if (aNbF==1) {
const TopoDS_Shape& aF=aMF(1);
GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
aKNF=aInfoF.KindOfName(); // mb: sphere, torus
if (aKNF==GEOMAlgo_KN_SPHERE ||
aKNF==GEOMAlgo_KN_TORUS) {
aInfo.SetKindOfName(aKNF);
aInfo.SetLocation(aInfoF.Location());
aInfo.SetPosition(aInfoF.Position());
aInfo.SetRadius1(aInfoF.Radius1());
if(aKNF==GEOMAlgo_KN_TORUS) {
aInfo.SetRadius2(aInfoF.Radius2());
}
return;
}
}
//modified by NIZNHY-PKV Tue Jul 03 13:23:55 2012f
else if (aNbF==2) {
// specific solid that should be treated as a sphere
bIsStepSphere=TreatStepSphere(aSd);
if (bIsStepSphere) {
return;
}
}
//modified by NIZNHY-PKV Tue Jul 03 13:23:57 2012t
//
aNbCyl=0;
aNbCon=0;
aNbPgn=0;
aNbRct=0;
aNbCrc=0;
for (i=1; i<=aNbF; ++i) {
const TopoDS_Shape& aF=aMF(i);
GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
aKNF=aInfoF.KindOfName();
if (aKNF==GEOMAlgo_KN_CYLINDER) {
aFCyl=aF;
++aNbCyl;
}
else if (aKNF==GEOMAlgo_KN_CONE) {
aFCon=aF;
++aNbCon;
}
else if (aKNF==GEOMAlgo_KN_DISKCIRCLE) {
++aNbCrc;
}
else if (aKNF==GEOMAlgo_KN_POLYGON ||
aKNF==GEOMAlgo_KN_TRIANGLE ||
aKNF==GEOMAlgo_KN_QUADRANGLE) {
++aNbPgn;
}
else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
++aNbPgn;
++aNbRct;
}
}
//
aNbX=aNbCyl+aNbCrc;
if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
// cylinder (as they understand it)
GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
aKNF=aInfoF.KindOfName();
aInfo.SetKindOfName(aKNF);
aInfo.SetLocation(aInfoF.Location());
aInfo.SetPosition(aInfoF.Position());
aInfo.SetRadius1(aInfoF.Radius1());
aInfo.SetHeight(aInfoF.Height());
return;
}
//
aNbX=aNbCon+aNbCrc;
if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
// cone
GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
aKNF=aInfoF.KindOfName();
aInfo.SetKindOfName(aKNF);
aInfo.SetLocation(aInfoF.Location());
aInfo.SetPosition(aInfoF.Position());
aInfo.SetRadius1(aInfoF.Radius1());
aInfo.SetRadius2(aInfoF.Radius2());
aInfo.SetHeight(aInfoF.Height());
return;
}
//
if (aNbF!=aNbPgn) {
return;// -> GEOMAlgo_KN_UNKNOWN
}
if (aNbPgn!=6) {
aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
return;
}
// aNbPgn==6
if (aNbPgn!=aNbRct) {
aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
return;
}
//===================================================
// aNbRct=6;
// box
Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
Standard_Real aDistMin, aDistMax;
gp_Pnt aPi, aPc;
gp_Dir aDir[3];
gp_XYZ aXYZc;
TColStd_IndexedMapOfInteger aMp;
TopTools_IndexedMapOfShape aMV, aMFi;
//
// barycenter aPc
TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
aNbV=aMV.Extent();
if (aNbV!=8) {
return;
}
//
aXYZc.SetCoord(0.,0.,0.);
for (i=1; i<=aNbV; ++i) {
const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
aPi=BRep_Tool::Pnt(aVi);
const gp_XYZ& aXYZ=aPi.XYZ();
aXYZc=aXYZc+aXYZ;
}
//
aXYZc.Divide(aNbV);
aPc.SetXYZ(aXYZc);
//
// 3 faces
for (i=1; i<=aNbF; ++i) {
if (aMp.Contains(i)) {
continue;
}
//
const TopoDS_Shape& aFi=aMF(i);
const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
const gp_Dir& aDNi=aIFi.Position().Direction();
//
for (j=i+1; j<=aNbF; ++j) {
if (aMp.Contains(j)) {
continue;
}
//
const TopoDS_Shape& aFj=aMF(j);
const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
const gp_Dir& aDNj=aIFj.Position().Direction();
//
aDot=aDNi*aDNj;
//modified by NIZNHY-PKV Tue Jul 03 10:01:56 2012f
if (aDot<0.) {
aDot=-aDot;
}
//modified by NIZNHY-PKV Tue Jul 03 10:01:52 2012t
if (fabs(1.-aDot)<0.0001) {
aMp.Add(i);
aMp.Add(j);
aMFi.Add(aFi);
break;
}
//
}
}
aNbFi=aMFi.Extent();
if (aNbFi!=3) {
return;
}
//
aDistMin=1.e15;
aDistMax=-aDistMin;
for (i=0; i<aNbFi; ++i) {
const TopoDS_Shape& aFi=aMFi(i+1);
const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
aPi=aIFi.Location();
aDist[i]=aPc.Distance(aPi);
if (aDist[i]>aDistMax) {
aDistMax=aDist[i];
iMax=i;
}
if (aDist[i]<aDistMin) {
aDistMin=aDist[i];
iMin=i;
}
gp_Vec aVi(aPc, aPi);
gp_Dir aDi(aVi);
aDir[i]=aDi;
}
//
if (iMax==iMin) {
iMax=0;
iMin=1;
}
iMid=3-iMax-iMin;
//
aLength=2.*aDist[iMax];
aWidth=2.*aDist[iMid];
aHeight=2.*aDist[iMin];
//
gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
gp_Ax3 aAx3(aAx2);
//
aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
aInfo.SetLocation(aPc);
aInfo.SetLength(aLength);
aInfo.SetWidth(aWidth);
aInfo.SetHeight(aHeight);
aInfo.SetPosition(aAx3);
}
//=======================================================================
//function : FillDetails
//purpose :
//=======================================================================
void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
const gp_Pln& aPln)
{
Standard_Integer aNbV, aNbE, i, j;
Standard_Real aDot, aD0, aD1, aLength, aWidth;
gp_Dir aDx[4], aDX;
gp_Pnt aPx[4], aP, aPc;
gp_XYZ aXYZc;
TopExp_Explorer aExp;
TopoDS_Shape aE;
TopoDS_Wire aW;
TopoDS_Edge aEx;
TopoDS_Iterator aIt;
TopTools_IndexedMapOfShape aMV;
BRepTools_WireExplorer aWExp;
GEOMAlgo_KindOfName aKN, aKNE;
GEOMAlgo_KindOfShape aKS;
//
GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
aKN=GEOMAlgo_KN_UNKNOWN;
aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
//
aKS=aInfo.KindOfShape();
if (aKS!=GEOMAlgo_KS_PLANE) {
return;
}
//
if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
return;
}
//
aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
//
// 1. may be it is circle/ellipse
if (aNbV==1 && aNbE==1) {
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
aE=aExp.Current();
break;
}
//
const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
aKNE=aInfoE.KindOfName();
if (aKNE==GEOMAlgo_KN_CIRCLE) {
aKN=GEOMAlgo_KN_DISKCIRCLE;
aInfo.SetKindOfName(aKN);
aInfo.SetRadius1(aInfoE.Radius1());
aInfo.SetLocation(aInfoE.Location());
aInfo.SetPosition(aInfoE.Position());
}
if (aKNE==GEOMAlgo_KN_ELLIPSE) {
aKN=GEOMAlgo_KN_DISKELLIPSE;
aInfo.SetKindOfName(aKN);
aInfo.SetRadius1(aInfoE.Radius1());
aInfo.SetRadius2(aInfoE.Radius2());
aInfo.SetLocation(aInfoE.Location());
aInfo.SetPosition(aInfoE.Position());
}
}
//
// 2. may be it is rectangle
else {
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
aE=aExp.Current();
const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
aKNE=aInfoE.KindOfName();
if (aKNE!=GEOMAlgo_KN_SEGMENT) {
return;
}
}
//
aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
//
if (aNbV==3 && aNbE==3) {
aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
//
aXYZc.SetCoord(0.,0.,0.);
TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
for (i=1; i<=aNbV; ++i) {
const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
aP=BRep_Tool::Pnt(aV);
const gp_XYZ& aXYZ=aP.XYZ();
aXYZc=aXYZc+aXYZ;
aPx[i-1]=aP;
}
aXYZc.Divide(3.);
//
aPc.SetXYZ(aXYZc);
gp_Vec aVX(aPc, aPx[0]);
aVX.Normalize();
aDX.SetXYZ(aVX.XYZ());
const gp_Dir& aDZ=aPln.Axis().Direction();
//
gp_Ax2 aAx2(aPc, aDZ, aDX);
gp_Ax3 aAx3(aAx2);
//
aInfo.SetLocation(aPc);
aInfo.SetPosition(aAx3);
//
return;
}
//
if (!(aNbV==4 && aNbE==4)) {
return;
}
//
// aNbV==4 && aNbE==4 and all edges are segments
aIt.Initialize(aF);
for (; aIt.More(); aIt.Next()){
aW=TopoDS::Wire(aIt.Value());
break;
}
//
aWExp.Init(aW, aF);
for (i=0; aWExp.More(); aWExp.Next(), ++i) {
aEx=aWExp.Current();
const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
aDx[i]=aInfoEx.Direction();
aPx[i]=aInfoEx.Location();
}
//
for (i=0; i<4; ++i) {
j=(i==3) ? 0 : i+1;
aDot=aDx[i]*aDx[j];
if (fabs (aDot) > myTolerance) {
aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
return;
}
}
//
// rectangle
aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
//
// shift location to the center and calc. sizes
aXYZc.SetCoord(0.,0.,0.);
TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
for (i=1; i<=aNbV; ++i) {
const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
aP=BRep_Tool::Pnt(aV);
const gp_XYZ& aXYZ=aP.XYZ();
aXYZc=aXYZc+aXYZ;
}
//
// Location : aPc in center of rectangle
// Position : 0z is plane normal
// 0x is along length
//
aXYZc.Divide(4.);
aPc.SetXYZ(aXYZc);
//
gp_Lin aL0(aPx[0], aDx[0]);
gp_Lin aL1(aPx[1], aDx[1]);
//
aD0=aL0.Distance(aPc);
aD1=aL1.Distance(aPc);
//
aLength=aD0;
aWidth =aD1;
aDX=aL1.Direction();
if (aD0<aD1) {
aLength=aD1;
aWidth =aD0;
aDX=aL0.Direction();
}
//
aLength=2.*aLength;
aWidth =2.*aWidth;
//
aInfo.SetLocation(aPc);
aInfo.SetLength(aLength);
aInfo.SetWidth(aWidth);
//
const gp_Dir& aDZ=aPln.Axis().Direction();
gp_Ax2 aAx2(aPc, aDZ, aDX);
gp_Ax3 aAx3(aAx2);
aInfo.SetPosition(aAx3);
}
return;
}
//=======================================================================
//function : FillDetails
//purpose :
//=======================================================================
void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
const gp_Sphere& )
{
Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
TopoDS_Edge aE;
TopExp_Explorer aExp;
TopTools_MapOfShape aM;
GEOMAlgo_KindOfShape aKS, aKSE;
//
GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
//
aKS=aInfo.KindOfShape();
if (aKS!=GEOMAlgo_KS_SPHERE) {
return;
}
//
aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
if (!(aNbV==2 && aNbE==3)) {
return;
}
//
aNbSE=0;
aNbDE=0;
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
aE=TopoDS::Edge(aExp.Current());
if(aM.Add(aE)) {
const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
aKSE=aInfoE.KindOfShape();
//
if (BRep_Tool::IsClosed(aE, aF)) {
++aNbSE;
}
else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
++aNbDE;
}
}
}
//
if (!(aNbSE==1 && aNbDE==2)) {
return;
}
aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
}
//=======================================================================
//function : FillDetails
//purpose :
//=======================================================================
void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
const gp_Cone& )//aCone)
{
Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
Standard_Real aR[3], aHeight;
gp_Pnt aPC[3], aPD, aPc, aPX[3];
TopoDS_Vertex aVD;
TopoDS_Edge aE;
TopoDS_Iterator aIt;
TopExp_Explorer aExp;
TopTools_MapOfShape aM;
GEOMAlgo_KindOfShape aKS, aKSE;
GEOMAlgo_KindOfName aKN, aKNE;
GEOMAlgo_KindOfClosed aKCE;
//
GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
aKN=GEOMAlgo_KN_UNKNOWN;
aInfo.SetKindOfName(aKN);
//
aKS=aInfo.KindOfShape();
if (aKS!=GEOMAlgo_KS_CONE) {
return;
}
//
if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
return;
}
//
aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
if (!(aNbV==2 && aNbE==3)) {
return;
}
//
i=0;
aNbCE=0;
aNbSE=0;
aNbDE=0;
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
aE=TopoDS::Edge(aExp.Current());
if(aM.Add(aE)) {
const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
aKNE=aInfoE.KindOfName();
aKCE=aInfoE.KindOfClosed();
aKSE=aInfoE.KindOfShape();
if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
aPC[i]=aInfoE.Location();
aR[i]=aInfoE.Radius1();
//
aIt.Initialize(aE);
for (; aIt.More(); aIt.Next()) {
aVD=TopoDS::Vertex(aIt.Value());
break;
}
aPX[i]=BRep_Tool::Pnt(aVD);
//
++i;
++aNbCE;
}
else if (aKNE==GEOMAlgo_KN_SEGMENT) {
if (BRep_Tool::IsClosed(aE, aF)) {
++aNbSE;
}
}
else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
aIt.Initialize(aE);
for (; aIt.More(); aIt.Next()) {
aVD=TopoDS::Vertex(aIt.Value());
break;
}
//
aPD=BRep_Tool::Pnt(aVD);
//
++aNbDE;
}
}
}
//
if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
return;
}
//
if (aNbDE==1) {
aPC[1]=aPD;
aR[1]=0.;
}
//
aHeight=aPC[0].Distance(aPC[1]);
//
Standard_Real aRmin, aRmax;
gp_Ax2 aAx2new;
//
if (aR[0]>aR[1]) {
aRmin=aR[1];
aRmax=aR[0];
aPc=aPC[0];
gp_Vec aVz(aPC[0], aPC[1]);
gp_Vec aVx(aPC[0], aPX[0]);
gp_Dir aDz(aVz);
gp_Dir aDx(aVx);
gp_Ax2 aAx2(aPc, aDz, aDx);
aAx2new=aAx2;
}
else {
aRmin=aR[0];
aRmax=aR[1];
aPc=aPC[1];
gp_Vec aVz(aPC[1], aPC[0]);
gp_Vec aVx(aPC[1], aPX[1]);
gp_Dir aDz(aVz);
gp_Dir aDx(aVx);
gp_Ax2 aAx2(aPc, aDz, aDx);
aAx2new=aAx2;
}
//
gp_Ax3 aAx3(aAx2new);
aInfo.SetLocation(aPc);
aInfo.SetPosition(aAx3);
aInfo.SetRadius1(aRmax);
aInfo.SetRadius2(aRmin);
aInfo.SetHeight(aHeight);
//
aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
}
//=======================================================================
//function : FillDetails
//purpose :
//=======================================================================
void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
const gp_Cylinder& aCyl)
{
Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
Standard_Real aT0, aT1, aHeight;
gp_Pnt aPC[3], aPc;
TopoDS_Edge aE;
TopExp_Explorer aExp;
TopTools_MapOfShape aM;
GEOMAlgo_KindOfShape aKS;
GEOMAlgo_KindOfName aKN, aKNE;
GEOMAlgo_KindOfClosed aKCE;
//
GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
aKN=GEOMAlgo_KN_UNKNOWN;
aInfo.SetKindOfName(aKN);
//
aKS=aInfo.KindOfShape();
if (aKS!=GEOMAlgo_KS_CYLINDER) {
return;
}
//
if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
return;
}
//
aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
if (!(aNbV==2 && aNbE==3)) {
return;
}
//
i=0;
aNbCE=0;
aNbSE=0;
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
aE=TopoDS::Edge(aExp.Current());
if(aM.Add(aE)) {
const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
aKNE=aInfoE.KindOfName();
aKCE=aInfoE.KindOfClosed();
if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
aPC[aNbCE]=aInfoE.Location();
++aNbCE;
}
else if (aKNE==GEOMAlgo_KN_SEGMENT) {
if (BRep_Tool::IsClosed(aE, aF)) {
++aNbSE;
}
}
}
}
//
if (!(aNbCE==2 && aNbSE==1)) {
return;
}
//
const gp_Ax1& aAx1=aCyl.Axis();
const gp_Dir& aDir=aAx1.Direction();
const gp_Pnt& aPLoc=aAx1.Location();
gp_Lin aLin(aPLoc, aDir);
//
aT0=ElCLib::Parameter(aLin, aPC[0]);
aT1=ElCLib::Parameter(aLin, aPC[1]);
//
aPc=aPC[0];;
if (aT0>aT1) {
aPc=aPC[1];
}
aHeight=aPC[0].Distance(aPC[1]);
//
gp_Ax3 aAx3=aCyl.Position();
aAx3.SetLocation(aPc);
//
aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
aInfo.SetPosition(aAx3);
aInfo.SetLocation(aPc);
aInfo.SetHeight(aHeight);
}
//=======================================================================
//function : FillDetails
//purpose :
//=======================================================================
void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
const gp_Torus& )
{
Standard_Integer aNbV, aNbE, aNbSE;
TopoDS_Edge aE;
TopExp_Explorer aExp;
TopTools_MapOfShape aM;
GEOMAlgo_KindOfShape aKS;
//
GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
//
aKS=aInfo.KindOfShape();
if (aKS!=GEOMAlgo_KS_TORUS) {
return;
}
//
aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
if (!(aNbV==1 && aNbE==2)) {
return;
}
//
aNbSE=0;
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
aE=TopoDS::Edge(aExp.Current());
if (aM.Add(aE)) {
if (BRep_Tool::IsClosed(aE, aF)) {
++aNbSE;
}
}
}
//
if (aNbSE!=2) {
return;
}
aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);
}
//modified by NIZNHY-PKV Tue Jul 03 13:29:41 2012f
//=======================================================================
//function : TreatStepSphere
//purpose :
//=======================================================================
Standard_Boolean
GEOMAlgo_ShapeInfoFiller::TreatStepSphere(const TopoDS_Solid& aSd)
{
Standard_Boolean bRet, bIsAllowedType, bOnlyClosed, bIsEqual;
Standard_Integer j;
Standard_Real aTolAng, aTolLin;
Standard_Real aVolume, aVolumeS, dV, aArea, aAreaS, dA;
gp_Sphere aSphere[2];
GeomAbs_SurfaceType aST;
Handle(Geom_Surface) aS;
GeomAdaptor_Surface aGAS;
TopExp_Explorer aExp;
//
bRet=Standard_False;
aTolLin=Precision::Confusion();
aTolAng=Precision::Angular();
//
aExp.Init(aSd, TopAbs_FACE);
for (j=0; aExp.More(); aExp.Next(), ++j) {
const TopoDS_Face& aF=*((TopoDS_Face*)&aExp.Current());
aS=BRep_Tool::Surface(aF);
aGAS.Load(aS);
aST=aGAS.GetType();
bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aST);
if (!bIsAllowedType) {
return bRet;
}
//
if (aST!=GeomAbs_Sphere) {
return bRet;
}
//
aSphere[j]=aGAS.Sphere();
}
//
bIsEqual=IsEqual(aSphere[0], aSphere[1], aTolLin);
if (!bIsEqual) {
return bRet;
}
//
//--------------------------------
GProp_GProps aGProps;
//
bOnlyClosed=Standard_False;
//
aVolume=aSphere[0].Volume();
//
BRepGProp::VolumeProperties(aSd, aGProps, bOnlyClosed);
aVolumeS=aGProps.Mass();
if (aVolumeS<0.) {
aVolumeS=-aVolumeS;
}
//
dV=fabs(aVolumeS-aVolume);
if (dV>aTolLin) {
return bRet;
}
//--------------------------------
aArea=aSphere[0].Area();
//
BRepGProp::SurfaceProperties(aSd, aGProps);
aAreaS=aGProps.Mass();
//
dA=fabs(aAreaS-aArea);
if (dA>aTolLin) {
return bRet;
}
//
//--------------------------------
gp_Pnt aP0;
gp_Ax3 aAx3;
Standard_Real aR1;
//
aP0=aSphere[0].Location();
aAx3=aSphere[0].Position();
aR1=aSphere[0].Radius();
//
GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
//
aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
aInfo.SetLocation(aP0);
aInfo.SetPosition(aAx3);
aInfo.SetRadius1(aR1);
//
return !bRet;// true
}
//=======================================================================
//function : IsEqual
//purpose :
//=======================================================================
Standard_Boolean IsEqual(const gp_Sphere& aSp1,
const gp_Sphere& aSp2,
const Standard_Real aTolLin)
{
Standard_Boolean bRet;
Standard_Real aR1, aR2, aD2;
//
bRet=Standard_False;
aR1=aSp1.Radius();
aR2=aSp2.Radius();
if (fabs(aR1-aR2)>aTolLin) {
return bRet;
}
//
const gp_Pnt& aPC1=aSp1.Position().Location();
const gp_Pnt& aPC2=aSp2.Position().Location();
//
aD2=aPC1.SquareDistance(aPC2);
bRet=(aD2<aTolLin*aTolLin);
//
return bRet;
}
//modified by NIZNHY-PKV Tue Jul 03 13:29:43 2012t