X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Import_1D2D.cxx;h=636cd73ec006e4eec21bdfd1a88121e092febb41;hp=8180f0a027ff93a692f6e7155cd949443c4f0902;hb=d9faba6c847c1c1a4d4f501ca5ac5725a25a8236;hpb=bd4e115a78b52e3fbc016e5e30bb0e19b2a9e7d6 diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.cxx b/src/StdMeshers/StdMeshers_Import_1D2D.cxx index 8180f0a02..636cd73ec 100644 --- a/src/StdMeshers/StdMeshers_Import_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_Import_1D2D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2014 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 @@ -6,7 +6,7 @@ // 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. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -38,6 +38,7 @@ #include "SMESH_Group.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_MesherHelper.hxx" +#include "SMESH_OctreeNode.hxx" #include "SMESH_subMesh.hxx" #include "Utils_SALOME_Exception.hxx" @@ -96,6 +97,7 @@ StdMeshers_Import_1D2D::StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen _compatibleHypothesis.push_back("ImportSource2D"); _requireDiscreteBoundary = false; + _supportSubmeshes = true; } //============================================================================= @@ -164,7 +166,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & { if ( !_sourceHyp ) return false; - const vector& srcGroups = _sourceHyp->GetGroups(); + const vector& srcGroups = _sourceHyp->GetGroups(/*loaded=*/true); if ( srcGroups.empty() ) return error("Invalid source groups"); @@ -191,9 +193,10 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & set subShapeIDs; subShapeIDs.insert( shapeID ); - // get nodes on vertices - list < SMESH_TNodeXYZ > vertexNodes; - list < SMESH_TNodeXYZ >::iterator vNIt; + // nodes already existing on sub-shapes of the FACE + TIDSortedNodeSet existingNodes; + + // get/make nodes on vertices and add them to existingNodes TopExp_Explorer exp( theShape, TopAbs_VERTEX ); for ( ; exp.More(); exp.Next() ) { @@ -207,8 +210,28 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & n = SMESH_Algo::VertexNode( v, tgtMesh ); if ( !n ) return false; // very strange } - vertexNodes.push_back( SMESH_TNodeXYZ( n )); + existingNodes.insert( n ); + } + + // get EDGESs and their ids and get existing nodes on EDGEs + vector< TopoDS_Edge > edges; + for ( exp.Init( theShape, TopAbs_EDGE ); exp.More(); exp.Next() ) + { + const TopoDS_Edge & edge = TopoDS::Edge( exp.Current() ); + if ( !SMESH_Algo::isDegenerated( edge )) + if ( subShapeIDs.insert( tgtMesh->ShapeToIndex( edge )).second ) + { + edges.push_back( edge ); + if ( SMESHDS_SubMesh* eSM = tgtMesh->MeshElements( edge )) + { + typedef SMDS_StdIterator< const SMDS_MeshNode*, SMDS_NodeIteratorPtr > iterator; + existingNodes.insert( iterator( eSM->GetNodes() ), iterator() ); + } + } } + // octree to find existing nodes + SMESH_OctreeNode existingNodeOcTr( existingNodes ); + std::map dist2foundNodes; // to count now many times a link between nodes encounters map linkCount; @@ -247,22 +270,20 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & SMDS_MeshElement::iterator node = face->begin_nodes(); for ( size_t i = 0; i < newNodes.size(); ++i, ++node ) { - StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; + StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt = + n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; if ( n2nIt->second ) { - if ( !subShapeIDs.count( n2nIt->second->getshapeId() )) + if ( !subShapeIDs.count( n2nIt->second->getshapeId() )) // node already on an EDGE break; } else { - // find an existing vertex node - for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt) - if ( vNIt->SquareDistance( *node ) < groupTol * groupTol) - { - (*n2nIt).second = vNIt->_node; - vertexNodes.erase( vNIt ); - break; - } + // find a pre-existing node + dist2foundNodes.clear(); + existingNodeOcTr.NodesAround( SMESH_TNodeXYZ( *node ), dist2foundNodes, groupTol ); + if ( !dist2foundNodes.empty() ) + (*n2nIt).second = dist2foundNodes.begin()->second; } if ( !n2nIt->second ) { @@ -290,6 +311,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & continue; // repeated face in source groups already created // check future face orientation + const int nbCorners = face->NbCornerNodes(); + const bool isQuad = ( nbCorners != (int) newNodes.size() ); if ( toCheckOri ) { int iNode = -1; @@ -300,10 +323,10 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & surface->D1( uv.X(),uv.Y(), p, du,dv ); geomNorm = reverse ? dv^du : du^dv; } - while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes()); + while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < nbCorners ); - int iNext = helper.WrapIndex( iNode+1, face->NbCornerNodes() ); - int iPrev = helper.WrapIndex( iNode-1, face->NbCornerNodes() ); + int iNext = helper.WrapIndex( iNode+1, nbCorners ); + int iPrev = helper.WrapIndex( iNode-1, nbCorners ); SMESH_TNodeXYZ prevNode( newNodes[iPrev] ); SMESH_TNodeXYZ curNode ( newNodes[iNode] ); @@ -313,40 +336,43 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & gp_Vec meshNorm = n1n2 ^ n1n0; if ( geomNorm * meshNorm < 0 ) - std::reverse( newNodes.begin(), newNodes.end() ); + SMDS_MeshCell::applyInterlace + ( SMDS_MeshCell::reverseSmdsOrder( face->GetEntityType() ), newNodes ); } // 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; - } + if ( face->IsPoly() ) + newFace = tgtMesh->AddPolygonalFace( newNodes ); + else + 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 ) + for ( int i = 0; i < nbCorners; ++i ) { const SMDS_MeshNode* n1 = newNodes[i]; - const SMDS_MeshNode* n2 = newNodes[ (i+1)%nbNodes ]; - if ( newFace->IsQuadratic() ) - medium = newNodes[i+nbNodes]; + const SMDS_MeshNode* n2 = newNodes[ (i+1)%nbCorners ]; + if ( isQuad ) // quadratic face + medium = newNodes[i+nbCorners]; link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first; ++link2Nb->second; // if ( link2Nb->second == 1 ) @@ -366,11 +392,6 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & // 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() )); - // use large tolerance for projection of nodes to edges because of // BLSURF mesher specifics (issue 0020918, Study2.hdf) const double projTol = minGroupTol; @@ -395,7 +416,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN ) { const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2(); - if ( !subShapeIDs.count( n->getshapeId() )) + if ( !subShapeIDs.count( n->getshapeId() )) // n is assigned to FACE { for ( size_t iE = 0; iE < edges.size(); ++iE ) if ( helper.CheckNodeU( edges[iE], n, u=0, projTol, /*force=*/true )) @@ -405,7 +426,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & // duplicated node on vertex return error("Source elements overlap one another"); tgtFaceSM->RemoveNode( n, /*isNodeDeleted=*/false ); - tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u ); + tgtMesh->SetNodeOnEdge( n, edges[iE], u ); break; } nodesOnBoundary = subShapeIDs.count( n->getshapeId()); @@ -424,13 +445,13 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & error("free internal link"); // just for an easier debug break; } - if ( bndShapes.front().ShapeType() == TopAbs_EDGE && + if ( bndShapes.front().ShapeType() == TopAbs_EDGE && // all link nodes are on EDGEs bndShapes.front() != bndShapes.back() ) // link nodes on different geom edges return error(COMPERR_BAD_INPUT_MESH, "Source nodes mismatch target vertices"); // find geom edge the link is on - if ( bndShapes.back().ShapeType() != TopAbs_EDGE ) + if ( bndShapes.back().ShapeType() != TopAbs_EDGE ) // all link nodes are on VERTEXes { // find geom edge by two vertices TopoDS_Shape geomEdge = helper.GetCommonAncestor( bndShapes.back(), @@ -453,8 +474,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & 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] ); + edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], link._medium ); TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back()); helper.CheckNodeU( geomEdge, link._medium, u, projTol, /*force=*/true ); @@ -495,7 +515,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & int sId = editor.FindShape( edge ); nbEdges += subShapeIDs.count( sId ); } - if ( nbEdges < 2 ) + if ( nbEdges < 2 && !helper.IsRealSeam( s )) return false; // weird if ( nbEdges > 2 ) return error( COMPERR_BAD_INPUT_MESH, "Source elements overlap one another"); @@ -583,8 +603,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & for ( size_t iE = 0; iE < edges.size(); ++iE ) { SMESH_subMesh * sm = theMesh.GetSubMesh( edges[iE] ); - if ( BRep_Tool::Degenerated( edges[iE] )) - sm->SetIsAlwaysComputed( true ); + // if ( SMESH_Algo::isDegenerated( edges[iE] )) + // sm->SetIsAlwaysComputed( true ); sm->ComputeStateEngine(SMESH_subMesh::CHECK_COMPUTE_STATE); if ( sm->GetComputeState() != SMESH_subMesh::COMPUTE_OK ) return error(SMESH_Comment("Failed to create segments on the edge ")