mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-15 10:08:34 +05:00
0021144: [CEA 441] Problem with projection
+ bool projectBy2DSimilarity()
This commit is contained in:
parent
237e3eaae1
commit
d976fc7810
@ -30,18 +30,20 @@
|
|||||||
|
|
||||||
#include "StdMeshers_ProjectionSource2D.hxx"
|
#include "StdMeshers_ProjectionSource2D.hxx"
|
||||||
#include "StdMeshers_ProjectionUtils.hxx"
|
#include "StdMeshers_ProjectionUtils.hxx"
|
||||||
|
#include "StdMeshers_FaceSide.hxx"
|
||||||
|
|
||||||
|
#include "SMDS_EdgePosition.hxx"
|
||||||
|
#include "SMDS_FacePosition.hxx"
|
||||||
#include "SMESHDS_Hypothesis.hxx"
|
#include "SMESHDS_Hypothesis.hxx"
|
||||||
#include "SMESHDS_SubMesh.hxx"
|
#include "SMESHDS_SubMesh.hxx"
|
||||||
#include "SMESH_Block.hxx"
|
#include "SMESH_Block.hxx"
|
||||||
|
#include "SMESH_Comment.hxx"
|
||||||
#include "SMESH_Gen.hxx"
|
#include "SMESH_Gen.hxx"
|
||||||
#include "SMESH_Mesh.hxx"
|
#include "SMESH_Mesh.hxx"
|
||||||
#include "SMESH_MesherHelper.hxx"
|
#include "SMESH_MesherHelper.hxx"
|
||||||
#include "SMESH_Pattern.hxx"
|
#include "SMESH_Pattern.hxx"
|
||||||
#include "SMESH_subMesh.hxx"
|
#include "SMESH_subMesh.hxx"
|
||||||
#include "SMESH_subMeshEventListener.hxx"
|
#include "SMESH_subMeshEventListener.hxx"
|
||||||
#include "SMESH_Comment.hxx"
|
|
||||||
#include "SMDS_EdgePosition.hxx"
|
|
||||||
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
@ -360,11 +362,6 @@ namespace {
|
|||||||
/*!
|
/*!
|
||||||
* \brief Preform projection in case if tgtFace.IsPartner( srcFace ) and in case
|
* \brief Preform projection in case if tgtFace.IsPartner( srcFace ) and in case
|
||||||
* if projection by transformation is possible
|
* if projection by transformation is possible
|
||||||
* \param tgtFace - target face
|
|
||||||
* \param srcFace - source face
|
|
||||||
* \param tgtMesh - target mesh
|
|
||||||
* \param srcMesh - source mesh
|
|
||||||
* \retval bool - true if succeeded
|
|
||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
@ -529,48 +526,189 @@ namespace {
|
|||||||
helper.IsQuadraticSubMesh( tgtFace );
|
helper.IsQuadraticSubMesh( tgtFace );
|
||||||
helper.SetElementsOnShape( true );
|
helper.SetElementsOnShape( true );
|
||||||
|
|
||||||
|
SMESH_MesherHelper srcHelper( *srcMesh );
|
||||||
|
srcHelper.SetSubShape( srcFace );
|
||||||
|
|
||||||
const SMDS_MeshNode* nullNode = 0;
|
const SMDS_MeshNode* nullNode = 0;
|
||||||
|
|
||||||
SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
|
SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
|
||||||
SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements();
|
SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements();
|
||||||
|
vector< const SMDS_MeshNode* > tgtNodes;
|
||||||
while ( elemIt->more() ) // loop on all mesh faces on srcFace
|
while ( elemIt->more() ) // loop on all mesh faces on srcFace
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* elem = elemIt->next();
|
const SMDS_MeshElement* elem = elemIt->next();
|
||||||
vector< const SMDS_MeshNode* > tgtFaceNodes;
|
const int nbN = elem->NbCornerNodes();
|
||||||
tgtFaceNodes.reserve( elem->NbNodes() );
|
tgtNodes.resize( nbN );
|
||||||
SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
|
for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
|
||||||
while ( nodeIt->more() ) // loop on nodes of the source element
|
|
||||||
{
|
{
|
||||||
const SMDS_MeshNode* srcNode = (const SMDS_MeshNode*) nodeIt->next();
|
const SMDS_MeshNode* srcNode = elem->GetNode(i);
|
||||||
if (elem->IsMediumNode(srcNode))
|
|
||||||
continue;
|
|
||||||
srcN_tgtN = src2tgtNodes.insert( make_pair( srcNode, nullNode )).first;
|
srcN_tgtN = src2tgtNodes.insert( make_pair( srcNode, nullNode )).first;
|
||||||
if ( srcN_tgtN->second == nullNode )
|
if ( srcN_tgtN->second == nullNode )
|
||||||
{
|
{
|
||||||
// create a new node
|
// create a new node
|
||||||
gp_Pnt tgtP = gp_Pnt(srcNode->X(),srcNode->Y(),srcNode->Z()).Transformed( trsf );
|
gp_Pnt tgtP = gp_Pnt(srcNode->X(),srcNode->Y(),srcNode->Z()).Transformed( trsf );
|
||||||
srcN_tgtN->second = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
|
SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
|
||||||
//MESSAGE(tgtP.X() << " " << tgtP.Y() << " " << tgtP.Z());
|
srcN_tgtN->second = n;
|
||||||
|
|
||||||
|
gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode,
|
||||||
|
elem->GetNode( helper.WrapIndex(i+1,nbN)));
|
||||||
|
n->SetPosition( new SMDS_FacePosition( srcUV.X(), srcUV.Y() ));
|
||||||
}
|
}
|
||||||
tgtFaceNodes.push_back( srcN_tgtN->second );
|
tgtNodes[i] = srcN_tgtN->second;
|
||||||
}
|
}
|
||||||
// create a new face (with reversed orientation)
|
// create a new face (with reversed orientation)
|
||||||
//MESSAGE("tgtFaceNodes.size() " << tgtFaceNodes.size());
|
switch ( nbN )
|
||||||
switch (tgtFaceNodes.size())
|
|
||||||
{
|
{
|
||||||
case 3:
|
case 3: helper.AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break;
|
||||||
case 6:
|
case 4: helper.AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break;
|
||||||
helper.AddFace(tgtFaceNodes[0], tgtFaceNodes[2], tgtFaceNodes[1]);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
case 8:
|
|
||||||
helper.AddFace(tgtFaceNodes[0], tgtFaceNodes[3], tgtFaceNodes[2], tgtFaceNodes[1]);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
} // bool projectPartner()
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Preform projection in case if the faces are similar in 2D space
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
bool projectBy2DSimilarity(const TopoDS_Face& tgtFace,
|
||||||
|
const TopoDS_Face& srcFace,
|
||||||
|
SMESH_Mesh * tgtMesh,
|
||||||
|
SMESH_Mesh * srcMesh,
|
||||||
|
const TAssocTool::TShapeShapeMap& shape2ShapeMap)
|
||||||
|
{
|
||||||
|
// 1) Preparation
|
||||||
|
|
||||||
|
// get ordered src EDGEs
|
||||||
|
TError err;
|
||||||
|
TSideVector srcWires =
|
||||||
|
StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*theIgnoreMediumNodes = */false, err);
|
||||||
|
if ( err && !err->IsOK() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// make corresponding sequence of tgt EDGEs
|
||||||
|
TSideVector tgtWires( srcWires.size() );
|
||||||
|
for ( unsigned iW = 0; iW < srcWires.size(); ++iW )
|
||||||
|
{
|
||||||
|
list< TopoDS_Edge > tgtEdges;
|
||||||
|
StdMeshers_FaceSidePtr srcWire = srcWires[iW];
|
||||||
|
for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
|
||||||
|
tgtEdges.push_back( TopoDS::Edge( shape2ShapeMap( srcWire->Edge( iE ))));
|
||||||
|
|
||||||
|
tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
|
||||||
|
/*theIsForward = */ true,
|
||||||
|
/*theIgnoreMediumNodes = */false));
|
||||||
|
if ( srcWires[iW]->GetUVPtStruct().size() !=
|
||||||
|
tgtWires[iW]->GetUVPtStruct().size())
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2) Find transformation
|
||||||
|
|
||||||
|
gp_Trsf2d trsf;
|
||||||
|
{
|
||||||
|
// get ordered nodes data
|
||||||
|
const vector<UVPtStruct>& srcUVs = srcWires[0]->GetUVPtStruct();
|
||||||
|
const vector<UVPtStruct>& tgtUVs = tgtWires[0]->GetUVPtStruct();
|
||||||
|
|
||||||
|
// get 2 pairs of corresponding UVs
|
||||||
|
gp_XY srcP0( srcUVs[0].u, srcUVs[0].v );
|
||||||
|
gp_XY srcP1( srcUVs[1].u, srcUVs[1].v );
|
||||||
|
gp_XY tgtP0( tgtUVs[0].u, tgtUVs[0].v );
|
||||||
|
gp_XY tgtP1( tgtUVs[1].u, tgtUVs[1].v );
|
||||||
|
|
||||||
|
// make transformation
|
||||||
|
gp_Trsf2d fromTgtCS, toSrcCS; // from/to global CS
|
||||||
|
gp_Ax2d srcCS( srcP0, gp_Vec2d( srcP0, srcP1 ));
|
||||||
|
gp_Ax2d tgtCS( tgtP0, gp_Vec2d( tgtP0, tgtP1 ));
|
||||||
|
toSrcCS .SetTransformation( srcCS );
|
||||||
|
fromTgtCS.SetTransformation( tgtCS );
|
||||||
|
fromTgtCS.Invert();
|
||||||
|
|
||||||
|
trsf = fromTgtCS * toSrcCS;
|
||||||
|
|
||||||
|
// check transformation
|
||||||
|
const double tol = 1e-5 * gp_Vec2d( srcP0, srcP1 ).Magnitude();
|
||||||
|
const int nbCheckPnt = Min( 10, srcUVs.size()-2 );
|
||||||
|
const int dP = ( srcUVs.size()-2 ) / nbCheckPnt;
|
||||||
|
for ( unsigned iP = 2; iP < srcUVs.size(); iP += dP )
|
||||||
|
{
|
||||||
|
gp_Pnt2d srcUV( srcUVs[iP].u, srcUVs[iP].v );
|
||||||
|
gp_Pnt2d tgtUV( tgtUVs[iP].u, tgtUVs[iP].v );
|
||||||
|
gp_Pnt2d tgtUV2 = srcUV.Transformed( trsf );
|
||||||
|
if ( tgtUV.Distance( tgtUV2 ) > tol )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) Projection
|
||||||
|
|
||||||
|
typedef map<const SMDS_MeshNode* , const SMDS_MeshNode*, TIDCompare> TN2NMap;
|
||||||
|
TN2NMap src2tgtNodes;
|
||||||
|
TN2NMap::iterator srcN_tgtN;
|
||||||
|
|
||||||
|
// fill src2tgtNodes in with nodes on EDGEs
|
||||||
|
for ( unsigned iW = 0; iW < srcWires.size(); ++iW )
|
||||||
|
{
|
||||||
|
const vector<UVPtStruct>& srcUVs = srcWires[iW]->GetUVPtStruct();
|
||||||
|
const vector<UVPtStruct>& tgtUVs = tgtWires[iW]->GetUVPtStruct();
|
||||||
|
for ( unsigned i = 0; i < srcUVs.size(); ++i )
|
||||||
|
src2tgtNodes.insert( make_pair( srcUVs[i].node, tgtUVs[i].node ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// make elements
|
||||||
|
SMESH_MesherHelper helper( *tgtMesh );
|
||||||
|
helper.SetSubShape( tgtFace );
|
||||||
|
helper.IsQuadraticSubMesh( tgtFace );
|
||||||
|
helper.SetElementsOnShape( true );
|
||||||
|
Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace );
|
||||||
|
|
||||||
|
SMESH_MesherHelper srcHelper( *srcMesh );
|
||||||
|
srcHelper.SetSubShape( srcFace );
|
||||||
|
|
||||||
|
const SMDS_MeshNode* nullNode = 0;
|
||||||
|
|
||||||
|
SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
|
||||||
|
SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements();
|
||||||
|
vector< const SMDS_MeshNode* > tgtNodes;
|
||||||
|
bool uvOK;
|
||||||
|
while ( elemIt->more() ) // loop on all mesh faces on srcFace
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* elem = elemIt->next();
|
||||||
|
const int nbN = elem->NbCornerNodes();
|
||||||
|
tgtNodes.resize( nbN );
|
||||||
|
for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* srcNode = elem->GetNode(i);
|
||||||
|
srcN_tgtN = src2tgtNodes.insert( make_pair( srcNode, nullNode )).first;
|
||||||
|
if ( srcN_tgtN->second == nullNode )
|
||||||
|
{
|
||||||
|
// create a new node
|
||||||
|
gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode,
|
||||||
|
elem->GetNode( helper.WrapIndex(i+1,nbN)), &uvOK);
|
||||||
|
|
||||||
|
gp_Pnt2d tgtUV = srcUV.Transformed( trsf );
|
||||||
|
gp_Pnt tgtP = tgtSurface->Value( tgtUV.X(), tgtUV.Y() );
|
||||||
|
SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
|
||||||
|
n->SetPosition( new SMDS_FacePosition( tgtUV.X(), tgtUV.Y() ));
|
||||||
|
srcN_tgtN->second = n;
|
||||||
|
}
|
||||||
|
tgtNodes[i] = srcN_tgtN->second;
|
||||||
|
}
|
||||||
|
// create a new face (with reversed orientation)
|
||||||
|
switch ( nbN )
|
||||||
|
{
|
||||||
|
case 3: helper.AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break;
|
||||||
|
case 4: helper.AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} // bool projectBy2DSimilarity()
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
@ -628,6 +766,9 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
|
|||||||
if ( projectPartner( tgtFace, srcFace, tgtMesh, srcMesh, shape2ShapeMap ))
|
if ( projectPartner( tgtFace, srcFace, tgtMesh, srcMesh, shape2ShapeMap ))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if ( projectBy2DSimilarity( tgtFace, srcFace, tgtMesh, srcMesh, shape2ShapeMap ))
|
||||||
|
return true;
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
// Prepare to mapping
|
// Prepare to mapping
|
||||||
// --------------------
|
// --------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user