in GEOM::GEOM_Object theSubObject )
raises ( SALOME::SALOME_Exception );
+ /*!
+ * Evaluates size of prospective mesh on a shape
+ */
+ long_array Evaluate(in SMESH_Mesh theMesh,
+ in GEOM::GEOM_Object theSubObject)
+ //inout long_array theNbElems)
+ raises ( SALOME::SALOME_Exception );
+
/*!
* Calculate Mesh as preview till indicated dimension
* First, verify list of hypothesis associated with the subShape.
class SMESH_subMesh;
class SMESH_MesherHelper;
+typedef std::map< SMESH_subMesh*, std::vector<int> > MapShapeNbElems;
+// vector must have size 17:
+// 0 - node, 1 - edge lin, 2 - edge quad, 3 - triangle lin, 4 - triangle quad
+// 5 - quadrangle lin, 6 - quadrangle quad, 7 - polygon, 8 - tetra lin,
+// 9 - tetra quad, 10 - pyramid lin, 11 - pyramid quad, 12 - penta lin,
+// 13 - penta quad, 14 - hexa lin, 15 - hexa quad, 16 -polyhedra
+typedef std::map< SMESH_subMesh*, std::vector<int> >::iterator MapShapeNbElemsItr;
class SMESH_EXPORT SMESH_Algo:public SMESH_Hypothesis
{
*/
virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper);
+ /*!
+ * \brief evaluates size of prospective mesh on a shape
+ * \param aMesh - the mesh
+ * \param aShape - the shape
+ * \param aNbElems - prospective number of elements by types
+ * \retval bool - is a success
+ */
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap) = 0;
+
/*!
* \brief Returns a list of compatible hypotheses used to mesh a shape
* \param aMesh - the mesh
return ret;
}
+
+//=============================================================================
+/*!
+ * Evaluate a mesh
+ */
+//=============================================================================
+
+bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap,
+ const bool anUpward,
+ TSetOfInt* aShapesId)
+{
+ MESSAGE("SMESH_Gen::Evaluate");
+
+ bool ret = true;
+
+ SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
+
+ const bool includeSelf = true;
+ const bool complexShapeFirst = true;
+ SMESH_subMeshIteratorPtr smIt;
+
+ if ( anUpward ) { // is called from below code here
+ // -----------------------------------------------
+ // mesh all the subshapes starting from vertices
+ // -----------------------------------------------
+ smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
+ while ( smIt->more() ) {
+ SMESH_subMesh* smToCompute = smIt->next();
+
+ // do not mesh vertices of a pseudo shape
+ const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+ //if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
+ // continue;
+ if ( !aMesh.HasShapeToMesh() ) {
+ if( aShType == TopAbs_VERTEX || aShType == TopAbs_WIRE ||
+ aShType == TopAbs_SHELL )
+ continue;
+ }
+
+ smToCompute->Evaluate(aResMap);
+ if( aShapesId )
+ aShapesId->insert( smToCompute->GetId() );
+ }
+ return ret;
+ }
+ else {
+ // -----------------------------------------------------------------
+ // apply algos that DO NOT require descretized boundaries and DO NOT
+ // support submeshes, starting from the most complex shapes
+ // and collect submeshes with algos that DO support submeshes
+ // -----------------------------------------------------------------
+ list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes;
+ smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
+ while ( smIt->more() ) {
+ SMESH_subMesh* smToCompute = smIt->next();
+ const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
+ const int aShapeDim = GetShapeDim( aSubShape );
+ if ( aShapeDim < 1 ) break;
+
+ SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
+ if ( algo && !algo->NeedDescretBoundary() ) {
+ if ( algo->SupportSubmeshes() ) {
+ smWithAlgoSupportingSubmeshes.push_back( smToCompute );
+ }
+ else {
+ smToCompute->Evaluate(aResMap);
+ if ( aShapesId )
+ aShapesId->insert( smToCompute->GetId() );
+ }
+ }
+ }
+ // ------------------------------------------------------------
+ // compute submeshes under shapes with algos that DO NOT require
+ // descretized boundaries and DO support submeshes
+ // ------------------------------------------------------------
+ list< SMESH_subMesh* >::reverse_iterator subIt, subEnd;
+ subIt = smWithAlgoSupportingSubmeshes.rbegin();
+ subEnd = smWithAlgoSupportingSubmeshes.rend();
+ // start from lower shapes
+ for ( ; subIt != subEnd; ++subIt ) {
+ sm = *subIt;
+
+ // get a shape the algo is assigned to
+ TopoDS_Shape algoShape;
+ if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
+ continue; // strange...
+
+ // look for more local algos
+ smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst);
+ while ( smIt->more() ) {
+ SMESH_subMesh* smToCompute = smIt->next();
+
+ const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
+ const int aShapeDim = GetShapeDim( aSubShape );
+ if ( aShapeDim < 1 ) continue;
+
+ const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+
+ SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
+ filter
+ .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
+ .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape ));
+
+ if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
+ SMESH_Hypothesis::Hypothesis_Status status;
+ if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
+ // mesh a lower smToCompute starting from vertices
+ Evaluate( aMesh, aSubShape, aResMap, /*anUpward=*/true, aShapesId );
+ }
+ }
+ }
+ // ----------------------------------------------------------
+ // apply the algos that do not require descretized boundaries
+ // ----------------------------------------------------------
+ for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt ) {
+ sm->Evaluate(aResMap);
+ if ( aShapesId )
+ aShapesId->insert( sm->GetId() );
+ }
+
+ // -----------------------------------------------
+ // mesh the rest subshapes starting from vertices
+ // -----------------------------------------------
+ ret = Evaluate( aMesh, aShape, aResMap, /*anUpward=*/true, aShapesId );
+ }
+
+ MESSAGE( "VSR - SMESH_Gen::Evaluate() finished, OK = " << ret);
+ return ret;
+}
+
+
//=======================================================================
//function : checkConformIgnoredAlgos
//purpose :
const ::MeshDimension aDim=::MeshDim_3D,
TSetOfInt* aShapesId=0);
+ /*!
+ * \brief evaluates size of prospective mesh on a shape
+ * \param aMesh - the mesh
+ * \param aShape - the shape
+ * \param aResMap - map for prospective numbers of elements
+ * \retval bool - is a success
+ */
+ bool Evaluate(::SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap,
+ const bool anUpward=false,
+ TSetOfInt* aShapesId=0);
+
bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
// notify on bad state of attached algos, return false
// if Compute() would fail because of some algo bad state
return ret;
}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
+{
+ _computeError.reset();
+
+ bool ret = true;
+
+ if (_subShape.ShapeType() == TopAbs_VERTEX) {
+ std::vector<int> aVec(17);
+ aVec[0] = 1;
+ for(int i=1; i<17; i++) aVec[i] = 0;
+ aResMap.insert(std::make_pair(this,aVec));
+ return ret;
+ }
+
+ SMESH_Gen *gen = _father->GetGen();
+ SMESH_Algo *algo = 0;
+ SMESH_Hypothesis::Hypothesis_Status hyp_status;
+
+ algo = gen->GetAlgo((*_father), _subShape);
+ if(algo) {
+ ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
+ if (!ret) return false;
+
+ TopoDS_Shape shape = _subShape;
+
+ _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
+
+ ret = algo->Evaluate((*_father), shape, aResMap);
+ }
+
+ return ret;
+}
+
+
//=======================================================================
/*!
* \brief Update compute_state by _computeError and send proper events to
#include "SMESHDS_SubMesh.hxx"
#include "SMESH_Hypothesis.hxx"
#include "SMESH_ComputeError.hxx"
+#include "SMESH_Algo.hxx"
#include "Utils_SALOME_Exception.hxx"
bool ComputeStateEngine(int event);
+ bool Evaluate(MapShapeNbElems& aResMap);
+
bool IsConform(const SMESH_Algo* theAlgo);
// check if a conform mesh will be produced by the Algo
case 701: // COMPUTE MESH
case 711: // PRECOMPUTE MESH
+ case 712: // EVALUATE MESH
{
if (checkLock(aStudy)) break;
startOperation( theCommandID );
createSMESHAction( 704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" );
createSMESHAction( 710, "BUILD_COMPOUND", "ICON_BUILD_COMPOUND" );
createSMESHAction( 711, "PRECOMPUTE", "ICON_PRECOMPUTE" );
+ //createSMESHAction( 712, "EVALUATE", "ICON_EVALUATE" );
+ createSMESHAction( 712, "EVALUATE", "ICON_COMPUTE" );
createSMESHAction( 806, "CREATE_GEO_GROUP","ICON_CREATE_GEO_GROUP" );
createSMESHAction( 801, "CREATE_GROUP", "ICON_CREATE_GROUP" );
createSMESHAction( 802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
createMenu( separator(), meshId, -1 );
createMenu( 701, meshId, -1 );
createMenu( 711, meshId, -1 );
+ createMenu( 712, meshId, -1 );
createMenu( separator(), meshId, -1 );
createMenu( 801, meshId, -1 );
createMenu( 806, meshId, -1 );
createTool( separator(), meshTb );
createTool( 701, meshTb );
createTool( 711, meshTb );
+ createTool( 712, meshTb );
createTool( separator(), meshTb );
createTool( 801, meshTb );
createTool( 806, meshTb );
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( 701, OB, mesh, "&& isComputable" ); // COMPUTE
createPopupItem( 711, OB, mesh, "&& isComputable" ); // PRECOMPUTE
+ createPopupItem( 712, OB, mesh ); // EVALUATE
createPopupItem( 214, OB, mesh_group ); // UPDATE
createPopupItem( 900, OB, mesh_group ); // ADV_INFO
createPopupItem( 902, OB, mesh ); // STD_INFO
case 711: // Precompute mesh
op = new SMESHGUI_PrecomputeOp();
break;
+ case 712: // Evaluate mesh
+ op = new SMESHGUI_EvaluateOp();
+ break;
case 806: // Create group on geom
op = new SMESHGUI_GroupOnShapeOp();
break;
*/
//=======================================================================
-SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent )
+SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent, bool ForEval )
: SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
{
QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
aDlgLay->setMargin( 0 );
aDlgLay->setSpacing( SPACING );
- QFrame* aMainFrame = createMainFrame (mainFrame());
+ QFrame* aMainFrame = createMainFrame(mainFrame(),ForEval);
aDlgLay->addWidget(aMainFrame);
// purpose : Create frame containing dialog's fields
//=======================================================================
-QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
+QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent, bool ForEval)
{
QFrame* aFrame = new QFrame(theParent);
// constructor
- QGroupBox* aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame);
+ QGroupBox* aPixGrp;
+ if(ForEval) {
+ aPixGrp = new QGroupBox(tr("EVAL_DLG"), aFrame);
+ }
+ else {
+ aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame);
+ }
QButtonGroup* aBtnGrp = new QButtonGroup(this);
QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp);
aPixGrpLayout->setMargin(MARGIN); aPixGrpLayout->setSpacing(SPACING);
//================================================================================
SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp()
- : SMESHGUI_Operation(),
- myCompDlg( 0 )
+ : SMESHGUI_Operation(), myCompDlg( 0 )
{
myTShapeDisplayer = new SMESH::TShapeDisplayer();
myBadMeshDisplayer = 0;
if ( !myCompDlg )
{
SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
- me->myCompDlg = new SMESHGUI_ComputeDlg( desktop() );
+ me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), false );
// connect signals and slots
connect(myCompDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape()));
connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
{
return myPreviewMode->currentId();
}
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp()
+ : SMESHGUI_BaseComputeOp()
+{
+}
+
+
+//================================================================================
+/*!
+ * \brief Desctructor
+*/
+//================================================================================
+
+SMESHGUI_EvaluateOp::~SMESHGUI_EvaluateOp()
+{
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: compute mesh
+ */
+//================================================================================
+
+void SMESHGUI_EvaluateOp::startOperation()
+{
+ SMESHGUI_BaseComputeOp::evaluateDlg();
+ SMESHGUI_BaseComputeOp::startOperation();
+ evaluateMesh();
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_EvaluateOp::dlg() const
+{
+ return evaluateDlg();
+}
+
+//================================================================================
+/*!
+ * \brief evaluaateMesh()
+*/
+//================================================================================
+
+void SMESHGUI_BaseComputeOp::evaluateMesh()
+{
+ // EVALUATE MESH
+
+ SMESH::MemoryReserve aMemoryReserve;
+
+ SMESH::compute_error_array_var aCompErrors;
+ QString aHypErrors;
+
+ bool evaluateFailed = true, memoryLack = false;
+ std::vector<int> aResVec(18);
+
+ _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
+ bool hasShape = myMesh->HasShapeToMesh();
+ bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
+ if ( shapeOK && aMeshSObj )
+ {
+ myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
+ SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
+ SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
+ if ( errors->length() > 0 ) {
+ aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
+ }
+ SUIT_OverrideCursor aWaitCursor;
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ SMESH::long_array_var aVec = gen->Evaluate(myMesh, myMainShape);
+ for(int i=0; i<17; i++) {
+ aResVec[i] = aVec[i];
+ }
+ }
+ catch(const SALOME::SALOME_Exception & S_ex){
+ memoryLack = true;
+ }
+
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
+ }
+ catch(const SALOME::SALOME_Exception & S_ex){
+ memoryLack = true;
+ }
+ }
+
+ if ( memoryLack )
+ aMemoryReserve.release();
+
+ myCompDlg->setWindowTitle(tr( evaluateFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
+
+ // SHOW ERRORS
+
+ bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
+ bool noHypoError = ( aHypErrors.isEmpty() );
+
+ //SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
+ //int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
+
+ bool isShowResultDlg = true;
+ //if( noHypoError )
+ //switch( aNotifyMode ) {
+ //case 0: // show the mesh computation result dialog NEVER
+ //isShowResultDlg = false;
+ //commit();
+ //break;
+ //case 1: // show the mesh computation result dialog if there are some errors
+ //if ( memoryLack || !noHypoError )
+ // isShowResultDlg = true;
+ //else
+ //{
+ // isShowResultDlg = false;
+ // commit();
+ //}
+ //break;
+ //default: // show the result dialog after each mesh computation
+ //isShowResultDlg = true;
+ //}
+
+ // SHOW RESULTS
+ if ( isShowResultDlg )
+ //showComputeResult( memoryLack, noCompError,aCompErrors, noHypoError, aHypErrors );
+ showEvaluateResult( aResVec, memoryLack, noCompError, aCompErrors,
+ noHypoError, aHypErrors);
+}
+
+
+void SMESHGUI_BaseComputeOp::showEvaluateResult(std::vector<int> theVec,
+ const bool theMemoryLack,
+ const bool theNoCompError,
+ SMESH::compute_error_array_var& theCompErrors,
+ const bool theNoHypoError,
+ const QString& theHypErrors)
+{
+ bool hasShape = myMesh->HasShapeToMesh();
+ SMESHGUI_ComputeDlg* aCompDlg = evaluateDlg();
+ aCompDlg->myMemoryLackGroup->hide();
+
+ if ( theMemoryLack )
+ {
+ aCompDlg->myMemoryLackGroup->show();
+ aCompDlg->myFullInfo->hide();
+ aCompDlg->myBriefInfo->hide();
+ aCompDlg->myHypErrorGroup->hide();
+ aCompDlg->myCompErrorGroup->hide();
+ }
+ else if ( theNoCompError && theNoHypoError )
+ {
+ //aCompDlg->myFullInfo->SetInfoByMesh( myMesh );
+ aCompDlg->myFullInfo->SetInfoByEval( theVec );
+ aCompDlg->myFullInfo->show();
+ aCompDlg->myBriefInfo->hide();
+ aCompDlg->myHypErrorGroup->hide();
+ aCompDlg->myCompErrorGroup->hide();
+ }
+ else
+ {
+ QTableWidget* tbl = aCompDlg->myTable;
+ //aCompDlg->myBriefInfo->SetInfoByMesh( myMesh );
+ aCompDlg->myBriefInfo->SetInfoByEval( theVec );
+ aCompDlg->myBriefInfo->show();
+ aCompDlg->myFullInfo->hide();
+
+ if ( theNoHypoError ) {
+ aCompDlg->myHypErrorGroup->hide();
+ }
+ else {
+ aCompDlg->myHypErrorGroup->show();
+ aCompDlg->myHypErrorLabel->setText( theHypErrors );
+ }
+
+ if ( theNoCompError ) {
+ aCompDlg->myCompErrorGroup->hide();
+ }
+ else {
+ aCompDlg->myCompErrorGroup->show();
+
+ aCompDlg->myPublishBtn->hide();
+ aCompDlg->myShowBtn->hide();
+
+ // fill table of errors
+ tbl->setRowCount( theCompErrors->length() );
+ if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
+ else tbl->showColumn( COL_SHAPE );
+ tbl->setColumnWidth( COL_ERROR, 200 );
+
+ bool hasBadMesh = false;
+ for ( int row = 0; row < theCompErrors->length(); ++row )
+ {
+ SMESH::ComputeError & err = theCompErrors[ row ];
+
+ QString text = err.algoName.in();
+ if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_ALGO )->setText( text );
+
+ text = SMESH::errorText( err.code, err.comment.in() );
+ if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_ERROR )->setText( text );
+
+ text = QString("%1").arg( err.subShapeID );
+ if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_SHAPEID )->setText( text );
+
+ text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
+ if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_SHAPE )->setText( text );
+
+ text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
+ if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
+
+ text = err.hasBadMesh ? "hasBadMesh" : "";
+ if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_BAD_MESH )->setText( text );
+ if ( err.hasBadMesh ) hasBadMesh = true;
+
+ //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
+ tbl->resizeRowToContents( row );
+ }
+ tbl->resizeColumnToContents( COL_ALGO );
+ tbl->resizeColumnToContents( COL_SHAPE );
+
+ if ( hasBadMesh )
+ aCompDlg->myBadMeshBtn->show();
+ else
+ aCompDlg->myBadMeshBtn->hide();
+
+ tbl->setCurrentCell(0,0);
+ currentCellChanged(); // to update buttons
+ }
+ }
+ // show dialog and wait, becase Compute can be invoked from Preview operation
+ //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
+ aCompDlg->show();
+}
+
+
+// =========================================================================================
+/*!
+ * \brief Set mesh info
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshInfosBox::SetInfoByEval(std::vector<int> theVec)
+{
+ // nodes
+ myNbNode ->setText( QString("%1").arg( theVec[0] ));
+
+ // edges
+ int nbTot = theVec[1] + theVec[2];
+ myNbEdge ->setText( QString("%1").arg( nbTot ));
+ myNbLinEdge ->setText( QString("%1").arg( theVec[1] ));
+ myNbQuadEdge ->setText( QString("%1").arg( theVec[2] ));
+
+ // faces
+ nbTot = 0;
+ int i = 3;
+ for(; i<=7; i++) nbTot += theVec[i];
+ myNbFace ->setText( QString("%1").arg( nbTot ));
+ myNbLinFace ->setText( QString("%1").arg( theVec[3] + theVec[5] ));
+ myNbQuadFace ->setText( QString("%1").arg( theVec[4] + theVec[6] ));
+
+ // volumes
+ nbTot = 0;
+ for(i=8; i<=16; i++) nbTot += theVec[i];
+ int nbLin = 0, nbQua = 0;;
+ for(i=0; i<=3; i++) {
+ nbLin += theVec[8+2*i];
+ nbQua += theVec[9+2*i];
+ }
+ myNbVolum ->setText( QString("%1").arg( nbTot ));
+ myNbLinVolum ->setText( QString("%1").arg( nbLin ));
+ myNbQuadVolum->setText( QString("%1").arg( nbQua ));
+
+ if ( myFull )
+ {
+ // triangles
+ myNbTrai ->setText( QString("%1").arg( theVec[3] + theVec[4] ));
+ myNbLinTrai ->setText( QString("%1").arg( theVec[3] ));
+ myNbQuadTrai ->setText( QString("%1").arg( theVec[4] ));
+ // quadrangles
+ myNbQuad ->setText( QString("%1").arg( theVec[5] + theVec[6] ));
+ myNbLinQuad ->setText( QString("%1").arg( theVec[5] ));
+ myNbQuadQuad ->setText( QString("%1").arg( theVec[6] ));
+ // poligones
+ myNbPolyg ->setText( QString("%1").arg( theVec[7] ));
+
+ // tetras
+ myNbTetra ->setText( QString("%1").arg( theVec[8] + theVec[9] ));
+ myNbLinTetra ->setText( QString("%1").arg( theVec[8] ));
+ myNbQuadTetra->setText( QString("%1").arg( theVec[9] ));
+ // hexas
+ myNbHexa ->setText( QString("%1").arg( theVec[14] + theVec[15] ));
+ myNbLinHexa ->setText( QString("%1").arg( theVec[14] ));
+ myNbQuadHexa ->setText( QString("%1").arg( theVec[15] ));
+ // pyras
+ myNbPyra ->setText( QString("%1").arg( theVec[10] + theVec[11] ));
+ myNbLinPyra ->setText( QString("%1").arg( theVec[10] ));
+ myNbQuadPyra ->setText( QString("%1").arg( theVec[11] ));
+ // prisms
+ myNbPrism ->setText( QString("%1").arg( theVec[12] + theVec[13] ));
+ myNbLinPrism ->setText( QString("%1").arg( theVec[12] ));
+ myNbQuadPrism->setText( QString("%1").arg( theVec[13] ));
+ // polyedres
+ myNbPolyh ->setText( QString("%1").arg( theVec[16] ));
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of evaluate operation
+ * \retval SMESHGUI_ComputeDlg* - pointer to dialog of this operation
+ */
+//================================================================================
+
+SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::evaluateDlg() const
+{
+ if ( !myCompDlg )
+ {
+ SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
+ me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), true );
+ // connect signals and slots
+ connect(myCompDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape()));
+ connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
+ connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
+ QTableWidget* aTable = me->table();
+ connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
+ connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
+ }
+ return myCompDlg;
+}
+
class QtxComboBox;
class SMESHGUI_ComputeDlg;
class SMESHGUI_PrecomputeDlg;
+//class SMESHGUI_EvaluateDlg;
class SMESHGUI_MeshEditPreview;
class SMESH::compute_error_array;
SMESH::compute_error_array_var&,
const bool,
const QString& );
+ //SMESHGUI_EvaluateDlg* evaluateDlg() const;
+ SMESHGUI_ComputeDlg* evaluateDlg() const;
+ void evaluateMesh();
+ void showEvaluateResult(std::vector<int> theVec,
+ const bool,
+ const bool,
+ SMESH::compute_error_array_var&,
+ const bool,
+ const QString&);
protected slots:
virtual bool onApply();
private:
QPointer<SMESHGUI_ComputeDlg> myCompDlg;
+ //QPointer<SMESHGUI_EvaluateDlg> myEvalDlg;
protected:
SMESH::SMESH_Mesh_var myMesh;
SMESHGUI_MeshEditPreview* myPreviewDisplayer;
};
+/*!
+ * \brief Operation to evaluate a mesh and show result
+ */
+class SMESHGUI_EXPORT SMESHGUI_EvaluateOp: public SMESHGUI_BaseComputeOp
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_EvaluateOp();
+ virtual ~SMESHGUI_EvaluateOp();
+
+ virtual LightApp_Dialog* dlg() const;
+
+protected:
+ virtual void startOperation();
+
+protected slots:
+};
+
/*!
* \brief Box showing mesh info
*/
void SetInfoByMesh( SMESH::SMESH_Mesh_var );
+ void SetInfoByEval( std::vector<int> theVec );
+
private:
bool myFull;
QLabel* myNbNode;
Q_OBJECT
public:
- SMESHGUI_ComputeDlg( QWidget* );
+ SMESHGUI_ComputeDlg( QWidget*, bool );
virtual ~SMESHGUI_ComputeDlg();
protected:
- QFrame* createMainFrame( QWidget* );
+ QFrame* createMainFrame( QWidget*, bool );
QLabel* myMeshName;
QGroupBox* myMemoryLackGroup;
};
+/*!
+ * \brief Dialog to evaluate a mesh and show result
+ */
+/*
+class SMESHGUI_EXPORT SMESHGUI_EvaluateDlg : public SMESHGUI_Dialog
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_EvaluateDlg( QWidget* );
+ virtual ~SMESHGUI_EvaluateDlg();
+
+protected:
+ QFrame* createMainFrame( QWidget* );
+
+ QLabel* myMeshName;
+ QGroupBox* myMemoryLackGroup;
+ QGroupBox* myCompErrorGroup;
+ QGroupBox* myHypErrorGroup;
+ QLabel* myHypErrorLabel;
+ QTableWidget* myTable;
+ QPushButton* myShowBtn;
+ QPushButton* myPublishBtn;
+ QPushButton* myBadMeshBtn;
+
+ SMESHGUI_MeshInfosBox* myBriefInfo;
+ SMESHGUI_MeshInfosBox* myFullInfo;
+
+ friend class SMESHGUI_BaseComputeOp;
+};
+*/
+
#endif // SMESHGUI_COMPUTEDLG_H
<source>MEN_PRECOMPUTE</source>
<translation>Preview</translation>
</message>
+ <message>
+ <source>MEN_EVALUATE</source>
+ <translation>Evaluate</translation>
+ </message>
<message>
<source>MEN_CONNECTION</source>
<translation>Borders at Multi-Connection</translation>
<source>STB_PRECOMPUTE</source>
<translation>Preview</translation>
</message>
+ <message>
+ <source>STB_EVALUATE</source>
+ <translation>Evaluate</translation>
+ </message>
<message>
<source>STB_CONNECTION</source>
<translation>Borders at Multi-Connection</translation>
<source>TOP_PRECOMPUTE</source>
<translation>Preview</translation>
</message>
+ <message>
+ <source>TOP_EVALUATE</source>
+ <translation>Evaluate</translation>
+ </message>
<message>
<source>TOP_CONNECTION</source>
<translation>Borders at Multi-Connection</translation>
<source>CONSTRUCTOR</source>
<translation>Compute mesh</translation>
</message>
+ <message>
+ <source>EVAL_DLG</source>
+ <translation>Evaluate mesh</translation>
+ </message>
<message>
<source>ERRORS</source>
<translation>Errors</translation>
return result._retn();
}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::Evaluate
+ *
+ * Evaluate mesh on a shape
+ */
+//=============================================================================
+
+//CORBA::Boolean
+SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theShapeObject)
+// SMESH::long_array& theNbElems)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" );
+
+ if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
+ SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+ SALOME::BAD_PARAM );
+
+ SMESH::long_array_var nbels = new SMESH::long_array;
+
+ // Update Python script
+ TPythonDump() << "theNbElems = " << this << ".Evaluate( "
+ << theMesh << ", " << theShapeObject << ")";
+
+ try {
+ // get mesh servant
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+ ASSERT( meshServant );
+ if ( meshServant ) {
+ // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
+ meshServant->CheckGeomGroupModif();
+ // get local TopoDS_Shape
+ TopoDS_Shape myLocShape;
+ if(theMesh->HasShapeToMesh())
+ myLocShape = GeomObjectToShape( theShapeObject );
+ else
+ myLocShape = SMESH_Mesh::PseudoShape();
+ // call implementation compute
+ ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+ MapShapeNbElems aResMap;
+ CORBA::Boolean ret = myGen.Evaluate( myLocMesh, myLocShape, aResMap);
+ MapShapeNbElemsItr anIt = aResMap.begin();
+ vector<int> aResVec(17);
+ int i = 0;
+ for(; i<17; i++) aResVec[i] = 0;
+ for(; anIt!=aResMap.end(); anIt++) {
+ // 0 - node, 1 - edge lin, 2 - edge quad,
+ // 3 - triangle lin, 4 - triangle quad
+ // 5 - quadrangle lin, 6 - quadrangle quad
+ // 7 - polygon, 8 - tetra lin, 9 - tetra quad
+ // 10 - pyramid lin, 11 - pyramid quad,
+ // 12 - penta lin, 13 - penta quad, 14 - hexa lin,
+ // 15 - hexa quad, 16 -polyhedra
+ vector<int> aVec = (*anIt).second;
+ for(i=0; i<17; i++) {
+ aResVec[i] += aVec[i];
+ }
+ }
+ nbels->length(17);
+ for(i=0; i<17; i++) {
+ nbels[i] = aResVec[i];
+ }
+ cout<<endl;
+ return nbels._retn();
+ }
+ }
+ catch ( std::bad_alloc ) {
+ INFOS( "Evaluate(): lack of memory" );
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "Evaluate(): catch exception "<< S_ex.what() );
+ }
+ catch ( ... ) {
+ INFOS( "Evaluate(): unknown exception " );
+ }
+
+ return nbels._retn();
+}
+
//================================================================================
/*!
* \brief Return geometrical object the given element is built on
GEOM::GEOM_Object_ptr theShapeObject )
throw ( SALOME::SALOME_Exception );
+ // Evaluate mesh on a shape
+ //CORBA::Boolean
+ SMESH::long_array* Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theShapeObject)
+ // SMESH::long_array& theNbElems)
+ throw ( SALOME::SALOME_Exception );
+
// Returns true if mesh contains enough data to be computed
CORBA::Boolean IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
GEOM::GEOM_Object_ptr theShapeObject )
return Mesh_Prism3D(self, geom)
return Mesh_RadialPrism3D(self, geom)
+ ## Evaluates size of prospective mesh on a shape
+ # @return True or False
+ def Evaluate(self, geom=0):
+ if geom == 0 or not isinstance(geom, geompyDC.GEOM._objref_GEOM_Object):
+ if self.geom == 0:
+ geom = self.mesh.GetShapeToMesh()
+ else:
+ geom = self.geom
+ return self.smeshpyD.Evaluate(self.mesh, geom)
+
+
## Computes the mesh and returns the status of the computation
# @return True or False
# @ingroup l2_construct
#include <TopExp_Explorer.hxx>
#include <TopTools_MapIteratorOfMapOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
return true;
}
+
+//=======================================================================
+//function : GetNb2d
+//purpose : auxilary for Evaluate
+//=======================================================================
+int GetNb2d(_QuadFaceGrid* QFG, SMESH_Mesh& theMesh,
+ MapShapeNbElems& aResMap)
+{
+ int nb2d = 0;
+ _QuadFaceGrid::TChildIterator aCI = QFG->GetChildren();
+ while( aCI.more() ) {
+ const _QuadFaceGrid& currChild = aCI.next();
+ SMESH_subMesh *sm = theMesh.GetSubMesh(currChild.GetFace());
+ if( sm ) {
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb2d += Max(aVec[5],aVec[6]);
+ }
+ }
+ return nb2d;
+}
+
+
+//================================================================================
+/*!
+ * Evaluate
+ */
+//================================================================================
+
+bool StdMeshers_CompositeHexa_3D::Evaluate(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape,
+ MapShapeNbElems& aResMap)
+{
+ SMESH_MesherHelper aTool(theMesh);
+ bool _quadraticMesh = aTool.IsQuadraticSubMesh(theShape);
+
+
+ // -------------------------
+ // Try to find 6 side faces
+ // -------------------------
+ vector< _QuadFaceGrid > boxFaces; boxFaces.reserve( 6 );
+ TopExp_Explorer exp;
+ int iFace, nbFaces = 0;
+ for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces )
+ {
+ _QuadFaceGrid f;
+ if ( !f.Init( TopoDS::Face( exp.Current() )))
+ //return error (COMPERR_BAD_SHAPE);
+ return false;
+ bool isContinuous = false;
+ for ( int i=0; i < boxFaces.size() && !isContinuous; ++i )
+ isContinuous = boxFaces[ i ].AddContinuousFace( f );
+ if ( !isContinuous )
+ boxFaces.push_back( f );
+ }
+ // Check what we have
+ if ( boxFaces.size() != 6 && nbFaces != 6)
+ //return error
+ // (COMPERR_BAD_SHAPE,
+ // SMESH_Comment("Can't find 6 sides of a box. Number of found sides - ")<<boxFaces.size());
+ return false;
+
+ if ( boxFaces.size() != 6 && nbFaces == 6 ) { // strange ordinary box with continuous faces
+ boxFaces.resize( 6 );
+ iFace = 0;
+ for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++iFace )
+ boxFaces[ iFace ].Init( TopoDS::Face( exp.Current() ) );
+ }
+
+ // ----------------------------------------
+ // Find out position of faces within a box
+ // ----------------------------------------
+
+ _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
+ // start from a bottom face
+ fBottom = &boxFaces[0];
+ // find vertical faces
+ fFront = fBottom->FindAdjacentForSide( Q_BOTTOM, boxFaces );
+ fLeft = fBottom->FindAdjacentForSide( Q_RIGHT, boxFaces );
+ fBack = fBottom->FindAdjacentForSide( Q_TOP, boxFaces );
+ fRight = fBottom->FindAdjacentForSide( Q_LEFT, boxFaces );
+ // check the found
+ if ( !fFront || !fBack || !fLeft || !fRight )
+ //return error(COMPERR_BAD_SHAPE);
+ return false;
+ // top face
+ fTop = 0;
+ int i = 1;
+ for(; i < boxFaces.size() && !fTop; ++i ) {
+ fTop = & boxFaces[ i ];
+ if ( fTop==fFront || fTop==fLeft || fTop==fBack || fTop==fRight )
+ fTop = 0;
+ }
+ // set bottom of the top side
+ if ( !fTop->SetBottomSide( fFront->GetSide( Q_TOP ) )) {
+ if ( !fFront->IsComplex() )
+ //return error( ERR_LI("Error in StdMeshers_CompositeHexa_3D::Compute()"));
+ return false;
+ else {
+ _QuadFaceGrid::TChildIterator chIt = fFront->GetChildren();
+ while ( chIt.more() ) {
+ const _QuadFaceGrid& frontChild = chIt.next();
+ if ( fTop->SetBottomSide( frontChild.GetSide( Q_TOP )))
+ break;
+ }
+ }
+ }
+ if ( !fTop )
+ //return error(COMPERR_BAD_SHAPE);
+ return false;
+
+
+ TopTools_SequenceOfShape BottomFaces;
+ _QuadFaceGrid::TChildIterator aCI = fBottom->GetChildren();
+ while( aCI.more() ) {
+ const _QuadFaceGrid& currChild = aCI.next();
+ BottomFaces.Append(currChild.GetFace());
+ }
+ // find boundary edges and internal nodes for bottom face
+ TopTools_SequenceOfShape BndEdges;
+ int nb0d_in = 0;
+ //TopTools_MapOfShape BndEdges;
+ for(i=1; i<=BottomFaces.Length(); i++) {
+ for (TopExp_Explorer exp(BottomFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+ int nb0 = 0;
+ SMESH_subMesh *sm = theMesh.GetSubMesh(exp.Current());
+ if( sm ) {
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb0 = aVec[0];
+ }
+ int j = 1;
+ for(; j<=BndEdges.Length(); j++) {
+ if( BndEdges.Value(j) == exp.Current() ) {
+ // internal edge => remove it
+ BndEdges.Remove(j);
+ nb0d_in += nb0;
+ break;
+ }
+ }
+ if( j > BndEdges.Length() ) {
+ BndEdges.Append(exp.Current());
+ }
+ //if( BndEdges.Contains(exp.Current()) ) {
+ //BndEdges.Remove( exp.Current() );
+ //}
+ //else {
+ //BndEdges.Add( exp.Current() );
+ //}
+ }
+ }
+
+ // find number of 1d elems for bottom face
+ int nb1d = 0;
+ for(i=1; i<=BndEdges.Length(); i++) {
+ SMESH_subMesh *sm = theMesh.GetSubMesh(BndEdges.Value(i));
+ if( sm ) {
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb1d += Max(aVec[1],aVec[2]);
+ }
+ }
+
+ // find number of 2d elems on side faces
+ int nb2d = 0;
+ nb2d += GetNb2d(fFront, theMesh, aResMap);
+ nb2d += GetNb2d(fRight, theMesh, aResMap);
+ nb2d += GetNb2d(fBack, theMesh, aResMap);
+ nb2d += GetNb2d(fLeft, theMesh, aResMap);
+
+ // find number of 2d elems and nodes on bottom faces
+ int nb0d=0, nb2d_3=0, nb2d_4=0;
+ for(i=1; i<=BottomFaces.Length(); i++) {
+ SMESH_subMesh *sm = theMesh.GetSubMesh(BottomFaces.Value(i));
+ if( sm ) {
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb0d += aVec[0];
+ nb2d_3 += Max(aVec[3],aVec[4]);
+ nb2d_4 += Max(aVec[5],aVec[6]);
+ }
+ }
+ nb0d += nb0d_in;
+
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ if(_quadraticMesh) {
+ aResVec[13] = nb2d_3 * ( nb2d/nb1d );
+ aResVec[15] = nb2d_4 * ( nb2d/nb1d );
+ aResVec[0] = nb0d * ( 2*nb2d/nb1d - 1 );
+ }
+ else {
+ aResVec[0] = nb0d * ( nb2d/nb1d - 1 );
+ aResVec[12] = nb2d_3 * ( nb2d/nb1d );
+ aResVec[14] = nb2d_4 * ( nb2d/nb1d );
+ }
+ SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+
+ return true;
+}
+
+
//================================================================================
/*!
* \brief constructor of non-initialized _QuadFaceGrid
virtual bool Compute(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
Hypothesis_Status& aStatus);
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#include <gp_Pnt2d.hxx>
using namespace std;
-static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &);
+static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &,
+ const TopoDS_Shape &);
+
+static bool EvaluatePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &,
+ MapShapeNbElems &);
//=============================================================================
/*!
return ClearAndReturn( aQuads, true );
}
+
+//=============================================================================
+/*!
+ * Evaluate
+ */
+//=============================================================================
+
+bool StdMeshers_Hexa_3D::Evaluate(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap)
+{
+ vector < SMESH_subMesh * >meshFaces;
+ TopTools_SequenceOfShape aFaces;
+ for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
+ aFaces.Append(exp.Current());
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+ ASSERT(aSubMesh);
+ meshFaces.push_back(aSubMesh);
+ }
+ if (meshFaces.size() != 6) {
+ //return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block");
+ static StdMeshers_CompositeHexa_3D compositeHexa(-10, 0, aMesh.GetGen());
+ return compositeHexa.Evaluate(aMesh, aShape, aResMap);
+ }
+
+ int i = 0;
+ for(; i<6; i++) {
+ //TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
+ TopoDS_Shape aFace = aFaces.Value(i+1);
+ SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
+ string algoName = algo->GetName();
+ bool isAllQuad = false;
+ if (algoName == "Quadrangle_2D") {
+ MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ int nbtri = Max(aVec[3],aVec[4]);
+ if( nbtri == 0 )
+ isAllQuad = true;
+ }
+ if ( ! isAllQuad ) {
+ return EvaluatePentahedralMesh(aMesh, aShape, aResMap);
+ }
+ }
+
+ // find number of 1d elems for 1 face
+ int nb1d = 0;
+ TopTools_MapOfShape Edges1;
+ bool IsQuadratic = false;
+ bool IsFirst = true;
+ for (TopExp_Explorer exp(aFaces.Value(1), TopAbs_EDGE); exp.More(); exp.Next()) {
+ Edges1.Add(exp.Current());
+ SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current());
+ if( sm ) {
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb1d += Max(aVec[1],aVec[2]);
+ if(IsFirst) {
+ IsQuadratic = (aVec[2] > aVec[1]);
+ IsFirst = false;
+ }
+ }
+ }
+ // find face opposite to 1 face
+ int OppNum = 0;
+ for(i=2; i<=6; i++) {
+ bool IsOpposite = true;
+ for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+ if( Edges1.Contains(exp.Current()) ) {
+ IsOpposite = false;
+ break;
+ }
+ }
+ if(IsOpposite) {
+ OppNum = i;
+ break;
+ }
+ }
+ // find number of 2d elems on side faces
+ int nb2d = 0;
+ for(i=2; i<=6; i++) {
+ if( i == OppNum ) continue;
+ MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb2d += Max(aVec[5],aVec[6]);
+ }
+
+ MapShapeNbElemsItr anIt = aResMap.find( meshFaces[0] );
+ std::vector<int> aVec = (*anIt).second;
+ int nb2d_face0 = Max(aVec[5],aVec[6]);
+ int nb0d_face0 = aVec[0];
+
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ if(IsQuadratic) {
+ aResVec[15] = nb2d_face0 * ( nb2d/nb1d );
+ int nb1d_face0_int = ( nb2d_face0*4 - nb1d ) / 2;
+ aResVec[0] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
+ }
+ else {
+ aResVec[0] = nb0d_face0 * ( nb2d/nb1d - 1 );
+ aResVec[14] = nb2d_face0 * ( nb2d/nb1d );
+ }
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+
+ return true;
+}
+
+
//=============================================================================
/*!
*
}
+//=======================================================================
+//function : EvaluatePentahedralMesh
+//purpose :
+//=======================================================================
+
+bool EvaluatePentahedralMesh(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap)
+{
+ StdMeshers_Penta_3D anAlgo;
+ bool bOK = anAlgo.Evaluate(aMesh, aShape, aResMap);
+
+ //err = anAlgo.GetComputeError();
+ //if ( !bOK && anAlgo.ErrorStatus() == 5 )
+ if( !bOK ) {
+ static StdMeshers_Prism_3D * aPrism3D = 0;
+ if ( !aPrism3D ) {
+ SMESH_Gen* gen = aMesh.GetGen();
+ aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), 0, gen );
+ }
+ SMESH_Hypothesis::Hypothesis_Status aStatus;
+ if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) {
+ return aPrism3D->Evaluate(aMesh, aShape, aResMap);
+ }
+ }
+
+ return bOK;
+}
+
+
const TopoDS_Shape& aShape)
/*throw (SALOME_Exception)*/;
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
static TopoDS_Vertex OppositeVertex(const TopoDS_Vertex& aVertex,
const TopTools_IndexedMapOfShape& aQuads0Vertices,
FaceQuadStruct* aQuads[6]);
#include <BRepTools.hxx>
#include <BRep_Tool.hxx>
+#include <Geom_Curve.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom_Surface.hxx>
#include <TopExp.hxx>
#include <TopoDS_Iterator.hxx>
#include <gp_Pnt2d.hxx>
+#include <BRep_Tool.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
+
using namespace std;
//=============================================================================
return isOk;
}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_MEFISTO_2D::Evaluate(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap)
+{
+ MESSAGE("StdMeshers_MEFISTO_2D::Evaluate");
+
+ TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
+
+ double aLen = 0.0;
+ double NbSeg = 0;
+ bool IsQuadratic = false;
+ bool IsFirst = true;
+ TopExp_Explorer exp(F,TopAbs_EDGE);
+ for(; exp.More(); exp.Next()) {
+ TopoDS_Edge E = TopoDS::Edge(exp.Current());
+ MapShapeNbElemsItr anIt = aResMap.find( aMesh.GetSubMesh(E) );
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ int nbe = Max(aVec[1],aVec[2]);
+ NbSeg += nbe;
+ if(IsFirst) {
+ IsQuadratic = ( aVec[2] > aVec[1] );
+ IsFirst = false;
+ }
+ double a,b;
+ TopLoc_Location L;
+ Handle(Geom_Curve) C = BRep_Tool::Curve(E,L,a,b);
+ gp_Pnt P1;
+ C->D0(a,P1);
+ double dp = (b-a)/nbe;
+ for(int i=1; i<=nbe; i++) {
+ gp_Pnt P2;
+ C->D0(a+i*dp,P2);
+ aLen += P1.Distance(P2);
+ P1 = P2;
+ }
+ }
+ aLen = aLen/NbSeg; // middle length
+
+ _edgeLength = DBL_MAX;
+ double tmpLength = Min( _edgeLength, aLen );
+
+ GProp_GProps G;
+ BRepGProp::SurfaceProperties(aShape,G);
+ double anArea = G.Mass();
+
+ int nbFaces = (int) anArea/(tmpLength*tmpLength*sqrt(3)/4);
+ int nbNodes = (int) ( nbFaces*3 - (NbSeg-1)*2 ) / 6;
+
+ std::vector<int> aVec(17);
+ for(int i=0; i<17; i++) aVec[i] = 0;
+ if(IsQuadratic) {
+ aVec[4] = nbFaces;
+ aVec[0] = nbNodes + nbFaces*3 - (NbSeg-1);
+ }
+ else {
+ aVec[0] = nbNodes;
+ aVec[3] = nbFaces;
+ }
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aVec));
+
+ return true;
+}
+
+
//=======================================================================
//function : fixOverlappedLinkUV
//purpose : prevent failure due to overlapped adjacent links
virtual bool Compute(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
typedef boost::shared_ptr< StdMeshers_FaceSide> StdMeshers_FaceSidePtr;
typedef std::vector< StdMeshers_FaceSidePtr > TWireVector;
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shell.hxx>
}
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+bool StdMeshers_Penta_3D::Evaluate(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ MapShapeNbElems& aResMap)
+{
+ MESSAGE("StdMeshers_Penta_3D::Evaluate()");
+
+ // find face contains only triangles
+ vector < SMESH_subMesh * >meshFaces;
+ TopTools_SequenceOfShape aFaces;
+ int NumBase = 0, i = 0;
+ for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
+ i++;
+ aFaces.Append(exp.Current());
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+ meshFaces.push_back(aSubMesh);
+ MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
+ std::vector<int> aVec = (*anIt).second;
+ int nbtri = Max(aVec[3],aVec[4]);
+ int nbqua = Max(aVec[5],aVec[6]);
+ if( nbtri>0 && nbqua==0 ) {
+ NumBase = i;
+ }
+ }
+
+ if(NumBase==0) return false;
+
+ // find number of 1d elems for base face
+ int nb1d = 0;
+ TopTools_MapOfShape Edges1;
+ for (TopExp_Explorer exp(aFaces.Value(NumBase), TopAbs_EDGE); exp.More(); exp.Next()) {
+ Edges1.Add(exp.Current());
+ SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current());
+ if( sm ) {
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb1d += Max(aVec[1],aVec[2]);
+ }
+ }
+ // find face opposite to base face
+ int OppNum = 0;
+ for(i=1; i<=6; i++) {
+ if(i==NumBase) continue;
+ bool IsOpposite = true;
+ for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+ if( Edges1.Contains(exp.Current()) ) {
+ IsOpposite = false;
+ break;
+ }
+ }
+ if(IsOpposite) {
+ OppNum = i;
+ break;
+ }
+ }
+ // find number of 2d elems on side faces
+ int nb2d = 0;
+ for(i=1; i<=6; i++) {
+ if( i==OppNum || i==NumBase ) continue;
+ MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb2d += Max(aVec[5],aVec[6]);
+ }
+
+ MapShapeNbElemsItr anIt = aResMap.find( meshFaces[NumBase-1] );
+ std::vector<int> aVec = (*anIt).second;
+ int nb2d_face0 = Max(aVec[5],aVec[6]);
+ int nb0d_face0 = aVec[0];
+
+ anIt = aResMap.find( meshFaces[OppNum-1] );
+ for(i=0; i<17; i++)
+ (*anIt).second[i] = aVec[i];
+
+ SMESH_MesherHelper aTool (aMesh);
+ bool _quadraticMesh = aTool.IsQuadraticSubMesh(aShape);
+
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ if(_quadraticMesh) {
+ aResVec[13] = nb2d_face0 * ( nb2d/nb1d );
+ aResVec[0] = nb0d_face0 * ( 2*nb2d/nb1d - 1 );
+ }
+ else {
+ aResVec[0] = nb0d_face0 * ( nb2d/nb1d - 1 );
+ aResVec[12] = nb2d_face0 * ( nb2d/nb1d );
+ }
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+
+ return true;
+}
+
#include "SMESH_Block.hxx"
#include "SMESH_ComputeError.hxx"
#include "SMESH_MesherHelper.hxx"
+#include "SMESH_3D_Algo.hxx"
typedef std::map< double, std::vector<const SMDS_MeshNode*> > StdMeshers_IJNodeMap;
// The key of theIJNodes map is a normalized parameter of each
// 0-the node on theBaseEdge.
+ bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
protected: // methods
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
using namespace std;
return true;
}
+
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+
+bool StdMeshers_Prism_3D::Evaluate(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape,
+ MapShapeNbElems& aResMap)
+{
+ // find face contains only triangles
+ vector < SMESH_subMesh * >meshFaces;
+ TopTools_SequenceOfShape aFaces;
+ int NumBase = 0, i = 0, NbQFs = 0;
+ for (TopExp_Explorer exp(theShape, TopAbs_FACE); exp.More(); exp.Next()) {
+ i++;
+ aFaces.Append(exp.Current());
+ SMESH_subMesh *aSubMesh = theMesh.GetSubMesh(exp.Current());
+ meshFaces.push_back(aSubMesh);
+ MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i-1]);
+ std::vector<int> aVec = (*anIt).second;
+ int nbtri = Max(aVec[3],aVec[4]);
+ int nbqua = Max(aVec[5],aVec[6]);
+ if( nbtri==0 && nbqua>0 ) {
+ NbQFs++;
+ }
+ if( nbtri>0 ) {
+ NumBase = i;
+ }
+ }
+
+ if(NbQFs<4) {
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+ return false;
+ }
+
+ if(NumBase==0) NumBase = 1; // only quads => set 1 faces as base
+
+ // find number of 1d elems for base face
+ int nb1d = 0;
+ TopTools_MapOfShape Edges1;
+ for (TopExp_Explorer exp(aFaces.Value(NumBase), TopAbs_EDGE); exp.More(); exp.Next()) {
+ Edges1.Add(exp.Current());
+ SMESH_subMesh *sm = theMesh.GetSubMesh(exp.Current());
+ if( sm ) {
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb1d += Max(aVec[1],aVec[2]);
+ }
+ }
+ // find face opposite to base face
+ int OppNum = 0;
+ for(i=1; i<=6; i++) {
+ if(i==NumBase) continue;
+ bool IsOpposite = true;
+ for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+ if( Edges1.Contains(exp.Current()) ) {
+ IsOpposite = false;
+ break;
+ }
+ }
+ if(IsOpposite) {
+ OppNum = i;
+ break;
+ }
+ }
+ // find number of 2d elems on side faces
+ int nb2d = 0;
+ for(i=1; i<=6; i++) {
+ if( i==OppNum || i==NumBase ) continue;
+ MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb2d += Max(aVec[5],aVec[6]);
+ }
+
+ MapShapeNbElemsItr anIt = aResMap.find( meshFaces[NumBase-1] );
+ std::vector<int> aVec = (*anIt).second;
+ bool IsQuadratic = (aVec[4]>aVec[3]) || (aVec[6]>aVec[5]);
+ int nb2d_face0_3 = Max(aVec[3],aVec[4]);
+ int nb2d_face0_4 = Max(aVec[5],aVec[6]);
+ int nb0d_face0 = aVec[0];
+ int nb1d_face0_int = ( nb2d_face0_3*3 + nb2d_face0_4*4 - nb1d ) / 2;
+
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ if(IsQuadratic) {
+ aResVec[13] = nb2d_face0_3 * ( nb2d/nb1d );
+ aResVec[15] = nb2d_face0_4 * ( nb2d/nb1d );
+ aResVec[0] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
+ }
+ else {
+ aResVec[0] = nb0d_face0 * ( nb2d/nb1d - 1 );
+ aResVec[12] = nb2d_face0_3 * ( nb2d/nb1d );
+ aResVec[14] = nb2d_face0_4 * ( nb2d/nb1d );
+ }
+ SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+
+ return true;
+}
+
+
//================================================================================
/*!
* \brief Create prisms
virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
/*!
* \brief Enable removal of quadrangles from the bottom face and
* triangles creation there by projection from the top
return true;
}
+
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+
+bool StdMeshers_Projection_1D::Evaluate(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape,
+ MapShapeNbElems& aResMap)
+{
+ if ( !_sourceHypo )
+ return false;
+
+ SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+ SMESH_Mesh * tgtMesh = & theMesh;
+ if ( !srcMesh )
+ srcMesh = tgtMesh;
+
+ SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+
+ // ---------------------------
+ // Make subshapes association
+ // ---------------------------
+
+ TopoDS_Edge srcEdge, tgtEdge = TopoDS::Edge( theShape.Oriented(TopAbs_FORWARD));
+ TopoDS_Shape srcShape = _sourceHypo->GetSourceEdge().Oriented(TopAbs_FORWARD);
+
+ TAssocTool::TShapeShapeMap shape2ShapeMap;
+ TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtEdge );
+ if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcShape, srcMesh,
+ shape2ShapeMap) ||
+ !shape2ShapeMap.IsBound( tgtEdge ))
+ return error("Vertices association failed" );
+
+ srcEdge = TopoDS::Edge( shape2ShapeMap( tgtEdge ).Oriented(TopAbs_FORWARD));
+// cout << " srcEdge #" << srcMesh->GetMeshDS()->ShapeToIndex( srcEdge )
+// << " tgtEdge #" << tgtMesh->GetMeshDS()->ShapeToIndex( tgtEdge ) << endl;
+
+ TopoDS_Vertex tgtV[2], srcV[2];
+ TopExp::Vertices( tgtEdge, tgtV[0], tgtV[1] );
+ TopExp::Vertices( srcEdge, srcV[0], srcV[1] );
+
+ // ----------------------------------------------
+ // Assure that mesh on a source edge is computed
+ // ----------------------------------------------
+
+ SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( srcEdge );
+ //SMESH_subMesh* tgtSubMesh = tgtMesh->GetSubMesh( tgtEdge );
+
+ if ( tgtMesh == srcMesh ) {
+ if ( !TAssocTool::MakeComputed( srcSubMesh ))
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+ }
+ else {
+ if ( !srcSubMesh->IsMeshComputed() )
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+ }
+ // -----------------------------------------------
+ // Find out nodes distribution on the source edge
+ // -----------------------------------------------
+
+ double srcLength = EdgeLength( srcEdge );
+ double tgtLength = EdgeLength( tgtEdge );
+
+ vector< double > params; // sorted parameters of nodes on the source edge
+ if ( !SMESH_Algo::GetNodeParamOnEdge( srcMesh->GetMeshDS(), srcEdge, params ))
+ return error(COMPERR_BAD_INPUT_MESH,"Bad node parameters on the source edge");
+
+ int nbNodes = params.size();
+
+ std::vector<int> aVec(17);
+ for(int i=0; i<17; i++) aVec[i] = 0;
+
+ aVec[0] = nbNodes;
+
+ bool quadratic = false;
+ SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+ if ( elemIt->more() )
+ quadratic = elemIt->next()->IsQuadratic();
+ if(quadratic)
+ aVec[2] = (nbNodes-1)/2;
+ else
+ aVec[1] = nbNodes - 1;
+
+ SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+ aResMap.insert(std::make_pair(sm,aVec));
+
+ return true;
+}
+
+
//=============================================================================
/*!
* \brief Sets a default event listener to submesh of the source edge
virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
/*!
* \brief Sets a default event listener to submesh of the source edge
* \param whenSetToSubMesh - submesh where algo is set
return true;
}
+
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+
+bool StdMeshers_Projection_2D::Evaluate(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape,
+ MapShapeNbElems& aResMap)
+{
+ if ( !_sourceHypo )
+ return false;
+
+ SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+ SMESH_Mesh * tgtMesh = & theMesh;
+ if ( !srcMesh )
+ srcMesh = tgtMesh;
+
+ // ---------------------------
+ // Make subshapes association
+ // ---------------------------
+
+ TopoDS_Face tgtFace = TopoDS::Face( theShape.Oriented(TopAbs_FORWARD));
+ TopoDS_Shape srcShape = _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD);
+
+ TAssocTool::TShapeShapeMap shape2ShapeMap;
+ TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtFace );
+ if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcShape, srcMesh,
+ shape2ShapeMap) ||
+ !shape2ShapeMap.IsBound( tgtFace ))
+ return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" );
+
+ TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD));
+
+ // ----------------------------------------------
+ // Assure that mesh on a source Face is computed
+ // ----------------------------------------------
+
+ SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( srcFace );
+
+ if ( !srcSubMesh->IsMeshComputed() )
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+
+
+ std::vector<int> aVec(17);
+ for(int i=0; i<17; i++) aVec[i] = 0;
+
+ aVec[0] = srcSubMesh->GetSubMeshDS()->NbNodes();
+
+ //bool quadratic = false;
+ SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+ while ( elemIt->more() ) {
+ const SMDS_MeshElement* E = elemIt->next();
+ if( E->NbNodes()==3 ) {
+ aVec[3]++;
+ }
+ else if( E->NbNodes()==4 ) {
+ aVec[5]++;
+ }
+ else if( E->NbNodes()==6 && E->IsQuadratic() ) {
+ aVec[4]++;
+ }
+ else if( E->NbNodes()==8 && E->IsQuadratic() ) {
+ aVec[6]++;
+ }
+ else {
+ aVec[7]++;
+ }
+ }
+
+ SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+ aResMap.insert(std::make_pair(sm,aVec));
+
+ return true;
+}
+
+
//=============================================================================
/*!
* \brief Sets a default event listener to submesh of the source face
virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
/*!
* \brief Sets a default event listener to submesh of the source face
* \param whenSetToSubMesh - submesh where algo is set
return true;
}
+
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+
+bool StdMeshers_Projection_3D::Evaluate(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ MapShapeNbElems& aResMap)
+{
+ if ( !_sourceHypo )
+ return false;
+
+ SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+ SMESH_Mesh * tgtMesh = & aMesh;
+ if ( !srcMesh )
+ srcMesh = tgtMesh;
+
+ // get shell from shape3D
+ TopoDS_Shell srcShell, tgtShell;
+ TopExp_Explorer exp( _sourceHypo->GetSource3DShape(), TopAbs_SHELL );
+ int nbShell;
+ for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
+ srcShell = TopoDS::Shell( exp.Current() );
+ if ( nbShell != 1 )
+ return error(COMPERR_BAD_SHAPE,
+ SMESH_Comment("Source shape must have 1 shell but not ") << nbShell);
+
+ exp.Init( aShape, TopAbs_SHELL );
+ for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
+ tgtShell = TopoDS::Shell( exp.Current() );
+ if ( nbShell != 1 )
+ return error(COMPERR_BAD_SHAPE,
+ SMESH_Comment("Target shape must have 1 shell but not ") << nbShell);
+
+ // Check that shapes are blocks
+ if ( TAssocTool::Count( tgtShell, TopAbs_FACE , 1 ) != 6 ||
+ TAssocTool::Count( tgtShell, TopAbs_EDGE , 1 ) != 12 ||
+ TAssocTool::Count( tgtShell, TopAbs_WIRE , 1 ) != 6 )
+ return error(COMPERR_BAD_SHAPE, "Target shape is not a block");
+ if ( TAssocTool::Count( srcShell, TopAbs_FACE , 1 ) != 6 ||
+ TAssocTool::Count( srcShell, TopAbs_EDGE , 1 ) != 12 ||
+ TAssocTool::Count( srcShell, TopAbs_WIRE , 1 ) != 6 )
+ return error(COMPERR_BAD_SHAPE, "Source shape is not a block");
+
+ // Assure that mesh on a source shape is computed
+
+ SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() );
+
+ if ( !srcSubMesh->IsMeshComputed() )
+ return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+
+
+ std::vector<int> aVec(17);
+ for(int i=0; i<17; i++) aVec[i] = 0;
+
+ aVec[0] = srcSubMesh->GetSubMeshDS()->NbNodes();
+
+ //bool quadratic = false;
+ SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+ while ( elemIt->more() ) {
+ const SMDS_MeshElement* E = elemIt->next();
+ if( E->NbNodes()==4 ) {
+ aVec[8]++;
+ }
+ else if( E->NbNodes()==5 ) {
+ aVec[10]++;
+ }
+ else if( E->NbNodes()==6 ) {
+ aVec[12]++;
+ }
+ else if( E->NbNodes()==8 ) {
+ aVec[14]++;
+ }
+ else if( E->NbNodes()==10 && E->IsQuadratic() ) {
+ aVec[9]++;
+ }
+ else if( E->NbNodes()==13 && E->IsQuadratic() ) {
+ aVec[11]++;
+ }
+ else if( E->NbNodes()==15 && E->IsQuadratic() ) {
+ aVec[13]++;
+ }
+ else if( E->NbNodes()==20 && E->IsQuadratic() ) {
+ aVec[15]++;
+ }
+ else {
+ aVec[16]++;
+ }
+ }
+
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aVec));
+
+ return true;
+}
+
+
//=============================================================================
/*!
* \brief Sets a default event listener to submesh of the source shape
virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
/*!
* \brief Sets a default event listener to submesh of the source shape
* \param whenSetToSubMesh - submesh where algo is set
return isOk;
}
+
+//=============================================================================
+/*!
+ * Evaluate
+ */
+//=============================================================================
+
+bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ MapShapeNbElems& aResMap)
+
+{
+ aMesh.GetSubMesh(aShape);
+
+ std::vector<int> aNbNodes(4);
+ bool IsQuadratic = false;
+ if( !CheckNbEdgesForEvaluate( aMesh, aShape, aResMap, aNbNodes, IsQuadratic ) ) {
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+ return false;
+ }
+
+ if(myQuadranglePreference) {
+ int n1 = aNbNodes[0];
+ int n2 = aNbNodes[1];
+ int n3 = aNbNodes[2];
+ int n4 = aNbNodes[3];
+ int nfull = n1+n2+n3+n4;
+ int ntmp = nfull/2;
+ ntmp = ntmp*2;
+ if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) {
+ // special path for using only quandrangle faces
+ return EvaluateQuadPref(aMesh, aShape, aNbNodes, aResMap, IsQuadratic);
+ //return true;
+ }
+ }
+
+ int nbdown = aNbNodes[0];
+ int nbup = aNbNodes[2];
+
+ int nbright = aNbNodes[1];
+ int nbleft = aNbNodes[3];
+
+ int nbhoriz = Min(nbdown, nbup);
+ int nbvertic = Min(nbright, nbleft);
+
+ int dh = Max(nbdown, nbup) - nbhoriz;
+ int dv = Max(nbright, nbleft) - nbvertic;
+
+ int kdh = 0;
+ if(dh>0) kdh = 1;
+ int kdv = 0;
+ if(dv>0) kdv = 1;
+
+ int nbNodes = (nbhoriz-2)*(nbvertic-2);
+ int nbFaces3 = dh + dv + kdh*(nbvertic-1)*2 + kdv*(nbhoriz-1)*2;
+ if( kdh==1 && kdv==1 ) nbFaces3 -= 2;
+ int nbFaces4 = (nbhoriz-1-kdh)*(nbvertic-1-kdv);
+
+ std::vector<int> aVec(17);
+ for(int i=0; i<17; i++) aVec[i] = 0;
+ if(IsQuadratic) {
+ aVec[4] = nbFaces3;
+ aVec[6] = nbFaces4;
+ int nbbndedges = nbdown + nbup + nbright + nbleft -4;
+ int nbintedges = ( nbFaces4*4 + nbFaces3*3 - nbbndedges ) / 2;
+ aVec[0] = nbNodes + nbintedges;
+ }
+ else {
+ aVec[0] = nbNodes;
+ aVec[3] = nbFaces3;
+ aVec[5] = nbFaces4;
+ }
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aVec));
+
+ return true;
+}
+
+
//================================================================================
/*!
* \brief Return true if only two given edges meat at their common vertex
return quad;
}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_Quadrangle_2D::CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap,
+ std::vector<int>& aNbNodes,
+ bool& IsQuadratic)
+
+{
+ const TopoDS_Face & F = TopoDS::Face(aShape);
+
+ // verify 1 wire only, with 4 edges
+ TopoDS_Vertex V;
+ list< TopoDS_Edge > edges;
+ list< int > nbEdgesInWire;
+ int nbWire = SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+ if (nbWire != 1) {
+ return false;
+ }
+
+ aNbNodes.resize(4);
+
+ int nbSides = 0;
+ list< TopoDS_Edge >::iterator edgeIt = edges.begin();
+ SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt );
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) {
+ return false;
+ }
+ std::vector<int> aVec = (*anIt).second;
+ IsQuadratic = (aVec[2] > aVec[1]);
+ if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges
+ for(; edgeIt != edges.end(); edgeIt++) {
+ SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt );
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) {
+ return false;
+ }
+ std::vector<int> aVec = (*anIt).second;
+ if(IsQuadratic)
+ aNbNodes[nbSides] = (aVec[0]-1)/2 + 2;
+ else
+ aNbNodes[nbSides] = aVec[0] + 2;
+ nbSides++;
+ }
+ }
+ else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some
+ list< TopoDS_Edge > sideEdges;
+ while ( !edges.empty()) {
+ sideEdges.clear();
+ sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
+ bool sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ }
+ if ( nbSides == 0 ) { // go backward from the first edge
+ sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ }
+ }
+ list<TopoDS_Edge>::iterator ite = sideEdges.begin();
+ aNbNodes[nbSides] = 1;
+ for(; ite!=sideEdges.end(); ite++) {
+ SMESH_subMesh * sm = aMesh.GetSubMesh( *ite );
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) {
+ return false;
+ }
+ std::vector<int> aVec = (*anIt).second;
+ if(IsQuadratic)
+ aNbNodes[nbSides] += (aVec[0]-1)/2 + 1;
+ else
+ aNbNodes[nbSides] += aVec[0] + 1;
+ }
+ ++nbSides;
+ }
+ // issue 20222. Try to unite only edges shared by two same faces
+ if (nbSides < 4) {
+ nbSides = 0;
+ SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+ while ( !edges.empty()) {
+ sideEdges.clear();
+ sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ bool sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ sameSide =
+ SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ) &&
+ twoEdgesMeatAtVertex( sideEdges.back(), edges.front(), aMesh );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ }
+ if ( nbSides == 0 ) { // go backward from the first edge
+ sameSide = true;
+ while ( !edges.empty() && sameSide ) {
+ sameSide =
+ SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ) &&
+ twoEdgesMeatAtVertex( sideEdges.front(), edges.back(), aMesh );
+ if ( sameSide )
+ sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ }
+ }
+ list<TopoDS_Edge>::iterator ite = sideEdges.begin();
+ aNbNodes[nbSides] = 1;
+ for(; ite!=sideEdges.end(); ite++) {
+ SMESH_subMesh * sm = aMesh.GetSubMesh( *ite );
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if(anIt==aResMap.end()) {
+ return false;
+ }
+ std::vector<int> aVec = (*anIt).second;
+ if(IsQuadratic)
+ aNbNodes[nbSides] += (aVec[0]-1)/2 + 1;
+ else
+ aNbNodes[nbSides] += aVec[0] + 1;
+ }
+ ++nbSides;
+ }
+ }
+ }
+ if (nbSides != 4) {
+ if ( !nbSides )
+ nbSides = nbEdgesInWire.front();
+ error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides);
+ return false;
+ }
+
+ return true;
+}
+
+
//=============================================================================
/*!
* CheckAnd2Dcompute
}
}
+ int nbf=0;
for(j=1; j<nnn-1; j++) {
for(i=1; i<nb; i++) {
+ nbf++;
if(WisF) {
SMDS_MeshFace* F =
myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j),
}
}
}
-
int drl = abs(nr-nl);
// create faces for region C
StdMeshers_Array2OfNode NodesC(1,nb,1,drl+1+addv);
// create faces
for(j=1; j<=drl+addv; j++) {
for(i=1; i<nb; i++) {
+ nbf++;
if(WisF) {
SMDS_MeshFace* F =
myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
NodesLast.SetValue(nnn,1,NodesC.Value(nb,i));
}
for(i=1; i<nt; i++) {
+ nbf++;
if(WisF) {
SMDS_MeshFace* F =
myTool->AddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1),
return isOk;
}
+
+//=======================================================================
+/*!
+ * Evaluate only quandrangle faces
+ */
+//=======================================================================
+
+bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh,
+ const TopoDS_Shape& aShape,
+ std::vector<int>& aNbNodes,
+ MapShapeNbElems& aResMap,
+ bool IsQuadratic)
+{
+ // Auxilary key in order to keep old variant
+ // of meshing after implementation new variant
+ // for bug 0016220 from Mantis.
+ bool OldVersion = false;
+
+ const TopoDS_Face& F = TopoDS::Face(aShape);
+ Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+
+ int nb = aNbNodes[0];
+ int nr = aNbNodes[1];
+ int nt = aNbNodes[2];
+ int nl = aNbNodes[3];
+ int dh = abs(nb-nt);
+ int dv = abs(nr-nl);
+
+ if( dh>=dv ) {
+ if( nt>nb ) {
+ // it is a base case => not shift
+ }
+ else {
+ // we have to shift on 2
+ nb = aNbNodes[2];
+ nr = aNbNodes[3];
+ nt = aNbNodes[0];
+ nl = aNbNodes[1];
+ }
+ }
+ else {
+ if( nr>nl ) {
+ // we have to shift quad on 1
+ nb = aNbNodes[3];
+ nr = aNbNodes[0];
+ nt = aNbNodes[1];
+ nl = aNbNodes[2];
+ }
+ else {
+ // we have to shift quad on 3
+ nb = aNbNodes[1];
+ nr = aNbNodes[2];
+ nt = aNbNodes[3];
+ nl = aNbNodes[0];
+ }
+ }
+
+ dh = abs(nb-nt);
+ dv = abs(nr-nl);
+ int nbh = Max(nb,nt);
+ int nbv = Max(nr,nl);
+ int addh = 0;
+ int addv = 0;
+
+ if(dh>dv) {
+ addv = (dh-dv)/2;
+ nbv = nbv + addv;
+ }
+ else { // dv>=dh
+ addh = (dv-dh)/2;
+ nbh = nbh + addh;
+ }
+
+ int dl,dr;
+ if(OldVersion) {
+ // add some params to right and left after the first param
+ // insert to right
+ dr = nbv - nr;
+ // insert to left
+ dl = nbv - nl;
+ }
+
+ int nnn = Min(nr,nl);
+
+ int nbNodes = 0;
+ int nbFaces = 0;
+ if(OldVersion) {
+ // step1: create faces for left domain
+ if(dl>0) {
+ nbNodes += dl*(nl-1);
+ nbFaces += dl*(nl-1);
+ }
+ // step2: create faces for right domain
+ if(dr>0) {
+ nbNodes += dr*(nr-1);
+ nbFaces += dr*(nr-1);
+ }
+ // step3: create faces for central domain
+ nbNodes += (nb-2)*(nnn-1) + (nbv-nnn-1)*(nb-2);
+ nbFaces += (nb-1)*(nbv-1);
+ }
+ else { // New version (!OldVersion)
+ nbNodes += (nnn-2)*(nb-2);
+ nbFaces += (nnn-2)*(nb-1);
+ int drl = abs(nr-nl);
+ nbNodes += drl*(nb-1) + addv*nb;
+ nbFaces += (drl+addv)*(nb-1) + (nt-1);
+ } // end new version implementation
+
+ std::vector<int> aVec(17);
+ for(int i=0; i<17; i++) aVec[i] = 0;
+ if(IsQuadratic) {
+ aVec[6] = nbFaces;
+ aVec[0] = nbNodes + nbFaces*4;
+ }
+ else {
+ aVec[0] = nbNodes;
+ aVec[5] = nbFaces;
+ }
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aVec));
+
+ return true;
+}
+
+
//=============================================================================
/*! Split quadrangle in to 2 triangles by smallest diagonal
*
virtual bool Compute(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
const bool CreateQuadratic);
FaceQuadStruct* CheckNbEdges(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape);
+ bool CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap,
+ std::vector<int>& aNbNodes,
+ bool& IsQuadratic);
+
bool SetNormalizedGrid(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
FaceQuadStruct*& quad);
* Special function for creation only quandrangle faces
*/
bool ComputeQuadPref(SMESH_Mesh& aMesh,
-
const TopoDS_Shape& aShape,
FaceQuadStruct* quad);
+ bool EvaluateQuadPref(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ std::vector<int>& aNbNodes,
+ MapShapeNbElems& aResMap,
+ bool IsQuadratic);
+
UVPtStruct* LoadEdgePoints2(SMESH_Mesh& aMesh,
const TopoDS_Face& F, const TopoDS_Edge& E,
bool IsReverse);
#include <BRepAdaptor_Curve.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <gp.hxx>
#include <gp_Pnt.hxx>
}
RETURN_BAD_RESULT("Bad hypothesis");
}
+
+
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+
+bool StdMeshers_RadialPrism_3D::Evaluate(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ MapShapeNbElems& aResMap)
+{
+ // get 2 shells
+ TopoDS_Solid solid = TopoDS::Solid( aShape );
+ TopoDS_Shell outerShell = BRepTools::OuterShell( solid );
+ TopoDS_Shape innerShell;
+ int nbShells = 0;
+ for ( TopoDS_Iterator It (solid); It.More(); It.Next(), ++nbShells )
+ if ( !outerShell.IsSame( It.Value() ))
+ innerShell = It.Value();
+ if ( nbShells != 2 ) {
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+ return false;
+ }
+
+ // Associate subshapes of the shells
+ TAssocTool::TShapeShapeMap shape2ShapeMap;
+ if ( !TAssocTool::FindSubShapeAssociation( outerShell, &aMesh,
+ innerShell, &aMesh,
+ shape2ShapeMap) ) {
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+ return false;
+ }
+
+ // get info for outer shell
+ int nb0d_Out=0, nb2d_3_Out=0, nb2d_4_Out=0;
+ //TopTools_SequenceOfShape FacesOut;
+ for (TopExp_Explorer exp(outerShell, TopAbs_FACE); exp.More(); exp.Next()) {
+ //FacesOut.Append(exp.Current());
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+ MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+ std::vector<int> aVec = (*anIt).second;
+ nb0d_Out += aVec[0];
+ nb2d_3_Out += Max(aVec[3],aVec[4]);
+ nb2d_4_Out += Max(aVec[5],aVec[6]);
+ }
+ int nb1d_Out = 0;
+ TopTools_MapOfShape tmpMap;
+ for (TopExp_Explorer exp(outerShell, TopAbs_EDGE); exp.More(); exp.Next()) {
+ if( tmpMap.Contains( exp.Current() ) )
+ continue;
+ tmpMap.Add( exp.Current() );
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+ MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+ std::vector<int> aVec = (*anIt).second;
+ nb0d_Out += aVec[0];
+ nb1d_Out += Max(aVec[1],aVec[2]);
+ }
+ tmpMap.Clear();
+ for (TopExp_Explorer exp(outerShell, TopAbs_VERTEX); exp.More(); exp.Next()) {
+ if( tmpMap.Contains( exp.Current() ) )
+ continue;
+ tmpMap.Add( exp.Current() );
+ nb0d_Out++;
+ }
+
+ // get info for inner shell
+ int nb0d_In=0, nb2d_3_In=0, nb2d_4_In=0;
+ //TopTools_SequenceOfShape FacesIn;
+ for (TopExp_Explorer exp(innerShell, TopAbs_FACE); exp.More(); exp.Next()) {
+ //FacesIn.Append(exp.Current());
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+ MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+ std::vector<int> aVec = (*anIt).second;
+ nb0d_In += aVec[0];
+ nb2d_3_In += Max(aVec[3],aVec[4]);
+ nb2d_4_In += Max(aVec[5],aVec[6]);
+ }
+ int nb1d_In = 0;
+ tmpMap.Clear();
+ bool IsQuadratic = false;
+ bool IsFirst = true;
+ for (TopExp_Explorer exp(innerShell, TopAbs_EDGE); exp.More(); exp.Next()) {
+ if( tmpMap.Contains( exp.Current() ) )
+ continue;
+ tmpMap.Add( exp.Current() );
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+ MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+ std::vector<int> aVec = (*anIt).second;
+ nb0d_In += aVec[0];
+ nb1d_In += Max(aVec[1],aVec[2]);
+ if(IsFirst) {
+ IsQuadratic = (aVec[2] > aVec[1]);
+ IsFirst = false;
+ }
+ }
+ tmpMap.Clear();
+ for (TopExp_Explorer exp(innerShell, TopAbs_VERTEX); exp.More(); exp.Next()) {
+ if( tmpMap.Contains( exp.Current() ) )
+ continue;
+ tmpMap.Add( exp.Current() );
+ nb0d_In++;
+ }
+
+ bool IsOK = (nb0d_Out==nb0d_In) && (nb1d_Out==nb1d_In) &&
+ (nb2d_3_Out==nb2d_3_In) && (nb2d_4_Out==nb2d_4_In);
+ if(!IsOK) {
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+ return false;
+ }
+
+ int nbLayers = 0;
+ if( myNbLayerHypo ) {
+ nbLayers = myNbLayerHypo->GetNumberOfLayers();
+ }
+ if ( myDistributionHypo ) {
+ if ( !myDistributionHypo->GetLayerDistribution() ) {
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+ return false;
+ }
+ TopExp_Explorer exp(outerShell, TopAbs_VERTEX);
+ TopoDS_Vertex Vout = TopoDS::Vertex(exp.Current());
+ TopoDS_Vertex Vin = TopoDS::Vertex( shape2ShapeMap(Vout) );
+ if ( myLayerPositions.empty() ) {
+ gp_Pnt pIn = BRep_Tool::Pnt(Vin);
+ gp_Pnt pOut = BRep_Tool::Pnt(Vout);
+ computeLayerPositions( pIn, pOut );
+ }
+ nbLayers = myLayerPositions.size() + 1;
+ }
+
+ std::vector<int> aResVec(17);
+ for(int i=0; i<17; i++) aResVec[i] = 0;
+ if(IsQuadratic) {
+ aResVec[13] = nb2d_3_Out * nbLayers;
+ aResVec[15] = nb2d_4_Out * nbLayers;
+ int nb1d = ( nb2d_3_Out*3 + nb2d_4_Out*4 ) / 2;
+ aResVec[0] = nb0d_Out * ( 2*nbLayers - 1 ) - nb1d * nbLayers;
+ }
+ else {
+ aResVec[0] = nb0d_Out * ( nbLayers - 1 );
+ aResVec[12] = nb2d_3_Out * nbLayers;
+ aResVec[14] = nb2d_4_Out * nbLayers;
+ }
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+
+ return true;
+}
virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
protected:
typedef std::vector<const SMDS_MeshNode* > TNodeColumn;
return true;
}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh,
+ const TopoDS_Shape & theShape,
+ MapShapeNbElems& aResMap)
+{
+ if ( _hypType == NONE )
+ return false;
+
+ SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+
+ const TopoDS_Edge & EE = TopoDS::Edge(theShape);
+ TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
+ int shapeID = meshDS->ShapeToIndex( E );
+
+ double f, l;
+ Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l);
+
+ TopoDS_Vertex VFirst, VLast;
+ TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l
+
+ ASSERT(!VFirst.IsNull());
+ ASSERT(!VLast.IsNull());
+
+ std::vector<int> aVec(17);
+ for(int i=0; i<17; i++) aVec[i] = 0;
+
+ if (!Curve.IsNull()) {
+ list< double > params;
+ bool reversed = false;
+ if ( !_mainEdge.IsNull() )
+ reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED );
+
+ BRepAdaptor_Curve C3d( E );
+ double length = EdgeLength( E );
+ if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) {
+ SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+ aResMap.insert(std::make_pair(sm,aVec));
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+ return false;
+ }
+ redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast );
+
+ if(_quadraticMesh) {
+ aVec[0] = 2*params.size() + 1;
+ aVec[2] = params.size() + 1;
+ }
+ else {
+ aVec[0] = params.size();
+ aVec[1] = params.size() + 1;
+ }
+
+ }
+ else {
+ //MESSAGE("************* Degenerated edge! *****************");
+ // Edge is a degenerated Edge : We put n = 5 points on the edge.
+ if(_quadraticMesh) {
+ aVec[0] = 11;
+ aVec[2] = 6;
+ }
+ else {
+ aVec[0] = 5;
+ aVec[1] = 6;
+ }
+ }
+
+ SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+ aResMap.insert(std::make_pair(sm,aVec));
+
+ return true;
+}
+
+
//=============================================================================
/*!
* See comments in SMESH_Algo.cxx
virtual bool Compute(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
+
virtual const std::list <const SMESHDS_Hypothesis *> &
GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true);
// StdMeshers_SegmentLengthAroundVertex hypothesis
return true;
}
+
+
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+
+bool StdMeshers_SegmentAroundVertex_0D::Evaluate(SMESH_Mesh&,
+ const TopoDS_Shape&,
+ MapShapeNbElems&)
+{
+ // This algorithm exists in order just to enable assignation of
+ // StdMeshers_SegmentLengthAroundVertex hypothesis
+ return false;
+}
virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
};
#endif
bool StdMeshers_UseExisting_1D::Compute(SMESH_Mesh&, const TopoDS_Shape&)
{
- // This algorithm exists to allow mesh generation by mesh edition functions in TUI mode
+ // This algorithm exists to allow mesh generation by mesh
+ // edition functions in TUI mode
return true;
}
+
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+
+bool StdMeshers_UseExisting_1D::Evaluate(SMESH_Mesh&,
+ const TopoDS_Shape&,
+ MapShapeNbElems&)
+{
+ // This algorithm exists to allow mesh generation by mesh
+ // edition functions in TUI mode
+ return false;
+}
+
+
//=======================================================================
//function : StdMeshers_UseExisting_2D
//purpose :
bool StdMeshers_UseExisting_2D::Compute(SMESH_Mesh&, const TopoDS_Shape&)
{
- // This algorithm exists to allow mesh generation by mesh edition functions in TUI mode
+ // This algorithm exists to allow mesh generation by mesh edition
+ // functions in TUI mode
return true;
}
+
+
+//=======================================================================
+//function : Evaluate
+//purpose :
+//=======================================================================
+
+bool StdMeshers_UseExisting_2D::Evaluate(SMESH_Mesh&,
+ const TopoDS_Shape&,
+ MapShapeNbElems&)
+{
+ // This algorithm exists to allow mesh generation by mesh edition
+ // functions in TUI mode
+ return false;
+}
virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
};
class STDMESHERS_EXPORT StdMeshers_UseExisting_1D: public SMESH_1D_Algo
virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+ virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap);
};
#endif