#16662 EDF - ExportMED : too long (bis)

Compute precise bounding box for BSpline faces

+ Fix compilation warnings
This commit is contained in:
eap 2019-03-11 18:35:25 +03:00
parent 0b4f557c95
commit 4f3cfd814e
4 changed files with 109 additions and 57 deletions

View File

@ -4272,6 +4272,8 @@ struct ElementsOnShape::OctreeClassifier : public SMESH_Octree
std::vector< ElementsOnShape::Classifier >& cls ); std::vector< ElementsOnShape::Classifier >& cls );
void GetClassifiersAtPoint( const gp_XYZ& p, void GetClassifiersAtPoint( const gp_XYZ& p,
std::vector< ElementsOnShape::Classifier* >& classifiers ); std::vector< ElementsOnShape::Classifier* >& classifiers );
size_t GetSize();
protected: protected:
OctreeClassifier() {} OctreeClassifier() {}
SMESH_Octree* newChild() const { return new OctreeClassifier; } SMESH_Octree* newChild() const { return new OctreeClassifier; }
@ -4297,6 +4299,21 @@ ElementsOnShape::~ElementsOnShape()
Predicate* ElementsOnShape::clone() const Predicate* ElementsOnShape::clone() const
{ {
size_t size = sizeof( *this );
if ( myOctree )
size += myOctree->GetSize();
if ( !myClassifiers.empty() )
size += sizeof( myClassifiers[0] ) * myClassifiers.size();
if ( !myWorkClassifiers.empty() )
size += sizeof( myWorkClassifiers[0] ) * myWorkClassifiers.size();
if ( size > 1e+9 ) // 1G
{
#ifdef _DEBUG_
std::cout << "Avoid ElementsOnShape::clone(), too large: " << size << " bytes " << std::endl;
#endif
return 0;
}
ElementsOnShape* cln = new ElementsOnShape(); ElementsOnShape* cln = new ElementsOnShape();
cln->SetAllNodes ( myAllNodesFlag ); cln->SetAllNodes ( myAllNodesFlag );
cln->SetTolerance( myToler ); cln->SetTolerance( myToler );
@ -4453,6 +4470,8 @@ bool ElementsOnShape::IsSatisfy (const SMDS_MeshElement* elem)
for ( size_t i = 0; i < myClassifiers.size(); ++i ) for ( size_t i = 0; i < myClassifiers.size(); ++i )
myWorkClassifiers[ i ] = & myClassifiers[ i ]; myWorkClassifiers[ i ] = & myClassifiers[ i ];
myOctree = new OctreeClassifier( myWorkClassifiers ); myOctree = new OctreeClassifier( myWorkClassifiers );
SMESHUtils::FreeVector( myWorkClassifiers );
} }
for ( int i = 0, nb = elem->NbNodes(); i < nb && (isSatisfy == myAllNodesFlag); ++i ) for ( int i = 0, nb = elem->NbNodes(); i < nb && (isSatisfy == myAllNodesFlag); ++i )
@ -4624,6 +4643,16 @@ void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape,
{ {
Bnd_Box box; Bnd_Box box;
BRepBndLib::Add( myShape, box ); BRepBndLib::Add( myShape, box );
if ( myShape.ShapeType() == TopAbs_FACE )
{
BRepAdaptor_Surface SA( TopoDS::Face( myShape ), /*useBoundaries=*/false );
if ( SA.GetType() == GeomAbs_BSplineSurface )
{
box.SetVoid();
BRepBndLib::AddOptimal( myShape, box,
/*useTriangulation=*/true, /*useShapeTolerance=*/true );
}
}
myBox.Clear(); myBox.Clear();
myBox.Add( box.CornerMin() ); myBox.Add( box.CornerMin() );
myBox.Add( box.CornerMax() ); myBox.Add( box.CornerMax() );
@ -4643,19 +4672,19 @@ ElementsOnShape::Classifier::~Classifier()
delete mySolidClfr; mySolidClfr = 0; delete mySolidClfr; mySolidClfr = 0;
} }
bool ElementsOnShape::Classifier::isOutOfSolid (const gp_Pnt& p) bool ElementsOnShape::Classifier::isOutOfSolid( const gp_Pnt& p )
{ {
if ( isOutOfBox( p )) return true; if ( isOutOfBox( p )) return true;
mySolidClfr->Perform( p, myTol ); mySolidClfr->Perform( p, myTol );
return ( mySolidClfr->State() != TopAbs_IN && mySolidClfr->State() != TopAbs_ON ); return ( mySolidClfr->State() != TopAbs_IN && mySolidClfr->State() != TopAbs_ON );
} }
bool ElementsOnShape::Classifier::isOutOfBox (const gp_Pnt& p) bool ElementsOnShape::Classifier::isOutOfBox( const gp_Pnt& p )
{ {
return myBox.IsOut( p.XYZ() ); return myBox.IsOut( p.XYZ() );
} }
bool ElementsOnShape::Classifier::isOutOfFace (const gp_Pnt& p) bool ElementsOnShape::Classifier::isOutOfFace( const gp_Pnt& p )
{ {
if ( isOutOfBox( p )) return true; if ( isOutOfBox( p )) return true;
myProjFace.Perform( p ); myProjFace.Perform( p );
@ -4672,19 +4701,19 @@ bool ElementsOnShape::Classifier::isOutOfFace (const gp_Pnt& p)
return true; return true;
} }
bool ElementsOnShape::Classifier::isOutOfEdge (const gp_Pnt& p) bool ElementsOnShape::Classifier::isOutOfEdge( const gp_Pnt& p )
{ {
if ( isOutOfBox( p )) return true; if ( isOutOfBox( p )) return true;
myProjEdge.Perform( p ); myProjEdge.Perform( p );
return ! ( myProjEdge.NbPoints() > 0 && myProjEdge.LowerDistance() <= myTol ); return ! ( myProjEdge.NbPoints() > 0 && myProjEdge.LowerDistance() <= myTol );
} }
bool ElementsOnShape::Classifier::isOutOfVertex(const gp_Pnt& p) bool ElementsOnShape::Classifier::isOutOfVertex( const gp_Pnt& p )
{ {
return ( myVertexXYZ.Distance( p ) > myTol ); return ( myVertexXYZ.Distance( p ) > myTol );
} }
bool ElementsOnShape::Classifier::isBox (const TopoDS_Shape& theShape) bool ElementsOnShape::Classifier::isBox(const TopoDS_Shape& theShape )
{ {
TopTools_IndexedMapOfShape vMap; TopTools_IndexedMapOfShape vMap;
TopExp::MapShapes( theShape, TopAbs_VERTEX, vMap ); TopExp::MapShapes( theShape, TopAbs_VERTEX, vMap );
@ -4766,6 +4795,19 @@ OctreeClassifier::GetClassifiersAtPoint( const gp_XYZ& point,
} }
} }
size_t ElementsOnShape::OctreeClassifier::GetSize()
{
size_t res = sizeof( *this );
if ( !myClassifiers.empty() )
res += sizeof( myClassifiers[0] ) * myClassifiers.size();
if ( !isLeaf() )
for (int i = 0; i < nbChildren(); i++)
res += ((OctreeClassifier*) myChildren[i])->GetSize();
return res;
}
void ElementsOnShape::OctreeClassifier::buildChildrenData() void ElementsOnShape::OctreeClassifier::buildChildrenData()
{ {
// distribute myClassifiers among myChildren // distribute myClassifiers among myChildren
@ -4840,8 +4882,13 @@ BelongToGeom::BelongToGeom()
Predicate* BelongToGeom::clone() const Predicate* BelongToGeom::clone() const
{ {
BelongToGeom* cln = new BelongToGeom( *this ); BelongToGeom* cln = 0;
cln->myElementsOnShapePtr.reset( static_cast<ElementsOnShape*>( myElementsOnShapePtr->clone() )); if ( myElementsOnShapePtr )
if ( ElementsOnShape* eos = static_cast<ElementsOnShape*>( myElementsOnShapePtr->clone() ))
{
cln = new BelongToGeom( *this );
cln->myElementsOnShapePtr.reset( eos );
}
return cln; return cln;
} }
@ -5011,8 +5058,13 @@ LyingOnGeom::LyingOnGeom()
Predicate* LyingOnGeom::clone() const Predicate* LyingOnGeom::clone() const
{ {
LyingOnGeom* cln = new LyingOnGeom( *this ); LyingOnGeom* cln = 0;
cln->myElementsOnShapePtr.reset( static_cast<ElementsOnShape*>( myElementsOnShapePtr->clone() )); if ( myElementsOnShapePtr )
if ( ElementsOnShape* eos = static_cast<ElementsOnShape*>( myElementsOnShapePtr->clone() ))
{
cln = new LyingOnGeom( *this );
cln->myElementsOnShapePtr.reset( eos );
}
return cln; return cln;
} }

View File

@ -92,18 +92,18 @@ namespace MED
{ {
#ifdef WIN32 #ifdef WIN32
#ifdef UNICODE #ifdef UNICODE
int size_needed = MultiByteToWideChar(CP_UTF8, 0, fileName.c_str(), strlen(fileName.c_str()), NULL, 0); int size_needed = MultiByteToWideChar(CP_UTF8, 0, fileName.c_str(), strlen(fileName.c_str()), NULL, 0);
wchar_t* path = new wchar_t[size_needed + 1]; wchar_t* path = new wchar_t[size_needed + 1];
MultiByteToWideChar(CP_UTF8, 0, fileName.c_str(), strlen(fileName.c_str()), path, size_needed); MultiByteToWideChar(CP_UTF8, 0, fileName.c_str(), strlen(fileName.c_str()), path, size_needed);
path[size_needed] = '\0'; path[size_needed] = '\0';
#else #else
cosnt char* path = xmlPath.c_str(); cosnt char* path = xmlPath.c_str();
#endif #endif
bool res = (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES); bool res = (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES);
#ifdef UNICODE #ifdef UNICODE
delete path; delete path;
#endif #endif
return res; return res;
#else #else
return (access(fileName.c_str(), F_OK) == 0); return (access(fileName.c_str(), F_OK) == 0);
#endif #endif
@ -148,7 +148,7 @@ namespace MED
ok = true; ok = true;
else { else {
int medVersion = 10*major + minor; int medVersion = 10*major + minor;
for (int ii=0; ii < sizeof(medVersionsOK)/sizeof(int); ii++) for (size_t ii=0; ii < sizeof(medVersionsOK)/sizeof(int); ii++)
if (medVersionsOK[ii] == medVersion) { if (medVersionsOK[ii] == medVersion) {
ok =true; ok =true;
break; break;
@ -205,39 +205,39 @@ namespace MED
{ {
bool isCreated = false; bool isCreated = false;
if (!CheckCompatibility(fileName, true)) if (!CheckCompatibility(fileName, true))
{ {
remove(fileName.c_str()); remove(fileName.c_str());
isCreated = true; isCreated = true;
} }
int minor = -1; int minor = -1;
if (isCreated) if (isCreated)
{
med_int wantedMajor = MED_MAJOR_NUM;
med_int wantedMinor = MED_MINOR_NUM;
if (theVersion > 0)
{ {
med_int wantedMajor = MED_MAJOR_NUM; wantedMajor = theVersion/10;
med_int wantedMinor = MED_MINOR_NUM; wantedMinor = theVersion%10;
if (theVersion > 0)
{
wantedMajor = theVersion/10;
wantedMinor = theVersion%10;
}
if (wantedMajor == MED_MAJOR_NUM) // the med file will be actually created
{
if (wantedMinor < MED_MINOR_NUM)
minor = wantedMinor;
}
else // an empty existing med file of the right version will be used for append
{
int medVersionsOK[] = MED_VERSIONS_APPEND_COMPATIBLE;
bool isVersionOK = false;
for (int ii=0; ii < sizeof(medVersionsOK)/sizeof(int); ii++)
if (medVersionsOK[ii] == theVersion)
{
isVersionOK =true;
break;
}
if (isVersionOK) // copy an empty existing med file of the right version, for append
CreateEmptyMEDFile(fileName, theVersion);
}
} }
if (wantedMajor == MED_MAJOR_NUM) // the med file will be actually created
{
if (wantedMinor < MED_MINOR_NUM)
minor = wantedMinor;
}
else // an empty existing med file of the right version will be used for append
{
int medVersionsOK[] = MED_VERSIONS_APPEND_COMPATIBLE;
bool isVersionOK = false;
for (size_t ii=0; ii < sizeof(medVersionsOK)/sizeof(int); ii++)
if (medVersionsOK[ii] == theVersion)
{
isVersionOK =true;
break;
}
if (isVersionOK) // copy an empty existing med file of the right version, for append
CreateEmptyMEDFile(fileName, theVersion);
}
}
return new MED::TWrapper(fileName, minor); return new MED::TWrapper(fileName, minor);
} }
} }

View File

@ -188,8 +188,8 @@ namespace MED
//--------------------------------------------------------------- //---------------------------------------------------------------
TWrapper TWrapper
::TWrapper(const std::string& theFileName, TInt theMinor): ::TWrapper(const std::string& theFileName, TInt theMinor):
myMinor(theMinor), myFile(new TFile(theFileName, theMinor)),
myFile(new TFile(theFileName, theMinor)) myMinor(theMinor)
{ {
TErr aRet; TErr aRet;
myFile->Open(eLECTURE_ECRITURE, &aRet); myFile->Open(eLECTURE_ECRITURE, &aRet);

View File

@ -82,10 +82,10 @@ bool SMESH_File::open()
{ {
#ifdef WIN32 #ifdef WIN32
#ifdef UNICODE #ifdef UNICODE
std::wstring aName = Kernel_Utils::utf8_decode_s(_name); std::wstring aName = Kernel_Utils::utf8_decode_s(_name);
const wchar_t* name = aName.c_str(); const wchar_t* name = aName.c_str();
#else #else
char* name = name.data(); char* name = _name.data();
#endif #endif
_file = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, _file = CreateFile(name, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
@ -321,12 +321,12 @@ bool SMESH_File::openForWriting()
{ {
#ifdef WIN32 #ifdef WIN32
#ifdef UNICODE #ifdef UNICODE
std::wstring aName = Kernel_Utils::utf8_decode_s(_name); std::wstring aName = Kernel_Utils::utf8_decode_s(_name);
const wchar_t* name = aName.c_str(); const wchar_t* name = aName.c_str();
#else #else
char* name = name.data(); char* name = _name.data();
#endif #endif
_file = CreateFile( name, // name of the write _file = CreateFile( name, // name of the write
GENERIC_WRITE, // open for writing GENERIC_WRITE, // open for writing
0, // do not share 0, // do not share
NULL, // default security NULL, // default security