*/
namespace{
+
+ inline gp_XYZ gpXYZ(const SMDS_MeshNode* aNode )
+ {
+ return gp_XYZ(aNode->X(), aNode->Y(), aNode->Z() );
+ }
+
inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 )
{
gp_Vec v1( P1 - P2 ), v2( P3 - P2 );
return aResult;
}
+ gp_XYZ getNormale( const SMDS_MeshFace* theFace, bool* ok=0 )
+ {
+ int aNbNode = theFace->NbNodes();
+
+ gp_XYZ q1 = gpXYZ( theFace->GetNode(1)) - gpXYZ( theFace->GetNode(0));
+ gp_XYZ q2 = gpXYZ( theFace->GetNode(2)) - gpXYZ( theFace->GetNode(0));
+ gp_XYZ n = q1 ^ q2;
+ if ( aNbNode > 3 ) {
+ gp_XYZ q3 = gpXYZ( theFace->GetNode(3)) - gpXYZ( theFace->GetNode(0));
+ n += q2 ^ q3;
+ }
+ double len = n.Modulus();
+ bool zeroLen = ( len <= numeric_limits<double>::min());
+ if ( !zeroLen )
+ n /= len;
+
+ if (ok) *ok = !zeroLen;
+
+ return n;
+ }
}
using namespace SMESH::Controls;
/*
- FUNCTORS
-*/
+ * FUNCTORS
+ */
/*
Class : NumericalFunctor
return myGeomType;
}
+//================================================================================
+/*!
+ * \brief Class CoplanarFaces
+ */
+//================================================================================
+
+CoplanarFaces::CoplanarFaces()
+ : myMesh(0), myFaceID(0), myToler(0)
+{
+}
+bool CoplanarFaces::IsSatisfy( long theElementId )
+{
+ if ( myCoplanarIDs.empty() )
+ {
+ // Build a set of coplanar face ids
+
+ if ( !myMesh || !myFaceID || !myToler )
+ return false;
+
+ const SMDS_MeshElement* face = myMesh->FindElement( myFaceID );
+ if ( !face || face->GetType() != SMDSAbs_Face )
+ return false;
+
+ bool normOK;
+ gp_Vec myNorm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK );
+ if (!normOK)
+ return false;
+
+ const double radianTol = myToler * PI180;
+ typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TFaceIt;
+ std::set<const SMDS_MeshElement*> checkedFaces, checkedNodes;
+ std::list<const SMDS_MeshElement*> faceQueue( 1, face );
+ while ( !faceQueue.empty() )
+ {
+ face = faceQueue.front();
+ if ( checkedFaces.insert( face ).second )
+ {
+ gp_Vec norm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK );
+ if (!normOK || myNorm.Angle( norm ) <= radianTol)
+ {
+ myCoplanarIDs.insert( face->GetID() );
+ std::set<const SMDS_MeshElement*> neighborFaces;
+ for ( int i = 0; i < face->NbCornerNodes(); ++i )
+ {
+ const SMDS_MeshNode* n = face->GetNode( i );
+ if ( checkedNodes.insert( n ).second )
+ neighborFaces.insert( TFaceIt( n->GetInverseElementIterator(SMDSAbs_Face)),
+ TFaceIt());
+ }
+ faceQueue.insert( faceQueue.end(), neighborFaces.begin(), neighborFaces.end() );
+ }
+ }
+ faceQueue.pop_front();
+ }
+ }
+ return myCoplanarIDs.count( theElementId );
+}
+
/*
- Class : RangeOfIds
- Description : Predicate for Range of Ids.
- Range may be specified with two ways.
- 1. Using AddToRange method
- 2. With SetRangeStr method. Parameter of this method is a string
- like as "1,2,3,50-60,63,67,70-"
+ *Class : RangeOfIds
+ *Description : Predicate for Range of Ids.
+ * Range may be specified with two ways.
+ * 1. Using AddToRange method
+ * 2. With SetRangeStr method. Parameter of this method is a string
+ * like as "1,2,3,50-60,63,67,70-"
*/
//=======================================================================
}
}
-static gp_XYZ getNormale( const SMDS_MeshFace* theFace )
-{
- gp_XYZ n;
- int aNbNode = theFace->NbNodes();
- TColgp_Array1OfXYZ anArrOfXYZ(1,4);
- SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator();
- int i = 1;
- for ( ; aNodeItr->more() && i <= 4; i++ ) {
- SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
- anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
- }
-
- gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1);
- gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1);
- n = q1 ^ q2;
- if ( aNbNode > 3 ) {
- gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1);
- n += q2 ^ q3;
- }
- double len = n.Modulus();
- if ( len > 0 )
- n /= len;
-
- return n;
-}
-
bool ManifoldPart::findConnected
( const ManifoldPart::TDataMapFacePtrInt& theAllFacePtrInt,
SMDS_MeshFace* theStartFace,
}
if (!valid && theMsg) {
SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
- tr("SMESHGUI_INVALID_PARAMETERS"));
+ tr("SMESHGUI_INVALID_PARAMETERS"));
return false;
}
}
QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(i, 2));
if (clrBtn && !clrBtn->color().isValid())
errMsg = tr( "GROUPCOLOR_ERROR" );
- } else if (aCriterion == SMESH::FT_RangeOfIds ||
- aCriterion == SMESH::FT_BelongToGeom ||
- aCriterion == SMESH::FT_BelongToPlane ||
- aCriterion == SMESH::FT_BelongToCylinder ||
- aCriterion == SMESH::FT_BelongToGenSurface ||
- aCriterion == SMESH::FT_ElemGeomType ||
- aCriterion == SMESH::FT_LyingOnGeom) {
+ }
+ else if (aCriterion == SMESH::FT_RangeOfIds ||
+ aCriterion == SMESH::FT_BelongToGeom ||
+ aCriterion == SMESH::FT_BelongToPlane ||
+ aCriterion == SMESH::FT_BelongToCylinder ||
+ aCriterion == SMESH::FT_BelongToGenSurface ||
+ aCriterion == SMESH::FT_ElemGeomType ||
+ aCriterion == SMESH::FT_CoplanarFaces ||
+ aCriterion == SMESH::FT_LyingOnGeom)
+ {
if (aTable->text(i, 2).isEmpty())
errMsg = tr( "ERROR" );
}
if (!aRes && aTable->isEditable(i, 2))
errMsg = tr( "ERROR" );
else if (aType == SMESH::EDGE &&
- GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
- aThreshold == 1)
+ GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
+ aThreshold == 1)
errMsg = tr( "MULTIEDGES_ERROR" );
}
}
else if ( aCriterionType == SMESH::FT_ElemGeomType )
theCriterion.Threshold = (double)((ComboItem*)aTable->item(theRow, 2))->value();
+ else if ( aCriterionType == SMESH::FT_CoplanarFaces )
+ theCriterion.ThresholdID = aTable->text(theRow, 2).toLatin1().constData();
else if ( aCriterionType != SMESH::FT_RangeOfIds &&
aCriterionType != SMESH::FT_BelongToGeom &&
aCriterionType != SMESH::FT_BelongToPlane &&
aCriterionType != SMESH::FT_BelongToCylinder &&
aCriterionType != SMESH::FT_BelongToGenSurface &&
- aCriterionType != SMESH::FT_LyingOnGeom)
+ aCriterionType != SMESH::FT_LyingOnGeom )
{
theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->value();
theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble();
ComboItem* typeBox = (ComboItem*)aTable->item(theRow, 2);
typeBox->setValue( (int)(theCriterion.Threshold + 0.5) );
}
+ else if (theCriterion.Type == SMESH::FT_CoplanarFaces )
+ {
+ aTable->item( theRow, 2 )->setText( QString( theCriterion.ThresholdID ) );
+ }
else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
- theCriterion.Type != SMESH::FT_BelongToGeom &&
- theCriterion.Type != SMESH::FT_BelongToPlane &&
- theCriterion.Type != SMESH::FT_BelongToCylinder &&
- theCriterion.Type != SMESH::FT_BelongToGenSurface &&
- theCriterion.Type != SMESH::FT_LyingOnGeom &&
- theCriterion.Type != SMESH::FT_FreeBorders &&
- theCriterion.Type != SMESH::FT_FreeEdges &&
- theCriterion.Type != SMESH::FT_FreeNodes &&
- theCriterion.Type != SMESH::FT_FreeFaces &&
- theCriterion.Type != SMESH::FT_BadOrientedVolume &&
- theCriterion.Type != SMESH::FT_LinearOrQuadratic)
+ theCriterion.Type != SMESH::FT_BelongToGeom &&
+ theCriterion.Type != SMESH::FT_BelongToPlane &&
+ theCriterion.Type != SMESH::FT_BelongToCylinder &&
+ theCriterion.Type != SMESH::FT_BelongToGenSurface &&
+ theCriterion.Type != SMESH::FT_LyingOnGeom &&
+ theCriterion.Type != SMESH::FT_CoplanarFaces &&
+ theCriterion.Type != SMESH::FT_FreeBorders &&
+ theCriterion.Type != SMESH::FT_FreeEdges &&
+ theCriterion.Type != SMESH::FT_FreeNodes &&
+ theCriterion.Type != SMESH::FT_FreeFaces &&
+ theCriterion.Type != SMESH::FT_BadOrientedVolume &&
+ theCriterion.Type != SMESH::FT_LinearOrQuadratic)
+ {
aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
+ }
else
{
aTable->item( theRow, 2 )->setText(QString(theCriterion.ThresholdStr));
}
if (theCriterion.Compare == SMESH::FT_EqualTo ||
- theCriterion.Type == SMESH::FT_BelongToPlane ||
- theCriterion.Type == SMESH::FT_BelongToCylinder ||
- theCriterion.Type == SMESH::FT_BelongToGenSurface ||
- theCriterion.Type == SMESH::FT_BelongToGeom ||
- theCriterion.Type == SMESH::FT_LyingOnGeom)
+ theCriterion.Type == SMESH::FT_BelongToPlane ||
+ theCriterion.Type == SMESH::FT_BelongToCylinder ||
+ theCriterion.Type == SMESH::FT_BelongToGenSurface ||
+ theCriterion.Type == SMESH::FT_BelongToGeom ||
+ theCriterion.Type == SMESH::FT_LyingOnGeom ||
+ theCriterion.Type == SMESH::FT_CoplanarFaces)
{
QTableWidgetItem* anItem = aTable->item(theRow, 0);
if (!myAddWidgets.contains(anItem))
ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0));
int aCriterion = GetCriterionType(aRow);
- bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo &&
- aCriterion != SMESH::FT_RangeOfIds &&
- aCriterion != SMESH::FT_FreeEdges &&
- aCriterion != SMESH::FT_FreeFaces &&
- aCriterion != SMESH::FT_BadOrientedVolume;
+ bool toEnable = ((((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo &&
+ aCriterion != SMESH::FT_RangeOfIds &&
+ aCriterion != SMESH::FT_FreeEdges &&
+ aCriterion != SMESH::FT_FreeFaces &&
+ aCriterion != SMESH::FT_BadOrientedVolume)
+ ||
+ aCriterion == SMESH::FT_CoplanarFaces);
if (!myAddWidgets.contains(anItem))
{
case SMESH::FT_Warping:
case SMESH::FT_MinimumAngle:
case SMESH::FT_Skew:
+ case SMESH::FT_CoplanarFaces:
retval = "angle_precision"; break;
case SMESH::FT_Area:
retval = "area_precision"; break;
bool isComboItem = false;
if (aTableItem) {
int aTableType = aTable->item(row, 2)->type();
- isComboItem = aTableType == aComboType ? true : false;
+ isComboItem = ( aTableType == aComboType );
}
if ( (aCriterionType != SMESH::FT_GroupColor && clrBtn) ||
aTable->blockSignals( isSignalsBlocked );
}
- if (aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ||
- aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ||
- aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges ||
- aCriterionType == SMESH::FT_FreeFaces) ||
- aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume ||
+ if ((aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ) ||
+ (aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ) ||
+ (aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges ||
+ aCriterionType == SMESH::FT_FreeFaces)) ||
+ (aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume) ||
aCriterionType == SMESH::FT_LinearOrQuadratic ||
aCriterionType == SMESH::FT_GroupColor ||
- aCriterionType == SMESH::FT_ElemGeomType)
+ aCriterionType == SMESH::FT_ElemGeomType ||
+ aCriterionType == SMESH::FT_CoplanarFaces
+ )
{
bool isSignalsBlocked = aTable->signalsBlocked();
aTable->blockSignals( true );
aCompareItem->clear();
aTable->setEditable(false, row, 1);
aTable->setEditable(aCriterionType == SMESH::FT_GroupColor ||
- aCriterionType == SMESH::FT_ElemGeomType, row, 2);
+ aCriterionType == SMESH::FT_ElemGeomType ||
+ aCriterionType == SMESH::FT_CoplanarFaces, row, 2);
aTable->blockSignals( isSignalsBlocked );
}
else if (aCriterionType == SMESH::FT_RangeOfIds ||
aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE");
+ aCriteria[ SMESH::FT_CoplanarFaces ] = tr("COPLANAR_FACES");
}
return aCriteria;
}
// Purpose : Set text and internal value in cell of ID value
//=======================================================================
void SMESHGUI_FilterTable::SetID( const int theRow,
- const QString& theText,
- const int theEntityType )
+ const QString& theText,
+ const int theEntityType )
{
Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
aTable->item( theRow, 5 )->setText( theText );
aType == SMESH::FT_BelongToPlane ||
aType == SMESH::FT_BelongToCylinder ||
aType == SMESH::FT_BelongToGenSurface ||
- aType == SMESH::FT_LyingOnGeom) {
+ aType == SMESH::FT_LyingOnGeom)
+ {
QString aName;
myTable->GetThreshold(i, aName);
}
}
}
+ else if (aType == SMESH::FT_CoplanarFaces)
+ {
+ QString faceID;
+ myTable->GetThreshold(i, faceID);
+ if ( faceID.isEmpty() )
+ {
+ SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+ tr("FACE_ID_NOT_SELECTED"));
+ return false;
+ }
+ if ( myMesh->_is_nil() )
+ {
+ SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+ tr("MESH_IS_NOT_SELECTED"));
+ return false;
+ }
+ if ( myMesh->GetElementType( faceID.toLong(), /*iselem=*/true) != SMESH::FACE )
+ {
+ SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+ tr("NOT_FACE_ID").arg(faceID));
+ return false;
+ }
+ }
}
return true;
}
//=======================================================================
-// name : SMESHGUI_FilterDlg::SetGroupIds
+// name : SMESHGUI_FilterDlg::SetMesh
// Purpose : Set mesh
//=======================================================================
void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh)
QList<int> types;
types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
<< SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
- << SMESH::FT_LyingOnGeom;
+ << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces;
if (aList.Extent() != 1 || !myTable->CurrentCell(aRow, aCol) ||
!types.contains(myTable->GetCriterionType(aRow)))
return;
- Handle(SALOME_InteractiveObject) anIO = aList.First();
- GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
- if (!anObj->_is_nil())
+ if ( myTable->GetCriterionType(aRow) == SMESH::FT_CoplanarFaces )
+ {
+ QString aString;
+ int nbElems = SMESH::GetNameOfSelectedElements(mySelector,//myViewWindow->GetSelector(),
+ aList.First(), aString);
+ if (nbElems == 1)
+ myTable->SetThreshold(aRow, aString);
+ }
+ else
+ {
+ Handle(SALOME_InteractiveObject) anIO = aList.First();
+ GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
+ if (!anObj->_is_nil())
{
myTable->SetThreshold(aRow, GEOMBase::GetName(anObj));
//myTable->SetID( aRow, GEOMBase::GetIORFromObject(anObj));
myTable->SetID(aRow, anIO->getEntry());
}
+ }
}
if (mySelectionMgr == 0)
return;
- TColStd_MapOfInteger allTypes;
- for( int i=0; i<10; i++ )
- allTypes.Add( i );
+// TColStd_MapOfInteger allTypes;
+// for( int i=0; i<10; i++ )
+// allTypes.Add( i );
SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
if( !aStudy )
return;
aCriterionType == SMESH::FT_BelongToPlane ||
aCriterionType == SMESH::FT_BelongToCylinder ||
aCriterionType == SMESH::FT_BelongToGenSurface ||
- aCriterionType == SMESH::FT_LyingOnGeom)) {
-
+ aCriterionType == SMESH::FT_LyingOnGeom))
+ {
if (aCriterionType == SMESH::FT_BelongToGeom ||
aCriterionType == SMESH::FT_BelongToGenSurface ||
aCriterionType == SMESH::FT_LyingOnGeom) {
}
myIsSelectionChanged = true;
- } else {
+ }
+ else
+ {
if (myIsSelectionChanged) {
mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection
}
GeometryType ElemGeomType_i::GetGeometryType() const
{
- return (GeometryType)myElemGeomTypePtr->GetGeomType();;
+ return (GeometryType)myElemGeomTypePtr->GetGeomType();
}
FunctorType ElemGeomType_i::GetFunctorType()
return SMESH::FT_ElemGeomType;
}
+/*
+ Class : CoplanarFaces_i
+ Description : Returns true if a mesh face is a coplanar neighbour to a given one
+*/
+CoplanarFaces_i::CoplanarFaces_i()
+{
+ myCoplanarFacesPtr.reset(new Controls::CoplanarFaces());
+ myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr;
+}
+
+void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID )
+{
+ myCoplanarFacesPtr->SetFace(theFaceID);
+ TPythonDump()<<this<<".SetFace("<<theFaceID<<")";
+}
+
+void CoplanarFaces_i::SetTolerance( CORBA::Double theToler )
+{
+ myCoplanarFacesPtr->SetTolerance(theToler);
+ TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
+}
+
+CORBA::Long CoplanarFaces_i::GetFace () const
+{
+ return myCoplanarFacesPtr->GetFace();
+}
+
+char* CoplanarFaces_i::GetFaceAsString () const
+{
+ TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace()));
+ return CORBA::string_dup( str.ToCString() );
+}
+
+CORBA::Double CoplanarFaces_i::GetTolerance() const
+{
+ return myCoplanarFacesPtr->GetTolerance();
+}
+
+FunctorType CoplanarFaces_i::GetFunctorType()
+{
+ return SMESH::FT_CoplanarFaces;
+}
+
/*
Class : Comparator_i
Description : Base class for comparators
return anObj._retn();
}
+CoplanarFaces_ptr FilterManager_i::CreateCoplanarFaces()
+{
+ SMESH::CoplanarFaces_i* aServant = new SMESH::CoplanarFaces_i();
+ SMESH::CoplanarFaces_var anObj = aServant->_this();
+ TPythonDump()<<aServant<<" = "<<this<<".CreateCoplanarFaces()";
+ return anObj._retn();
+}
+
FreeBorders_ptr FilterManager_i::CreateFreeBorders()
{
SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
theCriteria[ i ].TypeOfElement = aPred->GetElementType();
theCriteria[ i ].Tolerance = aPred->GetTolerance();
+ return true;
+ }
+ case FT_CoplanarFaces:
+ {
+ CoplanarFaces_i* aPred = dynamic_cast<CoplanarFaces_i*>( thePred );
+
+ CORBA::ULong i = theCriteria->length();
+ theCriteria->length( i + 1 );
+
+ theCriteria[ i ] = createCriterion();
+ CORBA::String_var faceId = aPred->GetFaceAsString();
+
+ theCriteria[ i ].Type = FT_CoplanarFaces;
+ theCriteria[ i ].ThresholdID = faceId;
+ theCriteria[ i ].Tolerance = aPred->GetTolerance();
+
return true;
}
case FT_RangeOfIds:
aPredicate = tmpPred;
break;
}
+ case SMESH::FT_CoplanarFaces:
+ {
+ SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces();
+ tmpPred->SetFace( atol (aThresholdID ));
+ tmpPred->SetTolerance( aTolerance );
+ aPredicate = tmpPred;
+ break;
+ }
default:
continue;