Regression of smesh/mesh_Projection_2D_01/B7

Fix SMESH_MeshEditor::Smooth()

Optimize a bit SMDS_MeshNode::GetInverseElementIterator()

Minimize usage of BRepClass_FaceClassifier in StdMeshers_Import_1D2D::Compute()
This commit is contained in:
eap 2015-05-13 16:03:36 +03:00
parent 22463abfc9
commit df9cc07c95
3 changed files with 58 additions and 63 deletions

View File

@ -126,7 +126,7 @@ void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
{ {
return myPosition; return myPosition;
} }
//======================================================================= //=======================================================================
@ -149,30 +149,26 @@ public:
SMDS_MeshNode_MyInvIterator(SMDS_Mesh *mesh, vtkIdType* cells, int ncells, SMDSAbs_ElementType type) : SMDS_MeshNode_MyInvIterator(SMDS_Mesh *mesh, vtkIdType* cells, int ncells, SMDSAbs_ElementType type) :
myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0) myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0)
{ {
//MESSAGE("SMDS_MeshNode_MyInvIterator : ncells " << myNcells); cellList.reserve( ncells );
cellList.clear();
if (type == SMDSAbs_All) if (type == SMDSAbs_All)
cellList.assign( cells, cells + ncells );
else
for (int i = 0; i < ncells; i++) for (int i = 0; i < ncells; i++)
cellList.push_back(cells[i]);
else for (int i = 0; i < ncells; i++)
{ {
int vtkId = cells[i]; int vtkId = cells[i];
int smdsId = myMesh->fromVtkToSmds(vtkId); int smdsId = myMesh->fromVtkToSmds(vtkId);
const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
if (elem->GetType() == type) if (elem->GetType() == type)
{ {
//MESSAGE("Add element vtkId " << vtkId << " " << elem->GetType()) cellList.push_back(vtkId);
cellList.push_back(vtkId); }
}
} }
myCells = cellList.empty() ? 0 : &cellList[0]; myCells = cellList.empty() ? 0 : &cellList[0];
myNcells = cellList.size(); myNcells = cellList.size();
//MESSAGE("myNcells="<<myNcells);
} }
bool more() bool more()
{ {
//MESSAGE("iter " << iter << " ncells " << myNcells);
return (iter < myNcells); return (iter < myNcells);
} }

View File

@ -3768,8 +3768,11 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
// smooth elements on each TopoDS_Face separately // smooth elements on each TopoDS_Face separately
// =============================================== // ===============================================
set< int >::reverse_iterator fId = faceIdSet.rbegin(); // treate 0 fId at the end SMESH_MesherHelper helper( *GetMesh() );
for ( ; fId != faceIdSet.rend(); ++fId ) {
set< int >::reverse_iterator fId = faceIdSet.rbegin(); // treat 0 fId at the end
for ( ; fId != faceIdSet.rend(); ++fId )
{
// get face surface and submesh // get face surface and submesh
Handle(Geom_Surface) surface; Handle(Geom_Surface) surface;
SMESHDS_SubMesh* faceSubMesh = 0; SMESHDS_SubMesh* faceSubMesh = 0;
@ -3777,7 +3780,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
double fToler2 = 0, f,l; double fToler2 = 0, f,l;
double u1 = 0, u2 = 0, v1 = 0, v2 = 0; double u1 = 0, u2 = 0, v1 = 0, v2 = 0;
bool isUPeriodic = false, isVPeriodic = false; bool isUPeriodic = false, isVPeriodic = false;
if ( *fId ) { if ( *fId )
{
face = TopoDS::Face( aMesh->IndexToShape( *fId )); face = TopoDS::Face( aMesh->IndexToShape( *fId ));
surface = BRep_Tool::Surface( face ); surface = BRep_Tool::Surface( face );
faceSubMesh = aMesh->MeshElements( *fId ); faceSubMesh = aMesh->MeshElements( *fId );
@ -3790,6 +3794,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
if ( isVPeriodic ) if ( isVPeriodic )
surface->VPeriod(); surface->VPeriod();
surface->Bounds( u1, u2, v1, v2 ); surface->Bounds( u1, u2, v1, v2 );
helper.SetSubShape( face );
} }
// --------------------------------------------------------- // ---------------------------------------------------------
// for elements on a face, find movable and fixed nodes and // for elements on a face, find movable and fixed nodes and
@ -3811,7 +3816,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
int nbElemOnFace = 0; int nbElemOnFace = 0;
itElem = theElems.begin(); itElem = theElems.begin();
// loop on not yet smoothed elements: look for elems on a face // loop on not yet smoothed elements: look for elems on a face
while ( itElem != theElems.end() ) { while ( itElem != theElems.end() )
{
if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() ) if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
break; // all elements found break; // all elements found
@ -3867,12 +3873,15 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
// get nodes to check UV // get nodes to check UV
list< const SMDS_MeshNode* > uvCheckNodes; list< const SMDS_MeshNode* > uvCheckNodes;
const SMDS_MeshNode* nodeInFace = 0;
itN = elem->nodesIterator(); itN = elem->nodesIterator();
nn = 0; nbn = elem->NbNodes(); nn = 0; nbn = elem->NbNodes();
if(elem->IsQuadratic()) if(elem->IsQuadratic())
nbn = nbn/2; nbn = nbn/2;
while ( nn++ < nbn ) { while ( nn++ < nbn ) {
node = static_cast<const SMDS_MeshNode*>( itN->next() ); node = static_cast<const SMDS_MeshNode*>( itN->next() );
if ( node->GetPosition()->GetDim() == 2 )
nodeInFace = node;
if ( uvMap.find( node ) == uvMap.end() ) if ( uvMap.find( node ) == uvMap.end() )
uvCheckNodes.push_back( node ); uvCheckNodes.push_back( node );
// add nodes of elems sharing node // add nodes of elems sharing node
@ -3898,41 +3907,21 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
const SMDS_PositionPtr& pos = node->GetPosition(); const SMDS_PositionPtr& pos = node->GetPosition();
posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
// get existing UV // get existing UV
switch ( posType ) { if ( pos )
case SMDS_TOP_FACE: { {
SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos; bool toCheck = true;
uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() ); uv = helper.GetNodeUV( face, node, nodeInFace, &toCheck );
break;
}
case SMDS_TOP_EDGE: {
TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() );
Handle(Geom2d_Curve) pcurve;
if ( !S.IsNull() && S.ShapeType() == TopAbs_EDGE )
pcurve = BRep_Tool::CurveOnSurface( TopoDS::Edge( S ), face, f,l );
if ( !pcurve.IsNull() ) {
double u = (( SMDS_EdgePosition* ) pos )->GetUParameter();
uv = pcurve->Value( u ).XY();
}
break;
}
case SMDS_TOP_VERTEX: {
TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() );
if ( !S.IsNull() && S.ShapeType() == TopAbs_VERTEX )
uv = BRep_Tool::Parameters( TopoDS::Vertex( S ), face ).XY();
break;
}
default:;
}
// check existing UV
bool project = true;
gp_Pnt pNode ( node->X(), node->Y(), node->Z() );
double dist1 = DBL_MAX, dist2 = 0;
if ( posType != SMDS_TOP_3DSPACE ) {
dist1 = pNode.SquareDistance( surface->Value( uv.X(), uv.Y() ));
project = dist1 > fToler2;
} }
// compute not existing UV
bool project = ( posType == SMDS_TOP_3DSPACE );
// double dist1 = DBL_MAX, dist2 = 0;
// if ( posType != SMDS_TOP_3DSPACE ) {
// dist1 = pNode.SquareDistance( surface->Value( uv.X(), uv.Y() ));
// project = dist1 > fToler2;
// }
if ( project ) { // compute new UV if ( project ) { // compute new UV
gp_XY newUV; gp_XY newUV;
gp_Pnt pNode = SMESH_TNodeXYZ( node );
if ( !getClosestUV( projector, pNode, newUV )) { if ( !getClosestUV( projector, pNode, newUV )) {
MESSAGE("Node Projection Failed " << node); MESSAGE("Node Projection Failed " << node);
} }
@ -3942,9 +3931,9 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
if ( isVPeriodic ) if ( isVPeriodic )
newUV.SetY( ElCLib::InPeriod( newUV.Y(), v1, v2 )); newUV.SetY( ElCLib::InPeriod( newUV.Y(), v1, v2 ));
// check new UV // check new UV
if ( posType != SMDS_TOP_3DSPACE ) // if ( posType != SMDS_TOP_3DSPACE )
dist2 = pNode.SquareDistance( surface->Value( newUV.X(), newUV.Y() )); // dist2 = pNode.SquareDistance( surface->Value( newUV.X(), newUV.Y() ));
if ( dist2 < dist1 ) // if ( dist2 < dist1 )
uv = newUV; uv = newUV;
} }
} }
@ -4012,9 +4001,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
uv2 = pcurve->Value( f ); uv2 = pcurve->Value( f );
int iPar = Abs( uv1.X() - uv2.X() ) > Abs( uv1.Y() - uv2.Y() ) ? 1 : 2; int iPar = Abs( uv1.X() - uv2.X() ) > Abs( uv1.Y() - uv2.Y() ) ? 1 : 2;
// assure uv1 < uv2 // assure uv1 < uv2
if ( uv1.Coord( iPar ) > uv2.Coord( iPar )) { if ( uv1.Coord( iPar ) > uv2.Coord( iPar ))
gp_Pnt2d tmp = uv1; uv1 = uv2; uv2 = tmp; std::swap( uv1, uv2 );
}
// get nodes on seam and its vertices // get nodes on seam and its vertices
list< const SMDS_MeshNode* > seamNodes; list< const SMDS_MeshNode* > seamNodes;
SMDS_NodeIteratorPtr nSeamIt = sm->GetNodes(); SMDS_NodeIteratorPtr nSeamIt = sm->GetNodes();
@ -4064,12 +4052,14 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
setMovableNodes.find( n ) == setMovableNodes.end() ) setMovableNodes.find( n ) == setMovableNodes.end() )
continue; continue;
// add only nodes being closer to uv2 than to uv1 // add only nodes being closer to uv2 than to uv1
gp_Pnt pMid (0.5 * ( n->X() + nSeam->X() ), // gp_Pnt pMid (0.5 * ( n->X() + nSeam->X() ),
0.5 * ( n->Y() + nSeam->Y() ), // 0.5 * ( n->Y() + nSeam->Y() ),
0.5 * ( n->Z() + nSeam->Z() )); // 0.5 * ( n->Z() + nSeam->Z() ));
gp_XY uv; // gp_XY uv;
getClosestUV( projector, pMid, uv ); // getClosestUV( projector, pMid, uv );
if ( uv.Coord( iPar ) > uvMap[ n ]->Coord( iPar ) ) { double x = uvMap[ n ]->Coord( iPar );
if ( Abs( uv1.Coord( iPar ) - x ) >
Abs( uv2.Coord( iPar ) - x )) {
nodesNearSeam.insert( n ); nodesNearSeam.insert( n );
nbUseMap2++; nbUseMap2++;
} }
@ -4178,8 +4168,6 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
// move medium nodes of quadratic elements // move medium nodes of quadratic elements
if ( isQuadratic ) if ( isQuadratic )
{ {
SMESH_MesherHelper helper( *GetMesh() );
helper.SetSubShape( face );
vector<const SMDS_MeshNode*> nodes; vector<const SMDS_MeshNode*> nodes;
bool checkUV; bool checkUV;
list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();

View File

@ -192,11 +192,13 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
const int shapeID = tgtMesh->ShapeToIndex( geomFace ); const int shapeID = tgtMesh->ShapeToIndex( geomFace );
const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 ); const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace ); Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
const bool reverse = const bool reverse =
( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace ) == TopAbs_REVERSED ); ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace ) == TopAbs_REVERSED );
gp_Pnt p; gp_Vec du, dv; gp_Pnt p; gp_Vec du, dv;
// BRepClass_FaceClassifier is most time consuming, so minimize its usage
BRepClass_FaceClassifier classifier; BRepClass_FaceClassifier classifier;
Bnd_B2d bndBox2d; Bnd_B2d bndBox2d;
Bnd_Box bndBox3d; Bnd_Box bndBox3d;
@ -217,7 +219,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
bndBox2d.Enlarge( 1e-2 * Sqrt( bndBox2d.SquareExtent() )); bndBox2d.Enlarge( 1e-2 * Sqrt( bndBox2d.SquareExtent() ));
BRepBndLib::Add( geomFace, bndBox3d ); BRepBndLib::Add( geomFace, bndBox3d );
bndBox3d.Enlarge( 1e-4 * sqrt( bndBox3d.SquareExtent() )); bndBox3d.Enlarge( 1e-5 * sqrt( bndBox3d.SquareExtent() ));
} }
set<int> subShapeIDs; set<int> subShapeIDs;
@ -277,6 +279,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
vector<TopAbs_State> nodeState; vector<TopAbs_State> nodeState;
vector<const SMDS_MeshNode*> newNodes; // of a face vector<const SMDS_MeshNode*> newNodes; // of a face
set <const SMDS_MeshNode*> bndNodes; // nodes classified ON set <const SMDS_MeshNode*> bndNodes; // nodes classified ON
vector<bool> isNodeIn; // nodes classified IN, by node ID
for ( size_t iG = 0; iG < srcGroups.size(); ++iG ) for ( size_t iG = 0; iG < srcGroups.size(); ++iG )
{ {
@ -330,6 +333,9 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
{ {
if ( !subShapeIDs.count( newNode->getshapeId() )) if ( !subShapeIDs.count( newNode->getshapeId() ))
break; // node is Imported onto other FACE break; // node is Imported onto other FACE
if ( newNode->GetID() < (int) isNodeIn.size() &&
isNodeIn[ newNode->GetID() ])
isIn = true;
if ( !isIn && bndNodes.count( *node )) if ( !isIn && bndNodes.count( *node ))
nodeState[ i ] = TopAbs_ON; nodeState[ i ] = TopAbs_ON;
} }
@ -362,10 +368,15 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
newNode = tgtMesh->AddNode( nXYZ.X(), nXYZ.Y(), nXYZ.Z()); newNode = tgtMesh->AddNode( nXYZ.X(), nXYZ.Y(), nXYZ.Z());
tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() ); tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() );
nbCreatedNodes++; nbCreatedNodes++;
if ( newNode->GetID() >= (int) isNodeIn.size() )
{
isNodeIn.push_back( false ); // allow allocate more than newNode->GetID()
isNodeIn.resize( newNode->GetID() + 1, false );
}
if ( nodeState[i] == TopAbs_ON ) if ( nodeState[i] == TopAbs_ON )
bndNodes.insert( *node ); bndNodes.insert( *node );
else else
isIn = true; isNodeIn[ newNode->GetID() ] = isIn = true;
} }
} }
if ( !(newNodes[i] = newNode ) || isOut ) if ( !(newNodes[i] = newNode ) || isOut )