}
else
{
+ const bool skipMediumNodes = true;
map< double, const SMDS_MeshNode* > srcNodes, tgtNodes;
- if (( ! SMESH_Algo::GetSortedNodesOnEdge( srcMeshDS, TopoDS::Edge( srcE ),
- /*ignoreMediumNodes = */true,
- srcNodes ))
- ||
- ( ! SMESH_Algo::GetSortedNodesOnEdge( tgtMeshDS, TopoDS::Edge( tgtE ),
- /*ignoreMediumNodes = */true,
- tgtNodes ))
- )
+ if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMeshDS, srcE, skipMediumNodes, srcNodes) ||
+ !SMESH_Algo::GetSortedNodesOnEdge( tgtMeshDS, tgtE, skipMediumNodes, tgtNodes ))
return SMESH_ComputeError::New( COMPERR_BAD_INPUT_MESH,
"Invalid node parameters on edges");
if ( !tgtNodes.empty() )
{
map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
- map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin();
- for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
- src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
-
+ if ( srcE.Orientation() == tgtE.Orientation() )
+ {
+ map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin();
+ for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
+ src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
+ }
+ else
+ {
+ map< double, const SMDS_MeshNode* >::reverse_iterator u_sn = srcNodes.rbegin();
+ for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
+ src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
+ }
is1DComputed = true;
}
}
gp_Trsf srcTrsf = srcFace.Location();
gp_Trsf tgtTrsf = tgtFace.Location();
trsf.Set( srcTrsf.Inverted() * tgtTrsf );
+ // check
+ gp_Pnt srcP = BRep_Tool::Pnt( srcWires[0]->FirstVertex() );
+ gp_Pnt tgtP = BRep_Tool::Pnt( tgtWires[0]->FirstVertex() );
+ if ( tgtP.Distance( trsf.Transform( srcP )) > tol )
+ trsf.Set( tgtTrsf.Inverted() * srcTrsf );
}
else
{
vector< gp_XYZ > srcPnts, tgtPnts;
srcPnts.reserve( totNbSeg );
tgtPnts.reserve( totNbSeg );
+ gp_XYZ srcBC( 0,0,0 ), tgtBC( 0,0,0 );
for ( size_t iW = 0; iW < srcWires.size(); ++iW )
{
const double minSegLen = srcWires[iW]->Length() / totNbSeg;
tgtPnts.push_back( tgtWires[iW]->Value3d( tgtU ).XYZ() );
srcU += srcDu;
tgtU += tgtDu;
+ srcBC += srcPnts.back();
+ tgtBC += tgtPnts.back();
}
}
}
const int nbTestPnt = 20;
const size_t iStep = Max( 1, int( srcPnts.size() / nbTestPnt ));
// check boundary
+ gp_Pnt trsfTgt = trsf.Transform( srcBC / srcPnts.size() );
+ trsfIsOK = ( trsfTgt.SquareDistance( tgtBC / tgtPnts.size() ) < tol*tol );
for ( size_t i = 0; ( i < srcPnts.size() && trsfIsOK ); i += iStep )
{
gp_Pnt trsfTgt = trsf.Transform( srcPnts[i] );
{
BRepAdaptor_Surface srcSurf( srcFace );
gp_Pnt srcP =
- srcSurf.Value( 0.5 * ( srcSurf.FirstUParameter() + srcSurf.LastUParameter() ),
- 0.5 * ( srcSurf.FirstVParameter() + srcSurf.LastVParameter() ));
+ srcSurf.Value( 0.321 * ( srcSurf.FirstUParameter() + srcSurf.LastUParameter() ),
+ 0.123 * ( srcSurf.FirstVParameter() + srcSurf.LastVParameter() ));
gp_Pnt tgtTrsfP = trsf.Transform( srcP );
TopLoc_Location loc;
GeomAPI_ProjectPointOnSurf& proj = helper.GetProjector( tgtFace, loc, 0.1*tol );
if ( !tgtFace.IsPartner( srcFace ) )
{
+ SMESH_MesherHelper edgeHelper( *tgtMesh );
+ edgeHelper.ToFixNodeParameters( true );
+ helper.ToFixNodeParameters( true );
+
int nbOkPos = 0;
+ bool toCheck = true;
const double tol2d = 1e-12;
srcN_tgtN = src2tgtNodes.begin();
for ( ; srcN_tgtN != src2tgtNodes.end(); ++srcN_tgtN )
{
case SMDS_TOP_FACE:
{
+ if ( nbOkPos > 10 ) break;
gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv;
if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) &&
- (( uv - uvBis ).SquareModulus() < tol2d ) &&
- ( ++nbOkPos > 10 ))
- return true;
+ (( uv - uvBis ).SquareModulus() < tol2d ))
+ ++nbOkPos;
else
nbOkPos = 0;
break;
case SMDS_TOP_EDGE:
{
const TopoDS_Edge & tgtE = TopoDS::Edge( tgtMeshDS->IndexToShape( n->getshapeId() ));
- double u = helper.GetNodeU( tgtE, n ), uBis = u;
- if (( !helper.CheckNodeU( tgtE, n, u, tol )) ||
- (( u - uBis ) < tol2d ))
- nbOkPos = 0;
+ edgeHelper.SetSubShape( tgtE );
+ edgeHelper.GetNodeU( tgtE, n, 0, &toCheck );
break;
}
default:;
case SMDS_TOP_EDGE: {
TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
TopoDS_Edge tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true ));
- tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ));
- double U = srcHelper.GetNodeU( TopoDS::Edge( srcEdge ), srcNode );
+ double U = Precision::Infinite();
helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
- n->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition( U )));
+ tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ), U );
break;
}
case SMDS_TOP_VERTEX: {
*/
//================================================================================
- void fixDistortedFaces( SMESH_MesherHelper& helper,
- TSideVector& )
+ bool fixDistortedFaces( SMESH_MesherHelper& helper,
+ TSideVector& tgtWires )
{
- // Detect bad faces
-
- bool haveBadFaces = false;
-
- const TopoDS_Face& F = TopoDS::Face( helper.GetSubShape() );
- SMESHDS_SubMesh* smDS = helper.GetMeshDS()->MeshElements( F );
- if ( !smDS || smDS->NbElements() == 0 ) return;
+ SMESH_subMesh* faceSM = helper.GetMesh()->GetSubMesh( helper.GetSubShape() );
- SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
- double prevArea2D = 0;
- vector< const SMDS_MeshNode* > nodes;
- vector< gp_XY > uv;
- while ( faceIt->more() && !haveBadFaces )
- {
- const SMDS_MeshElement* face = faceIt->next();
-
- // get nodes
- nodes.resize( face->NbCornerNodes() );
- SMDS_MeshElement::iterator n = face->begin_nodes();
- for ( size_t i = 0; i < nodes.size(); ++n, ++i )
- nodes[ i ] = *n;
-
- // avoid elems on degenarate shapes as UV on them can be wrong
- if ( helper.HasDegeneratedEdges() )
- {
- bool isOnDegen = false;
- for ( size_t i = 0; ( i < nodes.size() && !isOnDegen ); ++i )
- isOnDegen = helper.IsDegenShape( nodes[ i ]->getshapeId() );
- if ( isOnDegen )
- continue;
- }
- // prepare to getting UVs
- const SMDS_MeshNode* inFaceNode = 0;
- if ( helper.HasSeam() )
- for ( size_t i = 0; ( i < nodes.size() && !inFaceNode ); ++i )
- if ( !helper.IsSeamShape( nodes[ i ]->getshapeId() ))
- inFaceNode = nodes[ i ];
-
- // get UVs
- uv.resize( nodes.size() );
- for ( size_t i = 0; i < nodes.size(); ++i )
- uv[ i ] = helper.GetNodeUV( F, nodes[ i ], inFaceNode );
-
- // compare orientation of triangles
- for ( int iT = 0, nbT = nodes.size()-2; iT < nbT; ++iT )
- {
- gp_XY v1 = uv[ iT+1 ] - uv[ 0 ];
- gp_XY v2 = uv[ iT+2 ] - uv[ 0 ];
- double area2D = v2 ^ v1;
- if (( haveBadFaces = ( area2D * prevArea2D < 0 )))
- break;
- prevArea2D = area2D;
- }
- }
-
- // Fix faces
-
- if ( haveBadFaces )
+ if ( helper.IsDistorted2D( faceSM, /*checkUV=*/false ))
{
SMESH_MeshEditor editor( helper.GetMesh() );
+ SMESHDS_SubMesh* smDS = faceSM->GetSubMeshDS();
+ const TopoDS_Face& F = TopoDS::Face( faceSM->GetSubShape() );
TIDSortedElemSet faces;
+ SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
for ( faceIt = smDS->GetElements(); faceIt->more(); )
faces.insert( faces.end(), faceIt->next() );
// choose smoothing algo
//SMESH_MeshEditor:: SmoothMethod algo = SMESH_MeshEditor::CENTROIDAL;
bool isConcaveBoundary = false;
- TError err;
- TSideVector tgtWires =
- StdMeshers_FaceSide::GetFaceWires( F, *helper.GetMesh(),/*skipMediumNodes=*/0, err);
for ( size_t iW = 0; iW < tgtWires.size() && !isConcaveBoundary; ++iW )
{
TopoDS_Edge prevEdge = tgtWires[iW]->Edge( tgtWires[iW]->NbEdges() - 1 );
set<const SMDS_MeshNode*> fixedNodes;
editor.Smooth( faces, fixedNodes, algo, /*nbIterations=*/ 10,
/*theTgtAspectRatio=*/1.0, /*the2D=*/!isPlanar);
+
+ helper.ToFixNodeParameters( true );
+
+ return !helper.IsDistorted2D( faceSM, /*checkUV=*/true );
}
+ return true;
}
} // namespace
if ( err && !err->IsOK() )
return error( err );
- bool done = false;
+ bool projDone = false;
- if ( !done )
+ if ( !projDone )
{
// try to project from the same face with different location
- done = projectPartner( tgtFace, srcFace, tgtWires, srcWires,
- shape2ShapeMap, _src2tgtNodes, is1DComputed );
+ projDone = projectPartner( tgtFace, srcFace, tgtWires, srcWires,
+ shape2ShapeMap, _src2tgtNodes, is1DComputed );
}
- if ( !done )
+ if ( !projDone )
{
// projection in case if the faces are similar in 2D space
- done = projectBy2DSimilarity( tgtFace, srcFace, tgtWires, srcWires,
- shape2ShapeMap, _src2tgtNodes, is1DComputed);
+ projDone = projectBy2DSimilarity( tgtFace, srcFace, tgtWires, srcWires,
+ shape2ShapeMap, _src2tgtNodes, is1DComputed);
}
SMESH_MesherHelper helper( theMesh );
helper.SetSubShape( tgtFace );
- if ( !done )
+ // it will remove mesh built on edges and vertices in failure case
+ MeshCleaner cleaner( tgtSubMesh );
+
+ if ( !projDone )
{
_src2tgtNodes.clear();
// --------------------
if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
return error("Can't make mesh by source mesh pattern");
- // it will remove mesh built by pattern mapper on edges and vertices
- // in failure case
- MeshCleaner cleaner( tgtSubMesh );
-
// -------------------------------------------------------------------------
// mapper doesn't take care of nodes already existing on edges and vertices,
// so we must merge nodes created by it with existing ones
if ( nbFaceBeforeMerge != nbFaceAtferMerge && !helper.HasDegeneratedEdges() )
return error(COMPERR_BAD_INPUT_MESH, "Probably invalid node parameters on geom faces");
-
- // ----------------------------------------------------------------
- // The mapper can create distorted faces by placing nodes out of the FACE
- // boundary -- fix bad faces by smoothing
- // ----------------------------------------------------------------
-
- fixDistortedFaces( helper, tgtWires );
-
// ----------------------------------------------------------------
// The mapper can't create quadratic elements, so convert if needed
// ----------------------------------------------------------------
editor.ConvertToQuadratic(/*theForce3d=*/false, tgtFaces, false);
}
- cleaner.Release(); // not to remove mesh
-
} // end of projection using Pattern mapping
+ if ( !projDone || is1DComputed )
+ // ----------------------------------------------------------------
+ // The mapper can create distorted faces by placing nodes out of the FACE
+ // boundary, also bad face can be created if EDGEs already discretized
+ // --> fix bad faces by smoothing
+ // ----------------------------------------------------------------
+ if ( !fixDistortedFaces( helper, tgtWires ))
+ return error("Invalid mesh generated");
+
// ---------------------------
// Check elements orientation
// ---------------------------
}
}
+ cleaner.Release(); // not to remove mesh
+
return true;
}