-// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012 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
using namespace std;
+namespace
+{
+ double getMinElemSize2( const SMESHDS_GroupBase* srcGroup )
+ {
+ double minSize2 = 1e100;
+ SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+ while ( srcElems->more() ) // loop on group contents
+ {
+ const SMDS_MeshElement* face = srcElems->next();
+ int nbN = face->NbCornerNodes();
+
+ SMESH_TNodeXYZ prevN( face->GetNode( nbN-1 ));
+ for ( int i = 0; i < nbN; ++i )
+ {
+ SMESH_TNodeXYZ n( face->GetNode( i ) );
+ double size2 = ( n - prevN ).SquareModulus();
+ minSize2 = std::min( minSize2, size2 );
+ prevN = n;
+ }
+ }
+ return minSize2;
+ }
+}
+
//=============================================================================
/*!
* Creates StdMeshers_Import_1D2D
_shapeType = (1 << TopAbs_FACE);
_compatibleHypothesis.push_back("ImportSource2D");
- _requireDescretBoundary = false;
+ _requireDiscreteBoundary = false;
}
//=============================================================================
// to count now many times a link between nodes encounters
map<TLink, int> linkCount;
map<TLink, int>::iterator link2Nb;
- double minLinkLen2 = Precision::Infinite();
+ double minGroupTol = Precision::Infinite();
// =========================
// Import faces from groups
if ( !srcMesh ) continue;
StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e );
+ const double groupTol = 0.5 * sqrt( getMinElemSize2( srcGroup ));
+ minGroupTol = std::min( groupTol, minGroupTol );
+
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
gp_XY uv( Precision::Infinite(), Precision::Infinite() );
{
// find an existing vertex node
for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
- if ( vNIt->SquareDistance( *node ) < 10 * faceTol * faceTol)
+ if ( vNIt->SquareDistance( *node ) < groupTol * groupTol)
{
(*n2nIt).second = vNIt->_node;
vertexNodes.erase( vNIt );
{
// find out if node lies on theShape
tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
- if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, /*force=*/true ))
+ uv.SetCoord( Precision::Infinite(), Precision::Infinite() );
+ if ( helper.CheckNodeUV( geomFace, tmpNode, uv, groupTol, /*force=*/true ))
{
SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
n2nIt->second = newNode;
medium = newNodes[i+nbNodes];
link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first;
++link2Nb->second;
- if ( link2Nb->second == 1 )
- {
- // measure link length
- double len2 = SMESH_TNodeXYZ( n1 ).SquareDistance( n2 );
- if ( len2 < minLinkLen2 )
- minLinkLen2 = len2;
- }
+ // if ( link2Nb->second == 1 )
+ // {
+ // // measure link length
+ // double len2 = SMESH_TNodeXYZ( n1 ).SquareDistance( n2 );
+ // if ( len2 < minGroupTol )
+ // minGroupTol = len2;
+ // }
}
}
helper.GetMeshDS()->RemoveNode(tmpNode);
// use large tolerance for projection of nodes to edges because of
// BLSURF mesher specifics (issue 0020918, Study2.hdf)
- const double projTol = 1e-3 * sqrt( minLinkLen2 );
+ const double projTol = minGroupTol;
bool isFaceMeshed = false;
SMESHDS_SubMesh* tgtFaceSM = tgtMesh->MeshElements( theShape );
}
}
if ( !nodesOnBoundary )
- break; // error: free internal link
+ {
+ error("free internal link"); // just for an easier debug
+ break;
+ }
if ( bndShapes.front().ShapeType() == TopAbs_EDGE &&
bndShapes.front() != bndShapes.back() )
- break; // error: link nodes on different geom edges
+ // 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 )
{
// find geom edge by two vertices
- TopoDS_Shape geomEdge;
- PShapeIteratorPtr edgeIt = helper.GetAncestors( bndShapes.back(), theMesh, TopAbs_EDGE );
- while ( edgeIt->more() )
+ TopoDS_Shape geomEdge = helper.GetCommonAncestor( bndShapes.back(),
+ bndShapes.front(),
+ theMesh, TopAbs_EDGE );
+ if ( geomEdge.IsNull() )
{
- geomEdge = *(edgeIt->next());
- if ( !helper.IsSubShape( bndShapes.front(), geomEdge ))
- geomEdge.Nullify();
+ error("free internal link");
+ break; // vertices belong to different edges
}
- if ( geomEdge.IsNull() )
- break; // vertices belong to different edges -> error: free internal link
bndShapes.push_back( geomEdge );
}
edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back());
- helper.CheckNodeU( geomEdge, link._medium, u, 10*faceTol, /*force=*/true );
+ helper.CheckNodeU( geomEdge, link._medium, u, projTol, /*force=*/true );
tgtFaceSM->RemoveNode( link._medium, /*isNodeDeleted=*/false );
tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u );
}
}
else if ( nbFaces > 2 )
{
- return error( "Non-manifold source mesh");
+ return error( COMPERR_BAD_INPUT_MESH, "Non-manifold source mesh");
}
}
isFaceMeshed = ( link2Nb == linkCount.end() && !linkCount.empty());
if ( nbEdges < 2 )
return false; // weird
if ( nbEdges > 2 )
- return error( "Source elements overlap one another");
+ return error( COMPERR_BAD_INPUT_MESH, "Source elements overlap one another");
}
}
}
if ( !isFaceMeshed )
- return error( "Source elements don't cover totally the geometrical face" );
+ return error( COMPERR_BAD_INPUT_MESH,
+ "Source elements don't cover totally the geometrical face" );
if ( helper.HasSeam() )
{
helper.SetSubShape(theShape);
const TopoDS_Face& geomFace = TopoDS::Face( theShape );
- const double faceTol = helper.MaxTolerance( geomFace );
// take into account nodes on vertices
TopExp_Explorer exp( theShape, TopAbs_VERTEX );
// count faces and nodes imported from groups
set<const SMDS_MeshNode* > allNodes;
gp_XY uv;
+ double minGroupTol = 1e100;
for ( int iG = 0; iG < srcGroups.size(); ++iG )
{
const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
+ const double groupTol = 0.5 * sqrt( getMinElemSize2( srcGroup ));
+ minGroupTol = std::min( groupTol, minGroupTol );
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
SMDS_MeshNode *tmpNode =helper.AddNode(0,0,0);
while ( srcElems->more() ) // loop on group contents
gp_XYZ gc(0,0,0);
gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes();
tmpNode->setXYZ( gc.X(), gc.Y(), gc.Z());
- if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, /*force=*/true ))
+ if ( helper.CheckNodeUV( geomFace, tmpNode, uv, groupTol, /*force=*/true ))
{
++aVec[ face->GetEntityType() ];
bool eraseLink = ( nbFacesOfLink != 1 );
if ( nbFacesOfLink == 1 )
{
- if ( helper.CheckNodeU( geomEdge, link.node1(), u, 10*faceTol, /*force=*/true )&&
- helper.CheckNodeU( geomEdge, link.node2(), u, 10*faceTol, /*force=*/true ))
+ if ( helper.CheckNodeU( geomEdge, link.node1(), u, minGroupTol, /*force=*/true )&&
+ helper.CheckNodeU( geomEdge, link.node2(), u, minGroupTol, /*force=*/true ))
{
bool isQuadratic = ( link2Nb->second < 0 );
++edgeVec[ isQuadratic ? SMDSEntity_Quad_Edge : SMDSEntity_Edge ];