X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=55bd1be818f7adc0ca2cc1cf5ddaf3dc7b69c276;hb=bc5760bd4e1b0da9afd0777d0066c8012c816eaa;hp=db3d48077d56a5d71a5d1b9d286e4587a2cf623e;hpb=2c607013a23bd4e7ba07e72e0c04dee2c1209cff;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index db3d48077..55bd1be81 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -18,13 +18,12 @@ // 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 : idl implementation based on 'SMESH' unit's classes +// SMESH SMESH : idl implementation based on 'SMESH' unit's classes // File : SMESH_MeshEditor.cxx // Created : Mon Apr 12 16:10:22 2004 // Author : Edward AGAPOV (eap) -// + #define CHRONODEF #include "SMESH_MeshEditor.hxx" @@ -50,9 +49,12 @@ #include "SMESH_OctreeNode.hxx" #include "SMESH_subMesh.hxx" +#include + #include "utilities.h" #include +#include #include #include #include @@ -455,6 +457,25 @@ static void ShiftNodesQuadTria(const SMDS_MeshNode* aNodes[]) aNodes[5] = nd2; } +//======================================================================= +//function : edgeConnectivity +//purpose : auxilary +// return number of the edges connected with the theNode. +// if theEdges has connections with the other type of the +// elements, return -1 +//======================================================================= +static int nbEdgeConnectivity(const SMDS_MeshNode* theNode) +{ + SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator(); + int nb=0; + while(elemIt->more()) { + elemIt->next(); + nb++; + } + return nb; +} + + //======================================================================= //function : GetNodesFromTwoTria //purpose : auxilary @@ -1615,6 +1636,7 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, helper.SetIsQuadratic( false ); } vector nodes( (*elem)->begin_nodes(), (*elem)->end_nodes() ); + helper.SetElementsOnShape( true ); if ( splitMethod._baryNode ) { // make a node at barycenter @@ -1642,7 +1664,6 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, } // make tetras - helper.SetElementsOnShape( true ); vector tetras( splitMethod._nbTetra ); // splits of a volume const int* tetConn = splitMethod._connectivity; for ( int i = 0; i < splitMethod._nbTetra; ++i, tetConn += 4 ) @@ -1670,6 +1691,12 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, helper.SetElementsOnShape( false ); vector< const SMDS_MeshElement* > triangles; + // find submesh to add new triangles in + if ( !fSubMesh || !fSubMesh->Contains( face )) + { + int shapeID = FindShape( face ); + fSubMesh = GetMeshDS()->MeshElements( shapeID ); + } map::iterator iF_n = splitMethod._faceBaryNode.find(iF); if ( iF_n != splitMethod._faceBaryNode.end() ) { @@ -1681,6 +1708,9 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, if ( !volTool.IsFaceExternal( iF )) swap( n2, n3 ); triangles.push_back( helper.AddFace( n1,n2,n3 )); + + if ( fSubMesh && n3->getshapeId() < 1 ) + fSubMesh->AddNode( n3 ); } } else @@ -1719,12 +1749,6 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, volNodes[ facet->_n3 ])); } } - // find submesh to add new triangles in - if ( !fSubMesh || !fSubMesh->Contains( face )) - { - int shapeID = FindShape( face ); - fSubMesh = GetMeshDS()->MeshElements( shapeID ); - } for ( int i = 0; i < triangles.size(); ++i ) { if ( !triangles[i] ) continue; @@ -2826,8 +2850,13 @@ static bool getClosestUV (Extrema_GenExtPS& projector, if ( projector.IsDone() ) { double u, v, minVal = DBL_MAX; for ( int i = projector.NbExt(); i > 0; i-- ) +#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 + if ( projector.SquareDistance( i ) < minVal ) { + minVal = projector.SquareDistance( i ); +#else if ( projector.Value( i ) < minVal ) { minVal = projector.Value( i ); +#endif projector.Point( i ).Parameter( u, v ); } result.SetCoord( u, v ); @@ -3088,35 +3117,27 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, // fix nodes on mesh boundary if ( checkBoundaryNodes ) { - map< NLink, int > linkNbMap; // how many times a link encounters in elemsOnFace - map< NLink, int >::iterator link_nb; + map< SMESH_TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace + map< SMESH_TLink, int >::iterator link_nb; // put all elements links to linkNbMap list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { const SMDS_MeshElement* elem = (*elemIt); - int nbn = elem->NbNodes(); - if(elem->IsQuadratic()) - nbn = nbn/2; + int nbn = elem->NbCornerNodes(); // loop on elem links: insert them in linkNbMap - const SMDS_MeshNode* curNode, *prevNode = elem->GetNodeWrap( nbn ); for ( int iN = 0; iN < nbn; ++iN ) { - curNode = elem->GetNode( iN ); - NLink link; - if ( curNode < prevNode ) link = make_pair( curNode , prevNode ); - else link = make_pair( prevNode , curNode ); - prevNode = curNode; - link_nb = linkNbMap.find( link ); - if ( link_nb == linkNbMap.end() ) - linkNbMap.insert( make_pair ( link, 1 )); - else - link_nb->second++; + const SMDS_MeshNode* n1 = elem->GetNode( iN ); + const SMDS_MeshNode* n2 = elem->GetNode(( iN+1 ) % nbn); + SMESH_TLink link( n1, n2 ); + link_nb = linkNbMap.insert( make_pair( link, 0 )).first; + link_nb->second++; } } // remove nodes that are in links encountered only once from setMovableNodes for ( link_nb = linkNbMap.begin(); link_nb != linkNbMap.end(); ++link_nb ) { if ( link_nb->second == 1 ) { - setMovableNodes.erase( link_nb->first.first ); - setMovableNodes.erase( link_nb->first.second ); + setMovableNodes.erase( link_nb->first.node1() ); + setMovableNodes.erase( link_nb->first.node2() ); } } } @@ -4120,7 +4141,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, if ( f ) aMesh->ChangeElementNodes( f, &polygon_nodes[0], nbn ); else - myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes)); + AddElement(polygon_nodes, SMDSAbs_Face, polygon_nodes.size()>4); } } @@ -4686,8 +4707,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, } //Extrusion_Error err = MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList); - } - else if( aS.ShapeType() == TopAbs_WIRE ) { + } else if( aS.ShapeType() == TopAbs_WIRE ) { list< SMESH_subMesh* > LSM; TopTools_SequenceOfShape Edges; SMESH_subMeshIteratorPtr itSM = theTrack->getDependsOnIterator(false,true); @@ -4700,6 +4720,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, list< list > LLPPs; int startNid = theN1->GetID(); TColStd_MapOfInteger UsedNums; + int NbEdges = Edges.Length(); int i = 1; for(; i<=NbEdges; i++) { @@ -4833,8 +4854,127 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, list fullList; const TopoDS_Shape& aS = theTrack->GetShapeToMesh(); - // Sub shape for the Pattern must be an Edge or Wire - if( aS.ShapeType() == TopAbs_EDGE ) { + + if( aS == SMESH_Mesh::PseudoShape() ) { + //Mesh without shape + const SMDS_MeshNode* currentNode = NULL; + const SMDS_MeshNode* prevNode = theN1; + std::vector aNodesList; + aNodesList.push_back(theN1); + int nbEdges = 0, conn=0; + const SMDS_MeshElement* prevElem = NULL; + const SMDS_MeshElement* currentElem = NULL; + int totalNbEdges = theTrack->NbEdges(); + SMDS_ElemIteratorPtr nIt; + bool isClosed = false; + + //check start node + if( !theTrack->GetMeshDS()->Contains(theN1) ) { + return EXTR_BAD_STARTING_NODE; + } + + conn = nbEdgeConnectivity(theN1); + if(conn > 2) + return EXTR_PATH_NOT_EDGE; + + aItE = theN1->GetInverseElementIterator(); + prevElem = aItE->next(); + currentElem = prevElem; + //Get all nodes + if(totalNbEdges == 1 ) { + nIt = currentElem->nodesIterator(); + currentNode = static_cast(nIt->next()); + if(currentNode == prevNode) + currentNode = static_cast(nIt->next()); + aNodesList.push_back(currentNode); + } else { + nIt = currentElem->nodesIterator(); + while( nIt->more() ) { + currentNode = static_cast(nIt->next()); + if(currentNode == prevNode) + currentNode = static_cast(nIt->next()); + aNodesList.push_back(currentNode); + + //case of the closed mesh + if(currentNode == theN1) { + nbEdges++; + isClosed = true; + break; + } + + conn = nbEdgeConnectivity(currentNode); + if(conn > 2) { + return EXTR_PATH_NOT_EDGE; + }else if( conn == 1 && nbEdges > 0 ) { + //End of the path + nbEdges++; + break; + }else { + prevNode = currentNode; + aItE = currentNode->GetInverseElementIterator(); + currentElem = aItE->next(); + if( currentElem == prevElem) + currentElem = aItE->next(); + nIt = currentElem->nodesIterator(); + prevElem = currentElem; + nbEdges++; + } + } + } + + if(nbEdges != totalNbEdges) + return EXTR_PATH_NOT_EDGE; + + TopTools_SequenceOfShape Edges; + double x1,x2,y1,y2,z1,z2; + list< list > LLPPs; + int startNid = theN1->GetID(); + for(int i = 1; i < aNodesList.size(); i++) { + x1 = aNodesList[i-1]->X();x2 = aNodesList[i]->X(); + y1 = aNodesList[i-1]->Y();y2 = aNodesList[i]->Y(); + z1 = aNodesList[i-1]->Z();z2 = aNodesList[i]->Z(); + TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp_Pnt(x1,y1,z1),gp_Pnt(x2,y2,z2)); + list LPP; + aPrms.clear(); + MakeEdgePathPoints(aPrms, e, (aNodesList[i-1]->GetID()==startNid), LPP); + LLPPs.push_back(LPP); + if( aNodesList[i-1]->GetID() == startNid ) startNid = aNodesList[i]->GetID(); + else startNid = aNodesList[i-1]->GetID(); + + } + + list< list >::iterator itLLPP = LLPPs.begin(); + list firstList = *itLLPP; + list::iterator itPP = firstList.begin(); + for(; itPP!=firstList.end(); itPP++) { + fullList.push_back( *itPP ); + } + + SMESH_MeshEditor_PathPoint PP1 = fullList.back(); + SMESH_MeshEditor_PathPoint PP2; + fullList.pop_back(); + itLLPP++; + for(; itLLPP!=LLPPs.end(); itLLPP++) { + list currList = *itLLPP; + itPP = currList.begin(); + PP2 = currList.front(); + gp_Dir D1 = PP1.Tangent(); + gp_Dir D2 = PP2.Tangent(); + gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2, + (D1.Z()+D2.Z())/2 ) ); + PP1.SetTangent(Dnew); + fullList.push_back(PP1); + itPP++; + for(; itPP!=currList.end(); itPP++) { + fullList.push_back( *itPP ); + } + PP1 = fullList.back(); + fullList.pop_back(); + } + fullList.push_back(PP1); + + } // Sub shape for the Pattern must be an Edge or Wire + else if( aS.ShapeType() == TopAbs_EDGE ) { aTrackEdge = TopoDS::Edge( aS ); // the Edge must not be degenerated if ( BRep_Tool::Degenerated( aTrackEdge ) ) @@ -7048,7 +7188,7 @@ SMESH_ElementSearcher* SMESH_MeshEditor::GetElementSearcher() //======================================================================= /*! - * \brief Return SMESH_ElementSearcher + * \brief Return SMESH_ElementSearcher acting on a sub-set of elements */ //======================================================================= @@ -10790,7 +10930,11 @@ namespace { _extremum.Perform(aPnt); if ( _extremum.IsDone() ) for ( int iSol = 1; iSol <= _extremum.NbExt() && _state == TopAbs_OUT; ++iSol) +#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 + _state = ( _extremum.SquareDistance(iSol) <= theTol ? TopAbs_IN : TopAbs_OUT ); +#else _state = ( _extremum.Value(iSol) <= theTol ? TopAbs_IN : TopAbs_OUT ); +#endif } TopAbs_State State() const { @@ -11578,13 +11722,12 @@ namespace * \param group - a group to store created boundary elements in * \param targetMesh - a mesh to store created boundary elements in * \param toCopyElements - if true, the checked elements will be copied into the targetMesh - * \param toCopyExistingBondary - if true, not only new but also pre-existing + * \param toCopyExistingBoundary - if true, not only new but also pre-existing * boundary elements will be copied into the targetMesh * \param toAddExistingBondary - if true, not only new but also pre-existing * boundary elements will be added into the new group * \param aroundElements - if true, elements will be created on boundary of given - * elements else, on boundary of the whole mesh. This - * option works for 2D elements only. + * elements else, on boundary of the whole mesh. * \return nb of added boundary elements */ //================================================================================ @@ -11594,7 +11737,7 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, SMESH_Group* group/*=0*/, SMESH_Mesh* targetMesh/*=0*/, bool toCopyElements/*=false*/, - bool toCopyExistingBondary/*=false*/, + bool toCopyExistingBoundary/*=false*/, bool toAddExistingBondary/*= false*/, bool aroundElements/*= false*/) { @@ -11604,11 +11747,8 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, if ( !elements.empty() && (*elements.begin())->GetType() != elemType ) throw SALOME_Exception(LOCALIZED("wrong element type")); - if ( aroundElements && elemType == SMDSAbs_Volume ) - throw SALOME_Exception(LOCALIZED("wrong element type for aroundElements==true")); - if ( !targetMesh ) - toCopyElements = toCopyExistingBondary = false; + toCopyElements = toCopyExistingBoundary = false; SMESH_MeshEditor tgtEditor( targetMesh ? targetMesh : myMesh ); SMESHDS_Mesh* aMesh = GetMeshDS(), *tgtMeshDS = tgtEditor.GetMeshDS(); @@ -11646,11 +11786,13 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, if ( vTool.Set(elem) ) // elem is a volume ------------------------------------------ { vTool.SetExternalNormal(); + const SMDS_MeshElement* otherVol = 0; for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ ) { - if (!vTool.IsFreeFace(iface)) + if ( !vTool.IsFreeFace(iface, &otherVol) && + ( !aroundElements || elements.count( otherVol ))) continue; - int nbFaceNodes = vTool.NbFaceNodes(iface); + const int nbFaceNodes = vTool.NbFaceNodes(iface); const SMDS_MeshNode** nn = vTool.GetFaceNodes(iface); if ( missType == SMDSAbs_Edge ) // boundary edges { @@ -11679,6 +11821,21 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, presentBndElems.push_back( f ); else missingBndElems.push_back( nodes ); + + if ( targetMesh != myMesh ) + { + // add 1D elements on face boundary to be added to a new mesh + const SMDS_MeshElement* edge; + for ( inode = 0; inode < nbFaceNodes; inode += 1+iQuad) + { + if ( iQuad ) + edge = aMesh->FindEdge( nn[inode], nn[inode+1], nn[inode+2]); + else + edge = aMesh->FindEdge( nn[inode], nn[inode+1]); + if ( edge && avoidSet.insert( edge ).second ) + presentBndElems.push_back( edge ); + } + } } } } @@ -11709,7 +11866,7 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, // --------------------------------- if ( targetMesh != myMesh ) // instead of making a map of nodes in this mesh and targetMesh, - // we create nodes with same IDs. We can renumber them later, if needed + // we create nodes with same IDs. for ( int i = 0; i < missingBndElems.size(); ++i ) { TConnectivity& srcNodes = missingBndElems[i]; @@ -11738,14 +11895,14 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, // ---------------------------------- // 3. Copy present boundary elements // ---------------------------------- - if ( toCopyExistingBondary ) + if ( toCopyExistingBoundary ) for ( int i = 0 ; i < presentBndElems.size(); ++i ) { const SMDS_MeshElement* e = presentBndElems[i]; TConnectivity nodes( e->NbNodes() ); for ( inode = 0; inode < nodes.size(); ++inode ) nodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) ); - presentEditor->AddElement(nodes, missType, e->IsPoly()); + presentEditor->AddElement(nodes, e->GetType(), e->IsPoly()); } else // store present elements to add them to a group for ( int i = 0 ; i < presentBndElems.size(); ++i )