mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-11 16:19:16 +05:00
23404: EDF 14011 - Problem with Quadrangle (Medial Axis projection) algorithm
(SMESH_MAT2d.cxx) + IPAL53878: Quadrangle: Medial Axis Projection algorithm fails (StdMeshers_QuadFromMedialAxis_1D2D.cxx)
This commit is contained in:
parent
c3335563bc
commit
4b9725e701
@ -192,6 +192,7 @@ SET(SMESH_RESOURCES_FILES
|
|||||||
mesh_tree_hypo_source_3d_shape.png
|
mesh_tree_hypo_source_3d_shape.png
|
||||||
mesh_tree_hypo_projection_3d.png
|
mesh_tree_hypo_projection_3d.png
|
||||||
mesh_tree_hypo_projection_2d.png
|
mesh_tree_hypo_projection_2d.png
|
||||||
|
mesh_tree_hypo_quadratic.png
|
||||||
mesh_build_compound.png
|
mesh_build_compound.png
|
||||||
copy_mesh.png
|
copy_mesh.png
|
||||||
mesh_node_to_point.png
|
mesh_node_to_point.png
|
||||||
|
BIN
resources/mesh_tree_hypo_quadratic.png
Normal file
BIN
resources/mesh_tree_hypo_quadratic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 349 B |
@ -340,7 +340,7 @@ namespace
|
|||||||
return ( _inSeg->getGeomEdge( _edge->twin()->cell() ) != theNoEdgeID );
|
return ( _inSeg->getGeomEdge( _edge->twin()->cell() ) != theNoEdgeID );
|
||||||
}
|
}
|
||||||
|
|
||||||
// check a next segment in CW order
|
// check a next segment in CCW order
|
||||||
bool isSameBranch( const BndSeg& seg2 )
|
bool isSameBranch( const BndSeg& seg2 )
|
||||||
{
|
{
|
||||||
if ( !_edge || !seg2._edge )
|
if ( !_edge || !seg2._edge )
|
||||||
@ -1011,6 +1011,8 @@ namespace
|
|||||||
int branchID = 1; // we code orientation as branchID sign
|
int branchID = 1; // we code orientation as branchID sign
|
||||||
branchEdges.resize( branchID );
|
branchEdges.resize( branchID );
|
||||||
|
|
||||||
|
vector< std::pair< int, const TVDVertex* > > branchesToCheckEnd;
|
||||||
|
|
||||||
for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
|
for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
|
||||||
{
|
{
|
||||||
vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
|
vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
|
||||||
@ -1039,7 +1041,13 @@ namespace
|
|||||||
{
|
{
|
||||||
branchEdges.resize(( branchID = branchEdges.size()) + 1 );
|
branchEdges.resize(( branchID = branchEdges.size()) + 1 );
|
||||||
if ( bndSegs[i]._edge && bndSegs[i]._prev )
|
if ( bndSegs[i]._edge && bndSegs[i]._prev )
|
||||||
|
{
|
||||||
endType.insert( make_pair( bndSegs[i]._edge->vertex1(), SMESH_MAT2d::BE_BRANCH_POINT ));
|
endType.insert( make_pair( bndSegs[i]._edge->vertex1(), SMESH_MAT2d::BE_BRANCH_POINT ));
|
||||||
|
if ( bndSegs[i]._prev->_branchID < 0 )
|
||||||
|
// 0023404: a branch-point is inside a branch
|
||||||
|
branchesToCheckEnd.push_back( make_pair( bndSegs[i]._prev->branchID(),
|
||||||
|
bndSegs[i]._edge->vertex1() ));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( bndSegs[i]._prev->_branchID )
|
else if ( bndSegs[i]._prev->_branchID )
|
||||||
{
|
{
|
||||||
@ -1063,6 +1071,37 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !ignoreCorners && !branchesToCheckEnd.empty() )
|
||||||
|
{
|
||||||
|
// split branches having branch-point inside
|
||||||
|
// (a branch-point was not detected since another branch is joined at the opposite side)
|
||||||
|
for ( size_t i = 0; i < branchesToCheckEnd.size(); ++i )
|
||||||
|
{
|
||||||
|
vector<const TVDEdge*> & branch = branchEdges[ branchesToCheckEnd[i].first ];
|
||||||
|
const TVDVertex* branchPoint = branchesToCheckEnd[i].second;
|
||||||
|
if ( branch.front()->vertex1() == branchPoint ||
|
||||||
|
branch.back ()->vertex0() == branchPoint )
|
||||||
|
continue; // OK - branchPoint is at a branch end
|
||||||
|
|
||||||
|
// find a MA edge where another branch begins
|
||||||
|
size_t iE;
|
||||||
|
for ( iE = 0; iE < branch.size(); ++iE )
|
||||||
|
if ( branch[iE]->vertex1() == branchPoint )
|
||||||
|
break;
|
||||||
|
if ( iE < branch.size() )
|
||||||
|
{
|
||||||
|
// split the branch
|
||||||
|
branchEdges.resize(( branchID = branchEdges.size()) + 1 );
|
||||||
|
vector<const TVDEdge*> & branch2 = branchEdges[ branchID ];
|
||||||
|
branch2.assign( branch.begin()+iE, branch.end() );
|
||||||
|
branch.resize( iE );
|
||||||
|
for ( iE = 0; iE < branch2.size(); ++iE )
|
||||||
|
if ( BndSeg* bs = BndSeg::getBndSegOfEdge( branch2[iE], bndSegsPerEdge ))
|
||||||
|
bs->setBranch( branchID, bndSegsPerEdge );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// join the 1st and the last branch edges if it is the same branch
|
// join the 1st and the last branch edges if it is the same branch
|
||||||
// if ( bndSegs.back().branchID() != bndSegs.front().branchID() &&
|
// if ( bndSegs.back().branchID() != bndSegs.front().branchID() &&
|
||||||
// bndSegs.back().isSameBranch( bndSegs.front() ))
|
// bndSegs.back().isSameBranch( bndSegs.front() ))
|
||||||
@ -1073,10 +1112,14 @@ namespace
|
|||||||
// br2.clear();
|
// br2.clear();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// remove branches ending at BE_ON_VERTEX
|
// remove branches ending at BE_ON_VERTEX and BE_END
|
||||||
|
|
||||||
vector<bool> isBranchRemoved( branchEdges.size(), false );
|
vector<bool> isBranchRemoved( branchEdges.size(), false );
|
||||||
|
|
||||||
|
std::set< SMESH_MAT2d::BranchEndType > endTypeToRm;
|
||||||
|
endTypeToRm.insert( SMESH_MAT2d::BE_ON_VERTEX );
|
||||||
|
endTypeToRm.insert( SMESH_MAT2d::BE_END );
|
||||||
|
|
||||||
if ( ignoreCorners && branchEdges.size() > 2 && !branchEdges[2].empty() )
|
if ( ignoreCorners && branchEdges.size() > 2 && !branchEdges[2].empty() )
|
||||||
{
|
{
|
||||||
// find branches to remove
|
// find branches to remove
|
||||||
@ -1088,10 +1131,10 @@ namespace
|
|||||||
const TVDVertex* v0 = branchEdges[iB][0]->vertex1();
|
const TVDVertex* v0 = branchEdges[iB][0]->vertex1();
|
||||||
const TVDVertex* v1 = branchEdges[iB].back()->vertex0();
|
const TVDVertex* v1 = branchEdges[iB].back()->vertex0();
|
||||||
v2et = endType.find( v0 );
|
v2et = endType.find( v0 );
|
||||||
if ( v2et != endType.end() && v2et->second == SMESH_MAT2d::BE_ON_VERTEX )
|
if ( v2et != endType.end() && endTypeToRm.count( v2et->second ))
|
||||||
isBranchRemoved[ iB ] = true;
|
isBranchRemoved[ iB ] = true;
|
||||||
v2et = endType.find( v1 );
|
v2et = endType.find( v1 );
|
||||||
if ( v2et != endType.end() && v2et->second == SMESH_MAT2d::BE_ON_VERTEX )
|
if ( v2et != endType.end() && endTypeToRm.count( v2et->second ))
|
||||||
isBranchRemoved[ iB ] = true;
|
isBranchRemoved[ iB ] = true;
|
||||||
}
|
}
|
||||||
// try to join not removed branches into one
|
// try to join not removed branches into one
|
||||||
|
@ -1072,7 +1072,7 @@ namespace
|
|||||||
if ( ! ( theDivPoints[0]._iEdge == 0 &&
|
if ( ! ( theDivPoints[0]._iEdge == 0 &&
|
||||||
theDivPoints[0]._edgeParam == 0. )) // recursive call
|
theDivPoints[0]._edgeParam == 0. )) // recursive call
|
||||||
{
|
{
|
||||||
SMESH_MAT2d::BranchPoint brp( &branch, 0, 0 );
|
SMESH_MAT2d::BranchPoint brp( &branch, 0, 0. );
|
||||||
vector< SMESH_MAT2d::BranchPoint > divPoint( 1, brp );
|
vector< SMESH_MAT2d::BranchPoint > divPoint( 1, brp );
|
||||||
vector< std::size_t > edgeIDs1(2), edgeIDs2(2);
|
vector< std::size_t > edgeIDs1(2), edgeIDs2(2);
|
||||||
edgeIDs1[0] = theEdgeIDs1.back();
|
edgeIDs1[0] = theEdgeIDs1.back();
|
||||||
@ -1084,9 +1084,10 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// project theDivPoints
|
// project theDivPoints and keep projections to merge
|
||||||
|
|
||||||
TMAPar2NPoints::iterator u2NP;
|
TMAPar2NPoints::iterator u2NP;
|
||||||
|
vector< TMAPar2NPoints::iterator > projToMerge;
|
||||||
for ( size_t i = 0; i < theDivPoints.size(); ++i )
|
for ( size_t i = 0; i < theDivPoints.size(); ++i )
|
||||||
{
|
{
|
||||||
if ( !branch.getParameter( theDivPoints[i], uMA ))
|
if ( !branch.getParameter( theDivPoints[i], uMA ))
|
||||||
@ -1129,9 +1130,18 @@ namespace
|
|||||||
if ( isVertex[0] && isVertex[1] )
|
if ( isVertex[0] && isVertex[1] )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
|
// bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
|
||||||
if ( !isOppComputed )
|
// if ( isOppComputed )
|
||||||
continue;
|
projToMerge.push_back( u2NP );
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge projections
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < projToMerge.size(); ++i )
|
||||||
|
{
|
||||||
|
u2NP = projToMerge[i];
|
||||||
|
const size_t iVert = get( u2NP->second, 0 )._node ? 0 : 1; // side with a VERTEX
|
||||||
|
const size_t iNode = 1 - iVert; // opposite (meshed?) side
|
||||||
|
|
||||||
// a VERTEX is projected on a meshed EDGE; there are two options:
|
// a VERTEX is projected on a meshed EDGE; there are two options:
|
||||||
// 1) a projected point is joined with a closet node if a strip between this and neighbor
|
// 1) a projected point is joined with a closet node if a strip between this and neighbor
|
||||||
@ -1145,10 +1155,6 @@ namespace
|
|||||||
bool isShortPrev[2], isShortNext[2], isPrevCloser[2];
|
bool isShortPrev[2], isShortNext[2], isPrevCloser[2];
|
||||||
TMAPar2NPoints::iterator u2NPPrev = u2NP, u2NPNext = u2NP;
|
TMAPar2NPoints::iterator u2NPPrev = u2NP, u2NPNext = u2NP;
|
||||||
--u2NPPrev; ++u2NPNext;
|
--u2NPPrev; ++u2NPNext;
|
||||||
// bool hasPrev = ( u2NP != thePointsOnE.begin() );
|
|
||||||
// bool hasNext = ( u2NPNext != thePointsOnE.end() );
|
|
||||||
// if ( !hasPrev ) u2NPPrev = u2NP0;
|
|
||||||
// if ( !hasNext ) u2NPNext = u2NP1;
|
|
||||||
for ( int iS = 0; iS < 2; ++iS ) // side with Vertex and side with Nodes
|
for ( int iS = 0; iS < 2; ++iS ) // side with Vertex and side with Nodes
|
||||||
{
|
{
|
||||||
NodePoint np = get( u2NP->second, iS );
|
NodePoint np = get( u2NP->second, iS );
|
||||||
@ -1161,11 +1167,9 @@ namespace
|
|||||||
double distNext = p.Distance( pNext );
|
double distNext = p.Distance( pNext );
|
||||||
double r = distPrev / ( distPrev + distNext );
|
double r = distPrev / ( distPrev + distNext );
|
||||||
isShortPrev [iS] = ( r < rShort );
|
isShortPrev [iS] = ( r < rShort );
|
||||||
isShortNext [iS] = (( 1 - r ) > ( 1 - rShort ));
|
isShortNext [iS] = (( 1 - r ) < rShort );
|
||||||
isPrevCloser[iS] = (( r < 0.5 ) && ( u2NPPrev->first > 0 ));
|
isPrevCloser[iS] = (( r < 0.5 ) && ( theSinuFace.IsRing() || u2NPPrev->first > 0 ));
|
||||||
}
|
}
|
||||||
// if ( !hasPrev ) isShortPrev[0] = isShortPrev[1] = false;
|
|
||||||
// if ( !hasNext ) isShortNext[0] = isShortNext[1] = false;
|
|
||||||
|
|
||||||
TMAPar2NPoints::iterator u2NPClose;
|
TMAPar2NPoints::iterator u2NPClose;
|
||||||
|
|
||||||
@ -1174,17 +1178,18 @@ namespace
|
|||||||
{
|
{
|
||||||
u2NPClose = isPrevCloser[0] ? u2NPPrev : u2NPNext;
|
u2NPClose = isPrevCloser[0] ? u2NPPrev : u2NPNext;
|
||||||
NodePoint& npProj = get( u2NP->second, iNode ); // NP of VERTEX projection
|
NodePoint& npProj = get( u2NP->second, iNode ); // NP of VERTEX projection
|
||||||
|
NodePoint& npVert = get( u2NP->second, iVert ); // NP of VERTEX
|
||||||
NodePoint npCloseN = get( u2NPClose->second, iNode ); // NP close to npProj
|
NodePoint npCloseN = get( u2NPClose->second, iNode ); // NP close to npProj
|
||||||
NodePoint npCloseV = get( u2NPClose->second, iVert ); // NP close to VERTEX
|
NodePoint npCloseV = get( u2NPClose->second, iVert ); // NP close to npVert
|
||||||
if ( !npCloseV._node )
|
if ( !npCloseV._node || npCloseV._node == npVert._node )
|
||||||
{
|
{
|
||||||
npProj = npCloseN;
|
npProj = npCloseN;
|
||||||
thePointsOnE.erase( isPrevCloser[0] ? u2NPPrev : u2NPNext );
|
thePointsOnE.erase( u2NPClose );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// can't remove the neighbor projection as it is also from VERTEX, -> option 1)
|
// can't remove the neighbor projection as it is also from VERTEX -> option 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else: option 1) - wide enough -> "duplicate" existing node
|
// else: option 1) - wide enough -> "duplicate" existing node
|
||||||
|
@ -265,7 +265,7 @@
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>ICON_SMESH_TREE_HYPO_QuadraticMesh</source>
|
<source>ICON_SMESH_TREE_HYPO_QuadraticMesh</source>
|
||||||
<translation>mesh_tree_hypo_length.png</translation>
|
<translation>mesh_tree_hypo_quadratic.png</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>ICON_SMESH_TREE_HYPO_SegmentLengthAroundVertex</source>
|
<source>ICON_SMESH_TREE_HYPO_SegmentLengthAroundVertex</source>
|
||||||
|
Loading…
Reference in New Issue
Block a user