// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-// SMESH SMESH : implementaion of SMESH idl descriptions
+// SMESH SMESH : implementation of SMESH idl descriptions
// File : StdMeshers_Projection_2D.cxx
// Module : SMESH
// Created : Fri Oct 20 11:37:07 2006
using namespace std;
#define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
+#ifdef _DEBUG_
+// enable printing algo + projection shapes while meshing
+//#define PRINT_WHO_COMPUTE_WHAT
+#endif
namespace TAssocTool = StdMeshers_ProjectionUtils;
//typedef StdMeshers_ProjectionUtils TAssocTool;
//purpose :
//=======================================================================
-StdMeshers_Projection_2D::StdMeshers_Projection_2D(int hypId, int studyId, SMESH_Gen* gen)
- :SMESH_2D_Algo(hypId, studyId, gen)
+StdMeshers_Projection_2D::StdMeshers_Projection_2D(int hypId, SMESH_Gen* gen)
+ :SMESH_2D_Algo(hypId, gen)
{
_name = "Projection_2D";
_compatibleHypothesis.push_back("ProjectionSource2D");
const TopoDS_Face& srcFace,
SMESH_Mesh * tgtMesh,
SMESH_Mesh * srcMesh,
+ SMESH_MesherHelper* tgtHelper,
const TAssocTool::TShapeShapeMap& shape2ShapeMap,
TSideVector& srcWires,
TSideVector& tgtWires,
// get ordered src EDGEs
TError err;
- srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err);
+ srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err );
if (( err && !err->IsOK() ) ||
( srcWires.empty() ))
return err;
-
- SMESH_MesherHelper srcHelper( *srcMesh );
- srcHelper.SetSubShape( srcFace );
+#ifdef PRINT_WHO_COMPUTE_WHAT
+ cout << "Projection_2D" << " F "
+ << tgtMesh->GetMeshDS()->ShapeToIndex( tgtFace ) << " <- "
+ << srcMesh->GetMeshDS()->ShapeToIndex( srcFace ) << endl;
+#endif
// make corresponding sequence of tgt EDGEs
tgtWires.resize( srcWires.size() );
tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
/*theIsForward = */ true,
- /*theIgnoreMediumNodes = */false));
+ /*theIgnoreMediumNodes = */false,
+ tgtHelper ));
StdMeshers_FaceSidePtr tgtWire = tgtWires[ iW ];
// Fill map of src to tgt nodes with nodes on edges
for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
{
+#ifdef PRINT_WHO_COMPUTE_WHAT
+ if ( tgtMesh->GetSubMesh( tgtWire->Edge(iE) )->IsEmpty() )
+ cout << "Projection_2D" << " E "
+ << tgtWire->EdgeID(iE) << " <- " << srcWire->EdgeID(iE) << endl;
+#endif
if ( srcMesh->GetSubMesh( srcWire->Edge(iE) )->IsEmpty() ||
tgtMesh->GetSubMesh( tgtWire->Edge(iE) )->IsEmpty() )
{
else
{
const bool skipMedium = true, isFwd = true;
- StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), srcMesh, isFwd, skipMedium);
- StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), tgtMesh, isFwd, skipMedium);
-
+ StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE),
+ srcMesh, isFwd, skipMedium, srcWires[0]->FaceHelper() );
+ StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE),
+ tgtMesh, isFwd, skipMedium, tgtHelper);
+
vector< const SMDS_MeshNode* > srcNodes = srcEdge.GetOrderedNodes();
vector< const SMDS_MeshNode* > tgtNodes = tgtEdge.GetOrderedNodes();
//================================================================================
/*!
- * \brief Preform projection in case if tgtFace.IsPartner( srcFace ) and in case
+ * \brief Perform projection in case if tgtFace.IsPartner( srcFace ) and in case
* if projection by 3D transformation is possible
*/
//================================================================================
TAssocTool::TNodeNodeMap& src2tgtNodes,
const bool is1DComputed)
{
- SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh();
- SMESH_Mesh * srcMesh = srcWires[0]->GetMesh();
- SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
- SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
- SMESH_MesherHelper helper( *tgtMesh );
+ SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh();
+ SMESH_Mesh * srcMesh = srcWires[0]->GetMesh();
+ SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
+ SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
+ SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper();
const double tol = 1.e-7 * srcMeshDS->getMaxDim();
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 );
+ GeomAPI_ProjectPointOnSurf& proj = helper->GetProjector( tgtFace, loc, 0.1*tol );
if ( !loc.IsIdentity() )
tgtTrsfP.Transform( loc.Transformation().Inverted() );
proj.Perform( tgtTrsfP );
// Make new faces
// prepare the helper to adding quadratic elements if necessary
- //helper.SetSubShape( tgtFace );
- helper.IsQuadraticSubMesh( tgtFace );
+ helper->IsQuadraticSubMesh( tgtFace );
SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );
if ( !is1DComputed && srcSubDS->NbElements() )
- helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
+ helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
- SMESH_MesherHelper srcHelper( *srcMesh );
- srcHelper.SetSubShape( srcFace );
- SMESH_MesherHelper edgeHelper( *tgtMesh );
+ SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper();
+ SMESH_MesherHelper edgeHelper( *tgtMesh );
edgeHelper.ToFixNodeParameters( true );
const SMDS_MeshNode* nullNode = 0;
const SMDS_MeshElement* elem = elemIt->next();
const int nbN = elem->NbCornerNodes();
tgtNodes.resize( nbN );
- helper.SetElementsOnShape( false );
+ helper->SetElementsOnShape( false );
for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
{
const SMDS_MeshNode* srcNode = elem->GetNode(i);
{
// create a new node
gp_Pnt tgtP = trsf.Transform( SMESH_TNodeXYZ( srcNode ));
- SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
+ SMDS_MeshNode* n = helper->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
srcN_tgtN->second = n;
switch ( srcNode->GetPosition()->GetTypeOfPosition() )
{
case SMDS_TOP_FACE:
{
- gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode );
- tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), srcUV.X(), srcUV.Y() );
+ gp_Pnt2d srcUV = srcHelper->GetNodeUV( srcFace, srcNode );
+ tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), srcUV.X(), srcUV.Y() );
break;
}
case SMDS_TOP_EDGE:
{
const TopoDS_Edge& srcE = TopoDS::Edge( srcMeshDS->IndexToShape( srcNode->getshapeId()));
const TopoDS_Edge& tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true ));
- double srcU = srcHelper.GetNodeU( srcE, srcNode );
+ double srcU = srcHelper->GetNodeU( srcE, srcNode );
tgtMeshDS->SetNodeOnEdge( n, tgtE, srcU );
if ( !tgtFace.IsPartner( srcFace ))
{
tgtNodes[i] = srcN_tgtN->second;
}
// create a new face
- helper.SetElementsOnShape( true );
+ helper->SetElementsOnShape( true );
switch ( nbN )
{
- case 3: helper.AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break;
- case 4: helper.AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break;
+ case 3: helper->AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break;
+ case 4: helper->AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break;
default:
if ( isReverse ) std::reverse( tgtNodes.begin(), tgtNodes.end() );
- helper.AddPolygonalFace( tgtNodes );
+ helper->AddPolygonalFace( tgtNodes );
}
}
if ( !tgtFace.IsPartner( srcFace ) )
{
- helper.ToFixNodeParameters( true );
+ helper->ToFixNodeParameters( true );
int nbOkPos = 0;
const double tol2d = 1e-12;
case SMDS_TOP_FACE:
{
if ( nbOkPos > 10 ) break;
- gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv;
- if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) &&
+ gp_XY uv = helper->GetNodeUV( tgtFace, n ), uvBis = uv;
+ if (( helper->CheckNodeUV( tgtFace, n, uv, tol )) &&
(( uv - uvBis ).SquareModulus() < tol2d ))
++nbOkPos;
else
//================================================================================
/*!
- * \brief Preform projection in case if the faces are similar in 2D space
+ * \brief Perform projection in case if the faces are similar in 2D space
*/
//================================================================================
SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
- SMESH_MesherHelper helper( *tgtMesh );
- helper.SetSubShape( tgtFace );
+ SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper();
if ( is1DComputed )
- helper.IsQuadraticSubMesh( tgtFace );
+ helper->IsQuadraticSubMesh( tgtFace );
else
- helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
- helper.SetElementsOnShape( true );
+ helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
+ helper->SetElementsOnShape( true );
Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace );
SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
- SMESH_MesherHelper srcHelper( *srcMesh );
- srcHelper.SetSubShape( srcFace );
+ SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper();
const SMDS_MeshNode* nullNode = 0;
TAssocTool::TNodeNodeMap::iterator srcN_tgtN;
while ( elemIt->more() ) // loop on all mesh faces on srcFace
{
const SMDS_MeshElement* elem = elemIt->next();
- const int nbN = elem->NbCornerNodes();
+ const int nbN = elem->NbCornerNodes();
tgtNodes.resize( nbN );
for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
{
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 srcUV = srcHelper->GetNodeUV( srcFace, srcNode,
+ elem->GetNode( helper->WrapIndex(i+1,nbN)), &uvOK);
gp_Pnt2d tgtUV = trsf.Transform( srcUV );
gp_Pnt tgtP = tgtSurface->Value( tgtUV.X(), tgtUV.Y() );
SMDS_MeshNode* n = tgtMeshDS->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
switch ( srcNode->GetPosition()->GetTypeOfPosition() )
{
case SMDS_TOP_FACE: {
- tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), tgtUV.X(), tgtUV.Y() );
+ tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), tgtUV.X(), tgtUV.Y() );
break;
}
case SMDS_TOP_EDGE: {
- TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
+ TopoDS_Shape srcEdge = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() );
TopoDS_Edge tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true ));
double U = Precision::Infinite();
- helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
+ helper->CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ), U );
break;
}
case SMDS_TOP_VERTEX: {
- TopoDS_Shape srcV = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
+ TopoDS_Shape srcV = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() );
TopoDS_Shape tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV ));
break;
// 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;
+ case 3: helper->AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break;
+ case 4: helper->AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break;
}
} // loop on all mesh faces on srcFace
//================================================================================
/*!
- * \brief Preform projection in case of quadrilateral faces
+ * \brief Perform projection in case of quadrilateral faces
*/
//================================================================================
// }
// else
// {
- // // find XY of src node withing the quadrilateral srcFace
+ // // find XY of src node within the quadrilateral srcFace
// if ( !block.ComputeParameters( SMESH_TNodeXYZ( srcNode ),
// tgtNodeOrXY.second, srcFaceBID ))
// return false;
// // as all XY are computed, create tgt nodes and faces
- // SMESH_MesherHelper helper( *tgtMesh );
- // helper.SetSubShape( tgtFace );
+ // SMESH_MesherHelper helper = *tgtWires[0]->FaceHelper();
// if ( is1DComputed )
// helper.IsQuadraticSubMesh( tgtFace );
// else
// helper.SetElementsOnShape( true );
// Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace );
- // SMESH_MesherHelper srcHelper( *srcMesh );
- // srcHelper.SetSubShape( srcFace );
+ // SMESH_MesherHelper srcHelper = *srcWires[0]->FaceHelper();
// vector< const SMDS_MeshNode* > tgtNodes;
// gp_XY uv;
{
SMESH_subMesh* faceSM = helper.GetMesh()->GetSubMesh( helper.GetSubShape() );
- if ( helper.IsDistorted2D( faceSM, /*checkUV=*/true ))
+ //if ( helper.IsDistorted2D( faceSM, /*checkUV=*/true ))
{
SMESH_MeshEditor editor( helper.GetMesh() );
SMESHDS_SubMesh* smDS = faceSM->GetSubMeshDS();
return true;
}
- typedef list< pair< const SMDS_MeshNode*, const BRepMesh_Triangle* > > TNodeTriaList;
-
- //================================================================================
- /*!
- * \brief Add in-FACE nodes surrounding a given node to a queue
- */
- //================================================================================
-
- void addCloseNodes( const SMDS_MeshNode* srcNode,
- const BRepMesh_Triangle* bmTria,
- const int srcFaceID,
- TNodeTriaList & noTriQueue )
- {
- // find in-FACE nodes
- SMDS_ElemIteratorPtr elems = srcNode->GetInverseElementIterator(SMDSAbs_Face);
- while ( elems->more() )
- {
- const SMDS_MeshElement* elem = elems->next();
- if ( elem->getshapeId() == srcFaceID )
- {
- for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
- {
- const SMDS_MeshNode* n = elem->GetNode( i );
- if ( !n->isMarked() )
- noTriQueue.push_back( make_pair( n, bmTria ));
- }
- }
- }
- }
-
- //================================================================================
- /*!
- * \brief Find a delauney triangle containing a given 2D point and return
- * barycentric coordinates within the found triangle
- */
- //================================================================================
-
- const BRepMesh_Triangle* findTriangle( const gp_XY& uv,
- const BRepMesh_Triangle* bmTria,
- Handle(BRepMesh_DataStructureOfDelaun)& triaDS,
- double bc[3] )
- {
- int nodeIDs[3];
- gp_XY nodeUVs[3];
- int linkIDs[3];
- Standard_Boolean ori[3];
-
- while ( bmTria )
- {
- // check bmTria
-
- triaDS->ElementNodes( *bmTria, nodeIDs );
- nodeUVs[0] = triaDS->GetNode( nodeIDs[0] ).Coord();
- nodeUVs[1] = triaDS->GetNode( nodeIDs[1] ).Coord();
- nodeUVs[2] = triaDS->GetNode( nodeIDs[2] ).Coord();
-
- SMESH_MeshAlgos::GetBarycentricCoords( uv,
- nodeUVs[0], nodeUVs[1], nodeUVs[2],
- bc[0], bc[1] );
- if ( bc[0] >= 0 && bc[1] >= 0 && bc[0] + bc[1] <= 1 )
- {
- bc[2] = 1 - bc[0] - bc[1];
- return bmTria;
- }
-
- // look for a neighbor triangle, which is adjacent to a link intersected
- // by a segment( triangle center -> uv )
-
- gp_XY gc = ( nodeUVs[0] + nodeUVs[1] + nodeUVs[2] ) / 3.;
- gp_XY seg = uv - gc;
-
- bmTria->Edges( linkIDs, ori );
- int triaID = triaDS->IndexOf( *bmTria );
- bmTria = 0;
-
- for ( int i = 0; i < 3; ++i )
- {
- const BRepMesh_PairOfIndex & triIDs = triaDS->ElementsConnectedTo( linkIDs[i] );
- if ( triIDs.Extent() < 2 )
- continue; // no neighbor triangle
-
- // check if a link intersects gc2uv
- const BRepMesh_Edge & link = triaDS->GetLink( linkIDs[i] );
- const BRepMesh_Vertex & n1 = triaDS->GetNode( link.FirstNode() );
- const BRepMesh_Vertex & n2 = triaDS->GetNode( link.LastNode() );
- gp_XY uv1 = n1.Coord();
- gp_XY lin = n2.Coord() - uv1; // link direction
-
- double crossSegLin = seg ^ lin;
- if ( Abs( crossSegLin ) < std::numeric_limits<double>::min() )
- continue; // parallel
-
- double uSeg = ( uv1 - gc ) ^ lin / crossSegLin;
- if ( 0. <= uSeg && uSeg <= 1. )
- {
- bmTria = & triaDS->GetElement( triIDs.Index( 1 + ( triIDs.Index(1) == triaID )));
- break;
- }
- }
- }
- return bmTria;
- }
-
- //================================================================================
- /*!
- * \brief Morph mesh on the target face to lie within FACE boundary w/o distortion
- *
- * algo:
- * - make a CDT on the src FACE
- * - find a triangle containing a src node and get its barycentric coordinates
- * - move the node to a point with the same barycentric coordinates in a corresponding
- * tgt triangle
- */
- //================================================================================
-
- bool morph( SMESH_MesherHelper& tgtHelper,
- const TopoDS_Face& tgtFace,
- const TopoDS_Face& srcFace,
- const TSideVector& tgtWires,
- const TSideVector& srcWires,
- const TAssocTool::TNodeNodeMap& src2tgtNodes )
- {
- if ( srcWires.size() != tgtWires.size() ) return false;
- if ( srcWires.size() == 1 ) return false; // tmp
-
- // count boundary points
- int iP = 1, nbP = 0;
- for ( size_t iW = 0; iW < srcWires.size(); ++iW )
- nbP += srcWires[iW]->NbPoints() - 1; // 1st and last points coincide
-
- // fill boundary points
- BRepMesh::Array1OfVertexOfDelaun srcVert( 1, 1 + nbP ), tgtVert( 1, 1 + nbP );
- vector< const SMDS_MeshNode* > bndSrcNodes( nbP + 1 ); bndSrcNodes[0] = 0;
- BRepMesh_Vertex v( 0, 0, BRepMesh_Frontier );
- for ( size_t iW = 0; iW < srcWires.size(); ++iW )
- {
- const UVPtStructVec& srcPnt = srcWires[iW]->GetUVPtStruct();
- const UVPtStructVec& tgtPnt = tgtWires[iW]->GetUVPtStruct();
- if ( srcPnt.size() != tgtPnt.size() ) return false;
-
- for ( int i = 0, nb = srcPnt.size() - 1; i < nb; ++i, ++iP )
- {
- bndSrcNodes[ iP ] = srcPnt[i].node;
- srcPnt[i].node->setIsMarked( true );
-
- v.ChangeCoord() = srcPnt[i].UV();
- srcVert( iP ) = v;
- v.ChangeCoord() = tgtPnt[i].UV();
- tgtVert( iP ) = v;
- }
- }
- // triangulate the srcFace in 2D
- BRepMesh_Delaun delauney( srcVert );
- Handle(BRepMesh_DataStructureOfDelaun) triaDS = delauney.Result();
-
- Handle(ShapeAnalysis_Surface) tgtSurface = tgtHelper.GetSurface( tgtFace );
- SMESHDS_Mesh* srcMesh = srcWires[0]->GetMesh()->GetMeshDS();
- SMESHDS_Mesh* tgtMesh = tgtHelper.GetMeshDS();
- const SMDS_MeshNode *srcNode, *tgtNode;
- const BRepMesh_Triangle *bmTria;
-
- // un-mark internal src nodes; later we will mark moved nodes
- SMDS_NodeIteratorPtr nIt = srcMesh->MeshElements( srcFace )->GetNodes();
- if ( !nIt || !nIt->more() ) return true;
- while ( nIt->more() )
- ( srcNode = nIt->next() )->setIsMarked( false );
-
- // initialize a queue of nodes with starting triangles
- const int srcFaceID = srcNode->getshapeId();
- TNodeTriaList noTriQueue;
- size_t iBndSrcN = 1;
- for ( ; iBndSrcN < bndSrcNodes.size() && noTriQueue.empty(); ++iBndSrcN )
- {
- // get a triangle
- const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN );
- const BRepMesh_PairOfIndex & triaIds = triaDS->ElementsConnectedTo( linkIds.First() );
- const BRepMesh_Triangle& tria = triaDS->GetElement( triaIds.Index(1) );
-
- addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue );
- }
-
- // Move tgt nodes
-
- double bc[3]; // barycentric coordinates
- int nodeIDs[3];
- bool checkUV = true;
- const SMDS_FacePosition* pos;
-
- while ( !noTriQueue.empty() )
- {
- srcNode = noTriQueue.front().first;
- bmTria = noTriQueue.front().second;
- noTriQueue.pop_front();
- if ( srcNode->isMarked() )
- continue;
- srcNode->setIsMarked( true );
-
- // find a delauney triangle containing the src node
- gp_XY uv = tgtHelper.GetNodeUV( srcFace, srcNode, NULL, &checkUV );
- bmTria = findTriangle( uv, bmTria, triaDS, bc );
- if ( !bmTria )
- continue;
-
- // compute new coordinates for a corresponding tgt node
- gp_XY uvNew( 0., 0. ), nodeUV;
- triaDS->ElementNodes( *bmTria, nodeIDs );
- for ( int i = 0; i < 3; ++i )
- uvNew += bc[i] * tgtVert( nodeIDs[i]).Coord();
- gp_Pnt xyz = tgtSurface->Value( uvNew );
-
- // find and move tgt node
- TAssocTool::TNodeNodeMap::const_iterator n2n = src2tgtNodes.find( srcNode );
- if ( n2n == src2tgtNodes.end() ) continue;
- tgtNode = n2n->second;
- tgtMesh->MoveNode( tgtNode, xyz.X(), xyz.Y(), xyz.Z() );
-
- if (( pos = dynamic_cast< const SMDS_FacePosition* >( tgtNode->GetPosition() )))
- const_cast<SMDS_FacePosition*>( pos )->SetParameters( uvNew.X(), uvNew.Y() );
-
- addCloseNodes( srcNode, bmTria, srcFaceID, noTriQueue );
-
- // assure that all src nodes are visited
- for ( ; iBndSrcN < bndSrcNodes.size() && noTriQueue.empty(); ++iBndSrcN )
- {
- const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN );
- const BRepMesh_PairOfIndex & triaIds = triaDS->ElementsConnectedTo( linkIds.First() );
- const BRepMesh_Triangle& tria = triaDS->GetElement( triaIds.Index(1) );
- addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue );
- }
- }
-
- return true;
- }
-
//=======================================================================
/*
* Set initial association of VERTEXes for the case of projection
// get ordered src and tgt EDGEs
TSideVector srcWires, tgtWires;
bool is1DComputed = false; // if any tgt EDGE is meshed
- TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh,
+ TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh, &helper,
shape2ShapeMap, srcWires, tgtWires, _src2tgtNodes, is1DComputed );
if ( err && !err->IsOK() )
return error( err );
TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front();
TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 );
reverse = ( ! srcE1.IsSame( srcE1bis ));
- if ( reverse &&
- //_sourceHypo->HasVertexAssociation() &&
+ if ( ( reverse || srcE1.Orientation() != srcE1bis.Orientation() ) &&
nbEdgesInWires.front() > 2 &&
helper.IsRealSeam( tgtEdges.front() ))
{
+ if ( srcE1.Orientation() != srcE1bis.Orientation() )
+ reverse = true;
// projection to a face with seam EDGE; pb is that GetOrderedEdges()
// always puts a seam EDGE first (if possible) and as a result
// we can't use only theReverse flag to correctly associate source
// boundary, also bad face can be created if EDGEs already discretized
// --> fix bad faces by smoothing
// ----------------------------------------------------------------
- if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false ))
+ if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false, &helper ))
{
- morph( helper, tgtFace, srcFace, tgtWires, srcWires, _src2tgtNodes );
+ TAssocTool::Morph morph( srcWires );
+ morph.Perform( helper, tgtWires, helper.GetSurface( tgtFace ),
+ _src2tgtNodes, /*moveAll=*/true );
if ( !fixDistortedFaces( helper, tgtWires ))
return error("Invalid mesh generated");