#include <TopExp_Explorer.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
// get ordered src EDGEs
TError err;
srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err);
- if ( err && !err->IsOK() )
+ if ( err && !err->IsOK() || srcWires.empty() )
return err;
+ SMESH_MesherHelper srcHelper( *srcMesh );
+ srcHelper.SetSubShape( srcFace );
+
// make corresponding sequence of tgt EDGEs
tgtWires.resize( srcWires.size() );
for ( size_t iW = 0; iW < srcWires.size(); ++iW )
{
- list< TopoDS_Edge > tgtEdges;
+ // check ori
+ bool reverse = false;
StdMeshers_FaceSidePtr srcWire = srcWires[iW];
+ // for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
+ // {
+ // if ( srcHelper.IsRealSeam( srcWire->EdgeID( iE )))
+ // continue;
+ // TopoDS_Shape srcE = srcWire->Edge( iE );
+ // TopoDS_Shape tgtE = shape2ShapeMap( srcE, /*isSrc=*/true);
+ // if ( shape2ShapeMap._assocType == TShapeShapeMap::PROPAGATION ||
+ // shape2ShapeMap._assocType == TShapeShapeMap::PROPAGATION)
+ // {
+ // reverse = false;
+ // }
+ // else if ( tgtMesh == srcMesh )
+ // {
+ // reverse = (( srcE.Orientation() == srcHelper.GetSubShapeOri( srcFace, srcE )) !=
+ // ( tgtE.Orientation() == srcHelper.GetSubShapeOri( tgtFace, tgtE )));
+ // }
+ // else
+ // {
+ // TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false );
+ // reverse = ( srcE.Orientation() != srcEbis.Orientation() );
+ // }
+ // break;
+ // }
+
+ list< TopoDS_Edge > tgtEdges;
TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
{
TopoDS_Edge tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true));
TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false );
if ( srcE.Orientation() != srcEbis.Orientation() )
+ //if ( reverse )
tgtE.Reverse();
// reverse a seam edge encountered for the second time
const int index = edgeMap.Add( tgtE );
srcMesh = tgtMesh;
SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+ SMESH_MesherHelper helper( theMesh );
// ---------------------------
// Make sub-shapes association
{
if ( srcShape.ShapeType() == TopAbs_FACE )
{
- int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
- int nbE2 = SMESH_MesherHelper::Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true );
+ int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
+ int nbE2 = helper.Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true );
if ( nbE1 != nbE2 )
return error(COMPERR_BAD_SHAPE,
SMESH_Comment("Different number of edges in source and target faces: ")
}
TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD));
+ // orient faces
+ // if ( srcMesh == tgtMesh )
+ // {
+ // TopoDS_Shape solid =
+ // helper.GetCommonAncestor( srcFace, tgtFace, *tgtMesh, TopAbs_SOLID );
+ // if ( !solid.IsNull() )
+ // {
+ // srcFace.Orientation( helper.GetSubShapeOri( solid, srcFace ));
+ // tgtFace.Orientation( helper.GetSubShapeOri( solid, tgtFace ));
+ // }
+ // else if ( helper.NbAncestors( srcFace, *tgtMesh, TopAbs_SOLID ) == 1 &&
+ // helper.NbAncestors( tgtFace, *tgtMesh, TopAbs_SOLID ) == 1 )
+ // {
+ // srcFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), srcFace ));
+ // tgtFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), tgtFace ));
+ // }
+ // }
// ----------------------------------------------
// Assure that mesh on a source Face is computed
// ----------------------------------------------
shape2ShapeMap, _src2tgtNodes, is1DComputed);
}
- SMESH_MesherHelper helper( theMesh );
helper.SetSubShape( tgtFace );
// it will remove mesh built on edges and vertices in failure case
// Check if node projection to a face is needed
Bnd_B2d uvBox;
SMDS_ElemIteratorPtr faceIt = srcSubMesh->GetSubMeshDS()->GetElements();
- int nbFaceNodes = 0;
- for ( ; nbFaceNodes < 3 && faceIt->more(); ) {
+ set< const SMDS_MeshNode* > faceNodes;
+ for ( ; faceNodes.size() < 3 && faceIt->more(); ) {
const SMDS_MeshElement* face = faceIt->next();
SMDS_ElemIteratorPtr nodeIt = face->nodesIterator();
while ( nodeIt->more() ) {
const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
- if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
- nbFaceNodes++;
+ if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE &&
+ faceNodes.insert( node ).second )
uvBox.Add( helper.GetNodeUV( srcFace, node ));
- }
}
}
- const bool toProjectNodes =
- ( nbFaceNodes > 0 && ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN ));
+ bool toProjectNodes = false;
+ if ( faceNodes.size() == 1 )
+ toProjectNodes = ( uvBox.IsVoid() || uvBox.CornerMin().IsEqual( gp_XY(0,0), 1e-12 ));
+ else if ( faceNodes.size() > 1 )
+ toProjectNodes = ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN );
// Find the corresponding source and target vertex
// and <theReverse> flag needed to call mapper.Apply()
TopoDS_Vertex srcV1, tgtV1;
bool reverse = false;
- if ( _sourceHypo->HasVertexAssociation() ) {
- srcV1 = _sourceHypo->GetSourceVertex(1);
- tgtV1 = _sourceHypo->GetTargetVertex(1);
- } else {
- srcV1 = TopoDS::Vertex( TopExp_Explorer( srcFace, TopAbs_VERTEX ).Current() );
- tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true ));
- }
+ TopExp_Explorer vSrcExp( srcFace, TopAbs_VERTEX );
+ srcV1 = TopoDS::Vertex( vSrcExp.Current() );
+ tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true ));
+
list< TopoDS_Edge > tgtEdges, srcEdges;
list< int > nbEdgesInWires;
SMESH_Block::GetOrderedEdges( tgtFace, tgtEdges, nbEdgesInWires, tgtV1 );
TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 );
reverse = ( ! srcE1.IsSame( srcE1bis ));
if ( reverse &&
- _sourceHypo->HasVertexAssociation() &&
+ //_sourceHypo->HasVertexAssociation() &&
nbEdgesInWires.front() > 2 &&
helper.IsRealSeam( tgtEdges.front() ))
{
// we can't use only theReverse flag to correctly associate source
// and target faces in the mapper. Thus we select srcV1 so that
// GetOrderedEdges() to return EDGEs in a needed order
- list< TopoDS_Edge >::iterator edge = srcEdges.begin();
- for ( ; edge != srcEdges.end(); ++edge ) {
- if ( srcE1bis.IsSame( *edge )) {
- srcV1 = helper.IthVertex( 0, *edge );
- break;
+ TopoDS_Face tgtFaceBis = tgtFace;
+ TopTools_MapOfShape checkedVMap( tgtEdges.size() );
+ checkedVMap.Add ( srcV1 );
+ for ( vSrcExp.Next(); vSrcExp.More(); )
+ {
+ tgtFaceBis.Reverse();
+ tgtEdges.clear();
+ SMESH_Block::GetOrderedEdges( tgtFaceBis, tgtEdges, nbEdgesInWires, tgtV1 );
+ bool ok = true;
+ list< TopoDS_Edge >::iterator edgeS = srcEdges.begin(), edgeT = tgtEdges.begin();
+ for ( ; edgeS != srcEdges.end() && ok ; ++edgeS, ++edgeT )
+ ok = edgeT->IsSame( shape2ShapeMap( *edgeS, /*isSrc=*/true ));
+ if ( ok )
+ break; // FOUND!
+
+ reverse = !reverse;
+ if ( reverse )
+ {
+ vSrcExp.Next();
+ while ( vSrcExp.More() && !checkedVMap.Add( vSrcExp.Current() ))
+ vSrcExp.Next();
+ }
+ else
+ {
+ srcV1 = TopoDS::Vertex( vSrcExp.Current() );
+ tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true ));
+ srcEdges.clear();
+ SMESH_Block::GetOrderedEdges( srcFace, srcEdges, nbEdgesInWires, srcV1 );
+ }
+ }
+ }
+ // for the case: project to a closed face from a non-closed face w/o vertex assoc;
+ // avoid projecting to a seam from two EDGEs with different nb nodes on them
+ // ( test mesh_Projection_2D_01/B1 )
+ if ( !_sourceHypo->HasVertexAssociation() &&
+ nbEdgesInWires.front() > 2 &&
+ helper.IsRealSeam( tgtEdges.front() ))
+ {
+ TopoDS_Shape srcEdge1 = shape2ShapeMap( tgtEdges.front() );
+ list< TopoDS_Edge >::iterator srcEdge2 =
+ std::find( srcEdges.begin(), srcEdges.end(), srcEdge1);
+ list< TopoDS_Edge >::iterator srcEdge3 =
+ std::find( srcEdges.begin(), srcEdges.end(), srcEdge1.Reversed());
+ if ( srcEdge2 == srcEdges.end() || srcEdge3 == srcEdges.end() ) // srcEdge1 is not a seam
+ {
+ // find srcEdge2 which also will be projected to tgtEdges.front()
+ for ( srcEdge2 = srcEdges.begin(); srcEdge2 != srcEdges.end(); ++srcEdge2 )
+ if ( !srcEdge1.IsSame( *srcEdge2 ) &&
+ tgtEdges.front().IsSame( shape2ShapeMap( *srcEdge2, /*isSrc=*/true )))
+ break;
+ // compare nb nodes on srcEdge1 and srcEdge2
+ if ( srcEdge2 != srcEdges.end() )
+ {
+ int nbN1 = 0, nbN2 = 0;
+ if ( SMESHDS_SubMesh* sm = srcMesh->GetMeshDS()->MeshElements( srcEdge1 ))
+ nbN1 = sm->NbNodes();
+ if ( SMESHDS_SubMesh* sm = srcMesh->GetMeshDS()->MeshElements( *srcEdge2 ))
+ nbN2 = sm->NbNodes();
+ if ( nbN1 != nbN2 )
+ srcV1 = helper.IthVertex( 1, srcEdges.front() );
}
}
}
// Compute mesh on a target face
mapper.Apply( tgtFace, tgtV1, reverse );
- if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
+ if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) {
+ // std::ofstream file("/tmp/Pattern.smp" );
+ // mapper.Save( file );
return error("Can't apply source mesh pattern to the face");
+ }
// Create the mesh
u2nodesOnSeam.size() > 0 &&
seam.ShapeType() == TopAbs_EDGE )
{
- int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
- int nbE2 = SMESH_MesherHelper::Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true );
+ int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
+ int nbE2 = helper.Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true );
if ( nbE1 != nbE2 ) // 2 EDGEs are mapped to a seam EDGE
{
// find the 2 EDGEs of srcFace