From f0bf265fc0ea849ad1a359e10ad0c9cf6b0b9bb8 Mon Sep 17 00:00:00 2001 From: ana Date: Thu, 1 Nov 2012 11:39:48 +0000 Subject: [PATCH] Fix for the "0021861: EDF 2226 : Documentation of numeric functor option in split quadrangles is unclear" issue. --- src/Controls/SMESH_Controls.cxx | 95 +++++++++++++------------- src/Controls/SMESH_ControlsDef.hxx | 1 + src/SMESH/SMESH_MeshEditor.cxx | 6 +- src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx | 9 ++- src/SMESHGUI/SMESH_msg_en.ts | 4 ++ src/SMESH_I/SMESH_2smeshpy.cxx | 11 +++ src/SMESH_I/SMESH_MeshEditor_i.cxx | 2 +- src/SMESH_SWIG/smeshDC.py | 14 +++- 8 files changed, 86 insertions(+), 56 deletions(-) diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 2fe0e0889..6b400350d 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -429,59 +429,56 @@ SMDSAbs_ElementType Volume::GetType() const Class : MaxElementLength2D Description : Functor calculating maximum length of 2D element */ +double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P ) +{ + if(P.size() == 0) + return 0.; + double aVal = 0; + int len = P.size(); + if( len == 3 ) { // triangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + aVal = Max(L1,Max(L2,L3)); + } + else if( len == 4 ) { // quadrangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double D1 = getDistance(P( 1 ),P( 3 )); + double D2 = getDistance(P( 2 ),P( 4 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); + } + else if( len == 6 ) { // quadratic triangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); + aVal = Max(L1,Max(L2,L3)); + } + else if( len == 8 || len == 9 ) { // quadratic quadrangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 )); + double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 )); + double D1 = getDistance(P( 1 ),P( 5 )); + double D2 = getDistance(P( 3 ),P( 7 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); + } + + if( myPrecision >= 0 ) + { + double prec = pow( 10., (double)myPrecision ); + aVal = floor( aVal * prec + 0.5 ) / prec; + } + return aVal; +} double MaxElementLength2D::GetValue( long theElementId ) { TSequenceOfXYZ P; - if( GetPoints( theElementId, P ) ) { - double aVal = 0; - const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId ); - SMDSAbs_ElementType aType = aElem->GetType(); - int len = P.size(); - switch( aType ) { - case SMDSAbs_Face: - if( len == 3 ) { // triangles - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 1 )); - aVal = Max(L1,Max(L2,L3)); - break; - } - else if( len == 4 ) { // quadrangles - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 1 )); - double D1 = getDistance(P( 1 ),P( 3 )); - double D2 = getDistance(P( 2 ),P( 4 )); - aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); - break; - } - else if( len == 6 ) { // quadratic triangles - double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); - double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); - double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); - aVal = Max(L1,Max(L2,L3)); - break; - } - else if( len == 8 || len == 9 ) { // quadratic quadrangles - double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); - double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); - double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 )); - double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 )); - double D1 = getDistance(P( 1 ),P( 5 )); - double D2 = getDistance(P( 3 ),P( 7 )); - aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); - break; - } - } - - if( myPrecision >= 0 ) - { - double prec = pow( 10., (double)myPrecision ); - aVal = floor( aVal * prec + 0.5 ) / prec; - } - return aVal; + if( GetPoints( theElementId, P ) && myMesh->FindElement( theElementId )->GetType() == SMDSAbs_Face) { + GetValue(P); } return 0.; } diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx index 81e7ba1cd..587f5b6d6 100644 --- a/src/Controls/SMESH_ControlsDef.hxx +++ b/src/Controls/SMESH_ControlsDef.hxx @@ -162,6 +162,7 @@ namespace SMESH{ class SMESHCONTROLS_EXPORT MaxElementLength2D: public virtual NumericalFunctor{ public: virtual double GetValue( long theElementId ); + virtual double GetValue( const TSequenceOfXYZ& P ); virtual double GetBadRate( double Value, int nbNodes ) const; virtual SMDSAbs_ElementType GetType() const; }; diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index c7eb28600..7691b580d 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1267,7 +1267,8 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, if( !elem->IsQuadratic() ) { // split liner quadrangle - + // for MaxElementLength2D functor we return minimum diagonal for splitting, + // because aBadRate1=2*len(diagonal 1-3); aBadRate2=2*len(diagonal 2-4) if ( aBadRate1 <= aBadRate2 ) { // tr1 + tr2 is better newElem1 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); @@ -1401,7 +1402,8 @@ int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad, SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); - + // for MaxElementLength2D functor we return minimum diagonal for splitting, + // because aBadRate1=2*len(diagonal 1-3); aBadRate2=2*len(diagonal 2-4) if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better return 1; // diagonal 1-3 diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx index b6aa6c3e2..b87346e63 100755 --- a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx @@ -225,7 +225,7 @@ QWidget* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool myComboBoxFunctor->addItem(tr("ASPECTRATIO_ELEMENTS")); myComboBoxFunctor->addItem(tr("MINIMUMANGLE_ELEMENTS")); myComboBoxFunctor->addItem(tr("SKEW_ELEMENTS")); - myComboBoxFunctor->addItem(tr("AREA_ELEMENTS")); + //myComboBoxFunctor->addItem(tr("AREA_ELEMENTS")); //myComboBoxFunctor->addItem(tr("LENGTH2D_EDGES")); // for existing elements only //myComboBoxFunctor->addItem(tr("MULTI2D_BORDERS")); // for existing elements only myComboBoxFunctor->setCurrentIndex(0); @@ -362,6 +362,8 @@ SMESH::NumericalFunctor_ptr SMESHGUI_MultiEditDlg::getNumericalFunctor() aNF = aFilterMgr->CreateLength2D(); else if (myComboBoxFunctor->currentText() == tr("MULTI2D_BORDERS")) aNF = aFilterMgr->CreateMultiConnection2D(); + else if (myComboBoxFunctor->currentText() == tr("MIN_DIAG_ELEMENTS")) + aNF = aFilterMgr->CreateMaxElementLength2D(); else; return aNF._retn(); @@ -1153,7 +1155,8 @@ SMESHGUI_UnionOfTrianglesDlg { setWindowTitle(tr("CAPTION")); - myComboBoxFunctor->setEnabled(true); + myComboBoxFunctor->setEnabled(true); + myComboBoxFunctor->addItem(tr("AREA_ELEMENTS")); myComboBoxFunctor->addItem(tr("WARP_ELEMENTS")); // for quadrangles only myComboBoxFunctor->addItem(tr("TAPER_ELEMENTS")); // for quadrangles only @@ -1240,6 +1243,8 @@ SMESHGUI_CuttingOfQuadsDlg myCriterionGrp->show(); myChoiceWidget->show(); + myComboBoxFunctor->insertItem(0, tr("MIN_DIAG_ELEMENTS")); + myComboBoxFunctor->setCurrentIndex(0); myComboBoxFunctor->setEnabled(false); connect(myPreviewChk, SIGNAL(stateChanged(int)), this, SLOT(onPreviewChk())); diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 868b81c7d..fa507c549 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -63,6 +63,10 @@ AREA_ELEMENTS Area + + MIN_DIAG_ELEMENTS + Minimum diagonal + ASPECTRATIO_3D_ELEMENTS Aspect Ratio 3D diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 43c0a524e..e62d2bc65 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -2125,6 +2125,17 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) theCommand->SetArg( 3, face ); } + if(method == "QuadToTri" || method == "QuadToTriObject") + { + int crit_arg = theCommand->GetNbArgs(); + _AString crit = theCommand->GetArg(crit_arg); + if(crit.Search("MaxElementLength2D") != -1) + { + theCommand->SetArg(crit_arg, ""); + isPyMeshMethod = true; + } + } + if ( isPyMeshMethod ) { theCommand->SetObject( myMesh ); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index d4274dc57..2d3f5b888 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -1546,7 +1546,7 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE dynamic_cast( SMESH_Gen_i::GetServant( Criterion ).in() ); SMESH::Controls::NumericalFunctorPtr aCrit; if ( !aNumericalFunctor ) - aCrit.reset( new SMESH::Controls::AspectRatio() ); + aCrit.reset( new SMESH::Controls::MaxElementLength2D() ); else aCrit = aNumericalFunctor->GetNumericalFunctor(); diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index 87d32ec81..6f2b63e79 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -2682,23 +2682,33 @@ class Mesh: return self.editor.TriToQuadObject(theObject, self.smeshpyD.GetFunctor(theCriterion), MaxAngle) ## Splits quadrangles into triangles. + # + # If @a theCriterion is None, quadrangles will be split by the smallest diagonal. + # # @param IDsOfElements the faces to be splitted. # @param theCriterion FT_...; used to choose a diagonal for splitting. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_cutquadr - def QuadToTri (self, IDsOfElements, theCriterion): + def QuadToTri (self, IDsOfElements, theCriterion = None): if IDsOfElements == []: IDsOfElements = self.GetElementsId() + if theCriterion is None: + theCriterion = FT_MaxElementLength2D return self.editor.QuadToTri(IDsOfElements, self.smeshpyD.GetFunctor(theCriterion)) ## Splits quadrangles into triangles. + # + # If @a theCriterion is None, quadrangles will be split by the smallest diagonal. + # # @param theObject the object from which the list of elements is taken, this is mesh, submesh or group # @param theCriterion FT_...; used to choose a diagonal for splitting. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_cutquadr - def QuadToTriObject (self, theObject, theCriterion): + def QuadToTriObject (self, theObject, theCriterion = None): if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() + if theCriterion is None: + theCriterion = FT_MaxElementLength2D return self.editor.QuadToTriObject(theObject, self.smeshpyD.GetFunctor(theCriterion)) ## Splits quadrangles into triangles.