+ tgtNodes[i] = srcN_tgtN->second;
+ }
+ // create a new face
+ 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;
+ }
+ }
+ 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,
+ const bool is1DComputed)
+ {
+ // 1) Preparation
+
+ // get ordered src EDGEs
+ TError err;
+ TSideVector srcWires =
+ StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*ignoreMediumNodes = */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 ( is1DComputed &&
+ srcWires[iW]->GetUVPtStruct().size() !=
+ tgtWires[iW]->GetUVPtStruct().size())
+ return false;
+ }
+
+ // 2) Find transformation
+
+ gp_Trsf2d trsf;
+ {
+ // get 2 pairs of corresponding UVs
+ gp_Pnt2d srcP0 = srcWires[0]->Value2d(0.0);
+ gp_Pnt2d srcP1 = srcWires[0]->Value2d(0.333);
+ gp_Pnt2d tgtP0 = tgtWires[0]->Value2d(0.0);
+ gp_Pnt2d tgtP1 = tgtWires[0]->Value2d(0.333);
+
+ // 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();
+ for ( double u = 0.12; u < 1.; u += 0.1 )
+ {
+ gp_Pnt2d srcUV = srcWires[0]->Value2d( u );
+ gp_Pnt2d tgtUV = tgtWires[0]->Value2d( u );
+ 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 )
+ if ( is1DComputed )
+ {
+ 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 ));