typedef const list<const SMDS_MeshFace*> TTriaList;
+static const char theDomainGroupNamePrefix[] = "Domain_";
+
static void removeFile( const TCollection_AsciiString& fileName )
{
try {
: SMESH_3D_Algo(hypId, studyId, gen)
{
MESSAGE("GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D");
- _name = "GHS3D_3D";
+ _name = Name();
_shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
_onlyUnaryInput = false; // Compute() will be called on a compound of solids
_iShape=0;
if (myStudy)
MESSAGE("myStudy->StudyId() = " << myStudy->StudyId());
-#ifdef WITH_SMESH_CANCEL_COMPUTE
_compute_canceled = false;
-#endif
}
//=============================================================================
}
}
+//=======================================================================
+//function : removeEmptyGroupsOfDomains
+//purpose : remove empty groups named "Domain_nb" created due to
+// "To make groups of domains" option.
+//=======================================================================
+
+static void removeEmptyGroupsOfDomains(SMESH_Mesh* mesh,
+ bool notEmptyAsWell = false)
+{
+ const char* refName = theDomainGroupNamePrefix;
+ const size_t refLen = strlen( theDomainGroupNamePrefix );
+
+ std::list<int> groupIDs = mesh->GetGroupIds();
+ std::list<int>::const_iterator id = groupIDs.begin();
+ for ( ; id != groupIDs.end(); ++id )
+ {
+ SMESH_Group* group = mesh->GetGroup( *id );
+ if ( !group || ( !group->GetGroupDS()->IsEmpty() && !notEmptyAsWell ))
+ continue;
+ const char* name = group->GetName();
+ char* end;
+ // check the name
+ if ( strncmp( name, refName, refLen ) == 0 && // starts from refName;
+ isdigit( *( name + refLen )) && // refName is followed by a digit;
+ strtol( name + refLen, &end, 10) && // there are only digits ...
+ *end == '\0') // ... till a string end.
+ {
+ mesh->RemoveGroup( *id );
+ }
+ }
+}
+
//=======================================================================
//function : readGMFFile
//purpose : read GMF file w/o geometry associated to mesh
//=======================================================================
static bool readGMFFile(const char* theFile,
-#ifdef WITH_SMESH_CANCEL_COMPUTE
GHS3DPlugin_GHS3D* theAlgo,
-#endif
SMESH_MesherHelper* theHelper,
TopoDS_Shape theSolid,
vector <const SMDS_MeshNode*> & theNodeByGhs3dId,
std::vector<std::string> & aNodeGroupByGhs3dId,
std::vector<std::string> & anEdgeGroupByGhs3dId,
std::vector<std::string> & aFaceGroupByGhs3dId,
- std::set<std::string> & groupsToRemove
- )
+ std::set<std::string> & groupsToRemove,
+ bool toMakeGroupsOfDomains=false)
{
std::string tmpStr;
SMESHDS_Mesh* theMeshDS = theHelper->GetMeshDS();
// ---------------------------------
int nbElem = 0, nbRef = 0;
- int aGMFNodeID = 0/*, shapeID*/;
- //int *nodeAssigne;
+ int aGMFNodeID = 0;
const SMDS_MeshNode** GMFNode;
#ifdef _DEBUG_
std::map<int, std::set<int> > subdomainId2tetraId;
#endif
std::map <GmfKwdCod,int> tabRef;
+ const bool force3d = true; // since there is no geometry
+ const int noID = 0;
tabRef[GmfVertices] = 3; // for new nodes and enforced nodes
tabRef[GmfCorners] = 1;
// Issue 0020682. Avoid creating nodes and tetras at place where
// volumic elements already exist
SMESH_ElementSearcher* elemSearcher = 0;
- vector< const SMDS_MeshElement* > foundVolumes;
+ std::vector< const SMDS_MeshElement* > foundVolumes;
if ( theHelper->GetMesh()->NbVolumes() > 0 )
elemSearcher = SMESH_MeshAlgos::GetElementSearcher( *theHelper->GetMeshDS() );
+ // IMP 0022172: [CEA 790] create the groups corresponding to domains
+ std::vector< std::vector< const SMDS_MeshElement* > > elemsOfDomain;
+
int nbVertices = GmfStatKwd(InpMsh, GmfVertices) - nbInitialNodes;
GMFNode = new const SMDS_MeshNode*[ nbVertices + 1 ];
- //nodeAssigne = new int[ nbVertices + 1 ];
std::map <GmfKwdCod,int>::const_iterator it = tabRef.begin();
for ( ; it != tabRef.end() ; ++it)
{
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if(theAlgo->computeCanceled()) {
GmfCloseMesh(InpMsh);
delete [] GMFNode;
- //delete [] nodeAssigne;
return false;
}
-#endif
int dummy;
GmfKwdCod token = it->first;
- nbRef = it->second;
+ nbRef = it->second;
nbElem = GmfStatKwd(InpMsh, token);
if (nbElem > 0) {
continue;
std::vector<int> id (nbElem*tabRef[token]); // node ids
+ std::vector<int> domainID( nbElem ); // domain
if (token == GmfVertices) {
(nbElem <= 1) ? tmpStr = " vertex" : tmpStr = " vertices";
double x, y, z;
const SMDS_MeshNode * aGMFNode;
- //shapeID = theMeshDS->ShapeToIndex( theSolid );
for ( int iElem = 0; iElem < nbElem; iElem++ ) {
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if(theAlgo->computeCanceled()) {
GmfCloseMesh(InpMsh);
delete [] GMFNode;
- //delete [] nodeAssigne;
return false;
}
-#endif
if (ver == GmfFloat) {
GmfGetLin(InpMsh, token, &VerTab_f[0], &VerTab_f[1], &VerTab_f[2], &dummy);
x = VerTab_f[0];
aGMFID = iElem -nbInitialNodes +1;
GMFNode[ aGMFID ] = aGMFNode;
- //nodeAssigne[ aGMFID ] = 0;
if (aGMFID-1 < aNodeGroupByGhs3dId.size() && !aNodeGroupByGhs3dId.at(aGMFID-1).empty())
addElemInMeshGroup(theHelper->GetMesh(), aGMFNode, aNodeGroupByGhs3dId.at(aGMFID-1), groupsToRemove);
}
else if (token == GmfEdges && nbElem > 0) {
(nbElem <= 1) ? tmpStr = " edge" : tmpStr = " edges";
for ( int iElem = 0; iElem < nbElem; iElem++ )
- GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &dummy);
+ GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &domainID[iElem]);
}
else if (token == GmfTriangles && nbElem > 0) {
(nbElem <= 1) ? tmpStr = " triangle" : tmpStr = " triangles";
for ( int iElem = 0; iElem < nbElem; iElem++ )
- GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &dummy);
+ GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &domainID[iElem]);
}
else if (token == GmfQuadrilaterals && nbElem > 0) {
(nbElem <= 1) ? tmpStr = " Quadrilateral" : tmpStr = " Quadrilaterals";
for ( int iElem = 0; iElem < nbElem; iElem++ )
- GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &dummy);
+ GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &domainID[iElem]);
}
else if (token == GmfTetrahedra && nbElem > 0) {
(nbElem <= 1) ? tmpStr = " Tetrahedron" : tmpStr = " Tetrahedra";
for ( int iElem = 0; iElem < nbElem; iElem++ ) {
- GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &dummy);
+ GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &domainID[iElem]);
#ifdef _DEBUG_
subdomainId2tetraId[dummy].insert(iElem+1);
// MESSAGE("subdomainId2tetraId["<<dummy<<"].insert("<<iElem+1<<")");
(nbElem <= 1) ? tmpStr = " Hexahedron" : tmpStr = " Hexahedra";
for ( int iElem = 0; iElem < nbElem; iElem++ )
GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3],
- &id[iElem*tabRef[token]+4], &id[iElem*tabRef[token]+5], &id[iElem*tabRef[token]+6], &id[iElem*tabRef[token]+7], &dummy);
+ &id[iElem*tabRef[token]+4], &id[iElem*tabRef[token]+5], &id[iElem*tabRef[token]+6], &id[iElem*tabRef[token]+7], &domainID[iElem]);
}
std::cout << tmpStr << std::endl;
std::cout << std::endl;
for ( int iElem = 0; iElem < nbElem; iElem++ )
{
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if(theAlgo->computeCanceled()) {
GmfCloseMesh(InpMsh);
delete [] GMFNode;
- //delete [] nodeAssigne;
return false;
}
-#endif
// Check if elem is already in input mesh. If yes => skip
bool fullyCreatedElement = false; // if at least one of the nodes was created
for ( int iRef = 0; iRef < nbRef; iRef++ )
node [ iRef ] = GMFNode[ aGMFNodeID ];
}
}
-
+ aCreatedElem = 0;
switch (token)
{
case GmfEdges:
if (fullyCreatedElement) {
- aCreatedElem = theHelper->AddEdge( node[0], node[1], /*id =*/0, /*force3d =*/false );
+ aCreatedElem = theHelper->AddEdge( node[0], node[1], noID, force3d );
if (anEdgeGroupByGhs3dId.size() && !anEdgeGroupByGhs3dId[iElem].empty())
addElemInMeshGroup(theHelper->GetMesh(), aCreatedElem, anEdgeGroupByGhs3dId[iElem], groupsToRemove);
}
break;
case GmfTriangles:
if (fullyCreatedElement) {
- aCreatedElem = theHelper->AddFace( node[0], node[1], node[2], /*id =*/0, /*force3d =*/false );
- // for ( int iRef = 0; iRef < nbRef; iRef++ )
- // nodeAssigne[ nodeID[ iRef ]] = 1;
+ aCreatedElem = theHelper->AddFace( node[0], node[1], node[2], noID, force3d );
if (aFaceGroupByGhs3dId.size() && !aFaceGroupByGhs3dId[iElem].empty())
addElemInMeshGroup(theHelper->GetMesh(), aCreatedElem, aFaceGroupByGhs3dId[iElem], groupsToRemove);
}
break;
case GmfQuadrilaterals:
if (fullyCreatedElement) {
- theHelper->AddFace( node[0], node[1], node[2], node[3], /*id =*/0, /*force3d =*/false );
- // for ( int iRef = 0; iRef < nbRef; iRef++ )
- // nodeAssigne[ nodeID[ iRef ]] = 1;
+ aCreatedElem = theHelper->AddFace( node[0], node[1], node[2], node[3], noID, force3d );
}
break;
case GmfTetrahedra:
SMDSAbs_Volume, foundVolumes ))
break;
}
- theHelper->AddVolume( node[1], node[0], node[2], node[3], /*id =*/0, /*force3d =*/false );
-// theMeshDS->SetMeshElementOnShape( aTet, shapeID );
+ aCreatedElem = theHelper->AddVolume( node[1], node[0], node[2], node[3], noID, force3d );
break;
case GmfHexahedra:
if ( elemSearcher ) {
SMDSAbs_Volume, foundVolumes ))
break;
}
- theHelper->AddVolume( node[0], node[3], node[2], node[1],
- node[4], node[7], node[6], node[5], /*id =*/0, /*force3d =*/false );
-// theMeshDS->SetMeshElementOnShape( aTet, shapeID );
+ aCreatedElem = theHelper->AddVolume( node[0], node[3], node[2], node[1],
+ node[4], node[7], node[6], node[5], noID, force3d );
break;
default: continue;
}
- }
+ if ( aCreatedElem && toMakeGroupsOfDomains )
+ {
+ if ( domainID[iElem] >= (int) elemsOfDomain.size() )
+ elemsOfDomain.resize( domainID[iElem] + 1 );
+ elemsOfDomain[ domainID[iElem] ].push_back( aCreatedElem );
+ }
+ } // loop on elements of one type
break;
- }
- }
- }
-
- // for ( int i = 0; i < nbVertices; ++i ) {
- // if ( !nodeAssigne[ i+1 ])
- // theMeshDS->SetNodeInVolume( GMFNode[ i+1 ], shapeID );
- // }
+ } // case ...
+ } // switch (token)
+ } // loop on tabRef
GmfCloseMesh(InpMsh);
delete [] GMFNode;
- //delete [] nodeAssigne;
-#ifdef _DEBUG_
+
+ // 0022172: [CEA 790] create the groups corresponding to domains
+ if ( toMakeGroupsOfDomains )
+ {
+ int nbDomains = 0;
+ for ( size_t i = 0; i < elemsOfDomain.size(); ++i )
+ nbDomains += ( elemsOfDomain[i].size() > 0 );
+
+ if ( nbDomains > 1 )
+ for ( size_t iDomain = 0; iDomain < elemsOfDomain.size(); ++iDomain )
+ {
+ std::vector< const SMDS_MeshElement* > & elems = elemsOfDomain[ iDomain ];
+ if ( elems.empty() ) continue;
+
+ // find existing groups
+ std::vector< SMESH_Group* > groupOfType( SMDSAbs_NbElementTypes, (SMESH_Group*)NULL );
+ const std::string domainName = ( SMESH_Comment( theDomainGroupNamePrefix ) << iDomain );
+ SMESH_Mesh::GroupIteratorPtr groupIt = theHelper->GetMesh()->GetGroups();
+ while ( groupIt->more() )
+ {
+ SMESH_Group* group = groupIt->next();
+ if ( domainName == group->GetName() &&
+ dynamic_cast< SMESHDS_Group* >( group->GetGroupDS()) )
+ groupOfType[ group->GetGroupDS()->GetType() ] = group;
+ }
+ // create and fill the groups
+ size_t iElem = 0;
+ int groupID;
+ do
+ {
+ SMESH_Group* group = groupOfType[ elems[ iElem ]->GetType() ];
+ if ( !group )
+ group = theHelper->GetMesh()->AddGroup( elems[ iElem ]->GetType(),
+ domainName.c_str(), groupID );
+ SMDS_MeshGroup& groupDS =
+ static_cast< SMESHDS_Group* >( group->GetGroupDS() )->SMDSGroup();
+
+ while ( iElem < elems.size() && groupDS.Add( elems[iElem] ))
+ ++iElem;
+
+ } while ( iElem < elems.size() );
+ }
+ }
+
+#ifdef _DEBUG_
MESSAGE("Nb subdomains " << subdomainId2tetraId.size());
std::map<int, std::set<int> >::const_iterator subdomainIt = subdomainId2tetraId.begin();
TCollection_AsciiString aSubdomainFileName = theFile;
#ifdef WNT
const char* fileName,
#endif
-#ifdef WITH_SMESH_CANCEL_COMPUTE
GHS3DPlugin_GHS3D* theAlgo,
-#endif
SMESH_MesherHelper& theHelper,
TopoDS_Shape tabShape[],
double** tabBox,
MESSAGE("nbEnforcedNodes: "<<nbEnforcedNodes);
// Reading the nodeCoor and update the nodeMap
for (int iNode=1; iNode <= nbNodes; iNode++) {
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if(theAlgo->computeCanceled())
return false;
-#endif
for (int iCoor=0; iCoor < 3; iCoor++)
coord[ iCoor ] = strtod(ptr, &ptr);
nodeAssigne[ iNode ] = 1;
tabID = new int[nbTriangle];
for (int i=0; i < nbTriangle; i++) {
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if(theAlgo->computeCanceled())
return false;
-#endif
tabID[i] = 0;
// find the solid corresponding to GHS3D sub-domain following
// the technique proposed in GHS3D manual in chapter
// Associating the tetrahedrons to the shapes
shapeID = compoundID;
for (int iElem = 0; iElem < nbElems; iElem++) {
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if(theAlgo->computeCanceled())
return false;
-#endif
for (int iNode = 0; iNode < 4; iNode++) {
ID = strtol(tetraPtr, &tetraPtr, 10);
itOnNode = theGhs3dIdToNodeMap.find(ID);
std::cout << "Ghs3d execution..." << std::endl;
std::cout << cmd << std::endl;
-#ifdef WITH_SMESH_CANCEL_COMPUTE
_compute_canceled = false;
-#endif
system( cmd.ToCString() ); // run
#ifdef WNT
aResultFileName.ToCString(),
#endif
-#ifdef WITH_SMESH_CANCEL_COMPUTE
this,
-#endif
/*theMesh, */helper, tabShape, tabBox, _nbShape,
aGhs3dIdToNodeMap, aNodeId2NodeIndexMap,
toMeshHoles,
{
if ( !_keepFiles )
removeFile( aLogFileName );
+
+ if ( _hyp && _hyp->GetToMakeGroupsOfDomains() )
+ error( COMPERR_WARNING, "'toMakeGroupsOfDomains' is ignored since the mesh is on shape" );
}
else if ( OSD_File( aLogFileName ).Size() > 0 )
{
}
if ( !_keepFiles ) {
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if (! Ok)
if(_compute_canceled)
removeFile( aLogFileName );
-#endif
removeFile( aFacesFileName );
removeFile( aPointsFileName );
removeFile( aResultFileName );
std::cout << "Ghs3d execution..." << std::endl;
std::cout << cmd << std::endl;
-#ifdef WITH_SMESH_CANCEL_COMPUTE
_compute_canceled = false;
-#endif
system( cmd.ToCString() ); // run
// read a result
// --------------
GHS3DPlugin_Hypothesis::TSetStrings groupsToRemove = GHS3DPlugin_Hypothesis::GetGroupsToRemove(_hyp);
+ const bool toMakeGroupsOfDomains = GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains( _hyp );
Ok = readGMFFile(aResultFileName.ToCString(),
-#ifdef WITH_SMESH_CANCEL_COMPUTE
this,
-#endif
theHelper, theShape, aNodeByGhs3dId, aNodeToGhs3dIdMap,
aNodeGroupByGhs3dId, anEdgeGroupByGhs3dId, aFaceGroupByGhs3dId,
- groupsToRemove);
+ groupsToRemove, toMakeGroupsOfDomains);
updateMeshGroups(theHelper->GetMesh(), groupsToRemove);
+ removeEmptyGroupsOfDomains( theHelper->GetMesh() );
if ( Ok ) {
GHS3DPlugin_Hypothesis* that = (GHS3DPlugin_Hypothesis*)this->_hyp;
{
if ( !_keepFiles )
removeFile( aLogFileName );
+
+ if ( !toMakeGroupsOfDomains && _hyp && _hyp->GetToMakeGroupsOfDomains() )
+ error( COMPERR_WARNING, "'toMakeGroupsOfDomains' is ignored since 'toMeshHoles' is OFF." );
}
else if ( OSD_File( aLogFileName ).Size() > 0 )
{
if ( !_keepFiles )
{
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if (! Ok)
if(_compute_canceled)
removeFile( aLogFileName );
-#endif
removeFile( aGMFFileName );
removeFile( aResultFileName );
removeFile( aRequiredVerticesFileName );
return Ok;
}
-#ifdef WITH_SMESH_CANCEL_COMPUTE
void GHS3DPlugin_GHS3D::CancelCompute()
{
_compute_canceled = true;
system( cmd.ToCString() );
#endif
}
-#endif
//================================================================================
/*!
bool GHS3DPlugin_GHS3D::storeErrorDescription(const TCollection_AsciiString& logFile,
const _Ghs2smdsConvertor & toSmdsConvertor )
{
-#ifdef WITH_SMESH_CANCEL_COMPUTE
if(_compute_canceled)
return error(SMESH_Comment("interruption initiated by user"));
-#endif
// open file
#ifdef WNT
int file = ::_open (logFile.ToCString(), _O_RDONLY|_O_BINARY);
std::set<std::string> dummyGroupsToRemove;
bool ok = readGMFFile(theGMFFileName,
-#ifdef WITH_SMESH_CANCEL_COMPUTE
this,
-#endif
helper, theMesh.GetShapeToMesh(), dummyNodeVector, dummyNodeMap, dummyElemGroup, dummyElemGroup, dummyElemGroup, dummyGroupsToRemove);
theMesh.GetMeshDS()->Modified();
return ok;
/*visitAncestors=*/true);
}
};
+
+ //================================================================================
+ /*!
+ * \brief Sub-mesh event listener removing empty groups created due to "To make
+ * groups of domains".
+ */
+ struct _GroupsOfDomainsRemover : public SMESH_subMeshEventListener
+ {
+ _GroupsOfDomainsRemover():
+ SMESH_subMeshEventListener( /*isDeletable = */true,
+ "GHS3DPlugin_GHS3D::_GroupsOfDomainsRemover" ) {}
+ /*!
+ * \brief Treat events of the subMesh
+ */
+ void ProcessEvent(const int event,
+ const int eventType,
+ SMESH_subMesh* subMesh,
+ SMESH_subMeshEventListenerData* data,
+ const SMESH_Hypothesis* hyp)
+ {
+ if (SMESH_subMesh::ALGO_EVENT == eventType &&
+ !subMesh->GetAlgo() )
+ {
+ removeEmptyGroupsOfDomains( subMesh->GetFather(), /*notEmptyAsWell=*/true );
+ }
+ }
+ };
}
//================================================================================
}
}
}
+
+//================================================================================
+/*!
+ * \brief Sets an event listener removing empty groups created due to "To make
+ * groups of domains".
+ * \param subMesh - submesh where algo is set
+ *
+ * This method is called when a submesh gets HYP_OK algo_state.
+ * After being set, event listener is notified on each event of a submesh.
+ */
+//================================================================================
+
+void GHS3DPlugin_GHS3D::SetEventListener(SMESH_subMesh* subMesh)
+{
+ subMesh->SetEventListener( new _GroupsOfDomainsRemover(), 0, subMesh );
+}