#include "SMESH_Pattern.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_EdgePosition.hxx"
#include "utilities.h"
+#include <BRep_Tool.hxx>
+#include <Bnd_B2d.hxx>
#include <TopExp.hxx>
-#include <TopoDS.hxx>
+#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <BRep_Tool.hxx>
-
+#include <TopoDS.hxx>
using namespace std;
-#define RETURN_BAD_RESULT(msg) { MESSAGE(msg); return false; }
+#define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
typedef StdMeshers_ProjectionUtils TAssocTool;
// target vertices
edge = TAssocTool::GetEdgeByVertices
( tgtMesh, _sourceHypo->GetTargetVertex(1), _sourceHypo->GetTargetVertex(2) );
- if ( edge.IsNull() ||
- !TAssocTool::IsSubShape( edge, tgtMesh ) ||
- !TAssocTool::IsSubShape( edge, theShape ))
+ if ( edge.IsNull() || !TAssocTool::IsSubShape( edge, tgtMesh ))
{
theStatus = HYP_BAD_PARAMETER;
SCRUTE((edge.IsNull()));
SCRUTE((TAssocTool::IsSubShape( edge, tgtMesh )));
+ }
+ // PAL16203
+ else if ( !_sourceHypo->IsCompoundSource() &&
+ !TAssocTool::IsSubShape( edge, theShape ))
+ {
+ theStatus = HYP_BAD_PARAMETER;
SCRUTE((TAssocTool::IsSubShape( edge, theShape )));
}
}
{
// old nodes are shared by edges and new ones are shared
// only by faces created by mapper
- bool isOld = false;
- SMDS_ElemIteratorPtr invElem = node->GetInverseElementIterator();
- while ( !isOld && invElem->more() )
- isOld = ( invElem->next()->GetType() == SMDSAbs_Edge );
+ SMDS_ElemIteratorPtr invEdge = node->GetInverseElementIterator(SMDSAbs_Edge);
+ bool isOld = invEdge->more();
return isOld;
}
MeshCleaner( SMESH_subMesh* faceSubMesh ): sm(faceSubMesh) {}
~MeshCleaner() { Clean(sm); }
void Release() { sm = 0; } // mesh will not be removed
- static void Clean( SMESH_subMesh* sm )
+ static void Clean( SMESH_subMesh* sm, bool withSub=true )
{
if ( !sm ) return;
- switch ( sm->GetSubShape().ShapeType() ) {
- case TopAbs_VERTEX:
- case TopAbs_EDGE: {
+ // PAL16567, 18920. Remove face nodes as well
+// switch ( sm->GetSubShape().ShapeType() ) {
+// case TopAbs_VERTEX:
+// case TopAbs_EDGE: {
SMDS_NodeIteratorPtr nIt = sm->GetSubMeshDS()->GetNodes();
SMESHDS_Mesh* mesh = sm->GetFather()->GetMeshDS();
while ( nIt->more() ) {
mesh->RemoveNode( node );
}
// do not break but iterate over DependsOn()
- }
- default:
- const map< int, SMESH_subMesh * >& subSM = sm->DependsOn();
- map< int, SMESH_subMesh * >::const_iterator i_sm = subSM.begin();
- for ( ; i_sm != subSM.end(); ++i_sm )
- Clean( i_sm->second );
- }
+// }
+// default:
+ if ( !withSub ) return;
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(false,false);
+ while ( smIt->more() )
+ Clean( smIt->next(), false );
+// }
}
};
// Find a new node connected to nV1 and belonging to edge submesh;
const SMDS_MeshNode* nE = 0;
SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
- SMDS_ElemIteratorPtr vElems = nV1->GetInverseElementIterator();
+ SMDS_ElemIteratorPtr vElems = nV1->GetInverseElementIterator(SMDSAbs_Face);
while ( vElems->more() && !nE ) {
const SMDS_MeshElement* elem = vElems->next();
- if ( elem->GetType() != SMDSAbs_Face )
- continue; // new nodes are shared by faces
int nbNodes = elem->NbNodes();
if ( elem->IsQuadratic() )
nbNodes /= 2;
int iV1 = elem->GetNodeIndex( nV1 );
- // try next aftre nV1
+ // try next after nV1
int iE = SMESH_MesherHelper::WrapIndex( iV1 + 1, nbNodes );
if ( smDS->Contains( elem->GetNode( iE ) ))
nE = elem->GetNode( iE );
if ( !_sourceHypo )
return false;
- TopoDS_Face tgtFace = TopoDS::Face( theShape.Oriented(TopAbs_FORWARD));
- TopoDS_Face srcFace = TopoDS::Face( _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD));
-
- SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+ SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
SMESH_Mesh * tgtMesh = & theMesh;
if ( !srcMesh )
srcMesh = tgtMesh;
SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
- SMESH_MesherHelper helper( theMesh );
- helper.SetSubShape( tgtFace );
-
// ---------------------------
// 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 );
- if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcFace, srcMesh,
- shape2ShapeMap) )
- RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+ 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
if ( tgtMesh == srcMesh ) {
if ( !TAssocTool::MakeComputed( srcSubMesh ))
- RETURN_BAD_RESULT("Impossible to compute the source mesh");
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
}
else {
if ( !srcSubMesh->IsMeshComputed() )
- RETURN_BAD_RESULT("Source mesh is not computed");
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
}
// --------------------
// Prepare to mapping
// --------------------
+ SMESH_MesherHelper helper( theMesh );
+ helper.SetSubShape( tgtFace );
+
+ // Check if node projection to a face is needed
+ Bnd_B2d uvBox;
+ SMDS_ElemIteratorPtr faceIt = srcSubMesh->GetSubMeshDS()->GetElements();
+ for ( int nbN = 0; nbN < 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 ) {
+ nbN++;
+ uvBox.Add( helper.GetNodeUV( srcFace, node ));
+ }
+ }
+ }
+ const bool toProjectNodes = ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN );
+
// Load pattern from the source face
SMESH_Pattern mapper;
- mapper.Load( srcMesh, srcFace );
+ mapper.Load( srcMesh, srcFace, toProjectNodes );
if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
- RETURN_BAD_RESULT("SMESH_Pattern::Load() failed");
+ return error(COMPERR_BAD_INPUT_MESH,"Can't load mesh pattern from the source face");
// Find the first target vertex corresponding to first vertex of the <mapper>
// and <theReverse> flag needed to call mapper.Apply()
if ( nbEdgesInWires.front() > 1 ) // possible to find out
{
TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front();
- reverse = ( ! srcE1.IsSame( shape2ShapeMap( tgtE1 )));
- if ( BRep_Tool::IsClosed( tgtE1, tgtFace )) {
- reverse = ( srcE1.Orientation() == tgtE1.Orientation() );
- if ( _sourceHypo->GetSourceFace().Orientation() != theShape.Orientation() )
- reverse = !reverse;
- }
+ TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 );
+ reverse = ( ! srcE1.IsSame( srcE1bis ));
}
else if ( nbEdgesInWires.front() == 1 )
{
mapper.Apply( tgtFace, tgtV1, reverse );
if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
- RETURN_BAD_RESULT("SMESH_Pattern::Apply() failed");
+ return error("Can't apply source mesh pattern to the face");
// Create the mesh
const bool toCreatePolygons = false, toCreatePolyedrs = false;
mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs );
if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
- RETURN_BAD_RESULT("SMESH_Pattern::MakeMesh() failed");
+ return error("Can't make mesh by source mesh pattern");
// it will remove mesh built by pattern mapper on edges and vertices
// in failure case
// Make groups of nodes to merge
// loop on edge and vertex submeshes of a target face
- const map< int, SMESH_subMesh * >& subSM = tgtSubMesh->DependsOn();
- map< int, SMESH_subMesh * >::const_iterator i_subSM = subSM.begin();
- for ( ; i_subSM != subSM.end(); ++i_subSM )
+ SMESH_subMeshIteratorPtr smIt = tgtSubMesh->getDependsOnIterator(false,false);
+ while ( smIt->more() )
{
- SMESH_subMesh* sm = i_subSM->second;
+ SMESH_subMesh* sm = smIt->next();
SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
// Sort new and old nodes of a submesh separately
- bool isSeam = helper.IsSeamShape( sm->GetId() );
+ bool isSeam = helper.IsRealSeam( sm->GetId() );
- enum { NEW_NODES, OLD_NODES };
+ enum { NEW_NODES = 0, OLD_NODES };
map< double, const SMDS_MeshNode* > u2nodesMaps[2], u2nodesOnSeam;
map< double, const SMDS_MeshNode* >::iterator u_oldNode, u_newNode, u_newOnSeam, newEnd;
set< const SMDS_MeshNode* > seamNodes;
continue; // node is already in the map
}
- // sort nodes on edges by its position
- map< double, const SMDS_MeshNode* > & pos2nodes = u2nodesMaps[ isOld ];
+ // sort nodes on edges by their position
+ map< double, const SMDS_MeshNode* > & pos2nodes = u2nodesMaps[isOld ? OLD_NODES : NEW_NODES];
switch ( node->GetPosition()->GetTypeOfPosition() )
{
case SMDS_TOP_VERTEX: {
node->GetPosition()->GetTypeOfPosition());
}
}
- if ( u2nodesMaps[ OLD_NODES ].size() != u2nodesMaps[ NEW_NODES ].size() )
- RETURN_BAD_RESULT("Different nb of old and new nodes " <<
+ if ( u2nodesMaps[ NEW_NODES ].size() != u2nodesMaps[ OLD_NODES ].size() )
+ {
+ if ( u2nodesMaps[ NEW_NODES ].size() == 0 &&
+ sm->GetSubShape().ShapeType() == TopAbs_EDGE &&
+ helper.IsDegenShape( sm->GetId() ) )
+ // NPAL15894 (tt88bis.py) - project mesh built by NETGEN_1d_2D that
+ // does not make segments/nodes on degenerated edges
+ continue;
+
+ RETURN_BAD_RESULT("Different nb of old and new nodes on shape #"<< sm->GetId() <<" "<<
u2nodesMaps[ OLD_NODES ].size() << " != " <<
u2nodesMaps[ NEW_NODES ].size());
- if ( isSeam && u2nodesMaps[ OLD_NODES ].size() != u2nodesOnSeam.size() )
+ }
+ if ( isSeam && u2nodesMaps[ OLD_NODES ].size() != u2nodesOnSeam.size() ) {
RETURN_BAD_RESULT("Different nb of old and seam nodes " <<
u2nodesMaps[ OLD_NODES ].size() << " != " << u2nodesOnSeam.size());
-
+ }
// Make groups of nodes to merge
u_oldNode = u2nodesMaps[ OLD_NODES ].begin();
u_newNode = u2nodesMaps[ NEW_NODES ].begin();
// Merge
+ int nbFaceBeforeMerge = tgtSubMesh->GetSubMeshDS()->NbElements();
editor.MergeNodes( groupsOfNodes );
+ int nbFaceAtferMerge = tgtSubMesh->GetSubMeshDS()->NbElements();
+ if ( nbFaceBeforeMerge != nbFaceAtferMerge )
+ return error(COMPERR_BAD_INPUT_MESH, "Probably invalid node parameters on geom faces");
// ---------------------------
// Check elements orientation
void StdMeshers_Projection_2D::SetEventListener(SMESH_subMesh* subMesh)
{
- if ( _sourceHypo && ! _sourceHypo->GetSourceFace().IsNull() )
- {
- SMESH_Mesh* srcMesh = _sourceHypo->GetSourceMesh();
- if ( !srcMesh )
- srcMesh = subMesh->GetFather();
-
- SMESH_subMesh* srcFaceSM =
- srcMesh->GetSubMesh( _sourceHypo->GetSourceFace() );
-
- subMesh->SetEventListener( new SMESH_subMeshEventListener(true),
- SMESH_subMeshEventListenerData::MakeData( subMesh ),
- srcFaceSM );
- }
+ TAssocTool::SetEventListener( subMesh,
+ _sourceHypo->GetSourceFace(),
+ _sourceHypo->GetSourceMesh() );
}