#include "SMDS_EdgePosition.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMDS_FacePosition.hxx"
+#include "SMDS_SpacePosition.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
while ( elemIt->more() )
{
const SMDS_MeshElement* elem = elemIt->next();
+ if ( elem->GetType() != SMDSAbs_Face )
+ continue;
// put all nodes in array
int nbNodes = 0, iNode = 0;
coord[2] += node->Z();
}
else { // smooth in 2D
- gp_XY* uv = theUVMap[ node ];
+ ASSERT( theUVMap.find( node ) != theUVMap.end() );
+ gp_XY* uv = theUVMap[ node ];
coord[0] += uv->X();
coord[1] += uv->Y();
}
}
int nbNodes = nodeSet.size();
+ if ( !nbNodes )
+ return;
coord[0] /= nbNodes;
coord[1] /= nbNodes;
if ( !theSurface.IsNull() ) {
+ ASSERT( theUVMap.find( theNode ) != theUVMap.end() );
theUVMap[ theNode ]->SetCoord( coord[0], coord[1] );
gp_Pnt p3d = theSurface->Value( coord[0], coord[1] );
coord[0] = p3d.X();
while ( elemIt->more() )
{
const SMDS_MeshElement* elem = elemIt->next();
+ if ( elem->GetType() != SMDSAbs_Face )
+ continue;
nbElems++;
gp_XYZ elemCenter(0.,0.,0.);
gp_XYZ aP( aNode->X(), aNode->Y(), aNode->Z() );
aNodePoints.push_back( aP );
if ( !theSurface.IsNull() ) { // smooth in 2D
+ ASSERT( theUVMap.find( aNode ) != theUVMap.end() );
gp_XY* uv = theUVMap[ aNode ];
aP.SetCoord( uv->X(), uv->Y(), 0. );
}
}
aNewXYZ /= totalArea;
if ( !theSurface.IsNull() ) {
+ ASSERT( theUVMap.find( theNode ) != theUVMap.end() );
theUVMap[ theNode ]->SetCoord( aNewXYZ.X(), aNewXYZ.Y() );
aNewXYZ = theSurface->Value( aNewXYZ.X(), aNewXYZ.Y() ).XYZ();
}
}
return false;
}
+
//=======================================================================
//function : Smooth
//purpose : Smooth theElements during theNbIterations or until a worst
// compute UV for them
// ---------------------------------------------------------
bool checkBoundaryNodes = false;
- set<const SMDS_MeshNode*> setMovableNodes, checkedNodes;
+ set<const SMDS_MeshNode*> setMovableNodes;
map< const SMDS_MeshNode*, gp_XY* > uvMap, uvMap2;
list< gp_XY > listUV; // uvs the 2 maps refer to
list< const SMDS_MeshElement* > elemsOnFace;
}
int nbElemOnFace = 0;
itElem = theElems.begin();
- while ( itElem != theElems.end() ) // loop on not yet smoothed elements
+ // loop on not yet smoothed elements: look for elems on a face
+ while ( itElem != theElems.end() )
{
+ if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
+ break; // all elements found
+
const SMDS_MeshElement* elem = (*itElem);
if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() < 3 ||
( faceSubMesh && !faceSubMesh->Contains( elem ))) {
theElems.erase( itElem++ );
nbElemOnFace++;
- // loop on elem nodes
+ // get movable nodes of elem
+ const SMDS_MeshNode* node;
+ SMDS_TypeOfPosition posType;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() )
- {
- const SMDS_MeshNode* node =
- static_cast<const SMDS_MeshNode*>( itN->next() );
- if ( !checkedNodes.insert( node ).second )
- continue;
- // get UV on face
- gp_XY uv( 0, 0 );
- bool project = !surface.IsNull();
- gp_Pnt pNode ( node->X(), node->Y(), node->Z() );
+ while ( itN->more() ) {
+ node = static_cast<const SMDS_MeshNode*>( itN->next() );
const SMDS_PositionPtr& pos = node->GetPosition();
- SMDS_TypeOfPosition posType = SMDS_TOP_3DSPACE;
- if ( faceSubMesh && pos.get() ) {
- posType = pos->GetTypeOfPosition();
- if ( posType == SMDS_TOP_FACE ) {
- SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos.get();
- uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() );
- gp_Pnt pSurf = surface->Value( uv.X(), uv.Y() );
- project = pSurf.SquareDistance( pNode ) > fToler2;
- }
- }
- if ( project ) {
- if ( !getClosestUV( projector, pNode, uv ))
- MESSAGE("Node Projection Failed " << node);
- if ( isUPeriodic )
- uv.SetX( ElCLib::InPeriod( uv.X(), u1, u2 ));
- if ( isVPeriodic )
- uv.SetY( ElCLib::InPeriod( uv.Y(), v1, v2 ));
- }
- if ( !surface.IsNull() ) {
- listUV.push_back( uv );
- uvMap.insert( make_pair( node, &listUV.back() ));
- }
-
- if ( posType == SMDS_TOP_3DSPACE )
- checkBoundaryNodes = true;
-
- // movable or not?
+ posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
if (posType != SMDS_TOP_EDGE &&
posType != SMDS_TOP_VERTEX &&
theFixedNodes.find( node ) == theFixedNodes.end())
{
// check if all faces around the node are on faceSubMesh
+ // because a node on edge may be bound to face
SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
bool all = true;
- while ( eIt->more() && all ) {
- const SMDS_MeshElement* e = eIt->next();
- if ( e->GetType() == SMDSAbs_Face )
- all = faceSubMesh->Contains( e );
+ if ( faceSubMesh ) {
+ while ( eIt->more() && all ) {
+ const SMDS_MeshElement* e = eIt->next();
+ if ( e->GetType() == SMDSAbs_Face )
+ all = faceSubMesh->Contains( e );
+ }
}
if ( all )
setMovableNodes.insert( node );
else
checkBoundaryNodes = true;
}
+ if ( posType == SMDS_TOP_3DSPACE )
+ checkBoundaryNodes = true;
+ }
- } // loop on elem nodes
-
- if ( nbElemOnFace == faceSubMesh->NbElements() )
- break; // all elements found
+ if ( surface.IsNull() )
+ continue;
+ // get nodes to check UV
+ list< const SMDS_MeshNode* > uvCheckNodes;
+ itN = elem->nodesIterator();
+ while ( itN->more() ) {
+ node = static_cast<const SMDS_MeshNode*>( itN->next() );
+ if ( uvMap.find( node ) == uvMap.end() )
+ uvCheckNodes.push_back( node );
+ // add nodes of elems sharing node
+// SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
+// while ( eIt->more() ) {
+// const SMDS_MeshElement* e = eIt->next();
+// if ( e != elem && e->GetType() == SMDSAbs_Face ) {
+// SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+// while ( nIt->more() ) {
+// const SMDS_MeshNode* n =
+// static_cast<const SMDS_MeshNode*>( nIt->next() );
+// if ( uvMap.find( n ) == uvMap.end() )
+// uvCheckNodes.push_back( n );
+// }
+// }
+// }
+ }
+ // check UV on face
+ list< const SMDS_MeshNode* >::iterator n = uvCheckNodes.begin();
+ for ( ; n != uvCheckNodes.end(); ++n )
+ {
+ node = *n;
+ gp_XY uv( 0, 0 );
+ bool project = true;
+ gp_Pnt pNode ( node->X(), node->Y(), node->Z() );
+ const SMDS_PositionPtr& pos = node->GetPosition();
+ posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
+ if (faceSubMesh && posType == SMDS_TOP_FACE )
+ {
+ // check if existing UV is OK
+ SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos.get();
+ uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() );
+ gp_Pnt pSurf = surface->Value( uv.X(), uv.Y() );
+ project = pSurf.SquareDistance( pNode ) > fToler2;
+ }
+ if ( project ) {
+ if ( !getClosestUV( projector, pNode, uv ))
+ MESSAGE("Node Projection Failed " << node);
+ if ( isUPeriodic )
+ uv.SetX( ElCLib::InPeriod( uv.X(), u1, u2 ));
+ if ( isVPeriodic )
+ uv.SetY( ElCLib::InPeriod( uv.Y(), v1, v2 ));
+ }
+ listUV.push_back( uv );
+ uvMap.insert( make_pair( node, &listUV.back() ));
+ }
} // loop on not yet smoothed elements
- if ( !faceSubMesh || elemsOnFace.size() != nbElemOnFace )
+ if ( !faceSubMesh || nbElemOnFace != faceSubMesh->NbElements() )
checkBoundaryNodes = true;
- // fix nodes on boundary of elemsOnFace
+ // fix nodes on mesh boundary
if ( checkBoundaryNodes )
{
} // loop on edge of a face
} // if ( !face.IsNull() )
+ if ( setMovableNodes.empty() ) {
+ MESSAGE( "Face id : " << *fId << " - NO SMOOTHING: no nodes to move!!!");
+ continue; // goto next face
+ }
+
// -------------
// SMOOTHING //
// -------------
- set<const SMDS_MeshNode*>::iterator nodeToMove;
int it = -1;
double maxRatio = -1., maxDisplacement = -1.;
+ set<const SMDS_MeshNode*>::iterator nodeToMove;
for ( it = 0; it < theNbIterations; it++ )
{
maxDisplacement = 0.;
// check elements quality
maxRatio = 0;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
+ list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
+ for ( ; elemIt != elemsOnFace.end(); ++elemIt )
{
- const SMDS_MeshElement* elem = (*itElem);
+ const SMDS_MeshElement* elem = (*elemIt);
if ( !elem || elem->GetType() != SMDSAbs_Face )
continue;
SMESH::Controls::TSequenceOfXYZ aPoints;
const SMDS_MeshNode * newNode = node;
if ( theCopy )
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
- else
+ else {
aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
+ // node position on shape becomes invalid
+ const_cast< SMDS_MeshNode* > ( node )->SetPosition
+ ( SMDS_SpacePosition::originSpacePosition() );
+ }
nodeMap.insert( TNodeNodeMap::value_type( node, newNode ));
// keep inverse elements