X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=8ae8331ab9fa9a693e4d1fe004eba648a726acd6;hp=e8756102484c9a0be90835252e8074d3c47ac1a8;hb=3ec0f6d7525fde8284aa1e0381022b64fa98aea3;hpb=9a54694a0ab1e5cbc558a35c4606ceea4f7af2ef diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index e87561024..8ae8331ab 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 @@ -6065,7 +6065,26 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens, if ( resElem != sourceElem ) resultElems.push_back( resElem ); - // add resultElems to groups made by ones the sourceElem belongs to + // there must be a top element + const SMDS_MeshElement* topElem = 0; + if ( isNodes ) + { + topElem = resultElems.back(); + resultElems.pop_back(); + } + else + { + list< const SMDS_MeshElement* >::reverse_iterator resElemIt = resultElems.rbegin(); + for ( ; resElemIt != resultElems.rend() ; ++resElemIt ) + if ( (*resElemIt)->GetType() == sourceElem->GetType() ) + { + topElem = *resElemIt; + resultElems.erase( --(resElemIt.base()) ); // erase *resElemIt + break; + } + } + + // add resultElems to groups originted from ones the sourceElem belongs to list< TOldNewGroup >::iterator gOldNew, gLast = groupsOldNew.end(); for ( gOldNew = groupsOldNew.begin(); gOldNew != gLast; ++gOldNew ) { @@ -6074,19 +6093,15 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens, { // fill in a new group SMDS_MeshGroup & newGroup = gOldNew->get<1>()->SMDSGroup(); - list< const SMDS_MeshElement* > rejectedElems; // elements of other type list< const SMDS_MeshElement* >::iterator resLast = resultElems.end(), resElemIt; for ( resElemIt = resultElems.begin(); resElemIt != resLast; ++resElemIt ) - if ( !newGroup.Add( *resElemIt )) - rejectedElems.push_back( *resElemIt ); + newGroup.Add( *resElemIt ); - // fill "top" group - if ( !rejectedElems.empty() ) + // fill a "top" group + if ( topElem ) { SMDS_MeshGroup & newTopGroup = gOldNew->get<2>()->SMDSGroup(); - resLast = rejectedElems.end(); - for ( resElemIt = rejectedElems.begin(); resElemIt != resLast; ++resElemIt ) - !newTopGroup.Add( *resElemIt ); + newTopGroup.Add( topElem ); } } } @@ -6116,7 +6131,9 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens, // make a name const bool isTop = ( nbNewGroups == 2 && - newGroupDS->GetType() == oldGroupDS->GetType() ); + newGroupDS->GetType() == oldGroupDS->GetType() && + is2nd ); + string name = oldGroupDS->GetStoreName(); if ( !targetMesh ) { string suffix = ( isTop ? "top": postfix.c_str() ); @@ -7656,6 +7673,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) //MESSAGE(" node to remove " << nToRemove->GetID()); rmNodeIds.push_back( nToRemove->GetID() ); AddToSameGroups( nToKeep, nToRemove, aMesh ); + // set _alwaysComputed to a sub-mesh of VERTEX to enable mesh computing + // after MergeNodes() w/o creating node in place of merged ones. + const SMDS_PositionPtr& pos = nToRemove->GetPosition(); + if ( pos && pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + if ( SMESH_subMesh* sm = myMesh->GetSubMeshContaining( nToRemove->getshapeId() )) + sm->SetIsAlwaysComputed( true ); } SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); @@ -9587,14 +9610,26 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, { nbElem++; const SMDS_MeshElement* elem = ElemItr->next(); - if( !elem || elem->IsQuadratic() ) continue; + if( !elem ) continue; + const SMDSAbs_EntityType aGeomType = elem->GetEntityType(); + if ( elem->IsQuadratic() ) + { + bool alreadyOK; + switch ( aGeomType ) { + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_Quad_Hexa: alreadyOK = !theHelper.GetIsBiQuadratic(); break; + case SMDSEntity_BiQuad_Quadrangle: + case SMDSEntity_TriQuad_Hexa: alreadyOK = theHelper.GetIsBiQuadratic(); break; + default: alreadyOK = true; + } + if ( alreadyOK ) continue; + } // get elem data needed to re-create it // - const int id = elem->GetID(); - const int nbNodes = elem->NbNodes(); - const SMDSAbs_ElementType aType = elem->GetType(); - const SMDSAbs_EntityType aGeomType = elem->GetEntityType(); + const int id = elem->GetID(); + const int nbNodes = elem->NbCornerNodes(); + const SMDSAbs_ElementType aType = elem->GetType(); nodes.assign(elem->begin_nodes(), elem->end_nodes()); if ( aGeomType == SMDSEntity_Polyhedra ) nbNodeInFaces = static_cast( elem )->GetQuantities(); @@ -9643,6 +9678,8 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d); break; case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d); break; @@ -9661,18 +9698,20 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, } return nbElem; } - //======================================================================= //function : ConvertToQuadratic //purpose : //======================================================================= -void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) +void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theToBiQuad) { SMESHDS_Mesh* meshDS = GetMeshDS(); SMESH_MesherHelper aHelper(*myMesh); + aHelper.SetIsQuadratic( true ); + aHelper.SetIsBiQuadratic( theToBiQuad ); + aHelper.SetElementsOnShape(true); int nbCheckedElems = 0; if ( myMesh->HasShapeToMesh() ) @@ -9692,6 +9731,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) int totalNbElems = meshDS->NbEdges() + meshDS->NbFaces() + meshDS->NbVolumes(); if ( nbCheckedElems < totalNbElems ) // not all elements are in submeshes { + aHelper.SetElementsOnShape(false); SMESHDS_SubMesh *smDS = 0; SMDS_EdgeIteratorPtr aEdgeItr = meshDS->edgesIterator(); while(aEdgeItr->more()) @@ -9714,10 +9754,14 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) while(aFaceItr->more()) { const SMDS_MeshFace* face = aFaceItr->next(); - if(!face || face->IsQuadratic() ) continue; + if ( !face ) continue; + + const SMDSAbs_EntityType type = face->GetEntityType(); + if (( theToBiQuad && type == SMDSEntity_BiQuad_Quadrangle ) || + ( !theToBiQuad && type == SMDSEntity_Quad_Quadrangle )) + continue; const int id = face->GetID(); - const SMDSAbs_EntityType type = face->GetEntityType(); vector nodes ( face->begin_nodes(), face->end_nodes()); meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false); @@ -9743,8 +9787,12 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) const SMDS_MeshVolume* volume = aVolumeItr->next(); if(!volume || volume->IsQuadratic() ) continue; - const int id = volume->GetID(); const SMDSAbs_EntityType type = volume->GetEntityType(); + if (( theToBiQuad && type == SMDSEntity_TriQuad_Hexa ) || + ( !theToBiQuad && type == SMDSEntity_Quad_Hexa )) + continue; + + const int id = volume->GetID(); vector nodes (volume->begin_nodes(), volume->end_nodes()); if ( type == SMDSEntity_Polyhedra ) nbNodeInFaces = static_cast(volume)->GetQuantities(); @@ -9760,6 +9808,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d ); break; case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d); break; @@ -9795,7 +9845,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) //================================================================================ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, - TIDSortedElemSet& theElements) + TIDSortedElemSet& theElements, + const bool theToBiQuad) { if ( theElements.empty() ) return; @@ -9822,8 +9873,19 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const SMDS_MeshElement* e = invIt->next(); if ( e->IsQuadratic() ) { - quadAdjacentElems[ e->GetType() ].insert( e ); - continue; + bool alreadyOK; + switch ( e->GetEntityType() ) { + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_Quad_Hexa: alreadyOK = !theToBiQuad; break; + case SMDSEntity_BiQuad_Quadrangle: + case SMDSEntity_TriQuad_Hexa: alreadyOK = theToBiQuad; break; + default: alreadyOK = true; + } + if ( alreadyOK ) + { + quadAdjacentElems[ e->GetType() ].insert( e ); + continue; + } } if ( e->GetType() >= elemType ) { @@ -9845,6 +9907,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, SMESH_MesherHelper helper(*myMesh); helper.SetIsQuadratic( true ); + helper.SetIsBiQuadratic( theToBiQuad ); // add links of quadratic adjacent elements to the helper @@ -9867,18 +9930,32 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, helper.AddTLinks( static_cast< const SMDS_MeshVolume*> (*eIt) ); } - // make quadratic elements instead of linear ones + // make quadratic (or bi-tri-quadratic) elements instead of linear ones - SMESHDS_Mesh* meshDS = GetMeshDS(); + SMESHDS_Mesh* meshDS = GetMeshDS(); SMESHDS_SubMesh* smDS = 0; for ( eIt = theElements.begin(); eIt != theElements.end(); ++eIt ) { const SMDS_MeshElement* elem = *eIt; - if( elem->IsQuadratic() || elem->NbNodes() < 2 || elem->IsPoly() ) + if( elem->NbNodes() < 2 || elem->IsPoly() ) continue; - const int id = elem->GetID(); + if ( elem->IsQuadratic() ) + { + bool alreadyOK; + switch ( elem->GetEntityType() ) { + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_Quad_Hexa: alreadyOK = !theToBiQuad; break; + case SMDSEntity_BiQuad_Quadrangle: + case SMDSEntity_TriQuad_Hexa: alreadyOK = theToBiQuad; break; + default: alreadyOK = true; + } + if ( alreadyOK ) continue; + } + const SMDSAbs_ElementType type = elem->GetType(); + const int id = elem->GetID(); + const int nbNodes = elem->NbCornerNodes(); vector nodes ( elem->begin_nodes(), elem->end_nodes()); if ( !smDS || !smDS->Contains( elem )) @@ -9886,7 +9963,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, meshDS->RemoveFreeElement(elem, smDS, /*fromGroups=*/false); SMDS_MeshElement * newElem = 0; - switch( nodes.size() ) + switch( nbNodes ) { case 4: // cases for most frequently used element types go first (for optimization) if ( type == SMDSAbs_Volume ) @@ -11191,11 +11268,14 @@ double SMESH_MeshEditor::OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const /*! * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. - * The list of groups must describe a partition of the mesh volumes. - * The nodes of the internal faces at the boundaries of the groups are doubled. - * In option, the internal faces are replaced by flat elements. - * Triangles are transformed in prisms, and quadrangles in hexahedrons. - * The flat elements are stored in groups of volumes. + * The list of groups must contain at least two groups. The groups have to be disjoint: no common element into two different groups. + * The nodes of the internal faces at the boundaries of the groups are doubled. Optionally, the internal faces are replaced by flat elements. + * Triangles are transformed into prisms, and quadrangles into hexahedrons. + * The flat elements are stored in groups of volumes. These groups are named according to the position of the group in the list: + * the group j_n_p is the group of the flat elements that are built between the group #n and the group #p in the list. + * If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created. + * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation). + * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples". * @param theElems - list of groups of volumes, where a group of volume is a set of * SMDS_MeshElements sorted by Id. * @param createJointElems - if TRUE, create the elements @@ -11229,6 +11309,32 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector emptySet; emptyMap.clear(); + MESSAGE(".. Number of domains :"<FindElement(smdsId); if (! domain.count(elem)) // neighbor is in another domain : face is shared { - DownIdType face(downIds[n], downTypes[n]); - if (!faceDomains.count(face)) - faceDomains[face] = emptyMap; // create an empty entry for face - if (!faceDomains[face].count(idom)) - { - faceDomains[face][idom] = vtkId; // volume associated to face in this domain - celldom[vtkId] = idom; - //MESSAGE(" cell with a border " << vtkId << " domain " << idom); - } + bool ok = false ; + for (int idombis = 0; idombis < theElems.size(); idombis++) // check if the neighbor belongs to another domain of the list + { + // MESSAGE("Domain " << idombis); + const TIDSortedElemSet& domainbis = theElems[idombis]; + if ( domainbis.count(elem)) ok = true ; // neighbor is in a correct domain : face is kept + } + if ( ok ) // the characteristics of the face is stored + { + DownIdType face(downIds[n], downTypes[n]); + if (!faceDomains.count(face)) + faceDomains[face] = emptyMap; // create an empty entry for face + if (!faceDomains[face].count(idom)) + { + faceDomains[face][idom] = vtkId; // volume associated to face in this domain + celldom[vtkId] = idom; + //MESSAGE(" cell with a border " << vtkId << " domain " << idom); + } + } } } } @@ -11336,6 +11452,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector > mutipleNodes; // nodes multi domains with domain order std::map > mutipleNodesToFace; // nodes multi domains with domain order to transform in Face (junction between 3 or more 2D domains) + MESSAGE(".. Duplication of the nodes"); for (int idomain = 0; idomain < theElems.size(); idomain++) { itface = faceDomains.begin(); @@ -11398,6 +11515,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector > nodeQuadDomains; std::map mapOfJunctionGroups; + MESSAGE(".. Creation of elements: simple junction"); if (createJointElems) { int idg; @@ -11577,6 +11696,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector >::const_iterator itnod = nodeDomains.begin();