+//=============================================================================
+/*!
+ * SMESH_Gen_i::CancelCompute
+ *
+ * Cancel Compute mesh on a shape
+ */
+//=============================================================================
+
+void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theShapeObject )
+{
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+ ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+ TopoDS_Shape myLocShape;
+ if(theMesh->HasShapeToMesh())
+ myLocShape = GeomObjectToShape( theShapeObject );
+ else
+ myLocShape = SMESH_Mesh::PseudoShape();
+ myGen.CancelCompute( myLocMesh, myLocShape);
+#endif
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::Precompute
+ *
+ * Compute mesh as preview till indicated dimension on shape
+ */
+//=============================================================================
+
+SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theShapeObject,
+ SMESH::Dimension theDimension,
+ SMESH::long_array& theShapesId)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" );
+
+ if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
+ SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+ SALOME::BAD_PARAM );
+
+ SMESH::MeshPreviewStruct_var result = new SMESH::MeshPreviewStruct;
+ try {
+ // get mesh servant
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+ ASSERT( meshServant );
+ if ( meshServant ) {
+ // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
+ meshServant->CheckGeomGroupModif();
+ // get local TopoDS_Shape
+ TopoDS_Shape myLocShape;
+ if(theMesh->HasShapeToMesh())
+ myLocShape = GeomObjectToShape( theShapeObject );
+ else
+ return result._retn();;
+
+ // call implementation compute
+ ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+ TSetOfInt shapeIds;
+ ::MeshDimension aDim = (MeshDimension)theDimension;
+ if ( myGen.Compute( myLocMesh, myLocShape, false, aDim, &shapeIds ) )
+ {
+ int nbShapeId = shapeIds.size();
+ theShapesId.length( nbShapeId );
+ // iterates on shapes and collect mesh entities into mesh preview
+ TSetOfInt::const_iterator idIt = shapeIds.begin();
+ TSetOfInt::const_iterator idEnd = shapeIds.end();
+ std::map< int, int > mapOfShIdNb;
+ std::set< SMESH_TLink > setOfEdge;
+ std::list< SMDSAbs_ElementType > listOfElemType;
+ typedef map<const SMDS_MeshElement*, int > TNode2LocalIDMap;
+ typedef TNode2LocalIDMap::iterator TNodeLocalID;
+ TNode2LocalIDMap mapNode2LocalID;
+ list< TNodeLocalID > connectivity;
+ int i, nbConnNodes = 0;
+ std::set< const SMESH_subMesh* > setOfVSubMesh;
+ // iterates on shapes
+ for ( ; idIt != idEnd; idIt++ )
+ {
+ if ( mapOfShIdNb.find( *idIt ) != mapOfShIdNb.end() )
+ continue;
+ SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt);
+ if ( !sm || !sm->IsMeshComputed() )
+ continue;
+
+ const TopoDS_Shape& aSh = sm->GetSubShape();
+ const int shDim = myGen.GetShapeDim( aSh );
+ if ( shDim < 1 || shDim > theDimension )
+ continue;
+
+ mapOfShIdNb[ *idIt ] = 0;
+ theShapesId[ mapOfShIdNb.size() - 1 ] = *idIt;
+
+ SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+ if ( !smDS ) continue;
+
+ if ( theDimension == SMESH::DIM_2D )
+ {
+ SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
+ while ( faceIt->more() )
+ {
+ const SMDS_MeshElement* face = faceIt->next();
+ int aNbNode = face->NbNodes();
+ if ( aNbNode > 4 )
+ aNbNode /= 2; // do not take into account additional middle nodes
+
+ SMDS_MeshNode* node1 = (SMDS_MeshNode*)face->GetNode( 0 );
+ for ( int nIndx = 0; nIndx < aNbNode; nIndx++ )
+ {
+ SMDS_MeshNode* node2 = (SMDS_MeshNode*)face->GetNode( nIndx+1 < aNbNode ? nIndx+1 : 0 );
+ if ( setOfEdge.insert( SMESH_TLink ( node1, node2 ) ).second )
+ {
+ listOfElemType.push_back( SMDSAbs_Edge );
+ connectivity.push_back
+ ( mapNode2LocalID.insert( make_pair( node1, ++nbConnNodes)).first );
+ connectivity.push_back
+ ( mapNode2LocalID.insert( make_pair( node2, ++nbConnNodes)).first );
+ }
+ node1 = node2;
+ }
+ }
+ }
+ else if ( theDimension == SMESH::DIM_1D )
+ {
+ SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes();
+ while ( nodeIt->more() )
+ {
+ listOfElemType.push_back( SMDSAbs_Node );
+ connectivity.push_back
+ ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
+ }
+ // add corner nodes by first vertex from edge
+ SMESH_subMeshIteratorPtr edgeSmIt =
+ sm->getDependsOnIterator(/*includeSelf*/false,
+ /*complexShapeFirst*/false);
+ while ( edgeSmIt->more() )
+ {
+ SMESH_subMesh* vertexSM = edgeSmIt->next();
+ // check that vertex is not already treated
+ if ( !setOfVSubMesh.insert( vertexSM ).second )
+ continue;
+ if ( vertexSM->GetSubShape().ShapeType() != TopAbs_VERTEX )
+ continue;
+
+ const SMESHDS_SubMesh* vertexSmDS = vertexSM->GetSubMeshDS();
+ SMDS_NodeIteratorPtr nodeIt = vertexSmDS->GetNodes();
+ while ( nodeIt->more() )
+ {
+ listOfElemType.push_back( SMDSAbs_Node );
+ connectivity.push_back
+ ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
+ }
+ }
+ }
+ }
+
+ // fill node coords and assign local ids to the nodes
+ int nbNodes = mapNode2LocalID.size();
+ result->nodesXYZ.length( nbNodes );
+ TNodeLocalID node2ID = mapNode2LocalID.begin();
+ for ( i = 0; i < nbNodes; ++i, ++node2ID ) {
+ node2ID->second = i;
+ const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first;
+ result->nodesXYZ[i].x = node->X();
+ result->nodesXYZ[i].y = node->Y();
+ result->nodesXYZ[i].z = node->Z();
+ }
+ // fill connectivity
+ result->elementConnectivities.length( nbConnNodes );
+ list< TNodeLocalID >::iterator connIt = connectivity.begin();
+ for ( i = 0; i < nbConnNodes; ++i, ++connIt ) {
+ result->elementConnectivities[i] = (*connIt)->second;
+ }
+
+ // fill element types
+ result->elementTypes.length( listOfElemType.size() );
+ std::list< SMDSAbs_ElementType >::const_iterator typeIt = listOfElemType.begin();
+ std::list< SMDSAbs_ElementType >::const_iterator typeEnd = listOfElemType.end();
+ for ( i = 0; typeIt != typeEnd; ++i, ++typeIt )
+ {
+ SMDSAbs_ElementType elemType = *typeIt;
+ result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType)elemType;
+ result->elementTypes[i].isPoly = false;
+ result->elementTypes[i].nbNodesInElement = elemType == SMDSAbs_Edge ? 2 : 1;
+ }
+
+ // correct number of shapes
+ theShapesId.length( mapOfShIdNb.size() );
+ }
+ }
+ }
+ catch ( std::bad_alloc ) {
+ INFOS( "Precompute(): lack of memory" );
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "Precompute(): catch exception "<< S_ex.what() );
+ }
+ catch ( ... ) {
+ INFOS( "Precompute(): unknown exception " );
+ }
+ return result._retn();
+}
+
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::Evaluate
+ *
+ * Evaluate mesh on a shape
+ */
+//=============================================================================
+
+SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theShapeObject)
+// SMESH::long_array& theNbElems)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" );
+
+ if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
+ SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+ SALOME::BAD_PARAM );
+
+ SMESH::long_array_var nbels = new SMESH::long_array;
+ nbels->length(SMESH::Entity_Last);
+ int i = SMESH::Entity_Node;
+ for (; i < SMESH::Entity_Last; i++)
+ nbels[i] = 0;
+
+ // Update Python script
+ TPythonDump() << "theNbElems = " << this << ".Evaluate( "
+ << theMesh << ", " << theShapeObject << ")";
+
+ try {
+ // get mesh servant
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+ ASSERT( meshServant );
+ if ( meshServant ) {
+ // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
+ meshServant->CheckGeomGroupModif();
+ // get local TopoDS_Shape
+ TopoDS_Shape myLocShape;
+ if(theMesh->HasShapeToMesh())
+ myLocShape = GeomObjectToShape( theShapeObject );
+ else
+ myLocShape = SMESH_Mesh::PseudoShape();
+ // call implementation compute
+ ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+ MapShapeNbElems aResMap;
+ /*CORBA::Boolean ret =*/ myGen.Evaluate( myLocMesh, myLocShape, aResMap);
+ MapShapeNbElemsItr anIt = aResMap.begin();
+ for(; anIt!=aResMap.end(); anIt++) {
+ const vector<int>& aVec = (*anIt).second;
+ for(i = SMESH::Entity_Node; i < aVec.size(); i++) {
+ int nbElem = aVec[i];
+ if ( nbElem < 0 ) // algo failed, check that it has reported a message
+ {
+ SMESH_subMesh* sm = anIt->first;
+ SMESH_ComputeErrorPtr& error = sm->GetComputeError();
+ const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape());
+ if ( (algo && !error.get()) || error->IsOK() )
+ error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo));
+ }
+ else
+ {
+ nbels[i] += aVec[i];
+ }
+ }
+ }
+ return nbels._retn();
+ }
+ }
+ catch ( std::bad_alloc ) {
+ INFOS( "Evaluate(): lack of memory" );
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "Evaluate(): catch exception "<< S_ex.what() );
+ }
+ catch ( ... ) {
+ INFOS( "Evaluate(): unknown exception " );
+ }
+
+ return nbels._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Return geometrical object the given element is built on
+ * \param theMesh - the mesh the element is in
+ * \param theElementID - the element ID
+ * \param theGeomName - the name of the result geom object if it is not yet published
+ * \retval GEOM::GEOM_Object_ptr - the found or just published geom object
+ */
+//================================================================================
+
+GEOM::GEOM_Object_ptr
+SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh,
+ CORBA::Long theElementID,
+ const char* theGeomName)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+
+ GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID);
+ if ( !geom->_is_nil() ) {
+ GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
+ GEOM::GEOM_Gen_ptr geomGen = GetGeomEngine();
+
+ // try to find the corresponding SObject
+ SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() );
+ if ( SObj->_is_nil() ) // submesh can be not found even if published
+ {
+ // try to find published submesh
+ GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
+ if ( !geom->IsMainShape() && list->length() == 1 ) {
+ SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
+ SALOMEDS::ChildIterator_var it;
+ if ( !mainSO->_is_nil() )
+ it = myCurrentStudy->NewChildIterator( mainSO );
+ if ( !it->_is_nil() ) {
+ for ( it->InitEx(true); SObj->_is_nil() && it->More(); it->Next() ) {
+ GEOM::GEOM_Object_var subGeom =
+ GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() ));
+ if ( !subGeom->_is_nil() ) {
+ GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices();
+ if ( subList->length() == 1 && list[0] == subList[0] ) {
+ SObj = it->Value();
+ geom = subGeom;
+ }
+ }
+ }
+ }
+ }
+ }
+ if ( SObj->_is_nil() ) // publish a new subshape
+ SObj = geomGen->AddInStudy( myCurrentStudy, geom, theGeomName, mainShape );
+
+ // return only published geometry
+ if ( !SObj->_is_nil() )
+ return geom._retn();
+ }
+ return GEOM::GEOM_Object::_nil();
+}
+
+//================================================================================
+/*!
+ * \brief Return geometrical object the given element is built on.
+ * \param theMesh - the mesh the element is in
+ * \param theElementID - the element ID
+ * \retval GEOM::GEOM_Object_ptr - the found geom object
+ */
+//================================================================================
+
+GEOM::GEOM_Object_ptr
+SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh,
+ CORBA::Long theElementID)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", SALOME::BAD_PARAM );
+
+ GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
+ GEOM::GEOM_Gen_ptr geomGen = GetGeomEngine();
+
+ // get a core mesh DS
+ SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
+ if ( meshServant && !geomGen->_is_nil() && !mainShape->_is_nil() )
+ {
+ ::SMESH_Mesh & mesh = meshServant->GetImpl();
+ SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
+ // find the element in mesh
+ if ( const SMDS_MeshElement * elem = meshDS->FindElement( theElementID ) ) {
+ // find a shape id by the element
+ if ( int shapeID = ::SMESH_MeshEditor( &mesh ).FindShape( elem )) {
+ // get a geom object by the shape id
+ GEOM::GEOM_Object_var geom = ShapeToGeomObject( meshDS->IndexToShape( shapeID ));
+ if ( geom->_is_nil() ) {
+ // try to find a published sub-shape
+ SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
+ SALOMEDS::ChildIterator_var it;
+ if ( !mainSO->_is_nil() )
+ it = myCurrentStudy->NewChildIterator( mainSO );
+ if ( !it->_is_nil() ) {
+ for ( it->InitEx(true); it->More(); it->Next() ) {
+ GEOM::GEOM_Object_var subGeom =
+ GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() ));
+ if ( !subGeom->_is_nil() ) {
+ GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices();
+ if ( subList->length() == 1 && shapeID == subList[0] ) {
+ geom = subGeom;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if ( geom->_is_nil() ) {
+ // explode
+ GEOM::GEOM_IShapesOperations_var op =
+ geomGen->GetIShapesOperations( GetCurrentStudyID() );
+ if ( !op->_is_nil() )
+ geom = op->GetSubShape( mainShape, shapeID );
+ }
+ if ( !geom->_is_nil() ) {
+ GeomObjectToShape( geom ); // let geom client remember the found shape
+ return geom._retn();
+ }
+ }
+ }
+ }
+ return GEOM::GEOM_Object::_nil();
+}
+
+//================================================================================
+/*!
+ * SMESH_Gen_i::Concatenate
+ *
+ * Concatenate the given meshes into one mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray,
+ CORBA::Boolean theUniteIdenticalGroups,
+ CORBA::Boolean theMergeNodesAndElements,
+ CORBA::Double theMergeTolerance)
+ throw ( SALOME::SALOME_Exception )
+{
+ return ConcatenateCommon(theMeshesArray,
+ theUniteIdenticalGroups,
+ theMergeNodesAndElements,
+ theMergeTolerance,
+ false);
+}
+
+//================================================================================
+/*!
+ * SMESH_Gen_i::ConcatenateWithGroups
+ *
+ * Concatenate the given meshes into one mesh
+ * Create the groups of all elements from initial meshes
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr
+SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
+ CORBA::Boolean theUniteIdenticalGroups,
+ CORBA::Boolean theMergeNodesAndElements,
+ CORBA::Double theMergeTolerance)
+ throw ( SALOME::SALOME_Exception )
+{
+ return ConcatenateCommon(theMeshesArray,
+ theUniteIdenticalGroups,
+ theMergeNodesAndElements,
+ theMergeTolerance,
+ true);
+}
+
+//================================================================================
+/*!
+ * SMESH_Gen_i::ConcatenateCommon
+ *
+ * Concatenate the given meshes into one mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr
+SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
+ CORBA::Boolean theUniteIdenticalGroups,
+ CORBA::Boolean theMergeNodesAndElements,
+ CORBA::Double theMergeTolerance,
+ CORBA::Boolean theCommonGroups)
+ throw ( SALOME::SALOME_Exception )
+{
+ typedef map<int, int> TIDsMap;
+ typedef list<SMESH::SMESH_Group_var> TListOfNewGroups;
+ typedef map< pair<string, SMESH::ElementType>, TListOfNewGroups > TGroupsMap;
+ typedef std::set<SMESHDS_GroupBase*> TGroups;
+
+ TPythonDump* pPythonDump = new TPythonDump;
+ TPythonDump& aPythonDump = *pPythonDump; // prevent dump of called methods
+
+ // create mesh
+ SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh();
+
+ SMESHDS_Mesh* aNewMeshDS = 0;
+ if ( !aNewMesh->_is_nil() ) {
+ SMESH_Mesh_i* aNewImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( aNewMesh ).in() );
+ if ( aNewImpl ) {
+ ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl();
+ aNewMeshDS = aLocMesh.GetMeshDS();
+
+ TGroupsMap aGroupsMap;
+ TListOfNewGroups aListOfNewGroups;
+ SMESH_MeshEditor aNewEditor = ::SMESH_MeshEditor(&aLocMesh);
+ SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
+
+ // loop on meshes
+ for ( int i = 0; i < theMeshesArray.length(); i++) {
+ SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i];
+ if ( !anInitMesh->_is_nil() ) {
+ SMESH_Mesh_i* anInitImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( anInitMesh ).in() );
+ if ( anInitImpl ) {
+ ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
+ SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
+
+ TIDsMap nodesMap;
+ TIDsMap elemsMap;
+
+ // loop on elements of mesh
+ SMDS_ElemIteratorPtr itElems = anInitMeshDS->elementsIterator();
+ const SMDS_MeshElement* anElem = 0;
+ const SMDS_MeshElement* aNewElem = 0;
+ int anElemNbNodes = 0;
+
+ int anNbNodes = 0;
+ int anNbEdges = 0;
+ int anNbFaces = 0;
+ int anNbVolumes = 0;
+
+ SMESH::long_array_var anIDsNodes = new SMESH::long_array();
+ SMESH::long_array_var anIDsEdges = new SMESH::long_array();
+ SMESH::long_array_var anIDsFaces = new SMESH::long_array();
+ SMESH::long_array_var anIDsVolumes = new SMESH::long_array();
+
+ if( theCommonGroups ) {
+ anIDsNodes->length( anInitMeshDS->NbNodes() );
+ anIDsEdges->length( anInitMeshDS->NbEdges() );
+ anIDsFaces->length( anInitMeshDS->NbFaces() );
+ anIDsVolumes->length( anInitMeshDS->NbVolumes() );
+ }
+
+ for ( int j = 0; itElems->more(); j++) {
+ anElem = itElems->next();
+ SMDSAbs_ElementType anElemType = anElem->GetType();
+ anElemNbNodes = anElem->NbNodes();
+ std::vector<const SMDS_MeshNode*> aNodesArray (anElemNbNodes);
+
+ // loop on nodes of element
+ const SMDS_MeshNode* aNode = 0;
+ const SMDS_MeshNode* aNewNode = 0;
+ SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator();
+
+ for ( int k = 0; itNodes->more(); k++) {
+ aNode = static_cast<const SMDS_MeshNode*>(itNodes->next());
+ if ( nodesMap.find(aNode->GetID()) == nodesMap.end() ) {
+ aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+ nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
+ if( theCommonGroups )
+ anIDsNodes[anNbNodes++] = aNewNode->GetID();
+ }
+ else
+ aNewNode = aNewMeshDS->FindNode( nodesMap.find(aNode->GetID())->second );
+ aNodesArray[k] = aNewNode;
+ }//nodes loop
+
+ // creates a corresponding element on existent nodes in new mesh
+ if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume )
+ {
+ const SMDS_VtkVolume* aVolume =
+ dynamic_cast<const SMDS_VtkVolume*> (anElem);
+ if ( aVolume ) {
+ aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray,
+ aVolume->GetQuantities());
+ elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+ if( theCommonGroups )
+ anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
+ }
+ }
+ else {
+
+ aNewElem = aNewEditor.AddElement(aNodesArray,
+ anElemType,
+ anElem->IsPoly());
+ elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+ if( theCommonGroups ) {
+ if( anElemType == SMDSAbs_Edge )
+ anIDsEdges[anNbEdges++] = aNewElem->GetID();
+ else if( anElemType == SMDSAbs_Face )
+ anIDsFaces[anNbFaces++] = aNewElem->GetID();
+ else if( anElemType == SMDSAbs_Volume )
+ anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
+ }
+ }
+ }//elems loop
+
+ // copy orphan nodes
+ SMDS_NodeIteratorPtr itNodes = anInitMeshDS->nodesIterator();
+ while ( itNodes->more() )
+ {
+ const SMDS_MeshNode* aNode = itNodes->next();
+ if ( aNode->NbInverseElements() == 0 )
+ {
+ const SMDS_MeshNode* aNewNode =
+ aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+ nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
+ if( theCommonGroups )
+ anIDsNodes[anNbNodes++] = aNewNode->GetID();
+ }
+ }
+
+
+ aListOfGroups = anInitImpl->GetGroups();
+ SMESH::SMESH_GroupBase_ptr aGroup;
+
+ // loop on groups of mesh
+ SMESH::long_array_var anInitIDs = new SMESH::long_array();
+ SMESH::long_array_var anNewIDs = new SMESH::long_array();
+ SMESH::SMESH_Group_var aNewGroup;
+
+ SMESH::ElementType aGroupType;
+ CORBA::String_var aGroupName;
+ if ( theCommonGroups ) {
+ for(aGroupType=SMESH::NODE;aGroupType<=SMESH::VOLUME;aGroupType=(SMESH::ElementType)(aGroupType+1)) {
+ string str = "Gr";
+ SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh );
+ if(aMeshSObj)
+ str += aMeshSObj->GetName();
+ str += "_";
+
+ int anLen = 0;
+
+ switch(aGroupType) {
+ case SMESH::NODE:
+ str += "Nodes";
+ anIDsNodes->length(anNbNodes);
+ anLen = anNbNodes;
+ break;
+ case SMESH::EDGE:
+ str += "Edges";
+ anIDsEdges->length(anNbEdges);
+ anLen = anNbEdges;
+ break;
+ case SMESH::FACE:
+ str += "Faces";
+ anIDsFaces->length(anNbFaces);
+ anLen = anNbFaces;
+ break;
+ case SMESH::VOLUME:
+ str += "Volumes";
+ anIDsVolumes->length(anNbVolumes);
+ anLen = anNbVolumes;
+ break;
+ default:
+ break;
+ }
+
+ if(anLen) {
+ aGroupName = str.c_str();
+
+ // add a new group in the mesh
+ aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+
+ switch(aGroupType) {
+ case SMESH::NODE:
+ aNewGroup->Add( anIDsNodes );
+ break;
+ case SMESH::EDGE:
+ aNewGroup->Add( anIDsEdges );
+ break;
+ case SMESH::FACE:
+ aNewGroup->Add( anIDsFaces );
+ break;
+ case SMESH::VOLUME:
+ aNewGroup->Add( anIDsVolumes );
+ break;
+ default:
+ break;
+ }
+
+ aListOfNewGroups.clear();
+ aListOfNewGroups.push_back(aNewGroup);
+ aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
+ }
+ }
+ }
+
+ // check that current group name and type don't have identical ones in union mesh
+ for (int i = 0; i < aListOfGroups->length(); i++) {
+ aGroup = aListOfGroups[i];
+ aListOfNewGroups.clear();
+ aGroupType = aGroup->GetType();
+ aGroupName = aGroup->GetName();
+
+ TGroupsMap::iterator anIter = aGroupsMap.find(make_pair(aGroupName, aGroupType));
+
+ // convert a list of IDs
+ anInitIDs = aGroup->GetListOfID();
+ anNewIDs->length(anInitIDs->length());
+ if ( aGroupType == SMESH::NODE )
+ for (int j = 0; j < anInitIDs->length(); j++) {
+ anNewIDs[j] = nodesMap.find(anInitIDs[j])->second;
+ }
+ else
+ for (int j = 0; j < anInitIDs->length(); j++) {
+ anNewIDs[j] = elemsMap.find(anInitIDs[j])->second;
+ }
+
+ // check that current group name and type don't have identical ones in union mesh
+ if ( anIter == aGroupsMap.end() ) {
+ // add a new group in the mesh
+ aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+ // add elements into new group
+ aNewGroup->Add( anNewIDs );
+
+ aListOfNewGroups.push_back(aNewGroup);
+ aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
+ }
+
+ else if ( theUniteIdenticalGroups ) {
+ // unite identical groups
+ TListOfNewGroups& aNewGroups = anIter->second;
+ aNewGroups.front()->Add( anNewIDs );
+ }
+
+ else {
+ // rename identical groups
+ aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+ aNewGroup->Add( anNewIDs );
+
+ TListOfNewGroups& aNewGroups = anIter->second;
+ string aNewGroupName;
+ if (aNewGroups.size() == 1) {
+ aNewGroupName = string(aGroupName) + "_1";
+ aNewGroups.front()->SetName(aNewGroupName.c_str());
+ }
+ char aGroupNum[128];
+ sprintf(aGroupNum, "%u", aNewGroups.size()+1);
+ aNewGroupName = string(aGroupName) + "_" + string(aGroupNum);
+ aNewGroup->SetName(aNewGroupName.c_str());
+ aNewGroups.push_back(aNewGroup);
+ }
+ }//groups loop
+ }
+ }
+ }//meshes loop
+
+ if (theMergeNodesAndElements) {
+ // merge nodes
+ TIDSortedNodeSet aMeshNodes; // no input nodes
+ SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
+ aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes );
+ aNewEditor.MergeNodes( aGroupsOfNodes );
+ // merge elements
+ aNewEditor.MergeEqualElements();
+ }
+ }
+ }
+
+ // Update Python script
+ aPythonDump << aNewMesh << " = " << this;
+ if( !theCommonGroups )
+ aPythonDump << ".Concatenate(";
+ else
+ aPythonDump << ".ConcatenateWithGroups(";
+ aPythonDump << "[";
+ for ( int i = 0; i < theMeshesArray.length(); i++) {
+ if (i > 0) aPythonDump << ", ";
+ aPythonDump << theMeshesArray[i];
+ }
+ aPythonDump << "], ";
+ aPythonDump << theUniteIdenticalGroups << ", "
+ << theMergeNodesAndElements << ", "
+ << theMergeTolerance << ")";
+
+ delete pPythonDump; // enable python dump from GetGroups()
+
+ // 0020577: EDF 1164 SMESH: Bad dump of concatenate with create common groups
+ if ( !aNewMesh->_is_nil() )
+ {
+ SMESH::ListOfGroups_var groups = aNewMesh->GetGroups();
+ }
+
+ // IPAL21468 Change icon of compound because it need not be computed.
+ SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, aNewMesh );
+ if( !aMeshSObj->_is_nil() ) {
+ SALOMEDS::GenericAttribute_var anAttr;
+ SALOMEDS::StudyBuilder_var aBuilder = myCurrentStudy->NewBuilder();
+ anAttr = aBuilder->FindOrCreateAttribute( aMeshSObj,"AttributePixMap" );
+ SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
+ aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
+ }
+ if (aNewMeshDS)
+ aNewMeshDS->Modified();
+ return aNewMesh._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Create a mesh by copying a part of another mesh
+ * \param meshPart - a part of mesh to copy
+ * \param toCopyGroups - to create in the new mesh groups
+ * the copied elements belongs to
+ * \param toKeepIDs - to preserve IDs of the copied elements or not
+ * \retval SMESH::SMESH_Mesh_ptr - the new mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
+ const char* meshName,
+ CORBA::Boolean toCopyGroups,
+ CORBA::Boolean toKeepIDs)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+
+ TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh()
+
+ // 1. Get source mesh
+
+ if ( CORBA::is_nil( meshPart ))
+ THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM );
+
+ SMESH::SMESH_Mesh_var srcMesh = meshPart->GetMesh();
+ SMESH_Mesh_i* srcMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( srcMesh );
+ if ( !srcMesh_i )
+ THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM );
+
+ SMESHDS_Mesh* srcMeshDS = srcMesh_i->GetImpl().GetMeshDS();
+
+ // 2. Make a new mesh
+
+ SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil());
+ SMESH_Mesh_i* newMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
+ if ( !newMesh_i )
+ THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR );
+ SALOMEDS::SObject_var meshSO = ObjectToSObject(myCurrentStudy, newMesh );
+ if ( !meshSO->_is_nil() )
+ {
+ SetName( meshSO, meshName, "Mesh" );
+ SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
+ }
+ SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
+ ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
+
+ // 3. Get elements to copy
+
+ SMDS_ElemIteratorPtr srcElemIt;
+ TIDSortedElemSet srcElems;
+ SMESH::array_of_ElementType_var srcElemTypes = meshPart->GetTypes();
+ if ( SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
+ {
+ srcElemIt = srcMeshDS->elementsIterator();
+ }
+ else
+ {
+ SMESH::long_array_var ids = meshPart->GetIDs();
+ if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes
+ {
+ for (int i=0; i < ids->length(); i++)
+ if ( const SMDS_MeshElement * elem = srcMeshDS->FindNode( ids[i] ))
+ srcElems.insert( elem );
+ }
+ else
+ {
+ for (int i=0; i < ids->length(); i++)
+ if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] ))
+ srcElems.insert( elem );
+ }
+ if ( srcElems.empty() )
+ return newMesh._retn();
+
+ typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator > ElIter;
+ srcElemIt = SMDS_ElemIteratorPtr( new ElIter( srcElems.begin(), srcElems.end() ));
+ }
+
+ // 4. Copy elements
+
+ typedef map<SMDS_pElement, SMDS_pElement, TIDCompare> TE2EMap;
+ TE2EMap e2eMapByType[ SMDSAbs_NbElementTypes ];
+ TE2EMap& n2nMap = e2eMapByType[ SMDSAbs_Node ];
+ int iN;
+ const SMDS_MeshNode *nSrc, *nTgt;
+ vector< const SMDS_MeshNode* > nodes;
+ while ( srcElemIt->more() )
+ {
+ const SMDS_MeshElement * elem = srcElemIt->next();
+ nodes.resize( elem->NbNodes());
+ SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+ if ( toKeepIDs ) {
+ for ( iN = 0; nIt->more(); ++iN )
+ {
+ nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ nTgt = newMeshDS->FindNode( nSrc->GetID());
+ if ( !nTgt )
+ nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID());
+ nodes[ iN ] = nTgt;
+ }
+ }
+ else {
+ for ( iN = 0; nIt->more(); ++iN )
+ {
+ nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ TE2EMap::iterator n2n = n2nMap.insert( make_pair( nSrc, SMDS_pNode(0) )).first;
+ if ( !n2n->second )
+ n2n->second = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() );
+ nodes[ iN ] = (const SMDS_MeshNode*) n2n->second;
+ }
+ }
+ if ( elem->GetType() != SMDSAbs_Node )
+ {
+ int ID = toKeepIDs ? elem->GetID() : 0;
+ const SMDS_MeshElement * newElem = editor.AddElement( nodes,
+ elem->GetType(),
+ elem->IsPoly(),
+ ID);
+ if ( toCopyGroups && !toKeepIDs )
+ e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
+ }
+ }
+
+ // 5. Copy groups
+
+ int nbNewGroups = 0;
+ if ( toCopyGroups )
+ {
+ SMESH_Mesh::GroupIteratorPtr gIt = srcMesh_i->GetImpl().GetGroups();
+ while ( gIt->more() )
+ {
+ SMESH_Group* group = gIt->next();
+ const SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+
+ // Check group type. We copy nodal groups containing nodes of copied element
+ SMDSAbs_ElementType groupType = groupDS->GetType();
+ if ( groupType != SMDSAbs_Node &&
+ newMeshDS->GetMeshInfo().NbElements( groupType ) == 0 )
+ continue; // group type differs from types of meshPart
+
+ // Find copied elements in the group
+ vector< const SMDS_MeshElement* > groupElems;
+ SMDS_ElemIteratorPtr eIt = groupDS->GetElements();
+ if ( toKeepIDs )
+ {
+ const SMDS_MeshElement* foundElem;
+ if ( groupType == SMDSAbs_Node )
+ {
+ while ( eIt->more() )
+ if (( foundElem = newMeshDS->FindNode( eIt->next()->GetID() )))
+ groupElems.push_back( foundElem );
+ }
+ else
+ {
+ while ( eIt->more() )
+ if (( foundElem = newMeshDS->FindElement( eIt->next()->GetID() )))
+ groupElems.push_back( foundElem );
+ }
+ }
+ else
+ {
+ TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ];
+ if ( e2eMap.empty() ) continue;
+ int minID = e2eMap.begin()->first->GetID();
+ int maxID = e2eMap.rbegin()->first->GetID();
+ TE2EMap::iterator e2e;
+ while ( eIt->more() && groupElems.size() < e2eMap.size())
+ {
+ const SMDS_MeshElement* e = eIt->next();
+ if ( e->GetID() < minID || e->GetID() > maxID ) continue;
+ if ((e2e = e2eMap.find( e )) != e2eMap.end())
+ groupElems.push_back( e2e->second );
+ }
+ }
+ // Make a new group
+ if ( !groupElems.empty() )
+ {
+ SMESH::SMESH_Group_var newGroupObj =
+ newMesh->CreateGroup( SMESH::ElementType(groupType), group->GetName() );
+ if ( SMESH_GroupBase_i* newGroup_i = SMESH::DownCast<SMESH_GroupBase_i*>( newGroupObj))
+ {
+ SMESHDS_GroupBase * newGroupDS = newGroup_i->GetGroupDS();
+ SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup();
+ for ( unsigned i = 0; i < groupElems.size(); ++i )
+ smdsGroup.Add( groupElems[i] );
+
+ nbNewGroups++;
+ }
+ }
+ }
+ }
+
+ newMeshDS->Modified();
+
+ *pyDump << newMesh << " = " << this
+ << ".CopyMesh( " << meshPart << ", "
+ << "'" << meshName << "', "
+ << toCopyGroups << ", "
+ << toKeepIDs << ")";
+
+ delete pyDump; pyDump = 0; // allow dump in GetGroups()
+
+ if ( nbNewGroups > 0 ) // dump created groups
+ SMESH::ListOfGroups_var groups = newMesh->GetGroups();
+
+ return newMesh._retn();
+}
+
+//================================================================================
+/*!
+ * SMESH_Gen_i::GetMEDVersion
+ *
+ * Get MED version of the file by its name
+ */
+//================================================================================
+CORBA::Boolean SMESH_Gen_i::GetMEDVersion(const char* theFileName,
+ SMESH::MED_VERSION& theVersion)
+{
+ theVersion = SMESH::MED_V2_1;
+ MED::EVersion aVersion = MED::GetVersionId( theFileName );
+ switch( aVersion ) {
+ case MED::eV2_1 : theVersion = SMESH::MED_V2_1; return true;
+ case MED::eV2_2 : theVersion = SMESH::MED_V2_2; return true;
+ case MED::eVUnknown : return false;
+ }
+ return false;
+}
+
+//================================================================================
+/*!
+ * SMESH_Gen_i::GetMeshNames
+ *
+ * Get names of meshes defined in file with the specified name
+ */
+//================================================================================
+SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName)
+{
+ SMESH::string_array_var aResult = new SMESH::string_array();
+ MED::PWrapper aMed = MED::CrWrapper( theFileName );
+ MED::TErr anErr;
+ MED::TInt aNbMeshes = aMed->GetNbMeshes( &anErr );
+ if( anErr >= 0 ) {
+ aResult->length( aNbMeshes );
+ for( MED::TInt i = 0; i < aNbMeshes; i++ ) {
+ MED::PMeshInfo aMeshInfo = aMed->GetPMeshInfo( i+1 );
+ aResult[i] = CORBA::string_dup( aMeshInfo->GetName().c_str() );
+ }
+ }
+ return aResult._retn();
+}
+