mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-12-28 18:30:36 +05:00
902 lines
22 KiB
C++
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
|