Fix for the "0021861: EDF 2226 : Documentation of numeric functor option in split quadrangles is unclear" issue.

This commit is contained in:
ana 2012-11-01 11:39:48 +00:00
parent 7348db21e5
commit f0bf265fc0
8 changed files with 86 additions and 56 deletions

View File

@ -429,23 +429,17 @@ SMDSAbs_ElementType Volume::GetType() const
Class : MaxElementLength2D Class : MaxElementLength2D
Description : Functor calculating maximum length of 2D element Description : Functor calculating maximum length of 2D element
*/ */
double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P )
double MaxElementLength2D::GetValue( long theElementId )
{ {
TSequenceOfXYZ P; if(P.size() == 0)
if( GetPoints( theElementId, P ) ) { return 0.;
double aVal = 0; double aVal = 0;
const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
SMDSAbs_ElementType aType = aElem->GetType();
int len = P.size(); int len = P.size();
switch( aType ) {
case SMDSAbs_Face:
if( len == 3 ) { // triangles if( len == 3 ) { // triangles
double L1 = getDistance(P( 1 ),P( 2 )); double L1 = getDistance(P( 1 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 3 )); double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 1 )); double L3 = getDistance(P( 3 ),P( 1 ));
aVal = Max(L1,Max(L2,L3)); aVal = Max(L1,Max(L2,L3));
break;
} }
else if( len == 4 ) { // quadrangles else if( len == 4 ) { // quadrangles
double L1 = getDistance(P( 1 ),P( 2 )); double L1 = getDistance(P( 1 ),P( 2 ));
@ -455,14 +449,12 @@ double MaxElementLength2D::GetValue( long theElementId )
double D1 = getDistance(P( 1 ),P( 3 )); double D1 = getDistance(P( 1 ),P( 3 ));
double D2 = getDistance(P( 2 ),P( 4 )); double D2 = getDistance(P( 2 ),P( 4 ));
aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
break;
} }
else if( len == 6 ) { // quadratic triangles else if( len == 6 ) { // quadratic triangles
double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); 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 L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
aVal = Max(L1,Max(L2,L3)); aVal = Max(L1,Max(L2,L3));
break;
} }
else if( len == 8 || len == 9 ) { // quadratic quadrangles else if( len == 8 || len == 9 ) { // quadratic quadrangles
double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
@ -472,8 +464,6 @@ double MaxElementLength2D::GetValue( long theElementId )
double D1 = getDistance(P( 1 ),P( 5 )); double D1 = getDistance(P( 1 ),P( 5 ));
double D2 = getDistance(P( 3 ),P( 7 )); double D2 = getDistance(P( 3 ),P( 7 ));
aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
break;
}
} }
if( myPrecision >= 0 ) if( myPrecision >= 0 )
@ -482,6 +472,13 @@ double MaxElementLength2D::GetValue( long theElementId )
aVal = floor( aVal * prec + 0.5 ) / prec; aVal = floor( aVal * prec + 0.5 ) / prec;
} }
return aVal; return aVal;
}
double MaxElementLength2D::GetValue( long theElementId )
{
TSequenceOfXYZ P;
if( GetPoints( theElementId, P ) && myMesh->FindElement( theElementId )->GetType() == SMDSAbs_Face) {
GetValue(P);
} }
return 0.; return 0.;
} }

View File

@ -162,6 +162,7 @@ namespace SMESH{
class SMESHCONTROLS_EXPORT MaxElementLength2D: public virtual NumericalFunctor{ class SMESHCONTROLS_EXPORT MaxElementLength2D: public virtual NumericalFunctor{
public: public:
virtual double GetValue( long theElementId ); virtual double GetValue( long theElementId );
virtual double GetValue( const TSequenceOfXYZ& P );
virtual double GetBadRate( double Value, int nbNodes ) const; virtual double GetBadRate( double Value, int nbNodes ) const;
virtual SMDSAbs_ElementType GetType() const; virtual SMDSAbs_ElementType GetType() const;
}; };

View File

@ -1267,7 +1267,8 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
if( !elem->IsQuadratic() ) { if( !elem->IsQuadratic() ) {
// split liner quadrangle // 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 ) { if ( aBadRate1 <= aBadRate2 ) {
// tr1 + tr2 is better // tr1 + tr2 is better
newElem1 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); 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 tr3 ( aNodes[1], aNodes[2], aNodes[3] );
SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); 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 if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better
return 1; // diagonal 1-3 return 1; // diagonal 1-3

View File

@ -225,7 +225,7 @@ QWidget* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool
myComboBoxFunctor->addItem(tr("ASPECTRATIO_ELEMENTS")); myComboBoxFunctor->addItem(tr("ASPECTRATIO_ELEMENTS"));
myComboBoxFunctor->addItem(tr("MINIMUMANGLE_ELEMENTS")); myComboBoxFunctor->addItem(tr("MINIMUMANGLE_ELEMENTS"));
myComboBoxFunctor->addItem(tr("SKEW_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("LENGTH2D_EDGES")); // for existing elements only
//myComboBoxFunctor->addItem(tr("MULTI2D_BORDERS")); // for existing elements only //myComboBoxFunctor->addItem(tr("MULTI2D_BORDERS")); // for existing elements only
myComboBoxFunctor->setCurrentIndex(0); myComboBoxFunctor->setCurrentIndex(0);
@ -362,6 +362,8 @@ SMESH::NumericalFunctor_ptr SMESHGUI_MultiEditDlg::getNumericalFunctor()
aNF = aFilterMgr->CreateLength2D(); aNF = aFilterMgr->CreateLength2D();
else if (myComboBoxFunctor->currentText() == tr("MULTI2D_BORDERS")) else if (myComboBoxFunctor->currentText() == tr("MULTI2D_BORDERS"))
aNF = aFilterMgr->CreateMultiConnection2D(); aNF = aFilterMgr->CreateMultiConnection2D();
else if (myComboBoxFunctor->currentText() == tr("MIN_DIAG_ELEMENTS"))
aNF = aFilterMgr->CreateMaxElementLength2D();
else; else;
return aNF._retn(); return aNF._retn();
@ -1154,6 +1156,7 @@ SMESHGUI_UnionOfTrianglesDlg
setWindowTitle(tr("CAPTION")); 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("WARP_ELEMENTS")); // for quadrangles only
myComboBoxFunctor->addItem(tr("TAPER_ELEMENTS")); // for quadrangles only myComboBoxFunctor->addItem(tr("TAPER_ELEMENTS")); // for quadrangles only
@ -1240,6 +1243,8 @@ SMESHGUI_CuttingOfQuadsDlg
myCriterionGrp->show(); myCriterionGrp->show();
myChoiceWidget->show(); myChoiceWidget->show();
myComboBoxFunctor->insertItem(0, tr("MIN_DIAG_ELEMENTS"));
myComboBoxFunctor->setCurrentIndex(0);
myComboBoxFunctor->setEnabled(false); myComboBoxFunctor->setEnabled(false);
connect(myPreviewChk, SIGNAL(stateChanged(int)), this, SLOT(onPreviewChk())); connect(myPreviewChk, SIGNAL(stateChanged(int)), this, SLOT(onPreviewChk()));

View File

@ -63,6 +63,10 @@
<source>AREA_ELEMENTS</source> <source>AREA_ELEMENTS</source>
<translation>Area</translation> <translation>Area</translation>
</message> </message>
<message>
<source>MIN_DIAG_ELEMENTS</source>
<translation>Minimum diagonal</translation>
</message>
<message> <message>
<source>ASPECTRATIO_3D_ELEMENTS</source> <source>ASPECTRATIO_3D_ELEMENTS</source>
<translation>Aspect Ratio 3D</translation> <translation>Aspect Ratio 3D</translation>

View File

@ -2125,6 +2125,17 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
theCommand->SetArg( 3, face ); 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 ) if ( isPyMeshMethod )
{ {
theCommand->SetObject( myMesh ); theCommand->SetObject( myMesh );

View File

@ -1546,7 +1546,7 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE
dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() ); dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
SMESH::Controls::NumericalFunctorPtr aCrit; SMESH::Controls::NumericalFunctorPtr aCrit;
if ( !aNumericalFunctor ) if ( !aNumericalFunctor )
aCrit.reset( new SMESH::Controls::AspectRatio() ); aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
else else
aCrit = aNumericalFunctor->GetNumericalFunctor(); aCrit = aNumericalFunctor->GetNumericalFunctor();

View File

@ -2682,23 +2682,33 @@ class Mesh:
return self.editor.TriToQuadObject(theObject, self.smeshpyD.GetFunctor(theCriterion), MaxAngle) return self.editor.TriToQuadObject(theObject, self.smeshpyD.GetFunctor(theCriterion), MaxAngle)
## Splits quadrangles into triangles. ## 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 IDsOfElements the faces to be splitted.
# @param theCriterion FT_...; used to choose a diagonal for splitting. # @param theCriterion FT_...; used to choose a diagonal for splitting.
# @return TRUE in case of success, FALSE otherwise. # @return TRUE in case of success, FALSE otherwise.
# @ingroup l2_modif_cutquadr # @ingroup l2_modif_cutquadr
def QuadToTri (self, IDsOfElements, theCriterion): def QuadToTri (self, IDsOfElements, theCriterion = None):
if IDsOfElements == []: if IDsOfElements == []:
IDsOfElements = self.GetElementsId() IDsOfElements = self.GetElementsId()
if theCriterion is None:
theCriterion = FT_MaxElementLength2D
return self.editor.QuadToTri(IDsOfElements, self.smeshpyD.GetFunctor(theCriterion)) return self.editor.QuadToTri(IDsOfElements, self.smeshpyD.GetFunctor(theCriterion))
## Splits quadrangles into triangles. ## 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 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. # @param theCriterion FT_...; used to choose a diagonal for splitting.
# @return TRUE in case of success, FALSE otherwise. # @return TRUE in case of success, FALSE otherwise.
# @ingroup l2_modif_cutquadr # @ingroup l2_modif_cutquadr
def QuadToTriObject (self, theObject, theCriterion): def QuadToTriObject (self, theObject, theCriterion = None):
if ( isinstance( theObject, Mesh )): if ( isinstance( theObject, Mesh )):
theObject = theObject.GetMesh() theObject = theObject.GetMesh()
if theCriterion is None:
theCriterion = FT_MaxElementLength2D
return self.editor.QuadToTriObject(theObject, self.smeshpyD.GetFunctor(theCriterion)) return self.editor.QuadToTriObject(theObject, self.smeshpyD.GetFunctor(theCriterion))
## Splits quadrangles into triangles. ## Splits quadrangles into triangles.