diff --git a/doc/salome/gui/SMESH/input/mesh_infos.doc b/doc/salome/gui/SMESH/input/mesh_infos.doc index 8222f1764..cd9860ae8 100644 --- a/doc/salome/gui/SMESH/input/mesh_infos.doc +++ b/doc/salome/gui/SMESH/input/mesh_infos.doc @@ -43,7 +43,8 @@ information about the selected mesh node(s) or element(s), namely: - For a node: - Node ID; - Coordinates (X, Y, Z); - - Connectivity information (connected elements); + - Connectivity information (connected elements); double click in + this line makes the dialog show information of these elements; - Position on a shape (for meshes built on a geometry); - Groups information (names of groups the node belongs to). @@ -55,7 +56,8 @@ information about the selected mesh node(s) or element(s), namely: - Element ID; - Type (triangle, quadrangle, etc.); - Gravity center (X, Y, Z coordinates); - - Connectivity information (connected nodes); + - Connectivity information (connected nodes); double click in + a line of a node makes the dialog show information of this node; - Quality controls (area, aspect ration, volume, etc.); - Position on a shape (for meshes built on a geometry); - Groups information (names of groups the element belongs to). @@ -63,7 +65,7 @@ information about the selected mesh node(s) or element(s), namely:
\image html eleminfo2.png "Element Info" page, element information
-The use can either input the ID of a node or element he wants to +The user can either input the ID of a node or element he wants to analyze directly in the dialog box or select the node(s) or element(s) in the 3D viewer. diff --git a/src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx b/src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx index 3907afff8..6f9d02a30 100644 --- a/src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx +++ b/src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx @@ -252,9 +252,10 @@ namespace gp_XY p = _prev->_xy - v->_xy; gp_XY t = this->_xy - v->_xy; gp_XY n = _next->_xy - v->_xy; - return (( p ^ t ) > 0 && - ( t ^ n ) > 0 && - ( n ^ p ) > 0 ); + const double tol = -1e-12; + return (( p ^ t ) >= tol && + ( t ^ n ) >= tol && + ( n ^ p ) >= tol ); // return ( Area( _prev, this, v ) > 0 && // Area( this, _next, v ) > 0 && // Area( _next, _prev, v ) > 0 ); @@ -370,8 +371,9 @@ namespace v->GetTriaNodes( &nodes[ iN ] ); iN += 3; v = v->Delete(); + --nbVertices; } - + return true; } // triangulate() diff --git a/src/SMDS/SMDS_VolumeTool.cxx b/src/SMDS/SMDS_VolumeTool.cxx index 8296de035..c0c506d9c 100644 --- a/src/SMDS/SMDS_VolumeTool.cxx +++ b/src/SMDS/SMDS_VolumeTool.cxx @@ -1011,7 +1011,7 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const ori = ( minProj < 0 ? +1 : -1 ); me->myPolyFacetOri[ faceIndex ] = ori; - if ( !me->myFwdLinks.empty() ) // concave polyhedron; collect oriented links + if ( !myFwdLinks.empty() ) // concave polyhedron; collect oriented links for ( int i = 0; i < myCurFace.myNbNodes; ++i ) { NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1], ori ); @@ -1024,10 +1024,10 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const // concave polyhedron - if ( me->myFwdLinks.empty() ) // get links of the least ambiguously oriented facet + if ( myFwdLinks.empty() ) // get links of the least ambiguously oriented facet { for ( size_t i = 0; i < myPolyFacetOri.size() && !ori; ++i ) - ori = me->myPolyFacetOri[ i ]; + ori = myPolyFacetOri[ i ]; if ( !ori ) // none facet is oriented yet { @@ -1058,10 +1058,10 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const me->myPolyFacetOri[ faceMostConvex ] = ori; } } - // collect links of the oriented facets in me->myFwdLinks + // collect links of the oriented facets in myFwdLinks for ( size_t iF = 0; iF < myPolyFacetOri.size(); ++iF ) { - ori = me->myPolyFacetOri[ iF ]; + ori = myPolyFacetOri[ iF ]; if ( !ori ) continue; setFace( iF ); for ( int i = 0; i < myCurFace.myNbNodes; ++i ) @@ -1079,8 +1079,8 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const for ( int i = 0; i < myCurFace.myNbNodes && !ori; ++i ) { NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] ); - std::map::iterator l2o = me->myFwdLinks.find( link ); - if ( l2o != me->myFwdLinks.end() ) + std::map::const_iterator l2o = myFwdLinks.find( link ); + if ( l2o != myFwdLinks.end() ) ori = link.myOri * l2o->second * -1; links[ i ] = link; } @@ -1089,15 +1089,15 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const // orient and collect links of other non-oriented facets for ( size_t iF = 0; iF < myPolyFacetOri.size(); ++iF ) { - if ( me->myPolyFacetOri[ iF ] ) continue; // already oriented + if ( myPolyFacetOri[ iF ] ) continue; // already oriented setFace( iF ); links2.clear(); ori = 0; for ( int i = 0; i < myCurFace.myNbNodes && !ori; ++i ) { NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] ); - std::map::iterator l2o = me->myFwdLinks.find( link ); - if ( l2o != me->myFwdLinks.end() ) + std::map::const_iterator l2o = myFwdLinks.find( link ); + if ( l2o != myFwdLinks.end() ) ori = link.myOri * l2o->second * -1; links2.push_back( link ); } @@ -1116,8 +1116,8 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const ori = 0; for ( size_t i = 0; i < links.size() && !ori; ++i ) { - std::map::iterator l2o = me->myFwdLinks.find( links[i] ); - if ( l2o != me->myFwdLinks.end() ) + std::map::const_iterator l2o = myFwdLinks.find( links[i] ); + if ( l2o != myFwdLinks.end() ) ori = links[i].myOri * l2o->second * -1; } me->myPolyFacetOri[ faceIndex ] = ori; diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index ab24f4c20..8efefaf47 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -649,10 +649,10 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, } catch (Standard_Failure& exc) { } - if ( !uvOK ) { - for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() ) - uvOK = ( V == vert.Current() ); - if ( !uvOK ) { + if ( !uvOK ) + { + if ( !IsSubShape( V, F )) + { MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID << " not in face " << GetMeshDS()->ShapeToIndex( F ) ); // get UV of a vertex closest to the node @@ -669,7 +669,8 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, } } } - else { + else + { uvOK = false; TopTools_ListIteratorOfListOfShape it( myMesh->GetAncestors( V )); for ( ; it.More(); it.Next() ) { @@ -678,13 +679,23 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, double f,l; Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edge, F, f, l); if ( !C2d.IsNull() ) { - double u = ( V == TopExp::FirstVertex( edge ) ) ? f : l; + double u = ( V == IthVertex( 0, edge )) ? f : l; uv = C2d->Value( u ); uvOK = true; break; } } } + if ( !uvOK && V.Orientation() == TopAbs_INTERNAL ) + { + Handle(ShapeAnalysis_Surface) projector = GetSurface( F ); + if ( n2 ) uv = GetNodeUV( F, n2 ); + if ( Precision::IsInfinite( uv.X() )) + uv = projector->NextValueOfUV( uv, BRep_Tool::Pnt( V ), BRep_Tool::Tolerance( F )); + else + uv = projector->ValueOfUV( BRep_Tool::Pnt( V ), BRep_Tool::Tolerance( F )); + uvOK = ( projector->Gap() < getFaceMaxTol( F )); + } } } if ( n2 && IsSeamShape( vertexID )) @@ -812,7 +823,7 @@ GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face& //purpose : Return a cached ShapeAnalysis_Surface of a FACE //======================================================================= -Handle(ShapeAnalysis_Surface) SMESH_MesherHelper::GetSurface(const TopoDS_Face& F ) +Handle(ShapeAnalysis_Surface) SMESH_MesherHelper::GetSurface(const TopoDS_Face& F ) const { Handle(Geom_Surface) surface = BRep_Tool::Surface( F ); int faceID = GetMeshDS()->ShapeToIndex( F ); diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index 9e8d82958..fdf863f03 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -532,14 +532,14 @@ public: /*! * \brief Return a cached ShapeAnalysis_Surface of a FACE */ - Handle(ShapeAnalysis_Surface) GetSurface(const TopoDS_Face& F ); + Handle(ShapeAnalysis_Surface) GetSurface(const TopoDS_Face& F ) const; /*! * \brief Check if shape is a degenerated edge or it's vertex - * \param subShape - edge or vertex index in SMESHDS - * \retval bool - true if subShape is a degenerated shape - * - * It works only if IsQuadraticSubMesh() or SetSubShape() has been called + * \param subShape - edge or vertex index in SMESHDS + * \retval bool - true if subShape is a degenerated shape + * + * It works only if IsQuadraticSubMesh() or SetSubShape() has been called */ bool IsDegenShape(const int subShape) const { return myDegenShapeIds.find( subShape ) != myDegenShapeIds.end(); } @@ -739,7 +739,7 @@ public: typedef std::map< int, Handle(ShapeAnalysis_Surface)> TID2Surface; typedef std::map< int, GeomAPI_ProjectPointOnSurf* > TID2ProjectorOnSurf; typedef std::map< int, GeomAPI_ProjectPointOnCurve* > TID2ProjectorOnCurve; - TID2Surface myFace2Surface; + mutable TID2Surface myFace2Surface; TID2ProjectorOnSurf myFace2Projector; TID2ProjectorOnCurve myEdge2Projector; diff --git a/src/SMESHGUI/SMESHGUI_MergeDlg.cxx b/src/SMESHGUI/SMESHGUI_MergeDlg.cxx index d084d32b1..92642d384 100644 --- a/src/SMESHGUI/SMESHGUI_MergeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MergeDlg.cxx @@ -898,7 +898,13 @@ void SMESHGUI_MergeDlg::updateControls() { if (ListEdit->count() == 0) SetFirstButton->setEnabled(false); - bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == TYPE_AUTO)); + + bool groupsEmpty = ( myTypeId != TYPE_AUTO ); + for (int i = 0; i < ListCoincident->count() && groupsEmpty; i++) { + QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts); + groupsEmpty = ( aListIds.count() < 2 ); + } + bool enable = ( !myMesh->_is_nil() && !groupsEmpty ); buttonOk->setEnabled(enable); buttonApply->setEnabled(enable); DetectButton->setEnabled( !myMesh->_is_nil() ); @@ -973,7 +979,7 @@ void SMESHGUI_MergeDlg::onDetect() ListCoincident->addItem(anIDs.join(" ")); } - } catch(...) { + } catch(...) { } ListCoincident->selectAll(); @@ -997,7 +1003,7 @@ void SMESHGUI_MergeDlg::onSelectGroup() myIsBusy = true; ListEdit->clear(); - + TColStd_MapOfInteger anIndices; QList selItems = ListCoincident->selectedItems(); QListWidgetItem* anItem; @@ -1010,7 +1016,7 @@ void SMESHGUI_MergeDlg::onSelectGroup() for (int i = 0; i < aListIds.count(); i++) anIndices.Add(aListIds[i].toInt()); } - + if (selItems.count() == 1) { ListEdit->addItems(aListIds); ListEdit->selectAll(); diff --git a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx index 5f3443ed5..9531609ab 100644 --- a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx @@ -32,7 +32,6 @@ #include "SMESHGUI_MeshUtils.h" #include "SMESHGUI_IdValidator.h" #include "SMESHGUI_FilterDlg.h" -#include "SMESHGUI_MeshEditPreview.h" #include #include @@ -362,9 +361,21 @@ void SMESHGUI_RotationDlg::Init (bool ResetControls) buttonOk->setEnabled(false); buttonApply->setEnabled(false); + if ( !ResetControls && !isApplyAndClose() && // make highlight move upon [Apply] (IPAL20729) + myActor && !myActor->getIO().IsNull() && + ActionGroup->button( MOVE_ELEMS_BUTTON )->isChecked() && + !CheckBoxMesh->isChecked() ) // move selected elements + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + { + aViewWindow->highlight( myActor->getIO(), false, false ); + aViewWindow->highlight( myActor->getIO(), true, true ); + } + } myActor = 0; - if (ResetControls) { + if (ResetControls) + { SpinBox_X->SetValue(0.0); SpinBox_Y->SetValue(0.0); SpinBox_Z->SetValue(0.0); @@ -378,10 +389,6 @@ void SMESHGUI_RotationDlg::Init (bool ResetControls) CheckBoxMesh->setChecked(false); myPreviewCheckBox->setChecked(false); onDisplaySimulation(false); - -// MakeGroupsCheck->setChecked(false); -// MakeGroupsCheck->setEnabled(false); -// onSelectMesh(false); } onSelectMesh(CheckBoxMesh->isChecked()); @@ -524,7 +531,6 @@ bool SMESHGUI_RotationDlg::ClickOnApply() anApp->browseObjects( anEntryList, isApplyAndClose() ); } Init(false); - SelectionIntoArgument(); SMESHGUI::Modified(); } @@ -747,52 +753,13 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument() if ( myMeshes.isEmpty() ) return; - // get IDs from mesh - /* - SMDS_Mesh* aSMDSMesh = myActor->GetObject()->GetMesh(); - if (!aSMDSMesh) - return; - - for (int i = aSMDSMesh->MinElementID(); i <= aSMDSMesh->MaxElementID(); i++) { - const SMDS_MeshElement * e = aSMDSMesh->FindElement(i); - if (e) { - myElementsId += QString(" %1").arg(i); - aNbUnits++; - } - } - } else if (!SMESH::IObjectToInterface(IO)->_is_nil()) { //SUBMESH - // get submesh - SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(IO); - - // get IDs from submesh - SMESH::long_array_var anElementsIds = new SMESH::long_array; - anElementsIds = aSubMesh->GetElementsId(); - for (int i = 0; i < anElementsIds->length(); i++) { - myElementsId += QString(" %1").arg(anElementsIds[i]); - } - aNbUnits = anElementsIds->length(); - } else { // GROUP - // get smesh group - SMESH::SMESH_GroupBase_var aGroup = - SMESH::IObjectToInterface(IO); - if (aGroup->_is_nil()) - return; - - // get IDs from smesh group - SMESH::long_array_var anElementsIds = new SMESH::long_array; - anElementsIds = aGroup->GetListOfID(); - for (int i = 0; i < anElementsIds->length(); i++) { - myElementsId += QString(" %1").arg(anElementsIds[i]); - } - aNbUnits = anElementsIds->length(); - } - */ - } else { + } + else { aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, aList.First(), aString); myElementsId = aString; if (aNbUnits < 1) return; - } + } myNbOkElements = true; @@ -800,13 +767,13 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument() Handle(SALOME_InteractiveObject) IO = aList.First(); if ((SMESH::GetMeshByIO(IO))->_is_nil()) return; - + SMESH_Actor* anActor = SMESH::FindActorByObject(SMESH::GetMeshByIO(IO)); if (!anActor) anActor = SMESH::FindActorByEntry(IO->getEntry()); if (!anActor && !CheckBoxMesh->isChecked()) return; - + aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString); if (aNbUnits != 1) return; @@ -980,7 +947,6 @@ void SMESHGUI_RotationDlg::onSelectMesh (bool toSelectMesh) aViewWindow->SetSelectionMode( CellSelection ); LineEditElements->setReadOnly(false); LineEditElements->setValidator(myIdValidator); - onTextChange(LineEditElements->text()); hidePreview(); } diff --git a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx index bf7057ddc..f934288b8 100644 --- a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx @@ -407,7 +407,7 @@ bool SMESHGUI_SmoothingDlg::ClickOnApply() if (aResult) { SMESH::Update(myIO, SMESH::eDisplay); SMESHGUI::Modified(); - Init(); + //Init(); mySelectedObject = SMESH::SMESH_IDSource::_nil(); } @@ -560,7 +560,7 @@ void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText) //================================================================================= // function : SelectionIntoArgument() -// purpose : Called when selection as changed or other case +// purpose : Called when selection has changed or other cases //================================================================================= void SMESHGUI_SmoothingDlg::SelectionIntoArgument() { @@ -594,44 +594,44 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument() SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList); int nbSel = aList.Extent(); - if (nbSel != 1) - return; - - Handle(SALOME_InteractiveObject) IO = aList.First(); - - if (myEditCurrentArgument == LineEditElements) { - myMesh = SMESH::GetMeshByIO(IO); - if (myMesh->_is_nil()) - return; - myIO = IO; - myActor = SMESH::FindActorByObject(myMesh); - - if (CheckBoxMesh->isChecked()) { - SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); - - SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( myIO ); - if ( !CORBA::is_nil( obj ) ) - mySelectedObject = obj; - else - return; - myNbOkElements = true; - } else { - // get indices of selected elements - TColStd_IndexedMapOfInteger aMapIndex; - mySelector->GetIndex(IO,aMapIndex); - myNbOkElements = aMapIndex.Extent(); - - if (myNbOkElements < 1) - return; - - QStringList elements; - for ( int i = 0; i < myNbOkElements; ++i ) - elements << QString::number( aMapIndex( i+1 ) ); - aString = elements.join(" "); - } - } else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myIO->isSame(IO) ) + if (nbSel == 1) { - myNbOkNodes = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString); + Handle(SALOME_InteractiveObject) IO = aList.First(); + + if (myEditCurrentArgument == LineEditElements) { + myMesh = SMESH::GetMeshByIO(IO); + if (myMesh->_is_nil()) + return; + myIO = IO; + myActor = SMESH::FindActorByObject(myMesh); + + if (CheckBoxMesh->isChecked()) { + SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); + + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( myIO ); + if ( !CORBA::is_nil( obj ) ) + mySelectedObject = obj; + else + return; + myNbOkElements = true; + } else { + // get indices of selected elements + TColStd_IndexedMapOfInteger aMapIndex; + mySelector->GetIndex(IO,aMapIndex); + myNbOkElements = aMapIndex.Extent(); + + if (myNbOkElements < 1) + return; + + QStringList elements; + for ( int i = 0; i < myNbOkElements; ++i ) + elements << QString::number( aMapIndex( i+1 ) ); + aString = elements.join(" "); + } + } else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myIO->isSame(IO) ) + { + myNbOkNodes = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString); + } } myEditCurrentArgument->setText(aString); diff --git a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx index b913ce179..7cc3006b8 100644 --- a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx @@ -32,7 +32,6 @@ #include "SMESHGUI_MeshUtils.h" #include "SMESHGUI_IdValidator.h" #include "SMESHGUI_FilterDlg.h" -#include "SMESHGUI_MeshEditPreview.h" #include #include @@ -358,14 +357,25 @@ void SMESHGUI_SymmetryDlg::Init (bool ResetControls) myObjects.clear(); myObjectsNames.clear(); - myEditCurrentArgument = 0; - LineEditElements->clear(); + myEditCurrentArgument = LineEditElements; + LineEditElements->setFocus(); myElementsId = ""; myNbOkElements = 0; buttonOk->setEnabled(false); buttonApply->setEnabled(false); + if ( !ResetControls && !isApplyAndClose() && // make highlight move upon [Apply] (IPAL20729) + myActor && !myActor->getIO().IsNull() && + ActionGroup->button( MOVE_ELEMS_BUTTON )->isChecked() && + !CheckBoxMesh->isChecked() ) // move selected elements + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + { + aViewWindow->highlight( myActor->getIO(), false, false ); + aViewWindow->highlight( myActor->getIO(), true, true ); + } + } myActor = 0; if (ResetControls) { @@ -380,11 +390,8 @@ void SMESHGUI_SymmetryDlg::Init (bool ResetControls) CheckBoxMesh->setChecked(false); myPreviewCheckBox->setChecked(false); onDisplaySimulation(false); - -// MakeGroupsCheck->setChecked(false); -// MakeGroupsCheck->setEnabled(false); - onSelectMesh(false); } + onSelectMesh(CheckBoxMesh->isChecked()); } //================================================================================= @@ -584,8 +591,6 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply() anApp->browseObjects( anEntryList, isApplyAndClose() ); } Init(false); - ConstructorsClicked(GetConstructorId()); - SelectionIntoArgument(); SMESHGUI::Modified(); } diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx index bd5db98e7..32c94694a 100644 --- a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx @@ -362,14 +362,25 @@ void SMESHGUI_TranslationDlg::Init (bool ResetControls) myObjectsNames.clear(); myMeshes.clear(); - myEditCurrentArgument = 0; - LineEditElements->clear(); + myEditCurrentArgument = LineEditElements; + LineEditElements->setFocus(); myElementsId = ""; myNbOkElements = 0; buttonOk->setEnabled(false); buttonApply->setEnabled(false); + if ( !ResetControls && !isApplyAndClose() && // make highlight move upon [Apply] (IPAL20729) + myActor && !myActor->getIO().IsNull() && + ActionGroup->button( MOVE_ELEMS_BUTTON )->isChecked() && + !CheckBoxMesh->isChecked() ) // move selected elements + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + { + aViewWindow->highlight( myActor->getIO(), false, false ); + aViewWindow->highlight( myActor->getIO(), true, true ); + } + } myActor = 0; if (ResetControls) { @@ -382,12 +393,10 @@ void SMESHGUI_TranslationDlg::Init (bool ResetControls) ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true); CheckBoxMesh->setChecked(false); -// MakeGroupsCheck->setChecked(false); -// MakeGroupsCheck->setEnabled(false); myPreviewCheckBox->setChecked(false); onDisplaySimulation(false); - onSelectMesh(false); } + onSelectMesh(CheckBoxMesh->isChecked()); } //================================================================================= @@ -593,7 +602,6 @@ bool SMESHGUI_TranslationDlg::ClickOnApply() Init(false); ConstructorsClicked(GetConstructorId()); - SelectionIntoArgument(); SMESHGUI::Modified(); } @@ -999,7 +1007,6 @@ void SMESHGUI_TranslationDlg::onSelectMesh (bool toSelectMesh) aViewWindow->SetSelectionMode( CellSelection ); LineEditElements->setReadOnly(false); LineEditElements->setValidator(myIdValidator); - onTextChange(LineEditElements->text()); hidePreview(); } @@ -1138,12 +1145,13 @@ bool SMESHGUI_TranslationDlg::isValid() // function : onDisplaySimulation // purpose : Show/Hide preview //================================================================================= -void SMESHGUI_TranslationDlg::onDisplaySimulation( bool toDisplayPreview ) { +void SMESHGUI_TranslationDlg::onDisplaySimulation( bool toDisplayPreview ) +{ if (myPreviewCheckBox->isChecked() && toDisplayPreview) { - + if (isValid() && myNbOkElements) { QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts); - + SMESH::long_array_var anElementsId = new SMESH::long_array; anElementsId->length(aListElementsId.count()); @@ -1179,7 +1187,7 @@ void SMESHGUI_TranslationDlg::onDisplaySimulation( bool toDisplayPreview ) { } setSimulationPreview( aMeshPreviewStruct ); } catch (...) { - + } } else { diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 5e962796a..5f7d8da91 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -339,10 +339,17 @@ SMESH_Gen_i::~SMESH_Gen_i() MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" ); // delete hypothesis creators - map::iterator itHyp; + map::iterator itHyp, itHyp2; for (itHyp = myHypCreatorMap.begin(); itHyp != myHypCreatorMap.end(); itHyp++) { - delete (*itHyp).second; + // same creator can be mapped under different names + GenericHypothesisCreator_i* creator = (*itHyp).second; + if ( !creator ) + continue; + delete creator; + for (itHyp2 = itHyp; itHyp2 != myHypCreatorMap.end(); itHyp2++) + if ( creator == (*itHyp2).second ) + (*itHyp2).second = 0; } myHypCreatorMap.clear(); diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index c173428be..4cd7ccf9a 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -228,6 +228,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, myHelper = &helper; _quadraticMesh = myHelper->IsQuadraticSubMesh(aShape); + myHelper->SetElementsOnShape( true ); myNeedSmooth = false; myCheckOri = false; @@ -249,7 +250,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, enum { NOT_COMPUTED = -1, COMPUTE_FAILED = 0, COMPUTE_OK = 1 }; int res = NOT_COMPUTED; - if (myQuadranglePreference) + if ( myQuadranglePreference ) { int nfull = n1+n2+n3+n4; if ((nfull % 2) == 0 && ((n1 != n3) || (n2 != n4))) @@ -258,7 +259,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, res = computeQuadPref( aMesh, F, quad ); } } - else if (myQuadType == QUAD_REDUCED) + else if ( myQuadType == QUAD_REDUCED ) { int n13 = n1 - n3; int n24 = n2 - n4; @@ -471,10 +472,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, b = quad->uv_grid[ j * nbhoriz + i + 1].node; c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node; d = quad->uv_grid[(j + 1) * nbhoriz + i ].node; - SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); - if (face) { - meshDS->SetMeshElementOnShape(face, geomFaceID); - } + myHelper->AddFace(a, b, c, d); } } @@ -558,8 +556,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = myHelper->AddFace(a, b, c); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, b, c); } else { // make quadrangle if (near - 1 < ilow) @@ -569,8 +566,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); if (!myTrianglePreference){ - SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, b, c, d); } else { splitQuadFace(meshDS, geomFaceID, a, b, c, d); @@ -584,8 +580,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, d = uv_e3[1].node; else d = quad->uv_grid[nbhoriz + k - 1].node; - SMDS_MeshFace* face = myHelper->AddFace(a, c, d); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, c, d); } } g = near; @@ -642,14 +637,12 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, d = quad->UVPt( g, nbvertic-2 ).node; if ( myTrianglePreference ) { - if ( SMDS_MeshFace* face = myHelper->AddFace(a, d, c)) - meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, d, c); } else { if ( SMDS_MeshFace* face = myHelper->AddFace(a, b, d, c)) { - meshDS->SetMeshElementOnShape(face, geomFaceID); SMESH_ComputeErrorPtr& err = aMesh.GetSubMesh( aFace )->GetComputeError(); if ( !err || err->IsOK() || err->myName < COMPERR_WARNING ) { @@ -696,8 +689,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = myHelper->AddFace(a, b, c); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, b, c); } else { // make quadrangle if (near + 1 > iup) @@ -706,8 +698,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node; //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); if (!myTrianglePreference){ - SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, b, c, d); } else { splitQuadFace(meshDS, geomFaceID, a, b, c, d); @@ -720,8 +711,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, d = uv_e1[nbright - 2].node; else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node; - SMDS_MeshFace* face = myHelper->AddFace(a, c, d); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, c, d); } } g = near; @@ -770,8 +760,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = myHelper->AddFace(a, b, c); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, b, c); } else { // make quadrangle if (near - 1 < jlow) @@ -781,8 +770,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); if (!myTrianglePreference){ - SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, b, c, d); } else { splitQuadFace(meshDS, geomFaceID, a, b, c, d); @@ -795,8 +783,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, d = uv_e0[nbdown - 2].node; else d = quad->uv_grid[nbhoriz*k - 2].node; - SMDS_MeshFace* face = myHelper->AddFace(a, c, d); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, c, d); } } g = near; @@ -823,14 +810,12 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, d = quad->UVPt( 1, g ).node; if ( myTrianglePreference ) { - if ( SMDS_MeshFace* face = myHelper->AddFace(a, d, c)) - meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, d, c); } else { if ( SMDS_MeshFace* face = myHelper->AddFace(a, b, d, c)) { - meshDS->SetMeshElementOnShape(face, geomFaceID); SMESH_ComputeErrorPtr& err = aMesh.GetSubMesh( aFace )->GetComputeError(); if ( !err || err->IsOK() || err->myName < COMPERR_WARNING ) { @@ -876,8 +861,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = myHelper->AddFace(a, b, c); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, b, c); } else { // make quadrangle if (near + 1 > jup) @@ -885,8 +869,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, else d = quad->uv_grid[nbhoriz*(near + 1) + 1].node; if (!myTrianglePreference) { - SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, b, c, d); } else { splitQuadFace(meshDS, geomFaceID, a, b, c, d); @@ -899,8 +882,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, d = quad->uv_grid[nbhoriz*jup + 1].node; //uv_e2[1].node; else d = quad->uv_grid[nbhoriz*(k + 1) + 1].node; - SMDS_MeshFace* face = myHelper->AddFace(a, c, d); - if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); + myHelper->AddFace(a, c, d); } } g = near; @@ -1453,6 +1435,8 @@ bool StdMeshers_Quadrangle_2D::setNormalizedGrid (FaceQuadStruct::Ptr quad) int nbhoriz = Min( bSide.NbPoints(), tSide.NbPoints() ); int nbvertic = Min( rSide.NbPoints(), lSide.NbPoints() ); + if ( nbhoriz < 1 || nbvertic < 1 ) + return error("Algo error: empty quad"); if ( myQuadList.size() == 1 ) { @@ -1853,6 +1837,10 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, } sideLCb = StdMeshers_FaceSide::New( pointsLCb, aFace ); p3dom = pointsLCb.back(); + + gp_Pnt xyz = S->Value( p3dom.u, p3dom.v ); + p3dom.node = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z(), 0, p3dom.u, p3dom.v ); + pointsLCb.back() = p3dom; } // Make a side separating domains L and Ct StdMeshers_FaceSidePtr sideLCt; @@ -2004,6 +1992,16 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, sideRCb = StdMeshers_FaceSide::New( pointsRCb, aFace ); pTBL = pointsLCb.back(); pTBR = pointsRCb.back(); + { + gp_Pnt xyz = S->Value( pTBL.u, pTBL.v ); + pTBL.node = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z(), 0, pTBL.u, pTBL.v ); + pointsLCb.back() = pTBL; + } + { + gp_Pnt xyz = S->Value( pTBR.u, pTBR.v ); + pTBR.node = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z(), 0, pTBR.u, pTBR.v ); + pointsRCb.back() = pTBR; + } } // Make sides separating domains Ct and L and R StdMeshers_FaceSidePtr sideLCt, sideRCt; @@ -2207,10 +2205,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, for (i=1; i<=dl; i++) { for (j=1; jAddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), - NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); - if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + myHelper->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), + NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); } } } @@ -2264,10 +2260,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, for (i=1; i<=dr; i++) { for (j=1; jAddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), - NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); - if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + myHelper->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), + NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); } } } @@ -2337,10 +2331,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, for (i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), - NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); - if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); } } } @@ -2369,10 +2361,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, for (j=1; jAddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j), - NodesBRD.Value(i+1,j+1), NodesBRD.Value(i,j+1)); - if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + myHelper->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j), + NodesBRD.Value(i+1,j+1), NodesBRD.Value(i,j+1)); } } } @@ -2475,10 +2465,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, for (j=1; j<=drl+addv; j++) { for (i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), - NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); - if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); } } } // end nrAddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1), - NodesLast.Value(i+1,2), NodesLast.Value(i,2)); - if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + myHelper->AddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1), + NodesLast.Value(i+1,2), NodesLast.Value(i,2)); } } } // if ((drl+addv) > 0) @@ -2664,21 +2650,16 @@ void StdMeshers_Quadrangle_2D::splitQuadFace(SMESHDS_Mesh * theMeshDS, const SMDS_MeshNode* theNode3, const SMDS_MeshNode* theNode4) { - SMDS_MeshFace* face; if ( SMESH_TNodeXYZ( theNode1 ).SquareDistance( theNode3 ) > SMESH_TNodeXYZ( theNode2 ).SquareDistance( theNode4 ) ) { - face = myHelper->AddFace(theNode2, theNode4 , theNode1); - if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); - face = myHelper->AddFace(theNode2, theNode3, theNode4); - if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); + myHelper->AddFace(theNode2, theNode4 , theNode1); + myHelper->AddFace(theNode2, theNode3, theNode4); } else { - face = myHelper->AddFace(theNode1, theNode2 ,theNode3); - if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); - face = myHelper->AddFace(theNode1, theNode3, theNode4); - if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); + myHelper->AddFace(theNode1, theNode2 ,theNode3); + myHelper->AddFace(theNode1, theNode3, theNode4); } } @@ -3090,10 +3071,8 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh & aMesh, // create faces for (i=1; i<=dl; i++) { for (j=1; jAddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), - NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); - if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + myHelper->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), + NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); } } } @@ -3145,10 +3124,8 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh & aMesh, // create faces for (i=1; i<=dr; i++) { for (j=1; jAddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), - NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); - if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + myHelper->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), + NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); } } } @@ -3209,10 +3186,8 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh & aMesh, // create faces for (i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), - NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); - if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); } } } // end Multiple Reduce implementation @@ -3312,8 +3287,6 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh & aMesh, if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl) return error(COMPERR_BAD_INPUT_MESH); - myHelper->SetElementsOnShape( true ); - gp_UV uv[ UV_SIZE ]; uv[ UV_A0 ].SetCoord( uv_eb.front().u, uv_eb.front().v); uv[ UV_A1 ].SetCoord( uv_eb.back().u, uv_eb.back().v ); @@ -3906,29 +3879,72 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) { if ( !myNeedSmooth ) return; - // Get nodes to smooth + SMESHDS_Mesh* meshDS = myHelper->GetMeshDS(); + const double tol = BRep_Tool::Tolerance( quad->face ); + Handle(ShapeAnalysis_Surface) surface = myHelper->GetSurface( quad->face ); - // TODO: do not smooth fixed nodes + if ( myHelper->HasDegeneratedEdges() && myForcedPnts.empty() ) + { + // "smooth" by computing node positions using 3D TFI and further projection + + int nbhoriz = quad->iSize; + int nbvertic = quad->jSize; + + SMESH_TNodeXYZ a0( quad->UVPt( 0, 0 ).node ); + SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0 ).node ); + SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node ); + SMESH_TNodeXYZ a3( quad->UVPt( 0, nbvertic-1 ).node ); + + for (int i = 1; i < nbhoriz-1; i++) + { + SMESH_TNodeXYZ p0( quad->UVPt( i, 0 ).node ); + SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node ); + for (int j = 1; j < nbvertic-1; j++) + { + SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node ); + SMESH_TNodeXYZ p3( quad->UVPt( 0, j ).node ); + + UVPtStruct& uvp = quad->UVPt( i, j ); + + gp_Pnt p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3); + gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol ); + gp_Pnt pnew = surface->Value( uv ); + + meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() ); + uvp.u = uv.X(); + uvp.v = uv.Y(); + } + } + return; + } + + // Get nodes to smooth typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap; TNo2SmooNoMap smooNoMap; - const TopoDS_Face& geomFace = TopoDS::Face( myHelper->GetSubShape() ); - Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace ); - double U1, U2, V1, V2; - surface->Bounds(U1, U2, V1, V2); - GeomAPI_ProjectPointOnSurf proj; - proj.Init( surface, U1, U2, V1, V2, BRep_Tool::Tolerance( geomFace ) ); - - SMESHDS_Mesh* meshDS = myHelper->GetMeshDS(); - SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( geomFace ); - SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes(); + // fixed nodes + set< const SMDS_MeshNode* > fixedNodes; + for ( size_t i = 0; i < myForcedPnts.size(); ++i ) + { + fixedNodes.insert( myForcedPnts[i].node ); + if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() ) + { + TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ]; + sNode._uv = myForcedPnts[i].uv; + sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node ); + } + } + SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face ); + SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes(); while ( nIt->more() ) // loop on nodes bound to a FACE { const SMDS_MeshNode* node = nIt->next(); TSmoothNode & sNode = smooNoMap[ node ]; - sNode._uv = myHelper->GetNodeUV( geomFace, node ); + sNode._uv = myHelper->GetNodeUV( quad->face, node ); sNode._xyz = SMESH_TNodeXYZ( node ); + if ( fixedNodes.count( node )) + continue; // fixed - no triangles // set sNode._triangles SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face ); @@ -3946,16 +3962,22 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) } } // set _uv of smooth nodes on FACE boundary - for ( unsigned i = 0; i < quad->side.size(); ++i ) - { - const vector& uvVec = quad->side[i].GetUVPtStruct(); - for ( unsigned j = 0; j < uvVec.size(); ++j ) - { - TSmoothNode & sNode = smooNoMap[ uvVec[j].node ]; - sNode._uv = uvVec[j].UV(); - sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node ); - } - } + set< StdMeshers_FaceSide* > sidesOnEdge; + list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin(); + for ( ; q != myQuadList.end() ; ++q ) + for ( size_t i = 0; i < (*q)->side.size(); ++i ) + if ( ! (*q)->side[i].grid->Edge(0).IsNull() && + //(*q)->nbNodeOut( i ) == 0 && + sidesOnEdge.insert( (*q)->side[i].grid.get() ).second ) + { + const vector& uvVec = (*q)->side[i].grid->GetUVPtStruct(); + for ( unsigned j = 0; j < uvVec.size(); ++j ) + { + TSmoothNode & sNode = smooNoMap[ uvVec[j].node ]; + sNode._uv = uvVec[j].UV(); + sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node ); + } + } // define refernce orientation in 2D TNo2SmooNoMap::iterator n2sn = smooNoMap.begin(); @@ -3984,22 +4006,16 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) { // compute a new XYZ gp_XYZ newXYZ (0,0,0); - for ( unsigned i = 0; i < sNode._triangles.size(); ++i ) + for ( size_t i = 0; i < sNode._triangles.size(); ++i ) newXYZ += sNode._triangles[i]._n1->_xyz; newXYZ /= sNode._triangles.size(); // compute a new UV by projection - proj.Perform( newXYZ ); - isValid = ( proj.IsDone() && proj.NbPoints() > 0 ); - if ( isValid ) - { - // check validity of the newUV - Quantity_Parameter u,v; - proj.LowerDistanceParameters( u, v ); - newUV.SetCoord( u, v ); - for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i ) - isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); - } + newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY(); + + // check validity of the newUV + for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i ) + isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); } if ( !isValid ) { @@ -4017,7 +4033,7 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) if ( isValid ) { sNode._uv = newUV; - sNode._xyz = surface->Value( newUV.X(), newUV.Y() ).XYZ(); + sNode._xyz = surface->Value( newUV ).XYZ(); } } } @@ -4031,7 +4047,7 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) continue; // not movable node SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first ); - gp_Pnt xyz = surface->Value( sNode._uv.X(), sNode._uv.Y() ); + gp_Pnt xyz = surface->Value( sNode._uv ); meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); // store the new UV @@ -4051,13 +4067,13 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) if ( node->getshapeId() != myHelper->GetSubShapeID() ) continue; // medium node is on EDGE or VERTEX - gp_XY uv1 = myHelper->GetNodeUV( geomFace, link.node1(), node ); - gp_XY uv2 = myHelper->GetNodeUV( geomFace, link.node2(), node ); + gp_XYZ pm = 0.5 * ( SMESH_TNodeXYZ( link.node1() ) + SMESH_TNodeXYZ( link.node2() )); + gp_XY uvm = myHelper->GetNodeUV( quad->face, node ); + + gp_Pnt2d uv = surface->NextValueOfUV( uvm, pm, 10*tol ); + gp_Pnt xyz = surface->Value( uv ); - gp_XY uv = myHelper->GetMiddleUV( surface, uv1, uv2 ); node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( uv.X(), uv.Y() ))); - - gp_Pnt xyz = surface->Value( uv.X(), uv.Y() ); meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); } } @@ -4158,6 +4174,7 @@ bool StdMeshers_Quadrangle_2D::check() if ( !myHelper->IsSeamShape( nn[i]->getshapeId() )) nInFace = nn[i]; + toCheckUV = true; for ( int i = 0; i < nbN; ++i ) uv[ i ] = myHelper->GetNodeUV( geomFace, nn[i], nInFace, &toCheckUV ); @@ -4253,7 +4270,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, if ( !theConsiderMesh || faceSide.VertexNode( iE )) { TopoDS_Vertex v = helper.IthVertex( 0, *edge ); - double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace, v ); + double angle = helper.GetAngle( prevE, *edge, theFace, v ); vertexByAngle.insert( make_pair( angle, v )); angleByVertex.Bind( v, angle ); } @@ -4645,49 +4662,66 @@ bool StdMeshers_Quadrangle_2D::getEnforcedUV() Standard_Real u1,u2,v1,v2; const TopoDS_Face& face = TopoDS::Face( myHelper->GetSubShape() ); const double tol = BRep_Tool::Tolerance( face ); - Handle(Geom_Surface) surf = BRep_Tool::Surface( face ); - surf->Bounds( u1,u2,v1,v2 ); - GeomAPI_ProjectPointOnSurf project; - project.Init(surf, u1,u2, v1,v2, tol ); + Handle(ShapeAnalysis_Surface) project = myHelper->GetSurface( face ); + project->Bounds( u1,u2,v1,v2 ); Bnd_Box bbox; BRepBndLib::Add( face, bbox ); double farTol = 0.01 * sqrt( bbox.SquareExtent() ); + // get internal VERTEXes of the FACE to use them instead of equal points + typedef map< pair< double, double >, TopoDS_Vertex > TUV2VMap; + TUV2VMap uv2intV; + for ( TopExp_Explorer vExp( face, TopAbs_VERTEX, TopAbs_EDGE ); vExp.More(); vExp.Next() ) + { + TopoDS_Vertex v = TopoDS::Vertex( vExp.Current() ); + gp_Pnt2d uv = project->ValueOfUV( BRep_Tool::Pnt( v ), tol ); + uv2intV.insert( make_pair( make_pair( uv.X(), uv.Y() ), v )); + } + for ( size_t iP = 0; iP < points.size(); ++iP ) { - project.Perform( points[ iP ]); - if ( !project.IsDone() ) - { - if ( isStrictCheck && iP < nbPoints ) - return error - (TComm("Projection of an enforced point to the face failed - (") - << points[ iP ].X() << ", "<< points[ iP ].Y() << ", "<< points[ iP ].Z() << " )"); - continue; - } - if ( project.LowerDistance() > farTol ) + gp_Pnt2d uv = project->ValueOfUV( points[ iP ], tol ); + if ( project->Gap() > farTol ) { if ( isStrictCheck && iP < nbPoints ) return error (COMPERR_BAD_PARMETERS, TComm("An enforced point is too far from the face, dist = ") - << project.LowerDistance() << " - (" + << points[ iP ].Distance( project->Value( uv )) << " - (" << points[ iP ].X() << ", "<< points[ iP ].Y() << ", "<< points[ iP ].Z() << " )"); continue; } - Quantity_Parameter u, v; - project.LowerDistanceParameters(u, v); - gp_Pnt2d uv( u, v ); BRepClass_FaceClassifier clsf ( face, uv, tol ); switch ( clsf.State() ) { case TopAbs_IN: { - double edgeDist = ( Min( Abs( u - u1 ), Abs( u - u2 )) + - Min( Abs( v - v1 ), Abs( v - v2 ))); + double edgeDist = ( Min( Abs( uv.X() - u1 ), Abs( uv.X() - u2 )) + + Min( Abs( uv.Y() - v1 ), Abs( uv.Y() - v2 ))); ForcedPoint fp; fp.uv = uv.XY(); fp.xyz = points[ iP ].XYZ(); if ( iP >= nbPoints ) fp.vertex = TopoDS::Vertex( vMap( iP - nbPoints + 1 )); + TUV2VMap::iterator uv2v = uv2intV.lower_bound( make_pair( uv.X()-tol, uv.Y()-tol )); + for ( ; uv2v != uv2intV.end() && uv2v->first.first <= uv.X()+tol; ++uv2v ) + if ( uv.SquareDistance( gp_Pnt2d( uv2v->first.first, uv2v->first.second )) < tol*tol ) + { + fp.vertex = uv2v->second; + break; + } + + fp.node = 0; + if ( myHelper->IsSubShape( fp.vertex, myHelper->GetMesh() )) + { + SMESH_subMesh* sm = myHelper->GetMesh()->GetSubMesh( fp.vertex ); + sm->ComputeStateEngine( SMESH_subMesh::COMPUTE ); + fp.node = SMESH_Algo::VertexNode( fp.vertex, myHelper->GetMeshDS() ); + } + else + { + fp.node = myHelper->AddNode( fp.xyz.X(), fp.xyz.Y(), fp.xyz.Z(), + 0, fp.uv.X(), fp.uv.Y() ); + } sortedFP.insert( make_pair( edgeDist, fp )); break; } @@ -4756,7 +4790,7 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes() { bool isNodeEnforced = false; - // look for a quad enclosing a enforced point + // look for a quad enclosing an enforced point for ( quadIt = myQuadList.begin(); quadIt != myQuadList.end(); ++quadIt ) { FaceQuadStruct::Ptr quad = *quadIt; @@ -4811,8 +4845,9 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes() } // make a node of a side forced vector& points = (vector&) side.GetUVPtStruct(); - points[ sideNodeIndex ].u = myForcedPnts[ iFP ].U(); - points[ sideNodeIndex ].v = myForcedPnts[ iFP ].V(); + points[ sideNodeIndex ].u = myForcedPnts[ iFP ].U(); + points[ sideNodeIndex ].v = myForcedPnts[ iFP ].V(); + points[ sideNodeIndex ].node = myForcedPnts[ iFP ].node; updateSideUV( side, sideNodeIndex, quadsBySide ); @@ -4859,6 +4894,9 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes() FaceQuadStruct::Ptr newQuad = myQuadList.back(); FaceQuadStruct::Side& newSide = newQuad->side[ iNewSide ]; + vector& points = (vector&) newSide.GetUVPtStruct(); + points[ indForced ].node = myForcedPnts[ iFP ].node; + newSide.forced_nodes.insert( indForced ); quad->side[( iNewSide+2 ) % 4 ].forced_nodes.insert( indForced ); @@ -4895,6 +4933,7 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes() << myForcedPnts[iFP].xyz.Y() << ", " << myForcedPnts[iFP].xyz.Z() << " )"); } + myNeedSmooth = true; } // loop on enforced points @@ -4912,25 +4951,31 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes() if ( quadVec.size() <= 1 ) continue; // outer side - bool missedNodesOnSide = false; const vector& points = side.grid->GetUVPtStruct(); for ( size_t iC = 0; iC < side.contacts.size(); ++iC ) { + if ( side.contacts[iC].point < side.from || + side.contacts[iC].point >= side.to ) + continue; + if ( side.contacts[iC].other_point < side.contacts[iC].other_side->from || + side.contacts[iC].other_point >= side.contacts[iC].other_side->to ) + continue; const vector& oGrid = side.contacts[iC].other_side->grid->GetUVPtStruct(); const UVPtStruct& uvPt = points[ side.contacts[iC].point ]; - if ( side.contacts[iC].other_point >= oGrid.size() || + if ( side.contacts[iC].other_point >= oGrid .size() || side.contacts[iC].point >= points.size() ) throw SALOME_Exception( "StdMeshers_Quadrangle_2D::addEnforcedNodes(): wrong contact" ); if ( oGrid[ side.contacts[iC].other_point ].node ) (( UVPtStruct& ) uvPt).node = oGrid[ side.contacts[iC].other_point ].node; } + + bool missedNodesOnSide = false; for ( size_t iP = 0; iP < points.size(); ++iP ) if ( !points[ iP ].node ) { UVPtStruct& uvPnt = ( UVPtStruct& ) points[ iP ]; - gp_Pnt P = surf->Value( uvPnt.u, uvPnt.v ); - uvPnt.node = meshDS->AddNode(P.X(), P.Y(), P.Z()); - meshDS->SetNodeOnFace( uvPnt.node, myHelper->GetSubShapeID(), uvPnt.u, uvPnt.v ); + gp_Pnt P = surf->Value( uvPnt.u, uvPnt.v ); + uvPnt.node = myHelper->AddNode(P.X(), P.Y(), P.Z(), 0, uvPnt.u, uvPnt.v ); missedNodesOnSide = true; } if ( missedNodesOnSide ) @@ -4990,8 +5035,10 @@ int StdMeshers_Quadrangle_2D::splitQuad(FaceQuadStruct::Ptr quad, int I, int J) newQuad->side[ QUAD_TOP_SIDE ].from = iTop; newQuad->name = ( TComm("Right of I=") << I ); - quad->side[ QUAD_BOTTOM_SIDE ].to = iBot + 1; - quad->side[ QUAD_TOP_SIDE ].to = iTop + 1; + bool bRev = quad->side[ QUAD_BOTTOM_SIDE ].IsReversed(); + bool tRev = quad->side[ QUAD_TOP_SIDE ].IsReversed(); + quad->side[ QUAD_BOTTOM_SIDE ].to = iBot + ( bRev ? -1 : +1 ); + quad->side[ QUAD_TOP_SIDE ].to = iTop + ( tRev ? -1 : +1 ); quad->uv_grid.clear(); return QUAD_LEFT_SIDE; @@ -5579,6 +5626,8 @@ void FaceQuadStruct::Side::AddContact( int ip, Side* side, int iop ) if ( ip >= GetUVPtStruct().size() || iop >= side->GetUVPtStruct().size() ) throw SALOME_Exception( "FaceQuadStruct::Side::AddContact(): wrong point" ); + if ( ip < from || ip >= to ) + return; { contacts.resize( contacts.size() + 1 ); Contact& c = contacts.back(); diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index 6a06c9a46..460a5e4ab 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -244,9 +244,10 @@ class STDMESHERS_EXPORT StdMeshers_Quadrangle_2D: public SMESH_2D_Algo struct ForcedPoint { - gp_XY uv; - gp_XYZ xyz; - TopoDS_Vertex vertex; + gp_XY uv; + gp_XYZ xyz; + TopoDS_Vertex vertex; + const SMDS_MeshNode* node; double U() const { return uv.X(); } double V() const { return uv.Y(); }