mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-27 09:50:34 +05:00
0020918: EDF 1447 SMESH: Mesh common borders
This commit is contained in:
parent
c613a3b5c2
commit
e1655668ae
@ -72,7 +72,10 @@ salomeinclude_HEADERS = \
|
||||
StdMeshers_MaxLength.hxx \
|
||||
StdMeshers_QuadrangleParams.hxx \
|
||||
StdMeshers_RadialQuadrangle_1D2D.hxx \
|
||||
StdMeshers_HexaFromSkin_3D.hxx
|
||||
StdMeshers_HexaFromSkin_3D.hxx \
|
||||
StdMeshers_ImportSource.hxx \
|
||||
StdMeshers_Import_1D.hxx \
|
||||
StdMeshers_Import_1D2D.hxx
|
||||
|
||||
# Libraries targets
|
||||
|
||||
@ -123,7 +126,10 @@ dist_libStdMeshers_la_SOURCES = \
|
||||
StdMeshers_MaxLength.cxx \
|
||||
StdMeshers_QuadrangleParams.cxx \
|
||||
StdMeshers_RadialQuadrangle_1D2D.cxx \
|
||||
StdMeshers_HexaFromSkin_3D.cxx
|
||||
StdMeshers_HexaFromSkin_3D.cxx \
|
||||
StdMeshers_ImportSource.cxx \
|
||||
StdMeshers_Import_1D.cxx \
|
||||
StdMeshers_Import_1D2D.cxx
|
||||
|
||||
|
||||
# additionnal information to compil and link file
|
||||
|
443
src/StdMeshers/StdMeshers_ImportSource.cxx
Normal file
443
src/StdMeshers/StdMeshers_ImportSource.cxx
Normal file
@ -0,0 +1,443 @@
|
||||
// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||
//
|
||||
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
// SMESH StdMeshers_ImportSource1D : implementaion of SMESH idl descriptions
|
||||
// File : StdMeshers_ImportSource1D.cxx
|
||||
// Module : SMESH
|
||||
//
|
||||
#include "StdMeshers_ImportSource.hxx"
|
||||
|
||||
#include "SMESHDS_GroupBase.hxx"
|
||||
#include "SMESHDS_Mesh.hxx"
|
||||
#include "SMESH_Algo.hxx"
|
||||
#include "SMESH_Gen.hxx"
|
||||
#include "SMESH_Group.hxx"
|
||||
#include "SMESH_Mesh.hxx"
|
||||
#include "SMESH_subMeshEventListener.hxx"
|
||||
|
||||
#include "utilities.h"
|
||||
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Creates StdMeshers_ImportSource1D
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
StdMeshers_ImportSource1D::StdMeshers_ImportSource1D(int hypId,
|
||||
int studyId,
|
||||
SMESH_Gen * gen)
|
||||
:SMESH_Hypothesis(hypId, studyId, gen),
|
||||
_toCopyMesh(false),
|
||||
_toCopyGroups(false)
|
||||
{
|
||||
_name = "ImportSource1D";
|
||||
_param_algo_dim = 1; // is used by StdMeshers_Import_1D;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Creates StdMeshers_ImportSource2D
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
StdMeshers_ImportSource2D::StdMeshers_ImportSource2D(int hypId,
|
||||
int studyId,
|
||||
SMESH_Gen * gen)
|
||||
:StdMeshers_ImportSource1D(hypId, studyId, gen)
|
||||
{
|
||||
_name = "ImportSource2D";
|
||||
_param_algo_dim = 2; // is used by StdMeshers_Import_2D;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
*
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
StdMeshers_ImportSource1D::~StdMeshers_ImportSource1D()
|
||||
{
|
||||
}
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Sets groups to import elements from
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
void StdMeshers_ImportSource1D::SetGroups(const std::vector<SMESH_Group*>& groups)
|
||||
{
|
||||
if (_groups != groups)
|
||||
{
|
||||
_groups = groups;
|
||||
NotifySubMeshesHypothesisModification();
|
||||
}
|
||||
}
|
||||
|
||||
void StdMeshers_ImportSource1D::SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups)
|
||||
{
|
||||
if ( !toCopyMesh ) toCopyGroups = false;
|
||||
if ( _toCopyMesh != toCopyMesh || _toCopyGroups != toCopyGroups )
|
||||
{
|
||||
_toCopyMesh = toCopyMesh; _toCopyGroups = toCopyGroups;
|
||||
NotifySubMeshesHypothesisModification();
|
||||
}
|
||||
}
|
||||
void StdMeshers_ImportSource1D::GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const
|
||||
{
|
||||
toCopyMesh = _toCopyMesh; toCopyGroups = _toCopyGroups;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return only alive groups
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
vector<SMESH_Group*> getValidGroups(const vector<SMESH_Group*>& groups,
|
||||
StudyContextStruct* studyContext)
|
||||
{
|
||||
vector<SMESH_Group*> okGroups;
|
||||
for ( int i = 0; i < groups.size(); ++i )
|
||||
{
|
||||
try
|
||||
{
|
||||
// we expect SIGSEGV on a dead group
|
||||
OCC_CATCH_SIGNALS;
|
||||
SMESH_Group* okGroup = 0;
|
||||
map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
|
||||
for ( ; !okGroup && itm != studyContext->mapMesh.end(); itm++)
|
||||
{
|
||||
SMESH_Mesh::GroupIteratorPtr gIt = itm->second->GetGroups();
|
||||
while ( gIt->more() && !okGroup )
|
||||
if ( gIt->next() == groups[i] )
|
||||
okGroup = groups[i];
|
||||
}
|
||||
if ( okGroup )
|
||||
okGroups.push_back( okGroup );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
}
|
||||
return okGroups;
|
||||
}
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Pack meshes into a pair of ints
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
pair<int, int> getResMapKey(const SMESHDS_Mesh& srcMesh, const SMESHDS_Mesh& tgtMesh)
|
||||
{
|
||||
return make_pair( srcMesh.GetPersistentId() , tgtMesh.GetPersistentId() );
|
||||
}
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return a target mesh by a pair of ints
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
SMESH_Mesh* getTgtMeshByKey( const pair<int, int> & resMapKey,
|
||||
StudyContextStruct* studyContext)
|
||||
{
|
||||
int tgtID = resMapKey.second;
|
||||
SMESH_Mesh* tgtMesh = 0;
|
||||
map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
|
||||
for ( ; !tgtMesh && itm != studyContext->mapMesh.end(); itm++)
|
||||
{
|
||||
tgtMesh = (*itm).second;
|
||||
if ( tgtMesh->GetMeshDS()->GetPersistentId() != tgtID )
|
||||
tgtMesh = 0;
|
||||
}
|
||||
return tgtMesh;
|
||||
}
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return a target mesh by a pair of ints
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
int getSrcMeshID( const pair<int, int> & resMapKey )
|
||||
{
|
||||
return resMapKey.first;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Returns groups to import elements from
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
const std::vector<SMESH_Group*>& StdMeshers_ImportSource1D::GetGroups() const
|
||||
{
|
||||
// filter off deleted groups
|
||||
vector<SMESH_Group*> okGroups = getValidGroups( _groups,
|
||||
_gen->GetStudyContext(_studyId) );
|
||||
if ( okGroups.size() != _groups.size() )
|
||||
((StdMeshers_ImportSource1D*)this)->_groups = okGroups;
|
||||
|
||||
return _groups;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return source meshes
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
std::vector<SMESH_Mesh*> StdMeshers_ImportSource1D::GetSourceMeshes() const
|
||||
{
|
||||
// GetPersistentId()'s of meshes
|
||||
set<int> meshIDs;
|
||||
const vector<SMESH_Group*>& groups = GetGroups();
|
||||
if ( !groups.empty() )
|
||||
{
|
||||
for ( unsigned i = 0; i < groups.size(); ++i )
|
||||
{
|
||||
const SMESHDS_GroupBase* gDS = groups[i]->GetGroupDS();
|
||||
int id = gDS->GetMesh()->GetPersistentId();
|
||||
meshIDs.insert( id );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( _resultGroups.empty() )
|
||||
((StdMeshers_ImportSource1D*)this)->RestoreGroups(_groups);
|
||||
TResGroupMap::const_iterator key_groups = _resultGroups.begin();
|
||||
for ( ; key_groups != _resultGroups.end(); ++key_groups )
|
||||
meshIDs.insert( getSrcMeshID( key_groups->first ));
|
||||
}
|
||||
|
||||
// Find corresponding meshes
|
||||
vector<SMESH_Mesh*> meshes;
|
||||
if ( !meshIDs.empty() )
|
||||
{
|
||||
StudyContextStruct* studyContext = _gen->GetStudyContext(_studyId);
|
||||
for ( set<int>::iterator id = meshIDs.begin(); id != meshIDs.end(); ++id )
|
||||
{
|
||||
map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
|
||||
for ( ; itm != studyContext->mapMesh.end(); itm++)
|
||||
{
|
||||
SMESH_Mesh* mesh = (*itm).second;
|
||||
if ( mesh->GetMeshDS()->GetPersistentId() == *id )
|
||||
{
|
||||
meshes.push_back( mesh );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return meshes;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Save _toCopyMesh and _toCopyGroups to a stream
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
ostream & StdMeshers_ImportSource1D::SaveTo(ostream & save)
|
||||
{
|
||||
resultGroupsToIntVec();
|
||||
|
||||
save << " " << _toCopyMesh << " " << _toCopyGroups;
|
||||
save << " " << _resultGroupsStorage.size();
|
||||
for ( unsigned i = 0; i < _resultGroupsStorage.size(); ++i )
|
||||
save << " " << _resultGroupsStorage[i];
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Load _toCopyMesh and _toCopyGroups from a stream
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
istream & StdMeshers_ImportSource1D::LoadFrom(istream & load)
|
||||
{
|
||||
load >> _toCopyMesh >> _toCopyGroups;
|
||||
|
||||
_resultGroupsStorage.clear();
|
||||
int val;
|
||||
if ( load >> val )
|
||||
{
|
||||
_resultGroupsStorage.reserve(val);
|
||||
while ( _resultGroupsStorage.size() < _resultGroupsStorage.capacity() && load >> val )
|
||||
_resultGroupsStorage.push_back( val );
|
||||
}
|
||||
return load;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Convert result groups into _resultGroupsStorage
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void StdMeshers_ImportSource1D::resultGroupsToIntVec()
|
||||
{
|
||||
_resultGroupsStorage.clear();
|
||||
|
||||
// store result groups
|
||||
TResGroupMap::iterator key2groups = _resultGroups.begin();
|
||||
for ( ; key2groups != _resultGroups.end(); ++key2groups )
|
||||
{
|
||||
const pair<int, int>& key = key2groups->first;
|
||||
const vector<SMESH_Group*>& groups = key2groups->second;
|
||||
// mesh ids, nb groups
|
||||
_resultGroupsStorage.push_back( key.first );
|
||||
_resultGroupsStorage.push_back( key.second );
|
||||
_resultGroupsStorage.push_back( groups.size() );
|
||||
for ( unsigned i = 0; i < groups.size(); ++i )
|
||||
{
|
||||
// store group names as sequence of ints each standing for a char
|
||||
// of a name; that is to avoid pb with names containing white spaces
|
||||
string name = groups[i]->GetGroupDS()->GetStoreName();
|
||||
_resultGroupsStorage.push_back( name.size() );
|
||||
for ( unsigned j = 0; j < name.size(); ++j )
|
||||
_resultGroupsStorage.push_back( name[j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Restore source groups and result groups by _resultGroupsStorage
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void StdMeshers_ImportSource1D::RestoreGroups(const std::vector<SMESH_Group*>& groups)
|
||||
{
|
||||
_groups = groups;
|
||||
|
||||
_resultGroups.clear();
|
||||
int i = 0;
|
||||
while ( i < _resultGroupsStorage.size() )
|
||||
{
|
||||
int key1 = _resultGroupsStorage[i++];
|
||||
int key2 = _resultGroupsStorage[i++];
|
||||
pair<int, int> resMapKey( key1, key2 );
|
||||
SMESH_Mesh* mesh = getTgtMeshByKey( resMapKey, _gen->GetStudyContext(_studyId));
|
||||
// restore mesh ids at least
|
||||
_resultGroups.insert( make_pair (resMapKey,vector<SMESH_Group*>() ));
|
||||
|
||||
int nbGroups = _resultGroupsStorage[i++];
|
||||
for ( int j = 0; j < nbGroups; ++j )
|
||||
{
|
||||
string::size_type nameSize = _resultGroupsStorage[i++];
|
||||
string groupName(nameSize, '\0');
|
||||
for ( unsigned k = 0; k < nameSize; ++k )
|
||||
groupName[k] = (char) _resultGroupsStorage[i++];
|
||||
|
||||
// find a group by name
|
||||
if ( mesh )
|
||||
{
|
||||
SMESH_Group* group = 0;
|
||||
SMESH_Mesh::GroupIteratorPtr gIt = mesh->GetGroups();
|
||||
while ( !group && gIt->more() )
|
||||
{
|
||||
group = gIt->next();
|
||||
if ( !group->GetGroupDS() || groupName != group->GetGroupDS()->GetStoreName() )
|
||||
group = 0;
|
||||
}
|
||||
if ( group )
|
||||
_resultGroups[ resMapKey ].push_back( group );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Remember groups imported from other mesh
|
||||
* \param groups - result groups
|
||||
* \param srcMesh - source mesh
|
||||
* \param tgtMesh - destination mesh
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void StdMeshers_ImportSource1D::StoreResultGroups(const std::vector<SMESH_Group*>& groups,
|
||||
const SMESHDS_Mesh& srcMesh,
|
||||
const SMESHDS_Mesh& tgtMesh)
|
||||
{
|
||||
_resultGroups[ getResMapKey(srcMesh,tgtMesh) ] = groups;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return groups imported from other mesh
|
||||
* \param srcMesh - source mesh
|
||||
* \param tgtMesh - destination mesh
|
||||
* \retval const std::vector<SMESH_Group*>& - groups
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
std::vector<SMESH_Group*>*
|
||||
StdMeshers_ImportSource1D::GetResultGroups(const SMESHDS_Mesh& srcMesh,
|
||||
const SMESHDS_Mesh& tgtMesh)
|
||||
{
|
||||
TResGroupMap::iterator key2groups = _resultGroups.find( getResMapKey(srcMesh,tgtMesh ));
|
||||
if ( key2groups == _resultGroups.end() )
|
||||
return 0;
|
||||
vector<SMESH_Group*> vec = getValidGroups((*key2groups).second,
|
||||
_gen->GetStudyContext(_studyId) );
|
||||
if ( vec.size() != key2groups->second.size())
|
||||
key2groups->second = vec;
|
||||
|
||||
return & key2groups->second;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Initialize ImportSource value by the mesh built on the geometry
|
||||
* \param theMesh - the built mesh
|
||||
* \param theShape - the geometry of interest
|
||||
* \retval bool - true if parameter values have been successfully defined
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool StdMeshers_ImportSource1D::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Initialize my parameter values by default parameters.
|
||||
* \retval bool - true if parameter values have been successfully defined
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool StdMeshers_ImportSource1D::SetParametersByDefaults(const TDefaults&, const SMESH_Mesh* )
|
||||
{
|
||||
return false;
|
||||
}
|
97
src/StdMeshers/StdMeshers_ImportSource.hxx
Normal file
97
src/StdMeshers/StdMeshers_ImportSource.hxx
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||
//
|
||||
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
// SMESH StdMeshers : implementaion of SMESH idl descriptions
|
||||
// File : StdMeshers_ImportSource1D.hxx
|
||||
// Module : SMESH
|
||||
//
|
||||
#ifndef _StdMeshers_ImportSource_HXX_
|
||||
#define _StdMeshers_ImportSource_HXX_
|
||||
|
||||
#include "SMESH_StdMeshers.hxx"
|
||||
|
||||
#include "SMESH_Hypothesis.hxx"
|
||||
#include "Utils_SALOME_Exception.hxx"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class SMESH_Group;
|
||||
class SMESHDS_Mesh;
|
||||
|
||||
//==============================================================================
|
||||
/*!
|
||||
* \brief Stores groups to import elements from
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
class STDMESHERS_EXPORT StdMeshers_ImportSource1D : public SMESH_Hypothesis
|
||||
{
|
||||
public:
|
||||
StdMeshers_ImportSource1D(int hypId, int studyId, SMESH_Gen * gen);
|
||||
virtual ~ StdMeshers_ImportSource1D();
|
||||
|
||||
void SetGroups(const std::vector<SMESH_Group*>& groups);
|
||||
const std::vector<SMESH_Group*>& GetGroups() const;
|
||||
|
||||
void SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups);
|
||||
void GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const;
|
||||
|
||||
virtual std::ostream & SaveTo(std::ostream & save);
|
||||
virtual std::istream & LoadFrom(std::istream & load);
|
||||
virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
|
||||
virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
|
||||
void RestoreGroups(const std::vector<SMESH_Group*>& groups);
|
||||
|
||||
void StoreResultGroups(const std::vector<SMESH_Group*>& groups,
|
||||
const SMESHDS_Mesh& srcMesh,
|
||||
const SMESHDS_Mesh& tgtMesh);
|
||||
std::vector<SMESH_Group*>* GetResultGroups(const SMESHDS_Mesh& srcMesh,
|
||||
const SMESHDS_Mesh& tgtMesh);
|
||||
|
||||
std::vector<SMESH_Mesh*> GetSourceMeshes() const;
|
||||
|
||||
private:
|
||||
|
||||
std::vector<SMESH_Group*> _groups;
|
||||
bool _toCopyMesh, _toCopyGroups;
|
||||
|
||||
// groups imported using this hypothesis
|
||||
typedef std::map< std::pair<int, int>, std::vector<SMESH_Group*> > TResGroupMap;
|
||||
TResGroupMap _resultGroups;
|
||||
std::vector<int> _resultGroupsStorage; // persistent representation of _resultGroups
|
||||
|
||||
void resultGroupsToIntVec();
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/*!
|
||||
* \brief Redefines name and dimension of inherited StdMeshers_ImportSource1D
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
class STDMESHERS_EXPORT StdMeshers_ImportSource2D : public StdMeshers_ImportSource1D
|
||||
{
|
||||
public:
|
||||
StdMeshers_ImportSource2D(int hypId, int studyId, SMESH_Gen * gen);
|
||||
};
|
||||
#endif
|
951
src/StdMeshers/StdMeshers_Import_1D.cxx
Normal file
951
src/StdMeshers/StdMeshers_Import_1D.cxx
Normal file
@ -0,0 +1,951 @@
|
||||
// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||
//
|
||||
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
// SMESH SMESH : implementaion of SMESH idl descriptions
|
||||
// File : StdMeshers_Import_1D.cxx
|
||||
// Module : SMESH
|
||||
//
|
||||
#include "StdMeshers_Import_1D.hxx"
|
||||
#include "StdMeshers_ImportSource.hxx"
|
||||
|
||||
#include "SMDS_MeshElement.hxx"
|
||||
#include "SMDS_MeshNode.hxx"
|
||||
#include "SMESHDS_Group.hxx"
|
||||
#include "SMESHDS_Mesh.hxx"
|
||||
#include "SMESH_Comment.hxx"
|
||||
#include "SMESH_Gen.hxx"
|
||||
#include "SMESH_Group.hxx"
|
||||
#include "SMESH_HypoFilter.hxx"
|
||||
#include "SMESH_Mesh.hxx"
|
||||
#include "SMESH_MesherHelper.hxx"
|
||||
#include "SMESH_subMesh.hxx"
|
||||
#include "SMESH_subMeshEventListener.hxx"
|
||||
|
||||
#include "Utils_SALOME_Exception.hxx"
|
||||
#include "utilities.h"
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Creates StdMeshers_Import_1D
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
StdMeshers_Import_1D::StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen * gen)
|
||||
:SMESH_1D_Algo(hypId, studyId, gen), _sourceHyp(0)
|
||||
{
|
||||
MESSAGE("StdMeshers_Import_1D::StdMeshers_Import_1D");
|
||||
_name = "Import_1D";
|
||||
_shapeType = (1 << TopAbs_EDGE);
|
||||
|
||||
_compatibleHypothesis.push_back("ImportSource1D");
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Check presence of a hypothesis
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
bool StdMeshers_Import_1D::CheckHypothesis
|
||||
(SMESH_Mesh& aMesh,
|
||||
const TopoDS_Shape& aShape,
|
||||
SMESH_Hypothesis::Hypothesis_Status& aStatus)
|
||||
{
|
||||
_sourceHyp = 0;
|
||||
|
||||
const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
|
||||
if ( hyps.size() == 0 )
|
||||
{
|
||||
aStatus = SMESH_Hypothesis::HYP_MISSING;
|
||||
return false; // can't work with no hypothesis
|
||||
}
|
||||
|
||||
if ( hyps.size() > 1 )
|
||||
{
|
||||
aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
|
||||
return false;
|
||||
}
|
||||
|
||||
const SMESHDS_Hypothesis *theHyp = hyps.front();
|
||||
|
||||
string hypName = theHyp->GetName();
|
||||
|
||||
if (hypName == _compatibleHypothesis.front())
|
||||
{
|
||||
_sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
|
||||
aStatus = SMESH_Hypothesis::HYP_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
namespace // INTERNAL STUFF
|
||||
//================================================================================
|
||||
{
|
||||
int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS, SMESH_Mesh* tgtMesh);
|
||||
|
||||
enum _ListenerDataType
|
||||
{
|
||||
WAIT_HYP_MODIF=1, // data indicating awaiting for valid parameters of src hyp
|
||||
SRC_HYP // data storing ImportSource hyp
|
||||
};
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief _ListenerData holding ImportSource hyp holding in its turn
|
||||
* imported groups
|
||||
*/
|
||||
struct _ListenerData : public SMESH_subMeshEventListenerData
|
||||
{
|
||||
const StdMeshers_ImportSource1D* _srcHyp;
|
||||
_ListenerData(const StdMeshers_ImportSource1D* h):
|
||||
SMESH_subMeshEventListenerData(/*isDeletable=*/true), _srcHyp(h)
|
||||
{
|
||||
myType = SRC_HYP;
|
||||
}
|
||||
};
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Container of data dedicated to one source mesh
|
||||
*/
|
||||
struct _ImportData
|
||||
{
|
||||
const SMESH_Mesh* _srcMesh;
|
||||
StdMeshers_Import_1D::TNodeNodeMap _n2n;
|
||||
StdMeshers_Import_1D::TElemElemMap _e2e;
|
||||
|
||||
set< SMESH_subMesh*> _subM; // submeshes relating to this srcMesh
|
||||
set< SMESH_subMesh*> _copyMeshSubM; // submeshes requesting mesh copying
|
||||
set< SMESH_subMesh*> _copyGroupSubM; // submeshes requesting mesh copying
|
||||
set< SMESH_subMesh*> _computedSubM;
|
||||
|
||||
SMESHDS_SubMesh* _importMeshSubDS; // submesh storing a copy of _srcMesh
|
||||
int _importMeshSubID; // id of _importMeshSubDS
|
||||
|
||||
_ImportData(const SMESH_Mesh* srcMesh=0):
|
||||
_srcMesh(srcMesh), _importMeshSubDS(0),_importMeshSubID(-1) {}
|
||||
|
||||
void removeImportedMesh( SMESHDS_Mesh* meshDS )
|
||||
{
|
||||
if ( !_importMeshSubDS ) return;
|
||||
SMDS_ElemIteratorPtr eIt = _importMeshSubDS->GetElements();
|
||||
while ( eIt->more() )
|
||||
meshDS->RemoveFreeElement( eIt->next(), _importMeshSubDS, /*fromGroups=*/false );
|
||||
SMDS_NodeIteratorPtr nIt = _importMeshSubDS->GetNodes();
|
||||
while ( nIt->more() )
|
||||
meshDS->RemoveFreeNode( nIt->next(), _importMeshSubDS, /*fromGroups=*/false );
|
||||
_n2n.clear();
|
||||
_e2e.clear();
|
||||
}
|
||||
void removeGroups( SMESH_subMesh* subM, const StdMeshers_ImportSource1D* srcHyp )
|
||||
{
|
||||
if ( !srcHyp ) return;
|
||||
SMESH_Mesh* tgtMesh = subM->GetFather();
|
||||
const SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
|
||||
const SMESHDS_Mesh* srcMeshDS = _srcMesh->GetMeshDS();
|
||||
vector<SMESH_Group*>* groups =
|
||||
const_cast<StdMeshers_ImportSource1D*>(srcHyp)->GetResultGroups(*srcMeshDS,*tgtMeshDS);
|
||||
if ( groups )
|
||||
{
|
||||
for ( unsigned i = 0; i < groups->size(); ++i )
|
||||
tgtMesh->RemoveGroup( groups->at(i)->GetGroupDS()->GetID() );
|
||||
groups->clear();
|
||||
}
|
||||
}
|
||||
void trackHypParams( SMESH_subMesh* sm, const StdMeshers_ImportSource1D* srcHyp )
|
||||
{
|
||||
if ( !srcHyp ) return;
|
||||
bool toCopyMesh, toCopyGroups;
|
||||
srcHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
|
||||
|
||||
if ( toCopyMesh )_copyMeshSubM.insert( sm );
|
||||
else _copyMeshSubM.erase( sm );
|
||||
|
||||
if ( toCopyGroups ) _copyGroupSubM.insert( sm );
|
||||
else _copyGroupSubM.erase( sm );
|
||||
}
|
||||
};
|
||||
//================================================================================
|
||||
/*!
|
||||
* Listener notified on events of an imported submesh
|
||||
*/
|
||||
class _Listener : public SMESH_subMeshEventListener
|
||||
{
|
||||
typedef map< SMESH_Mesh*, list< _ImportData > > TMesh2ImpData;
|
||||
TMesh2ImpData _tgtMesh2ImportData;
|
||||
|
||||
_Listener():SMESH_subMeshEventListener(/*isDeletable=*/false){}
|
||||
|
||||
public:
|
||||
// return poiter to a static listener
|
||||
static _Listener* get() { static _Listener theListener; return &theListener; }
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief Find or create ImportData for given meshes
|
||||
*/
|
||||
static _ImportData* getImportData(const SMESH_Mesh* srcMesh,
|
||||
SMESH_Mesh* tgtMesh)
|
||||
{
|
||||
list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh];
|
||||
list< _ImportData >::iterator d = dList.begin();
|
||||
for ( ; d != dList.end(); ++d )
|
||||
if ( d->_srcMesh == srcMesh )
|
||||
return &*d;
|
||||
dList.push_back(_ImportData(srcMesh));
|
||||
return &dList.back();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief Remember an imported mesh and groups
|
||||
* \param smDS - submesh DS holding the imported mesh
|
||||
* \param sm - submesh computed by Import algo
|
||||
* \param srcMeshDS - source mesh
|
||||
* \param srcHyp - ImportSource hypothesis
|
||||
*/
|
||||
static _ImportData* storeImportSubmesh(SMESH_subMesh* importSub,
|
||||
const SMESH_Mesh* srcMesh,
|
||||
const StdMeshers_ImportSource1D* srcHyp)
|
||||
{
|
||||
// set listener to hear events of the submesh computed by "Import" algo
|
||||
importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub );
|
||||
|
||||
// set a listener to hear events of the source mesh
|
||||
SMESH_subMesh* smToNotify = importSub;
|
||||
SMESH_subMesh* smToListen = srcMesh->GetSubMeshContaining(1);
|
||||
importSub->SetEventListener
|
||||
( new SMESH_subMeshEventListener(/*isDeletable=*/true),
|
||||
SMESH_subMeshEventListenerData::MakeData( smToNotify ),
|
||||
smToListen );
|
||||
|
||||
// remeber the submesh
|
||||
_ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
|
||||
iData->_subM.insert( importSub );
|
||||
iData->trackHypParams( importSub, srcHyp );
|
||||
if ( !importSub->IsEmpty() )
|
||||
iData->_computedSubM.insert( importSub );
|
||||
if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 )
|
||||
{
|
||||
SMESH_Mesh* tgtMesh = importSub->GetFather();
|
||||
iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh);
|
||||
iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID );
|
||||
}
|
||||
if ( !importSub->IsEmpty() )
|
||||
iData->_computedSubM.insert( importSub );
|
||||
|
||||
return iData;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief mark sm as missing src hyp with valid groups
|
||||
*/
|
||||
static void waitHypModification(SMESH_subMesh* sm)
|
||||
{
|
||||
sm->SetEventListener
|
||||
(get(), SMESH_subMeshEventListenerData::MakeData( sm, WAIT_HYP_MODIF ), sm);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief Remove imported mesh and/or groups as soon as no more imported submeshes
|
||||
* remain computed
|
||||
* \param sm - submesh loosing Import algo
|
||||
* \param data - data holding imported groups
|
||||
*/
|
||||
void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
|
||||
{
|
||||
list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
|
||||
list< _ImportData >::iterator d = dList.begin();
|
||||
for ( ; d != dList.end(); ++d )
|
||||
if ( (*d)._subM.erase( sm ))
|
||||
{
|
||||
d->_computedSubM.erase( sm );
|
||||
bool rmMesh = d->_copyMeshSubM.erase( sm ) && d->_copyMeshSubM.empty();
|
||||
bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh;
|
||||
if ( rmMesh )
|
||||
d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
|
||||
if ( rmGroups && data )
|
||||
d->removeGroups( sm, data->_srcHyp );
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief Remove imported mesh and/or groups and
|
||||
* clear all submeshes with common source mesh
|
||||
* \param sm - cleared submesh
|
||||
* \param data - data holding imported groups
|
||||
*/
|
||||
void clearSubmesh( SMESH_subMesh* sm, _ListenerData* data )
|
||||
{
|
||||
list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
|
||||
list< _ImportData >::iterator d = dList.begin();
|
||||
for ( ; d != dList.end(); ++d )
|
||||
{
|
||||
if ( !d->_subM.count( sm )) continue;
|
||||
if ( (*d)._computedSubM.erase( sm ) )
|
||||
{
|
||||
bool copyMesh = !d->_copyMeshSubM.empty();
|
||||
if ( copyMesh )
|
||||
{
|
||||
// clear submeshes
|
||||
if ( !d->_computedSubM.empty() )
|
||||
{
|
||||
set< SMESH_subMesh*> subs;
|
||||
subs.swap( d->_computedSubM ); // avoid recursion via events
|
||||
while ( !subs.empty() )
|
||||
{
|
||||
SMESH_subMesh* subM = *subs.begin(); subs.erase( subs.begin() );
|
||||
_ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
|
||||
if ( hypData )
|
||||
d->removeGroups( sm, hypData->_srcHyp );
|
||||
|
||||
subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
|
||||
}
|
||||
}
|
||||
// remove imported mesh and groups
|
||||
d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
|
||||
|
||||
if ( data )
|
||||
d->removeGroups( sm, data->_srcHyp );
|
||||
}
|
||||
}
|
||||
if ( data )
|
||||
d->trackHypParams( sm, data->_srcHyp );
|
||||
d->_n2n.clear();
|
||||
d->_e2e.clear();
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief Remove imported mesh and/or groups
|
||||
*/
|
||||
virtual void ProcessEvent(const int event,
|
||||
const int eventType,
|
||||
SMESH_subMesh* subMesh,
|
||||
SMESH_subMeshEventListenerData* data,
|
||||
const SMESH_Hypothesis* /*hyp*/)
|
||||
{
|
||||
if ( data && data->myType == WAIT_HYP_MODIF )
|
||||
{
|
||||
if ( SMESH_subMesh::MODIF_HYP == event &&
|
||||
SMESH_subMesh::ALGO_EVENT == eventType )
|
||||
{
|
||||
SMESH_Gen* gen = subMesh->GetFather()->GetGen();
|
||||
if ( SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(), subMesh->GetSubShape()))
|
||||
algo->SetEventListener( subMesh );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK )
|
||||
// treate removal of Import algo from subMesh
|
||||
removeSubmesh( subMesh, (_ListenerData*) data );
|
||||
|
||||
else if ( subMesh->IsEmpty() )
|
||||
// treate modification of ImportSource hypothesis
|
||||
clearSubmesh( subMesh, (_ListenerData*) data );
|
||||
|
||||
else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event &&
|
||||
SMESH_subMesh::COMPUTE_EVENT == eventType )
|
||||
{
|
||||
// check compute state of all submeshes impoting from same src mesh;
|
||||
// this is to take into account 1D computed submeshes hidden by 2D import algo
|
||||
list< _ImportData > & dList = _tgtMesh2ImportData[ subMesh->GetFather() ];
|
||||
list< _ImportData >::iterator d = dList.begin();
|
||||
for ( ; d != dList.end(); ++d )
|
||||
if ( d->_subM.count( subMesh ))
|
||||
{
|
||||
set<SMESH_subMesh*>::iterator smIt = d->_subM.begin();
|
||||
for( ; smIt != d->_subM.end(); ++smIt )
|
||||
if ( (*smIt)->IsMeshComputed() )
|
||||
d->_computedSubM.insert( *smIt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}; // class _Listener
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return an ID of submesh to store nodes and elements of a copied mesh
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS,
|
||||
SMESH_Mesh* tgtMesh)
|
||||
{
|
||||
// To get SMESH_subMesh corresponding to srcMeshDS we need to have a shape
|
||||
// for which SMESHDS_Mesh::IsGroupOfSubShapes() returns true.
|
||||
// And this shape must be different from subshapes of the main shape.
|
||||
// So we create a compound containing
|
||||
// 1) some sub-shapes of SMESH_Mesh::PseudoShape() corresponding to
|
||||
// srcMeshDS->GetPersistentId()
|
||||
// 2) the 1-st vertex of the main shape to assure
|
||||
// SMESHDS_Mesh::IsGroupOfSubShapes(shape)==true
|
||||
TopoDS_Shape shapeForSrcMesh;
|
||||
TopTools_IndexedMapOfShape pseudoSubShapes;
|
||||
TopExp::MapShapes( SMESH_Mesh::PseudoShape(), pseudoSubShapes );
|
||||
|
||||
// index of pseudoSubShapes corresponding to srcMeshDS
|
||||
int subIndex = srcMeshDS->GetPersistentId() % pseudoSubShapes.Extent();
|
||||
int nbSubShapes = 1 + srcMeshDS->GetPersistentId() / pseudoSubShapes.Extent();
|
||||
|
||||
// try to find already present shapeForSrcMesh
|
||||
SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
|
||||
for ( int i = tgtMeshDS->MaxShapeIndex(); i > 0 && shapeForSrcMesh.IsNull(); --i )
|
||||
{
|
||||
const TopoDS_Shape& s = tgtMeshDS->IndexToShape(i);
|
||||
if ( s.ShapeType() != TopAbs_COMPOUND ) break;
|
||||
TopoDS_Iterator sSubIt( s );
|
||||
for ( int iSub = 0; iSub < nbSubShapes && sSubIt.More(); ++iSub, sSubIt.Next() )
|
||||
if ( pseudoSubShapes( subIndex+iSub ).IsSame( sSubIt.Value()))
|
||||
if ( iSub+1 == nbSubShapes )
|
||||
{
|
||||
shapeForSrcMesh = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( shapeForSrcMesh.IsNull() )
|
||||
{
|
||||
// make a new shapeForSrcMesh
|
||||
BRep_Builder aBuilder;
|
||||
TopoDS_Compound comp;
|
||||
aBuilder.MakeCompound( comp );
|
||||
shapeForSrcMesh = comp;
|
||||
for ( int iSub = 0; iSub < nbSubShapes; ++iSub )
|
||||
aBuilder.Add( comp, pseudoSubShapes( subIndex+iSub ));
|
||||
TopExp_Explorer vExp( tgtMeshDS->ShapeToMesh(), TopAbs_VERTEX );
|
||||
aBuilder.Add( comp, vExp.Current() );
|
||||
}
|
||||
SMESH_subMesh* sm = tgtMesh->GetSubMesh( shapeForSrcMesh );
|
||||
SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
|
||||
if ( !smDS )
|
||||
smDS = tgtMeshDS->NewSubMesh( sm->GetId() );
|
||||
|
||||
// make ordinary submesh from a complex one
|
||||
if ( smDS->IsComplexSubmesh() )
|
||||
{
|
||||
list< const SMESHDS_SubMesh* > subSM;
|
||||
SMESHDS_SubMeshIteratorPtr smIt = smDS->GetSubMeshIterator();
|
||||
while ( smIt->more() ) subSM.push_back( smIt->next() );
|
||||
list< const SMESHDS_SubMesh* >::iterator sub = subSM.begin();
|
||||
for ( ; sub != subSM.end(); ++sub)
|
||||
smDS->RemoveSubMesh( *sub );
|
||||
}
|
||||
return sm->GetId();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return a submesh to store nodes and elements of a copied mesh
|
||||
* and set event listeners in order to clear
|
||||
* imported mesh and groups as soon as submesh state requires it
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
SMESHDS_SubMesh* getSubmeshForCopiedMesh(const SMESH_Mesh* srcMesh,
|
||||
SMESH_Mesh* tgtMesh,
|
||||
const TopoDS_Shape& tgtShape,
|
||||
StdMeshers_Import_1D::TNodeNodeMap*& n2n,
|
||||
StdMeshers_Import_1D::TElemElemMap*& e2e,
|
||||
bool & toCopyGroups)
|
||||
{
|
||||
StdMeshers_Import_1D::getMaps( srcMesh, tgtMesh, n2n,e2e );
|
||||
|
||||
_ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
|
||||
|
||||
SMESH_subMesh* importedSM = tgtMesh->GetSubMesh( tgtShape );
|
||||
iData->_computedSubM.insert( importedSM );
|
||||
if ( iData->_computedSubM.size() != iData->_subM.size() )
|
||||
return 0; // not all submeshes computed yet
|
||||
|
||||
toCopyGroups = !iData->_copyGroupSubM.empty();
|
||||
|
||||
if ( !iData->_copyMeshSubM.empty())
|
||||
{
|
||||
// make submesh to store a copied mesh
|
||||
int smID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(), tgtMesh );
|
||||
SMESHDS_SubMesh* subDS = tgtMesh->GetMeshDS()->NewSubMesh( smID );
|
||||
|
||||
iData->_importMeshSubID = smID;
|
||||
iData->_importMeshSubDS = subDS;
|
||||
return subDS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Import elements from the other mesh
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
|
||||
{
|
||||
if ( !_sourceHyp ) return false;
|
||||
|
||||
const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
|
||||
if ( srcGroups.empty() )
|
||||
return error("Invalid source groups");
|
||||
|
||||
SMESH_MesherHelper helper(theMesh);
|
||||
helper.SetSubShape(theShape);
|
||||
SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
|
||||
|
||||
const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape );
|
||||
const double edgeTol = BRep_Tool::Tolerance( geomEdge );
|
||||
const int shapeID = tgtMesh->ShapeToIndex( geomEdge );
|
||||
|
||||
set<int> subShapeIDs;
|
||||
subShapeIDs.insert( shapeID );
|
||||
|
||||
// get nodes on vertices
|
||||
list < SMESH_MeshEditor::TNodeXYZ > vertexNodes;
|
||||
list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt;
|
||||
TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
|
||||
for ( ; vExp.More(); vExp.Next() )
|
||||
{
|
||||
const TopoDS_Vertex& v = TopoDS::Vertex( vExp.Current() );
|
||||
if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second )
|
||||
continue; // closed edge
|
||||
const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
|
||||
if ( !n )
|
||||
{
|
||||
_gen->Compute(theMesh,v,/*anUpward=*/true);
|
||||
n = SMESH_Algo::VertexNode( v, tgtMesh );
|
||||
if ( !n ) return false; // very strange
|
||||
}
|
||||
vertexNodes.push_back( SMESH_MeshEditor::TNodeXYZ( n ));
|
||||
}
|
||||
|
||||
// import edges from groups
|
||||
TNodeNodeMap* n2n;
|
||||
TElemElemMap* e2e;
|
||||
for ( int iG = 0; iG < srcGroups.size(); ++iG )
|
||||
{
|
||||
const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
|
||||
|
||||
const int meshID = srcGroup->GetMesh()->GetPersistentId();
|
||||
const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID );
|
||||
if ( !srcMesh ) continue;
|
||||
getMaps( srcMesh, &theMesh, n2n, e2e );
|
||||
|
||||
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
|
||||
vector<const SMDS_MeshNode*> newNodes;
|
||||
SMDS_MeshNode tmpNode(0,0,0);
|
||||
double u;
|
||||
while ( srcElems->more() ) // loop on group contents
|
||||
{
|
||||
const SMDS_MeshElement* edge = srcElems->next();
|
||||
// find or create nodes of a new edge
|
||||
newNodes.resize( edge->NbNodes() );
|
||||
newNodes.back() = 0;
|
||||
SMDS_MeshElement::iterator node = edge->begin_nodes();
|
||||
for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
|
||||
{
|
||||
TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
|
||||
if ( n2nIt->second )
|
||||
{
|
||||
if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() ))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find an existing vertex node
|
||||
for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
|
||||
if ( vNIt->SquareDistance( *node ) < 10 * edgeTol * edgeTol)
|
||||
{
|
||||
(*n2nIt).second = vNIt->_node;
|
||||
vertexNodes.erase( vNIt );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !n2nIt->second )
|
||||
{
|
||||
// find out if node lies on theShape
|
||||
tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
|
||||
if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true ))
|
||||
{
|
||||
SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
|
||||
n2nIt->second = newNode;
|
||||
tgtMesh->SetNodeOnEdge( newNode, shapeID, u );
|
||||
}
|
||||
}
|
||||
if ( !(newNodes[i] = n2nIt->second ))
|
||||
break;
|
||||
}
|
||||
if ( !newNodes.back() )
|
||||
continue; // not all nodes of edge lie on theShape
|
||||
|
||||
// make a new edge
|
||||
SMDS_MeshElement * newEdge;
|
||||
if ( newNodes.size() == 3 )
|
||||
newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
|
||||
else
|
||||
newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
|
||||
tgtMesh->SetMeshElementOnShape( newEdge, shapeID );
|
||||
e2e->insert( make_pair( edge, newEdge ));
|
||||
}
|
||||
}
|
||||
if ( n2n->empty())
|
||||
return error("Empty source groups");
|
||||
|
||||
// check if the whole geom edge is covered by imported segments;
|
||||
// the check consist in passing by segments from one vetrex node to another
|
||||
bool isEdgeMeshed = false;
|
||||
if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape ))
|
||||
{
|
||||
const TopoDS_Vertex& v = ( vExp.ReInit(), TopoDS::Vertex( vExp.Current() ));
|
||||
const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
|
||||
const SMDS_MeshElement* seg = 0;
|
||||
SMDS_ElemIteratorPtr segIt = n->GetInverseElementIterator(SMDSAbs_Edge);
|
||||
while ( segIt->more() && !seg )
|
||||
if ( !tgtSM->Contains( seg = segIt->next()))
|
||||
seg = 0;
|
||||
int nbPassedSegs = 0;
|
||||
while ( seg )
|
||||
{
|
||||
++nbPassedSegs;
|
||||
const SMDS_MeshNode* n2 = seg->GetNode(0);
|
||||
n = ( n2 == n ? seg->GetNode(1) : n2 );
|
||||
if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
|
||||
break;
|
||||
const SMDS_MeshElement* seg2 = 0;
|
||||
segIt = n->GetInverseElementIterator(SMDSAbs_Edge);
|
||||
while ( segIt->more() && !seg2 )
|
||||
if ( seg == ( seg2 = segIt->next()))
|
||||
seg2 = 0;
|
||||
seg = seg2;
|
||||
}
|
||||
if (nbPassedSegs > 0 && tgtSM->NbElements() > nbPassedSegs )
|
||||
return error( "Source elements overlap one another");
|
||||
|
||||
isEdgeMeshed = ( tgtSM->NbElements() == nbPassedSegs &&
|
||||
n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX );
|
||||
}
|
||||
if ( !isEdgeMeshed )
|
||||
return error( "Source elements don't cover totally the geometrical edge" );
|
||||
|
||||
// copy meshes
|
||||
vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
|
||||
for ( unsigned i = 0; i < srcMeshes.size(); ++i )
|
||||
importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Copy mesh and groups
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh,
|
||||
SMESH_Mesh & tgtMesh,
|
||||
StdMeshers_ImportSource1D* srcHyp,
|
||||
const TopoDS_Shape& tgtShape)
|
||||
{
|
||||
// get submesh to store the imported mesh
|
||||
TNodeNodeMap* n2n;
|
||||
TElemElemMap* e2e;
|
||||
bool toCopyGroups;
|
||||
SMESHDS_SubMesh* tgtSubMesh =
|
||||
getSubmeshForCopiedMesh( srcMesh, &tgtMesh, tgtShape, n2n, e2e, toCopyGroups );
|
||||
if ( !tgtSubMesh || tgtSubMesh->NbNodes() + tgtSubMesh->NbElements() > 0 )
|
||||
return; // not to copy srcMeshDS twice
|
||||
|
||||
SMESHDS_Mesh* tgtMeshDS = tgtMesh.GetMeshDS();
|
||||
SMESH_MeshEditor additor( &tgtMesh );
|
||||
|
||||
// 1. Copy mesh
|
||||
|
||||
vector<const SMDS_MeshNode*> newNodes;
|
||||
const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
|
||||
SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator();
|
||||
while ( eIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement* elem = eIt->next();
|
||||
TElemElemMap::iterator e2eIt = e2e->insert( make_pair( elem, (SMDS_MeshElement*)0 )).first;
|
||||
if ( e2eIt->second ) continue; // already copied by Compute()
|
||||
newNodes.resize( elem->NbNodes() );
|
||||
SMDS_MeshElement::iterator node = elem->begin_nodes();
|
||||
for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
|
||||
{
|
||||
TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
|
||||
if ( !n2nIt->second )
|
||||
{
|
||||
(*n2nIt).second = tgtMeshDS->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
|
||||
tgtSubMesh->AddNode( n2nIt->second );
|
||||
}
|
||||
newNodes[i] = n2nIt->second;
|
||||
}
|
||||
const SMDS_MeshElement* newElem =
|
||||
tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false );
|
||||
if ( !newElem )
|
||||
{
|
||||
newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly());
|
||||
tgtSubMesh->AddElement( newElem );
|
||||
}
|
||||
if ( toCopyGroups )
|
||||
(*e2eIt).second = newElem;
|
||||
}
|
||||
// copy free nodes
|
||||
if ( tgtSubMesh->NbNodes() < srcMeshDS->NbNodes() )
|
||||
{
|
||||
SMDS_NodeIteratorPtr nIt = srcMeshDS->nodesIterator();
|
||||
while( nIt->more() )
|
||||
{
|
||||
const SMDS_MeshNode* node = nIt->next();
|
||||
if ( node->NbInverseElements() == 0 )
|
||||
{
|
||||
const SMDS_MeshNode* newNode = tgtMeshDS->AddNode( node->X(), node->Y(), node->Z());
|
||||
n2n->insert( make_pair( node, newNode ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Copy groups
|
||||
|
||||
vector<SMESH_Group*> resultGroups;
|
||||
if ( toCopyGroups )
|
||||
{
|
||||
// collect names of existing groups to assure uniqueness of group names within a type
|
||||
map< SMDSAbs_ElementType, set<string> > namesByType;
|
||||
SMESH_Mesh::GroupIteratorPtr groupIt = tgtMesh.GetGroups();
|
||||
while ( groupIt->more() )
|
||||
{
|
||||
SMESH_Group* tgtGroup = groupIt->next();
|
||||
namesByType[ tgtGroup->GetGroupDS()->GetType() ].insert( tgtGroup->GetName() );
|
||||
}
|
||||
if (srcMesh)
|
||||
{
|
||||
SMESH_Mesh::GroupIteratorPtr groupIt = srcMesh->GetGroups();
|
||||
while ( groupIt->more() )
|
||||
{
|
||||
SMESH_Group* srcGroup = groupIt->next();
|
||||
SMESHDS_GroupBase* srcGroupDS = srcGroup->GetGroupDS();
|
||||
string name = srcGroup->GetName();
|
||||
int nb = 1;
|
||||
while ( !namesByType[ srcGroupDS->GetType() ].insert( name ).second )
|
||||
name = SMESH_Comment(srcGroup->GetName()) << "_imported_" << nb++;
|
||||
SMESH_Group* newGroup = tgtMesh.AddGroup( srcGroupDS->GetType(), name.c_str(), nb );
|
||||
SMESHDS_Group* newGroupDS = (SMESHDS_Group*)newGroup->GetGroupDS();
|
||||
resultGroups.push_back( newGroup );
|
||||
|
||||
eIt = srcGroupDS->GetElements();
|
||||
if ( srcGroupDS->GetType() == SMDSAbs_Node )
|
||||
while (eIt->more())
|
||||
{
|
||||
TNodeNodeMap::iterator n2nIt = n2n->find((const SMDS_MeshNode*) eIt->next() );
|
||||
if ( n2nIt != n2n->end() && n2nIt->second )
|
||||
newGroupDS->SMDSGroup().Add((*n2nIt).second );
|
||||
}
|
||||
else
|
||||
while (eIt->more())
|
||||
{
|
||||
TElemElemMap::iterator e2eIt = e2e->find( eIt->next() );
|
||||
if ( e2eIt != e2e->end() && e2eIt->second )
|
||||
newGroupDS->SMDSGroup().Add((*e2eIt).second );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n2n->clear();
|
||||
e2e->clear();
|
||||
|
||||
// Remember created groups in order to remove them as soon as the srcHyp is
|
||||
// modified or something other similar happens. Store them in a hypothesis
|
||||
// as it stores its values anyway
|
||||
srcHyp->StoreResultGroups( resultGroups, *srcMeshDS, *tgtMeshDS );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* \brief Set needed event listeners and create a submesh for a copied mesh
|
||||
*
|
||||
* This method is called only if a submesh has HYP_OK algo_state.
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
void StdMeshers_Import_1D::setEventListener(SMESH_subMesh* subMesh,
|
||||
StdMeshers_ImportSource1D* sourceHyp)
|
||||
{
|
||||
if ( sourceHyp )
|
||||
{
|
||||
vector<SMESH_Mesh*> srcMeshes = sourceHyp->GetSourceMeshes();
|
||||
if ( srcMeshes.empty() )
|
||||
_Listener::waitHypModification( subMesh );
|
||||
for ( unsigned i = 0; i < srcMeshes.size(); ++i )
|
||||
// set a listener to remove the imported mesh and groups
|
||||
_Listener::storeImportSubmesh( subMesh, srcMeshes[i], sourceHyp );
|
||||
}
|
||||
}
|
||||
void StdMeshers_Import_1D::SetEventListener(SMESH_subMesh* subMesh)
|
||||
{
|
||||
if ( !_sourceHyp )
|
||||
{
|
||||
const TopoDS_Shape& tgtShape = subMesh->GetSubShape();
|
||||
SMESH_Mesh* tgtMesh = subMesh->GetFather();
|
||||
Hypothesis_Status aStatus;
|
||||
CheckHypothesis( *tgtMesh, tgtShape, aStatus );
|
||||
}
|
||||
setEventListener( subMesh, _sourceHyp );
|
||||
}
|
||||
|
||||
void StdMeshers_Import_1D::SubmeshRestored(SMESH_subMesh* subMesh)
|
||||
{
|
||||
SetEventListener(subMesh);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Predict nb of mesh entities created by Compute()
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh & theMesh,
|
||||
const TopoDS_Shape & theShape,
|
||||
MapShapeNbElems& aResMap)
|
||||
{
|
||||
if ( !_sourceHyp ) return false;
|
||||
|
||||
const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
|
||||
if ( srcGroups.empty() )
|
||||
return error("Invalid source groups");
|
||||
|
||||
vector<int> aVec(SMDSEntity_Last,0);
|
||||
|
||||
bool toCopyMesh, toCopyGroups;
|
||||
_sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
|
||||
if ( toCopyMesh ) // the whole mesh is copied
|
||||
{
|
||||
vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
|
||||
for ( unsigned i = 0; i < srcMeshes.size(); ++i )
|
||||
{
|
||||
SMESH_subMesh* sm = getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]);
|
||||
if ( !sm || aResMap.count( sm )) continue; // already counted
|
||||
aVec.assign( SMDSEntity_Last, 0);
|
||||
const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo();
|
||||
for (int i = 0; i < SMDSEntity_Last; i++)
|
||||
aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SMESH_MesherHelper helper(theMesh);
|
||||
|
||||
const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape );
|
||||
const double edgeTol = helper.MaxTolerance( geomEdge );
|
||||
|
||||
// take into account nodes on vertices
|
||||
TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
|
||||
for ( ; vExp.More(); vExp.Next() )
|
||||
theMesh.GetSubMesh( vExp.Current())->Evaluate( aResMap );
|
||||
|
||||
// count edges imported from groups
|
||||
int nbEdges = 0, nbQuadEdges = 0;
|
||||
for ( int iG = 0; iG < srcGroups.size(); ++iG )
|
||||
{
|
||||
const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
|
||||
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
|
||||
SMDS_MeshNode tmpNode(0,0,0);
|
||||
while ( srcElems->more() ) // loop on group contents
|
||||
{
|
||||
const SMDS_MeshElement* edge = srcElems->next();
|
||||
// find out if edge is located on geomEdge by projecting
|
||||
// a middle of edge to geomEdge
|
||||
SMESH_MeshEditor::TNodeXYZ p1( edge->GetNode(0));
|
||||
SMESH_MeshEditor::TNodeXYZ p2( edge->GetNode(1));
|
||||
gp_XYZ middle = ( p1 + p2 ) / 2.;
|
||||
tmpNode.setXYZ( middle.X(), middle.Y(), middle.Z());
|
||||
double u = 0;
|
||||
if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true ))
|
||||
++( edge->IsQuadratic() ? nbQuadEdges : nbEdges);
|
||||
}
|
||||
}
|
||||
|
||||
int nbNodes = nbEdges + 2 * nbQuadEdges - 1;
|
||||
|
||||
aVec[SMDSEntity_Node ] = nbNodes;
|
||||
aVec[SMDSEntity_Edge ] = nbEdges;
|
||||
aVec[SMDSEntity_Quad_Edge] = nbQuadEdges;
|
||||
}
|
||||
|
||||
SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
|
||||
aResMap.insert(make_pair(sm,aVec));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return node-node and element-element maps for import of geiven source mesh
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void StdMeshers_Import_1D::getMaps(const SMESH_Mesh* srcMesh,
|
||||
SMESH_Mesh* tgtMesh,
|
||||
TNodeNodeMap*& n2n,
|
||||
TElemElemMap*& e2e)
|
||||
{
|
||||
_ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
|
||||
n2n = &iData->_n2n;
|
||||
e2e = &iData->_e2e;
|
||||
if ( iData->_copyMeshSubM.empty() )
|
||||
{
|
||||
n2n->clear();
|
||||
e2e->clear();
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return submesh corresponding to the copied mesh
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
SMESH_subMesh* StdMeshers_Import_1D::getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh,
|
||||
SMESH_Mesh& srcMesh )
|
||||
{
|
||||
_ImportData* iData = _Listener::getImportData(&srcMesh,&tgtMesh);
|
||||
if ( iData->_copyMeshSubM.empty() ) return 0;
|
||||
SMESH_subMesh* sm = tgtMesh.GetSubMeshContaining( iData->_importMeshSubID );
|
||||
return sm;
|
||||
}
|
||||
|
81
src/StdMeshers/StdMeshers_Import_1D.hxx
Normal file
81
src/StdMeshers/StdMeshers_Import_1D.hxx
Normal file
@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||
//
|
||||
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
// SMESH SMESH : implementaion of SMESH idl descriptions
|
||||
// Module : SMESH
|
||||
//
|
||||
#ifndef _SMESH_Import_1D_HXX_
|
||||
#define _SMESH_Import_1D_HXX_
|
||||
|
||||
#include "SMESH_StdMeshers.hxx"
|
||||
|
||||
#include "SMESH_1D_Algo.hxx"
|
||||
#include "SMDS_MeshElement.hxx"
|
||||
|
||||
class StdMeshers_ImportSource1D;
|
||||
|
||||
/*!
|
||||
* \brief Copy elements from other the mesh
|
||||
*/
|
||||
class STDMESHERS_EXPORT StdMeshers_Import_1D: public SMESH_1D_Algo
|
||||
{
|
||||
public:
|
||||
StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen* gen);
|
||||
|
||||
virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
|
||||
const TopoDS_Shape& aShape,
|
||||
SMESH_Hypothesis::Hypothesis_Status& aStatus);
|
||||
|
||||
virtual bool Compute (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
|
||||
virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
|
||||
MapShapeNbElems& aResMap);
|
||||
|
||||
virtual void SetEventListener(SMESH_subMesh* subMesh);
|
||||
virtual void SubmeshRestored(SMESH_subMesh* subMesh);
|
||||
|
||||
// internal utilities
|
||||
|
||||
typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*, TIDCompare> TNodeNodeMap;
|
||||
typedef std::map<const SMDS_MeshElement*,const SMDS_MeshElement*,TIDCompare> TElemElemMap;
|
||||
|
||||
static void getMaps(const SMESH_Mesh* srcMesh,
|
||||
SMESH_Mesh* tgtMesh,
|
||||
TNodeNodeMap*& n2n,
|
||||
TElemElemMap*& e2e);
|
||||
|
||||
static void importMesh(const SMESH_Mesh* srcMesh,
|
||||
SMESH_Mesh & tgtMesh,
|
||||
StdMeshers_ImportSource1D* srcHyp,
|
||||
const TopoDS_Shape& tgtShape);
|
||||
|
||||
static void setEventListener( SMESH_subMesh* subMesh,
|
||||
StdMeshers_ImportSource1D* sourceHyp );
|
||||
|
||||
static SMESH_subMesh* getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh,
|
||||
SMESH_Mesh& srcMesh );
|
||||
|
||||
private:
|
||||
|
||||
StdMeshers_ImportSource1D* _sourceHyp;
|
||||
};
|
||||
|
||||
#endif
|
642
src/StdMeshers/StdMeshers_Import_1D2D.cxx
Normal file
642
src/StdMeshers/StdMeshers_Import_1D2D.cxx
Normal file
@ -0,0 +1,642 @@
|
||||
// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||
//
|
||||
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
// SMESH SMESH : implementaion of SMESH idl descriptions
|
||||
// File : StdMeshers_Import_1D2D.cxx
|
||||
// Module : SMESH
|
||||
//
|
||||
#include "StdMeshers_Import_1D2D.hxx"
|
||||
|
||||
#include "StdMeshers_Import_1D.hxx"
|
||||
#include "StdMeshers_ImportSource.hxx"
|
||||
|
||||
#include "SMDS_MeshElement.hxx"
|
||||
#include "SMDS_MeshNode.hxx"
|
||||
#include "SMESHDS_Group.hxx"
|
||||
#include "SMESHDS_Mesh.hxx"
|
||||
#include "SMESH_Comment.hxx"
|
||||
#include "SMESH_Gen.hxx"
|
||||
#include "SMESH_Group.hxx"
|
||||
#include "SMESH_Mesh.hxx"
|
||||
#include "SMESH_MesherHelper.hxx"
|
||||
#include "SMESH_subMesh.hxx"
|
||||
|
||||
#include "Utils_SALOME_Exception.hxx"
|
||||
#include "utilities.h"
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
#include <numeric>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Creates StdMeshers_Import_1D2D
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
StdMeshers_Import_1D2D::StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen * gen)
|
||||
:SMESH_2D_Algo(hypId, studyId, gen), _sourceHyp(0)
|
||||
{
|
||||
MESSAGE("StdMeshers_Import_1D2D::StdMeshers_Import_1D2D");
|
||||
_name = "Import_1D2D";
|
||||
_shapeType = (1 << TopAbs_FACE);
|
||||
|
||||
_compatibleHypothesis.push_back("ImportSource2D");
|
||||
_requireDescretBoundary = false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Check presence of a hypothesis
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
bool StdMeshers_Import_1D2D::CheckHypothesis
|
||||
(SMESH_Mesh& aMesh,
|
||||
const TopoDS_Shape& aShape,
|
||||
SMESH_Hypothesis::Hypothesis_Status& aStatus)
|
||||
{
|
||||
_sourceHyp = 0;
|
||||
|
||||
const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
|
||||
if ( hyps.size() == 0 )
|
||||
{
|
||||
aStatus = SMESH_Hypothesis::HYP_MISSING;
|
||||
return false; // can't work with no hypothesis
|
||||
}
|
||||
|
||||
if ( hyps.size() > 1 )
|
||||
{
|
||||
aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
|
||||
return false;
|
||||
}
|
||||
|
||||
const SMESHDS_Hypothesis *theHyp = hyps.front();
|
||||
|
||||
string hypName = theHyp->GetName();
|
||||
|
||||
if (hypName == _compatibleHypothesis.front())
|
||||
{
|
||||
_sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
|
||||
aStatus = SMESH_Hypothesis::HYP_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
/*!
|
||||
* \brief OrientedLink additionally storing a medium node
|
||||
*/
|
||||
struct TLink : public SMESH_OrientedLink
|
||||
{
|
||||
const SMDS_MeshNode* _medium;
|
||||
TLink( const SMDS_MeshNode* n1,
|
||||
const SMDS_MeshNode* n2,
|
||||
const SMDS_MeshNode* medium=0)
|
||||
: SMESH_OrientedLink( n1,n2 ), _medium( medium ) {}
|
||||
};
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Import elements from the other mesh
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
|
||||
{
|
||||
if ( !_sourceHyp ) return false;
|
||||
|
||||
const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
|
||||
if ( srcGroups.empty() )
|
||||
return error("Invalid source groups");
|
||||
|
||||
SMESH_MesherHelper helper(theMesh);
|
||||
helper.SetSubShape(theShape);
|
||||
SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
|
||||
|
||||
const TopoDS_Face& geomFace = TopoDS::Face( theShape );
|
||||
const double faceTol = helper.MaxTolerance( geomFace );
|
||||
const int shapeID = tgtMesh->ShapeToIndex( geomFace );
|
||||
const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
|
||||
|
||||
Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
|
||||
if ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED )
|
||||
surface->UReverse();
|
||||
gp_Pnt p; gp_Vec du, dv;
|
||||
|
||||
set<int> subShapeIDs;
|
||||
subShapeIDs.insert( shapeID );
|
||||
|
||||
// get nodes on vertices
|
||||
list < SMESH_MeshEditor::TNodeXYZ > vertexNodes;
|
||||
list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt;
|
||||
TopExp_Explorer exp( theShape, TopAbs_VERTEX );
|
||||
for ( ; exp.More(); exp.Next() )
|
||||
{
|
||||
const TopoDS_Vertex& v = TopoDS::Vertex( exp.Current() );
|
||||
if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second )
|
||||
continue;
|
||||
const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
|
||||
if ( !n )
|
||||
{
|
||||
_gen->Compute(theMesh,v,/*anUpward=*/true);
|
||||
n = SMESH_Algo::VertexNode( v, tgtMesh );
|
||||
if ( !n ) return false; // very strange
|
||||
}
|
||||
vertexNodes.push_back( SMESH_MeshEditor::TNodeXYZ( n ));
|
||||
}
|
||||
|
||||
// to count now many times a link between nodes encounters
|
||||
map<TLink, int> linkCount;
|
||||
map<TLink, int>::iterator link2Nb;
|
||||
|
||||
// =========================
|
||||
// Import faces from groups
|
||||
// =========================
|
||||
|
||||
StdMeshers_Import_1D::TNodeNodeMap* n2n;
|
||||
StdMeshers_Import_1D::TElemElemMap* e2e;
|
||||
vector<const SMDS_MeshNode*> newNodes;
|
||||
for ( int iG = 0; iG < srcGroups.size(); ++iG )
|
||||
{
|
||||
const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
|
||||
|
||||
const int meshID = srcGroup->GetMesh()->GetPersistentId();
|
||||
const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID );
|
||||
if ( !srcMesh ) continue;
|
||||
StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e );
|
||||
|
||||
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
|
||||
SMDS_MeshNode tmpNode(0,0,0);
|
||||
gp_XY uv;
|
||||
while ( srcElems->more() ) // loop on group contents
|
||||
{
|
||||
const SMDS_MeshElement* face = srcElems->next();
|
||||
// find or create nodes of a new face
|
||||
newNodes.resize( face->NbNodes() );
|
||||
newNodes.back() = 0;
|
||||
int nbCreatedNodes = 0;
|
||||
SMDS_MeshElement::iterator node = face->begin_nodes();
|
||||
for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
|
||||
{
|
||||
TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
|
||||
if ( n2nIt->second )
|
||||
{
|
||||
if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() ))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find an existing vertex node
|
||||
for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
|
||||
if ( vNIt->SquareDistance( *node ) < 10 * faceTol * faceTol)
|
||||
{
|
||||
(*n2nIt).second = vNIt->_node;
|
||||
vertexNodes.erase( vNIt );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !n2nIt->second )
|
||||
{
|
||||
// find out if node lies on theShape
|
||||
tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
|
||||
if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true ))
|
||||
{
|
||||
SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
|
||||
n2nIt->second = newNode;
|
||||
tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() );
|
||||
nbCreatedNodes++;
|
||||
}
|
||||
}
|
||||
if ( !(newNodes[i] = n2nIt->second ))
|
||||
break;
|
||||
}
|
||||
if ( !newNodes.back() )
|
||||
continue; // not all nodes of the face lie on theShape
|
||||
|
||||
// try to find already created face
|
||||
SMDS_MeshElement * newFace = 0;
|
||||
if ( nbCreatedNodes == 0 &&
|
||||
tgtMesh->FindElement(newNodes, SMDSAbs_Face, /*noMedium=*/false))
|
||||
continue; // repeated face in source groups already created
|
||||
|
||||
// check future face orientation
|
||||
if ( toCheckOri )
|
||||
{
|
||||
int iNode = -1;
|
||||
gp_Vec geomNorm;
|
||||
do
|
||||
{
|
||||
uv = helper.GetNodeUV( geomFace, newNodes[++iNode] );
|
||||
surface->D1( uv.X(),uv.Y(), p, du,dv );
|
||||
geomNorm = du ^ dv;
|
||||
}
|
||||
while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes());
|
||||
|
||||
int iNext = helper.WrapIndex( iNode+1, face->NbCornerNodes() );
|
||||
int iPrev = helper.WrapIndex( iNode-1, face->NbCornerNodes() );
|
||||
|
||||
gp_Vec n1n0( SMESH_MeshEditor::TNodeXYZ( newNodes[iPrev] ) -
|
||||
SMESH_MeshEditor::TNodeXYZ( newNodes[iNode] ));
|
||||
gp_Vec n1n2( SMESH_MeshEditor::TNodeXYZ( newNodes[iNext] ) -
|
||||
SMESH_MeshEditor::TNodeXYZ( newNodes[iNode] ));
|
||||
gp_Vec meshNorm = n1n2 ^ n1n0;
|
||||
|
||||
if ( geomNorm * meshNorm < 0 )
|
||||
std::reverse( newNodes.begin(), newNodes.end() );
|
||||
}
|
||||
|
||||
// make a new face
|
||||
switch ( newNodes.size() )
|
||||
{
|
||||
case 3:
|
||||
newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] );
|
||||
break;
|
||||
case 4:
|
||||
newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] );
|
||||
break;
|
||||
case 6:
|
||||
newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2],
|
||||
newNodes[3], newNodes[4], newNodes[5]);
|
||||
break;
|
||||
case 8:
|
||||
newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3],
|
||||
newNodes[4], newNodes[5], newNodes[6], newNodes[7]);
|
||||
break;
|
||||
default: continue;
|
||||
}
|
||||
tgtMesh->SetMeshElementOnShape( newFace, shapeID );
|
||||
e2e->insert( make_pair( face, newFace ));
|
||||
|
||||
// collect links
|
||||
int nbNodes = face->NbCornerNodes();
|
||||
const SMDS_MeshNode* medium = 0;
|
||||
for ( int i = 0; i < nbNodes; ++i )
|
||||
{
|
||||
const SMDS_MeshNode* n1 = newNodes[i];
|
||||
const SMDS_MeshNode* n2 = newNodes[ (i+1)%nbNodes ];
|
||||
if ( newFace->IsQuadratic() )
|
||||
medium = newNodes[i+nbNodes];
|
||||
link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first;
|
||||
++link2Nb->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================
|
||||
// Put nodes on geom edges and create edges on them;
|
||||
// check if the whole geom face is covered by imported faces
|
||||
// ==========================================================
|
||||
|
||||
vector< TopoDS_Edge > edges;
|
||||
for ( exp.Init( theShape, TopAbs_EDGE ); exp.More(); exp.Next() )
|
||||
if ( subShapeIDs.insert( tgtMesh->ShapeToIndex( exp.Current() )).second )
|
||||
edges.push_back( TopoDS::Edge( exp.Current() ));
|
||||
|
||||
bool isFaceMeshed = false;
|
||||
if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape ))
|
||||
{
|
||||
// the imported mesh is valid if all external links (encountered once)
|
||||
// lie on geom edges
|
||||
subShapeIDs.erase( shapeID ); // to contain edges and vertices only
|
||||
double u, f, l;
|
||||
for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ++link2Nb)
|
||||
{
|
||||
const TLink& link = (*link2Nb).first;
|
||||
int nbFaces = link2Nb->second;
|
||||
if ( nbFaces == 1 )
|
||||
{
|
||||
// check if the link lie on face boundary
|
||||
bool nodesOnBoundary = true;
|
||||
list< TopoDS_Shape > bndShapes;
|
||||
for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN )
|
||||
{
|
||||
const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2();
|
||||
if ( !subShapeIDs.count( n->GetPosition()->GetShapeId() ))
|
||||
{
|
||||
for ( unsigned iE = 0; iE < edges.size(); ++iE )
|
||||
if ( helper.CheckNodeU( edges[iE], n, u, 10 * faceTol, /*force=*/true ))
|
||||
{
|
||||
BRep_Tool::Range(edges[iE],f,l);
|
||||
if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol )
|
||||
// duplicated node on vertex
|
||||
return error("Source elements overlap one another");
|
||||
tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u );
|
||||
break;
|
||||
}
|
||||
nodesOnBoundary = subShapeIDs.count( n->GetPosition()->GetShapeId());
|
||||
}
|
||||
if ( nodesOnBoundary )
|
||||
{
|
||||
TopoDS_Shape s = helper.GetSubShapeByNode( n, tgtMesh );
|
||||
if ( s.ShapeType() == TopAbs_VERTEX )
|
||||
bndShapes.push_front( s ); // vertex first
|
||||
else
|
||||
bndShapes.push_back( s ); // edges last
|
||||
}
|
||||
}
|
||||
if ( !nodesOnBoundary )
|
||||
break; // free internal link
|
||||
if ( bndShapes.front().ShapeType() == TopAbs_EDGE &&
|
||||
bndShapes.front() != bndShapes.back() )
|
||||
break; // link nodes on different geom edges
|
||||
|
||||
// find geom edge the link is on
|
||||
if ( bndShapes.back().ShapeType() != TopAbs_EDGE )
|
||||
{
|
||||
// find geom edge by two vertices
|
||||
TopoDS_Shape geomEdge;
|
||||
PShapeIteratorPtr edgeIt = helper.GetAncestors( bndShapes.back(), theMesh, TopAbs_EDGE );
|
||||
while ( edgeIt->more() )
|
||||
{
|
||||
geomEdge = *(edgeIt->next());
|
||||
if ( !helper.IsSubShape( bndShapes.front(), geomEdge ))
|
||||
geomEdge.Nullify();
|
||||
}
|
||||
if ( geomEdge.IsNull() )
|
||||
break; // vertices belong to different edges -> free internal link
|
||||
bndShapes.push_back( geomEdge );
|
||||
}
|
||||
|
||||
// create an edge if not yet exists
|
||||
newNodes.resize(2);
|
||||
newNodes[0] = link.node1(), newNodes[1] = link.node2();
|
||||
const SMDS_MeshElement* edge = tgtMesh->FindElement( newNodes, SMDSAbs_Edge );
|
||||
if ( edge ) continue;
|
||||
|
||||
if ( link._reversed ) std::swap( newNodes[0], newNodes[1] );
|
||||
if ( link._medium )
|
||||
{
|
||||
newNodes.push_back( link._medium );
|
||||
edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
|
||||
|
||||
TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back());
|
||||
helper.CheckNodeU( geomEdge, link._medium, u, 10*faceTol, /*force=*/true );
|
||||
tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u );
|
||||
}
|
||||
else
|
||||
{
|
||||
edge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
|
||||
}
|
||||
// remove nodes from submesh of theShape
|
||||
for ( unsigned i = 0; i < newNodes.size(); ++i )
|
||||
tgtSM->RemoveNode( newNodes[i], /*isNodeDeleted=*/false );
|
||||
if ( !edge )
|
||||
return false;
|
||||
|
||||
tgtMesh->SetMeshElementOnShape( edge, bndShapes.back() );
|
||||
}
|
||||
else if ( nbFaces > 2 )
|
||||
{
|
||||
return error( "Non-manifold source mesh");
|
||||
}
|
||||
}
|
||||
isFaceMeshed = ( link2Nb == linkCount.end() && !linkCount.empty());
|
||||
if ( isFaceMeshed )
|
||||
{
|
||||
// check that source faces do not overlap:
|
||||
// there must be only two edges sharing each vertex and bound to sub-edges of theShape
|
||||
SMESH_MeshEditor editor( &theMesh );
|
||||
set<int>::iterator subID = subShapeIDs.begin();
|
||||
for ( ; subID != subShapeIDs.end(); ++subID )
|
||||
{
|
||||
const TopoDS_Shape& s = tgtMesh->IndexToShape( *subID );
|
||||
if ( s.ShapeType() != TopAbs_VERTEX ) continue;
|
||||
const SMDS_MeshNode* n = SMESH_Algo::VertexNode( TopoDS::Vertex(s), tgtMesh );
|
||||
SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(SMDSAbs_Edge);
|
||||
int nbEdges = 0;
|
||||
while ( eIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement* edge = eIt->next();
|
||||
int sId = editor.FindShape( edge );
|
||||
nbEdges += subShapeIDs.count( sId );
|
||||
}
|
||||
if ( nbEdges < 2 )
|
||||
return false; // weird
|
||||
if ( nbEdges > 2 )
|
||||
return error( "Source elements overlap one another");
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !isFaceMeshed )
|
||||
return error( "Source elements don't cover totally the geometrical face" );
|
||||
|
||||
// notify sub-meshes of edges on computation
|
||||
for ( unsigned iE = 0; iE < edges.size(); ++iE )
|
||||
theMesh.GetSubMesh( edges[iE] )->ComputeStateEngine(SMESH_subMesh::CHECK_COMPUTE_STATE);
|
||||
|
||||
// ============
|
||||
// Copy meshes
|
||||
// ============
|
||||
|
||||
vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
|
||||
for ( unsigned i = 0; i < srcMeshes.size(); ++i )
|
||||
StdMeshers_Import_1D::importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* \brief Set needed event listeners and create a submesh for a copied mesh
|
||||
*
|
||||
* This method is called only if a submesh has HYP_OK algo_state.
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
void StdMeshers_Import_1D2D::SetEventListener(SMESH_subMesh* subMesh)
|
||||
{
|
||||
if ( !_sourceHyp )
|
||||
{
|
||||
const TopoDS_Shape& tgtShape = subMesh->GetSubShape();
|
||||
SMESH_Mesh* tgtMesh = subMesh->GetFather();
|
||||
Hypothesis_Status aStatus;
|
||||
CheckHypothesis( *tgtMesh, tgtShape, aStatus );
|
||||
}
|
||||
StdMeshers_Import_1D::setEventListener( subMesh, _sourceHyp );
|
||||
}
|
||||
void StdMeshers_Import_1D2D::SubmeshRestored(SMESH_subMesh* subMesh)
|
||||
{
|
||||
SetEventListener(subMesh);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Predict nb of mesh entities created by Compute()
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh & theMesh,
|
||||
const TopoDS_Shape & theShape,
|
||||
MapShapeNbElems& aResMap)
|
||||
{
|
||||
if ( !_sourceHyp ) return false;
|
||||
|
||||
const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
|
||||
if ( srcGroups.empty() )
|
||||
return error("Invalid source groups");
|
||||
|
||||
vector<int> aVec(SMDSEntity_Last,0);
|
||||
|
||||
bool toCopyMesh, toCopyGroups;
|
||||
_sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
|
||||
if ( toCopyMesh ) // the whole mesh is copied
|
||||
{
|
||||
vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
|
||||
for ( unsigned i = 0; i < srcMeshes.size(); ++i )
|
||||
{
|
||||
SMESH_subMesh* sm = StdMeshers_Import_1D::getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]);
|
||||
if ( !sm || aResMap.count( sm )) continue; // already counted
|
||||
const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo();
|
||||
for (int i = 0; i < SMDSEntity_Last; i++)
|
||||
aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// std-like iterator used to get coordinates of nodes of mesh element
|
||||
typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
|
||||
|
||||
SMESH_MesherHelper helper(theMesh);
|
||||
helper.SetSubShape(theShape);
|
||||
|
||||
const TopoDS_Face& geomFace = TopoDS::Face( theShape );
|
||||
const double faceTol = helper.MaxTolerance( geomFace );
|
||||
|
||||
// take into account nodes on vertices
|
||||
TopExp_Explorer exp( theShape, TopAbs_VERTEX );
|
||||
for ( ; exp.More(); exp.Next() )
|
||||
theMesh.GetSubMesh( exp.Current())->Evaluate( aResMap );
|
||||
|
||||
// to count now many times a link between nodes encounters,
|
||||
// negative nb additionally means that a link is quadratic
|
||||
map<SMESH_TLink, int> linkCount;
|
||||
map<SMESH_TLink, int>::iterator link2Nb;
|
||||
|
||||
// count faces and nodes imported from groups
|
||||
set<const SMDS_MeshNode* > allNodes;
|
||||
gp_XY uv;
|
||||
for ( int iG = 0; iG < srcGroups.size(); ++iG )
|
||||
{
|
||||
const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
|
||||
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
|
||||
SMDS_MeshNode tmpNode(0,0,0);
|
||||
while ( srcElems->more() ) // loop on group contents
|
||||
{
|
||||
const SMDS_MeshElement* face = srcElems->next();
|
||||
// find out if face is located on geomEdge by projecting
|
||||
// a gravity center of face to geomFace
|
||||
gp_XYZ gc(0,0,0);
|
||||
gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes();
|
||||
tmpNode.setXYZ( gc.X(), gc.Y(), gc.Z());
|
||||
if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true ))
|
||||
{
|
||||
++aVec[ face->GetEntityType() ];
|
||||
|
||||
// collect links
|
||||
int nbConers = face->NbCornerNodes();
|
||||
for ( int i = 0; i < face->NbNodes(); ++i )
|
||||
{
|
||||
const SMDS_MeshNode* n1 = face->GetNode(i);
|
||||
allNodes.insert( n1 );
|
||||
if ( i < nbConers )
|
||||
{
|
||||
const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbConers );
|
||||
link2Nb = linkCount.insert( make_pair( SMESH_TLink( n1, n2 ), 0)).first;
|
||||
if ( (*link2Nb).second )
|
||||
link2Nb->second += (link2Nb->second < 0 ) ? -1 : 1;
|
||||
else
|
||||
link2Nb->second += ( face->IsQuadratic() ) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nbNodes = allNodes.size();
|
||||
allNodes.clear();
|
||||
|
||||
// count nodes and edges on geom edges
|
||||
|
||||
double u;
|
||||
for ( exp.Init(theShape, TopAbs_EDGE); exp.More(); exp.Next() )
|
||||
{
|
||||
TopoDS_Edge geomEdge = TopoDS::Edge( exp.Current() );
|
||||
SMESH_subMesh* sm = theMesh.GetSubMesh( geomEdge );
|
||||
vector<int>& edgeVec = aResMap[sm];
|
||||
if ( edgeVec.empty() )
|
||||
{
|
||||
edgeVec.resize(SMDSEntity_Last,0);
|
||||
for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); )
|
||||
{
|
||||
const SMESH_TLink& link = (*link2Nb).first;
|
||||
int nbFacesOfLink = Abs( link2Nb->second );
|
||||
bool eraseLink = ( nbFacesOfLink != 1 );
|
||||
if ( nbFacesOfLink == 1 )
|
||||
{
|
||||
if ( helper.CheckNodeU( geomEdge, link.node1(), u, 10*faceTol, /*force=*/true )&&
|
||||
helper.CheckNodeU( geomEdge, link.node2(), u, 10*faceTol, /*force=*/true ))
|
||||
{
|
||||
bool isQuadratic = ( link2Nb->second < 0 );
|
||||
++edgeVec[ isQuadratic ? SMDSEntity_Quad_Edge : SMDSEntity_Edge ];
|
||||
++edgeVec[ SMDSEntity_Node ];
|
||||
--nbNodes;
|
||||
eraseLink = true;
|
||||
}
|
||||
}
|
||||
if ( eraseLink )
|
||||
linkCount.erase(link2Nb++);
|
||||
else
|
||||
link2Nb++;
|
||||
}
|
||||
if ( edgeVec[ SMDSEntity_Node] > 0 )
|
||||
--edgeVec[ SMDSEntity_Node ]; // for one node on vertex
|
||||
}
|
||||
else if ( !helper.IsSeamShape( geomEdge ) ||
|
||||
geomEdge.Orientation() == TopAbs_FORWARD )
|
||||
{
|
||||
nbNodes -= 1+edgeVec[ SMDSEntity_Node ];
|
||||
}
|
||||
}
|
||||
|
||||
aVec[SMDSEntity_Node] = nbNodes;
|
||||
}
|
||||
|
||||
SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
|
||||
aResMap.insert(make_pair(sm,aVec));
|
||||
|
||||
return true;
|
||||
}
|
60
src/StdMeshers/StdMeshers_Import_1D2D.hxx
Normal file
60
src/StdMeshers/StdMeshers_Import_1D2D.hxx
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||
//
|
||||
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
// SMESH SMESH : implementaion of SMESH idl descriptions
|
||||
// Module : SMESH
|
||||
//
|
||||
#ifndef _SMESH_Import_2D_HXX_
|
||||
#define _SMESH_Import_2D_HXX_
|
||||
|
||||
#include "SMESH_StdMeshers.hxx"
|
||||
|
||||
#include "SMESH_2D_Algo.hxx"
|
||||
#include "SMDS_MeshElement.hxx"
|
||||
|
||||
class StdMeshers_ImportSource1D;
|
||||
|
||||
/*!
|
||||
* \brief Copy elements from other the mesh
|
||||
*/
|
||||
class STDMESHERS_EXPORT StdMeshers_Import_1D2D: public SMESH_2D_Algo
|
||||
{
|
||||
public:
|
||||
StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen* gen);
|
||||
|
||||
virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
|
||||
const TopoDS_Shape& aShape,
|
||||
SMESH_Hypothesis::Hypothesis_Status& aStatus);
|
||||
|
||||
virtual bool Compute (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
|
||||
virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
|
||||
MapShapeNbElems& aResMap);
|
||||
|
||||
virtual void SetEventListener(SMESH_subMesh* subMesh);
|
||||
virtual void SubmeshRestored(SMESH_subMesh* subMesh);
|
||||
|
||||
private:
|
||||
|
||||
StdMeshers_ImportSource1D* _sourceHyp;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user