-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// SMESH SMESH : implementaion of SMESH idl descriptions
// File : StdMeshers_Projection_2D.cxx
// Module : SMESH
#include "StdMeshers_ProjectionSource2D.hxx"
#include "StdMeshers_ProjectionUtils.hxx"
+#include "StdMeshers_FaceSide.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
#include "SMESHDS_Hypothesis.hxx"
#include "SMESHDS_SubMesh.hxx"
#include "SMESH_Block.hxx"
+#include "SMESH_Comment.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_Pattern.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
-#include "SMESH_Comment.hxx"
-#include "SMDS_EdgePosition.hxx"
#include "utilities.h"
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopoDS.hxx>
+#include <gp_Ax2.hxx>
+#include <gp_Ax3.hxx>
using namespace std;
:SMESH_2D_Algo(hypId, studyId, gen)
{
_name = "Projection_2D";
- _shapeType = (1 << TopAbs_FACE); // 1 bit per shape type
+ _shapeType = (1 << TopAbs_FACE); // 1 bit per shape type
_compatibleHypothesis.push_back("ProjectionSource2D");
_sourceHypo = 0;
TopoDS_Shape edge = TAssocTool::GetEdgeByVertices
( srcMesh, _sourceHypo->GetSourceVertex(1), _sourceHypo->GetSourceVertex(2) );
if ( edge.IsNull() ||
- !TAssocTool::IsSubShape( edge, srcMesh ) ||
- !TAssocTool::IsSubShape( edge, _sourceHypo->GetSourceFace() ))
+ !SMESH_MesherHelper::IsSubShape( edge, srcMesh ) ||
+ !SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSourceFace() ))
{
theStatus = HYP_BAD_PARAMETER;
SCRUTE((edge.IsNull()));
- SCRUTE((TAssocTool::IsSubShape( edge, srcMesh )));
- SCRUTE((TAssocTool::IsSubShape( edge, _sourceHypo->GetSourceFace() )));
+ SCRUTE((SMESH_MesherHelper::IsSubShape( edge, srcMesh )));
+ SCRUTE((SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSourceFace() )));
}
else
{
// target vertices
edge = TAssocTool::GetEdgeByVertices
( tgtMesh, _sourceHypo->GetTargetVertex(1), _sourceHypo->GetTargetVertex(2) );
- if ( edge.IsNull() || !TAssocTool::IsSubShape( edge, tgtMesh ))
+ if ( edge.IsNull() || !SMESH_MesherHelper::IsSubShape( edge, tgtMesh ))
{
theStatus = HYP_BAD_PARAMETER;
SCRUTE((edge.IsNull()));
- SCRUTE((TAssocTool::IsSubShape( edge, tgtMesh )));
+ SCRUTE((SMESH_MesherHelper::IsSubShape( edge, tgtMesh )));
}
// PAL16203
else if ( !_sourceHypo->IsCompoundSource() &&
- !TAssocTool::IsSubShape( edge, theShape ))
+ !SMESH_MesherHelper::IsSubShape( edge, theShape ))
{
theStatus = HYP_BAD_PARAMETER;
- SCRUTE((TAssocTool::IsSubShape( edge, theShape )));
+ SCRUTE((SMESH_MesherHelper::IsSubShape( edge, theShape )));
}
}
}
// check a source face
- if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh ) ||
+ if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh ) ||
( srcMesh == tgtMesh && theShape == _sourceHypo->GetSourceFace() ))
{
theStatus = HYP_BAD_PARAMETER;
- SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh )));
+ SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh )));
SCRUTE((srcMesh == tgtMesh));
SCRUTE(( theShape == _sourceHypo->GetSourceFace() ));
}
namespace {
-
//================================================================================
/*!
* \brief define if a node is new or old
- * \param node - node to check
- * \retval bool - true if the node existed before Compute() is called
+ * \param node - node to check
+ * \retval bool - true if the node existed before Compute() is called
*/
//================================================================================
RETURN_BAD_RESULT("Bad node position type: node " << node->GetID() <<
" pos type " << node->GetPosition()->GetTypeOfPosition());
const SMDS_EdgePosition* pos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
u2nodes.insert( make_pair( pos->GetUParameter(), node ));
seamNodes.insert( node );
}
} // bool getBoundaryNodes()
+ //================================================================================
+ /*!
+ * \brief Preform projection in case if tgtFace.IsPartner( srcFace ) and in case
+ * if projection by transformation is possible
+ */
+ //================================================================================
+
+ bool projectPartner(const TopoDS_Face& tgtFace,
+ const TopoDS_Face& srcFace,
+ SMESH_Mesh * tgtMesh,
+ SMESH_Mesh * srcMesh,
+ const TAssocTool::TShapeShapeMap& shape2ShapeMap)
+ {
+ MESSAGE("projectPartner");
+ const double tol = 1.e-7*srcMesh->GetMeshDS()->getMaxDim();
+
+ gp_Trsf trsf; // transformation to get location of target nodes from source ones
+ if ( tgtFace.IsPartner( srcFace ))
+ {
+ gp_Trsf srcTrsf = srcFace.Location();
+ gp_Trsf tgtTrsf = tgtFace.Location();
+ trsf = srcTrsf.Inverted() * tgtTrsf;
+ }
+ else
+ {
+ // Try to find the transformation
+
+ // make any local coord systems of src and tgt faces
+ vector<gp_Pnt> srcPP, tgtPP; // 3 points on face boundaries to make axes of CS
+ SMESH_subMesh * srcSM = srcMesh->GetSubMesh( srcFace );
+ SMESH_subMeshIteratorPtr smIt = srcSM->getDependsOnIterator(/*includeSelf=*/false,false);
+ srcSM = smIt->next(); // sm of a vertex
+ while ( smIt->more() && srcPP.size() < 3 )
+ {
+ srcSM = smIt->next();
+ SMESHDS_SubMesh* srcSmds = srcSM->GetSubMeshDS();
+ if ( !srcSmds ) continue;
+ SMDS_NodeIteratorPtr nIt = srcSmds->GetNodes();
+ while ( nIt->more() )
+ {
+ SMESH_TNodeXYZ p ( nIt->next());
+ bool pOK = false;
+ switch ( srcPP.size() )
+ {
+ case 0: pOK = true; break;
+
+ case 1: pOK = ( srcPP[0].SquareDistance( p ) > 10*tol ); break;
+
+ case 2:
+ {
+ gp_Vec p0p1( srcPP[0], srcPP[1] ), p0p( srcPP[0], p );
+ // pOK = !p0p1.IsParallel( p0p, tol );
+ pOK = !p0p1.IsParallel( p0p, 3.14/20 ); // angle min 18 degrees
+ break;
+ }
+ }
+ if ( !pOK )
+ continue;
+
+ // find corresponding point on target shape
+ pOK = false;
+ gp_Pnt tgtP;
+ const TopoDS_Shape& tgtShape = shape2ShapeMap( srcSM->GetSubShape() );
+ if ( tgtShape.ShapeType() == TopAbs_VERTEX )
+ {
+ tgtP = BRep_Tool::Pnt( TopoDS::Vertex( tgtShape ));
+ pOK = true;
+ //cout << "V - nS " << p._node->GetID() << " - nT " << SMESH_Algo::VertexNode(TopoDS::Vertex( tgtShape),tgtMesh->GetMeshDS())->GetID() << endl;
+ }
+ else if ( tgtPP.size() > 0 )
+ {
+ if ( SMESHDS_SubMesh* tgtSmds = tgtMesh->GetMeshDS()->MeshElements( tgtShape ))
+ {
+ double srcDist = srcPP[0].Distance( p );
+ double eTol = BRep_Tool::Tolerance( TopoDS::Edge( tgtShape ));
+ if (eTol < tol) eTol = tol;
+ SMDS_NodeIteratorPtr nItT = tgtSmds->GetNodes();
+ while ( nItT->more() && !pOK )
+ {
+ const SMDS_MeshNode* n = nItT->next();
+ tgtP = SMESH_TNodeXYZ( n );
+ pOK = ( fabs( srcDist - tgtPP[0].Distance( tgtP )) < 2*eTol );
+ //cout << "E - nS " << p._node->GetID() << " - nT " << n->GetID()<< " OK - " << pOK<< " " << fabs( srcDist - tgtPP[0].Distance( tgtP ))<< " tol " << eTol<< endl;
+ }
+ }
+ }
+ if ( !pOK )
+ continue;
+
+ srcPP.push_back( p );
+ tgtPP.push_back( tgtP );
+ }
+ }
+ if ( srcPP.size() != 3 )
+ return false;
+
+ // make transformation
+ gp_Trsf fromTgtCS, toSrcCS; // from/to global CS
+ gp_Ax2 srcCS( srcPP[0], gp_Vec( srcPP[0], srcPP[1] ), gp_Vec( srcPP[0], srcPP[2]));
+ gp_Ax2 tgtCS( tgtPP[0], gp_Vec( tgtPP[0], tgtPP[1] ), gp_Vec( tgtPP[0], tgtPP[2]));
+ toSrcCS .SetTransformation( gp_Ax3( srcCS ));
+ fromTgtCS.SetTransformation( gp_Ax3( tgtCS ));
+ fromTgtCS.Invert();
+
+ trsf = fromTgtCS * toSrcCS;
+ }
+
+ // Fill map of src to tgt nodes with nodes on edges
+
+ map<const SMDS_MeshNode* , const SMDS_MeshNode*> src2tgtNodes;
+ map<const SMDS_MeshNode* , const SMDS_MeshNode*>::iterator srcN_tgtN;
+
+ for ( TopExp_Explorer srcEdge( srcFace, TopAbs_EDGE); srcEdge.More(); srcEdge.Next() )
+ {
+ const TopoDS_Shape& tgtEdge = shape2ShapeMap( srcEdge.Current() );
+
+ map< double, const SMDS_MeshNode* > srcNodes, tgtNodes;
+ if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMesh->GetMeshDS(),
+ TopoDS::Edge( srcEdge.Current() ),
+ /*ignoreMediumNodes = */true,
+ srcNodes )
+ ||
+ !SMESH_Algo::GetSortedNodesOnEdge( tgtMesh->GetMeshDS(),
+ TopoDS::Edge( tgtEdge ),
+ /*ignoreMediumNodes = */true,
+ tgtNodes )
+ ||
+ srcNodes.size() != tgtNodes.size())
+ return false;
+
+ if ( !tgtEdge.IsPartner( srcEdge.Current() ))
+ {
+ // check that transformation is OK by three nodes
+ gp_Pnt p0S = SMESH_TNodeXYZ( (srcNodes.begin()) ->second);
+ gp_Pnt p1S = SMESH_TNodeXYZ( (srcNodes.rbegin()) ->second);
+ gp_Pnt p2S = SMESH_TNodeXYZ( (++srcNodes.begin())->second);
+
+ gp_Pnt p0T = SMESH_TNodeXYZ( (tgtNodes.begin()) ->second);
+ gp_Pnt p1T = SMESH_TNodeXYZ( (tgtNodes.rbegin()) ->second);
+ gp_Pnt p2T = SMESH_TNodeXYZ( (++tgtNodes.begin())->second);
+
+ // transform source points, they must coincide with target ones
+ if ( p0T.SquareDistance( p0S.Transformed( trsf )) > tol ||
+ p1T.SquareDistance( p1S.Transformed( trsf )) > tol ||
+ p2T.SquareDistance( p2S.Transformed( trsf )) > tol )
+ {
+ //cout << "KO trsf, 3 dist: "
+ //<< p0T.SquareDistance( p0S.Transformed( trsf ))<< ", "
+ //<< p1T.SquareDistance( p1S.Transformed( trsf ))<< ", "
+ //<< p2T.SquareDistance( p2S.Transformed( trsf ))<< ", "<<endl;
+ return false;
+ }
+ }
+
+ map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
+ map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin();
+ for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
+ src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
+ }
+
+ // Make new faces
+
+ // prepare the helper adding quadratic elements if necessary
+ SMESH_MesherHelper helper( *tgtMesh );
+ helper.SetSubShape( tgtFace );
+ helper.IsQuadraticSubMesh( tgtFace );
+ helper.SetElementsOnShape( true );
+
+ 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;
+ 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_Pnt tgtP = gp_Pnt(srcNode->X(),srcNode->Y(),srcNode->Z()).Transformed( trsf );
+ SMDS_MeshNode* n = helper.AddNode( 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() ));
+ }
+ 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 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
+
//=======================================================================
//function : Compute
//purpose :
bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape)
{
+ MESSAGE("Projection_2D Compute");
if ( !_sourceHypo )
return false;
return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
}
+ // try to project from same face with different location
+ if ( projectPartner( tgtFace, srcFace, tgtMesh, srcMesh, shape2ShapeMap ))
+ return true;
+
+ if ( projectBy2DSimilarity( tgtFace, srcFace, tgtMesh, srcMesh, shape2ShapeMap ))
+ return true;
+
// --------------------
// Prepare to mapping
// --------------------
RETURN_BAD_RESULT("Not associated vertices, srcV1 " << srcV1.TShape().operator->() );
TopoDS_Vertex tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1 ));
- if ( !TAssocTool::IsSubShape( srcV1, srcFace ))
+ if ( !SMESH_MesherHelper::IsSubShape( srcV1, srcFace ))
RETURN_BAD_RESULT("Wrong srcV1 " << srcV1.TShape().operator->());
- if ( !TAssocTool::IsSubShape( tgtV1, tgtFace ))
+ if ( !SMESH_MesherHelper::IsSubShape( tgtV1, tgtFace ))
RETURN_BAD_RESULT("Wrong tgtV1 " << tgtV1.TShape().operator->());
// try to find out orientation by order of edges
}
case SMDS_TOP_EDGE: {
const SMDS_EdgePosition* pos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
break;
}
return true;
}
+
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+
+bool StdMeshers_Projection_2D::Evaluate(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape,
+ MapShapeNbElems& aResMap)
+{
+ if ( !_sourceHypo )
+ return false;
+
+ SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+ SMESH_Mesh * tgtMesh = & theMesh;
+ if ( !srcMesh )
+ srcMesh = tgtMesh;
+
+ // ---------------------------
+ // Make subshapes association
+ // ---------------------------
+
+ TopoDS_Face tgtFace = TopoDS::Face( theShape.Oriented(TopAbs_FORWARD));
+ TopoDS_Shape srcShape = _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD);
+
+ TAssocTool::TShapeShapeMap shape2ShapeMap;
+ TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtFace );
+ if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcShape, srcMesh,
+ shape2ShapeMap) ||
+ !shape2ShapeMap.IsBound( tgtFace ))
+ return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" );
+
+ TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD));
+
+ // ----------------------------------------------
+ // Assure that mesh on a source Face is computed
+ // ----------------------------------------------
+
+ SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( srcFace );
+
+ if ( !srcSubMesh->IsMeshComputed() )
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+
+
+ std::vector<int> aVec(SMDSEntity_Last);
+ for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
+
+ aVec[SMDSEntity_Node] = srcSubMesh->GetSubMeshDS()->NbNodes();
+
+ //bool quadratic = false;
+ SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+ while ( elemIt->more() ) {
+ const SMDS_MeshElement* E = elemIt->next();
+ if( E->NbNodes()==3 ) {
+ aVec[SMDSEntity_Triangle]++;
+ }
+ else if( E->NbNodes()==4 ) {
+ aVec[SMDSEntity_Quadrangle]++;
+ }
+ else if( E->NbNodes()==6 && E->IsQuadratic() ) {
+ aVec[SMDSEntity_Quad_Triangle]++;
+ }
+ else if( E->NbNodes()==8 && E->IsQuadratic() ) {
+ aVec[SMDSEntity_Quad_Quadrangle]++;
+ }
+ else {
+ aVec[SMDSEntity_Polygon]++;
+ }
+ }
+
+ SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+ aResMap.insert(std::make_pair(sm,aVec));
+
+ return true;
+}
+
+
//=============================================================================
/*!
* \brief Sets a default event listener to submesh of the source face