mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-26 09:20:34 +05:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
776a610c84
@ -206,7 +206,7 @@ module SMESH
|
||||
{
|
||||
HYP_OK,
|
||||
HYP_MISSING, // algo misses a hypothesis
|
||||
HYP_CONCURENT, // several applicable hypotheses
|
||||
HYP_CONCURRENT, // several applicable hypotheses
|
||||
HYP_BAD_PARAMETER,// hypothesis has a bad parameter value
|
||||
HYP_HIDDEN_ALGO, // an algo is hidden by an upper dim algo generating all-dim elements
|
||||
HYP_HIDING_ALGO, // an algo hides lower dim algos by generating all-dim elements
|
||||
|
@ -1029,7 +1029,7 @@ static int ScaKwdTab(GmfMshSct *msh)
|
||||
if(isalpha(str[0]))
|
||||
{
|
||||
/* Search which kwd code this string is associated with,
|
||||
then get its header and save the curent position in file (just before the data) */
|
||||
then get its header and save the current position in file (just before the data) */
|
||||
|
||||
for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
|
||||
if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
|
||||
|
@ -675,7 +675,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh& aMesh,
|
||||
checkConform = false; // no more check conformity
|
||||
INFOS( "ERROR: Local <" << algo->GetName() <<
|
||||
"> would produce not conform mesh: "
|
||||
"<Not Conform Mesh Allowed> hypotesis is missing");
|
||||
"<Not Conform Mesh Allowed> hypothesis is missing");
|
||||
theErrors.push_back( SMESH_Gen::TAlgoStateError() );
|
||||
theErrors.back().Set( SMESH_Hypothesis::HYP_NOTCONFORM, algo, false );
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ int SMESH_HypoFilter::DimPredicate::Value( const SMESH_Hypothesis* aHyp ) const
|
||||
bool SMESH_HypoFilter::ApplicablePredicate::IsOk(const SMESH_Hypothesis* aHyp,
|
||||
const TopoDS_Shape& /*aShape*/) const
|
||||
{
|
||||
return SMESH_subMesh::IsApplicableHypotesis( aHyp, (TopAbs_ShapeEnum)_shapeType );
|
||||
return SMESH_subMesh::IsApplicableHypothesis( aHyp, (TopAbs_ShapeEnum)_shapeType );
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
{
|
||||
HYP_OK = 0,
|
||||
HYP_MISSING, // algo misses a hypothesis
|
||||
HYP_CONCURENT, // several applicable hypotheses assigned to father shapes
|
||||
HYP_CONCURRENT, // several applicable hypotheses assigned to father shapes
|
||||
HYP_BAD_PARAMETER,// hypothesis has a bad parameter value
|
||||
HYP_HIDDEN_ALGO, // an algo is hidden by an upper dim algo generating all-dim elements
|
||||
HYP_HIDING_ALGO, // an algo hides lower dim algos by generating all-dim elements
|
||||
|
@ -661,7 +661,7 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
|
||||
string hypName = anHyp->GetName();
|
||||
if ( hypName == "NotConformAllowed" )
|
||||
{
|
||||
if(MYDEBUG) MESSAGE( "Hypotesis <NotConformAllowed> can be only global" );
|
||||
if(MYDEBUG) MESSAGE( "Hypothesis <NotConformAllowed> can be only global" );
|
||||
return SMESH_Hypothesis::HYP_INCOMPATIBLE;
|
||||
}
|
||||
}
|
||||
@ -698,13 +698,13 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
|
||||
}
|
||||
|
||||
// check concurrent hypotheses on ancestors
|
||||
if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
|
||||
if (ret < SMESH_Hypothesis::HYP_CONCURRENT && !isGlobalHyp )
|
||||
{
|
||||
SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
|
||||
while ( smIt->more() ) {
|
||||
SMESH_subMesh* sm = smIt->next();
|
||||
if ( sm->IsApplicableHypotesis( anHyp )) {
|
||||
ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
|
||||
if ( sm->IsApplicableHypothesis( anHyp )) {
|
||||
ret2 = sm->CheckConcurrentHypothesis( anHyp->GetType() );
|
||||
if (ret2 > ret) {
|
||||
ret = ret2;
|
||||
break;
|
||||
@ -751,10 +751,10 @@ SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
|
||||
SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
|
||||
|
||||
// there may appear concurrent hyps that were covered by the removed hyp
|
||||
if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
|
||||
subMesh->IsApplicableHypotesis( anHyp ) &&
|
||||
subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
|
||||
ret = SMESH_Hypothesis::HYP_CONCURENT;
|
||||
if (ret < SMESH_Hypothesis::HYP_CONCURRENT &&
|
||||
subMesh->IsApplicableHypothesis( anHyp ) &&
|
||||
subMesh->CheckConcurrentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
|
||||
ret = SMESH_Hypothesis::HYP_CONCURRENT;
|
||||
|
||||
// sub-shapes
|
||||
if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
|
||||
@ -768,13 +768,13 @@ SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
|
||||
ret = ret2;
|
||||
|
||||
// check concurrent hypotheses on ancestors
|
||||
if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
|
||||
if (ret < SMESH_Hypothesis::HYP_CONCURRENT && !IsMainShape( aSubShape ) )
|
||||
{
|
||||
SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
|
||||
while ( smIt->more() ) {
|
||||
SMESH_subMesh* sm = smIt->next();
|
||||
if ( sm->IsApplicableHypotesis( anHyp )) {
|
||||
ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
|
||||
if ( sm->IsApplicableHypothesis( anHyp )) {
|
||||
ret2 = sm->CheckConcurrentHypothesis( anHyp->GetType() );
|
||||
if (ret2 > ret) {
|
||||
ret = ret2;
|
||||
break;
|
||||
@ -1169,7 +1169,7 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
|
||||
SMESH_Hypothesis* hyp = static_cast<SMESH_Hypothesis*>(anHyp);
|
||||
|
||||
// check if anHyp can be used to mesh aSubMesh
|
||||
if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp ))
|
||||
if ( !aSubMesh || !aSubMesh->IsApplicableHypothesis( hyp ))
|
||||
return false;
|
||||
|
||||
SMESH_Algo *algo = aSubMesh->GetAlgo();
|
||||
@ -1232,7 +1232,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
|
||||
{
|
||||
const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
|
||||
|
||||
if (( aSubMesh->IsApplicableHypotesis( hyp )) &&
|
||||
if (( aSubMesh->IsApplicableHypothesis( hyp )) &&
|
||||
( algo = aSubMesh->GetAlgo() ) &&
|
||||
( compatibleHypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() )) &&
|
||||
( compatibleHypoKind->IsOk( hyp, aSubShape )))
|
||||
|
@ -512,25 +512,25 @@ bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) cons
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsApplicableHypotesis
|
||||
//function : IsApplicableHypothesis
|
||||
//purpose : check if this sub-mesh can be computed using a hypothesis
|
||||
//=======================================================================
|
||||
|
||||
bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis) const
|
||||
bool SMESH_subMesh::IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis) const
|
||||
{
|
||||
if ( !_father->HasShapeToMesh() && _subShape.ShapeType() == TopAbs_SOLID )
|
||||
return true; // true for the PseudoShape
|
||||
|
||||
return IsApplicableHypotesis( theHypothesis, _subShape.ShapeType() );
|
||||
return IsApplicableHypothesis( theHypothesis, _subShape.ShapeType() );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsApplicableHypotesis
|
||||
//function : IsApplicableHypothesis
|
||||
//purpose : compare shape type and hypothesis type
|
||||
//=======================================================================
|
||||
|
||||
bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis,
|
||||
const TopAbs_ShapeEnum theShapeType)
|
||||
bool SMESH_subMesh::IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis,
|
||||
const TopAbs_ShapeEnum theShapeType)
|
||||
{
|
||||
if ( theHypothesis->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
|
||||
{
|
||||
@ -622,7 +622,7 @@ SMESH_Hypothesis::Hypothesis_Status
|
||||
bool modifiedHyp = (event == MODIF_HYP); // if set to true, force event MODIF_ALGO_STATE
|
||||
SMESH_Algo* algoRequiringCleaning = 0;
|
||||
|
||||
bool isApplicableHyp = IsApplicableHypotesis( anHyp );
|
||||
bool isApplicableHyp = IsApplicableHypothesis( anHyp );
|
||||
|
||||
if (event == ADD_ALGO || event == ADD_FATHER_ALGO)
|
||||
{
|
||||
@ -1072,7 +1072,7 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
|
||||
if ( !theAlgo ) return false;
|
||||
|
||||
// Suppose that theAlgo is applicable to _subShape, do not check it here
|
||||
//if ( !IsApplicableHypotesis( theAlgo )) return false;
|
||||
//if ( !IsApplicableHypothesis( theAlgo )) return false;
|
||||
|
||||
// check only algo that doesn't NeedDiscreteBoundary(): because mesh made
|
||||
// on a sub-shape will be ignored by theAlgo
|
||||
@ -2207,13 +2207,13 @@ const SMESH_Hypothesis* SMESH_subMesh::getSimilarAttached(const TopoDS_Shape&
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : CheckConcurentHypothesis
|
||||
//function : CheckConcurrentHypothesis
|
||||
//purpose : check if there are several applicable hypothesis attached to
|
||||
// ancestors
|
||||
//=======================================================================
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status
|
||||
SMESH_subMesh::CheckConcurentHypothesis (const int theHypType)
|
||||
SMESH_subMesh::CheckConcurrentHypothesis (const int theHypType)
|
||||
{
|
||||
// is there local hypothesis on me?
|
||||
if ( getSimilarAttached( _subShape, 0, theHypType ) )
|
||||
@ -2235,7 +2235,7 @@ SMESH_Hypothesis::Hypothesis_Status
|
||||
aPrevHyp = hyp;
|
||||
}
|
||||
else if ( aPrevWithHyp.ShapeType() == ancestor.ShapeType() && aPrevHyp != hyp )
|
||||
return SMESH_Hypothesis::HYP_CONCURENT;
|
||||
return SMESH_Hypothesis::HYP_CONCURRENT;
|
||||
else
|
||||
return SMESH_Hypothesis::HYP_OK;
|
||||
}
|
||||
|
@ -238,14 +238,14 @@ public:
|
||||
// return true if theHypothesis can be attached to me:
|
||||
// its dimension is checked
|
||||
|
||||
static bool IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis,
|
||||
static bool IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis,
|
||||
const TopAbs_ShapeEnum theShapeType);
|
||||
|
||||
bool IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis) const;
|
||||
bool IsApplicableHypothesis(const SMESH_Hypothesis* theHypothesis) const;
|
||||
// return true if theHypothesis can be used to mesh me:
|
||||
// its shape type is checked
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status CheckConcurentHypothesis (const int theHypType);
|
||||
SMESH_Hypothesis::Hypothesis_Status CheckConcurrentHypothesis (const int theHypType);
|
||||
// check if there are several applicable hypothesis on fathers
|
||||
|
||||
/*!
|
||||
|
@ -1994,7 +1994,7 @@ void SMESHGUI_PrecomputeOp::onPreview()
|
||||
{
|
||||
computeFailed = false;
|
||||
myPreviewDisplayer->SetData( previewRes );
|
||||
// append shape indeces with computed mesh entities
|
||||
// append shape indices with computed mesh entities
|
||||
for ( int i = 0, n = aShapesId->length(); i < n; i++ )
|
||||
myMapShapeId[ aShapesId[ i ] ] = 0;
|
||||
}
|
||||
|
@ -622,7 +622,7 @@ void SMESHGUI_CreatePatternDlg::onSelectionDone()
|
||||
|
||||
//=======================================================================
|
||||
// function : onDeactivate()
|
||||
// purpose : SLOT called when dialog must be deativated
|
||||
// purpose : SLOT called when dialog must be deactivated
|
||||
//=======================================================================
|
||||
void SMESHGUI_CreatePatternDlg::onDeactivate()
|
||||
{
|
||||
|
@ -315,7 +315,7 @@ void SMESHGUI_DeleteGroupDlg::onSelectionDone()
|
||||
|
||||
//=================================================================================
|
||||
// function : onDeactivate()
|
||||
// purpose : SLOT called when dialog must be deativated
|
||||
// purpose : SLOT called when dialog must be deactivated
|
||||
//=================================================================================
|
||||
void SMESHGUI_DeleteGroupDlg::onDeactivate()
|
||||
{
|
||||
|
@ -688,7 +688,7 @@ bool SMESHGUI_DuplicateNodesDlg::isValid()
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLOT called when dialog shoud be deativated.
|
||||
\brief SLOT called when dialog should be deactivated.
|
||||
*/
|
||||
void SMESHGUI_DuplicateNodesDlg::onDeactivate()
|
||||
{
|
||||
|
@ -3073,7 +3073,7 @@ void SMESHGUI_FilterDlg::onHelp()
|
||||
|
||||
//=======================================================================
|
||||
// name : SMESHGUI_FilterDlg::onDeactivate
|
||||
// Purpose : SLOT called when dialog must be deativated
|
||||
// Purpose : SLOT called when dialog must be deactivated
|
||||
//=======================================================================
|
||||
void SMESHGUI_FilterDlg::onDeactivate()
|
||||
{
|
||||
|
@ -517,7 +517,7 @@ void SMESHGUI_FilterLibraryDlg::onHelp()
|
||||
|
||||
//=======================================================================
|
||||
// name : SMESHGUI_FilterLibraryDlg::onDeactivate
|
||||
// Purpose : SLOT called when dialog must be deativated
|
||||
// Purpose : SLOT called when dialog must be deactivated
|
||||
//=======================================================================
|
||||
void SMESHGUI_FilterLibraryDlg::onDeactivate()
|
||||
{
|
||||
@ -602,7 +602,7 @@ QStringList SMESHGUI_FilterLibraryDlg::prepareFilters() const
|
||||
|
||||
//================================================================
|
||||
// Function : onBrowse
|
||||
// Purpose : SLOT. Display "Open file" dialog for chosing library name
|
||||
// Purpose : SLOT. Display "Open file" dialog for choosing library name
|
||||
//================================================================
|
||||
void SMESHGUI_FilterLibraryDlg::onBrowse()
|
||||
{
|
||||
|
@ -1197,7 +1197,7 @@ bool SMESHGUI_GroupDlg::onApply()
|
||||
anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta ); break;
|
||||
break;
|
||||
}
|
||||
// update a visible group accoding to a changed contents
|
||||
// update a visible group according to a changed contents
|
||||
if ( !isConversion && anActor->GetVisibility() )
|
||||
{
|
||||
SMESH::Update( anIO, true );
|
||||
@ -2310,7 +2310,7 @@ void SMESHGUI_GroupDlg::onHelp()
|
||||
|
||||
//=================================================================================
|
||||
// function : SMESHGUI_GroupDlg::onDeactivate
|
||||
// purpose : SLOT called when dialog must be deativated
|
||||
// purpose : SLOT called when dialog must be deactivated
|
||||
//=================================================================================
|
||||
void SMESHGUI_GroupDlg::onDeactivate()
|
||||
{
|
||||
|
@ -134,7 +134,7 @@ SMESHGUI_GroupOnShapeDlg::~SMESHGUI_GroupOnShapeDlg()
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief slot to enable/diable [Apply]
|
||||
* \brief slot to enable/disable [Apply]
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
@ -505,6 +505,6 @@ void SMESHGUI_GroupOnShapeOp::selectionDone()
|
||||
myNodeGeoIDs = goodIds;
|
||||
}
|
||||
|
||||
// enable/diable Apply, which can change at selection
|
||||
// enable/disable Apply, which can change at selection
|
||||
myDlg->updateButtons();
|
||||
}
|
||||
|
@ -482,7 +482,7 @@ void SMESHGUI_GroupOpDlg::setVisible( bool visible )
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLOT called when dialog must be deativated
|
||||
\brief SLOT called when dialog must be deactivated
|
||||
*/
|
||||
void SMESHGUI_GroupOpDlg::onDeactivate()
|
||||
{
|
||||
|
@ -692,7 +692,7 @@ void SMESHGUI_MeshDlg::reset()
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Sets curent tab
|
||||
* \brief Sets current tab
|
||||
*/
|
||||
//================================================================================
|
||||
void SMESHGUI_MeshDlg::setCurrentTab( const int theId )
|
||||
|
@ -122,7 +122,7 @@ static void addMeshItem( QListWidget* theList,
|
||||
|
||||
// =========================================================================================
|
||||
/*!
|
||||
* \brief Clear submesh names and indeces
|
||||
* \brief Clear submesh names and indices
|
||||
*/
|
||||
// =========================================================================================
|
||||
|
||||
@ -134,7 +134,7 @@ void SMESHGUI_MeshOrderBox::Clear()
|
||||
|
||||
// =========================================================================================
|
||||
/*!
|
||||
* \brief Set submesh names and indeces
|
||||
* \brief Set submesh names and indices
|
||||
*/
|
||||
// =========================================================================================
|
||||
|
||||
@ -159,7 +159,7 @@ void SMESHGUI_MeshOrderBox::SetMeshes(const ListListName& theMeshNames,
|
||||
|
||||
// =========================================================================================
|
||||
/*!
|
||||
* \brief cehck that item exists and not a separator
|
||||
* \brief check that item exists and not a separator
|
||||
*/
|
||||
// =========================================================================================
|
||||
|
||||
@ -191,7 +191,7 @@ ListListId SMESHGUI_MeshOrderBox::GetMeshIds() const
|
||||
|
||||
// =========================================================================================
|
||||
/*!
|
||||
* \brief Returns result (ordered by user) mesh indeces
|
||||
* \brief Returns result (ordered by user) mesh indices
|
||||
*/
|
||||
// =========================================================================================
|
||||
|
||||
|
@ -57,7 +57,7 @@ class SMESHGUI_EXPORT SMESHGUI_MeshOrderBox : public QGroupBox
|
||||
//! Clear mesh box
|
||||
void Clear();
|
||||
|
||||
//! Set mesh (submesh) names and indeces
|
||||
//! Set mesh (submesh) names and indices
|
||||
void SetMeshes(const ListListName& theMeshNames,
|
||||
const ListListId& theMeshIds);
|
||||
|
||||
@ -66,7 +66,7 @@ class SMESHGUI_EXPORT SMESHGUI_MeshOrderBox : public QGroupBox
|
||||
|
||||
//! Returns result (ordered by user) mesh names
|
||||
ListListId GetMeshIds() const;
|
||||
//! Returns result (ordered by user) mesh indeces
|
||||
//! Returns result (ordered by user) mesh indices
|
||||
ListListName GetMeshNames() const;
|
||||
|
||||
private slots:
|
||||
|
@ -120,7 +120,7 @@ void SMESHGUI_MeshOrderOp::initDialog()
|
||||
if ( !myMgr->GetMeshOrder() ) {
|
||||
SUIT_MessageBox::information(desktop(),
|
||||
tr("SMESH_INFORMATION"),
|
||||
tr("SMESH_NO_CONCURENT_MESH"));
|
||||
tr("SMESH_NO_CONCURRENT_MESH"));
|
||||
|
||||
onCancel();
|
||||
return;
|
||||
@ -199,7 +199,7 @@ void SMESHGUI_MeshOrderMgr::SetMesh(SMESH::SMESH_Mesh_var& theMesh)
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Check for concurents between submesh objects
|
||||
* \brief Check for concurrents between submesh objects
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
@ -211,7 +211,7 @@ bool SMESHGUI_MeshOrderMgr::GetMeshOrder()
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Check for concurents between submesh objects
|
||||
* \brief Check for concurrents between submesh objects
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
@ -300,8 +300,8 @@ bool SMESHGUI_MeshOrderMgr::SetMeshOrder( const ListListId& theListListIds )
|
||||
}
|
||||
}
|
||||
|
||||
// is it enought to set modifid attribute on root mesh objects only?
|
||||
// it is seems that modifaction flag will be set on child submeshes
|
||||
// is it enough to set modified attribute on root mesh objects only?
|
||||
// it is seems that modifcation flag will be set on child submeshes
|
||||
// automatically (see SMESH::ModifiedMesh for details)
|
||||
SMESH::ModifiedMesh( aMeshSObj, false, false );
|
||||
|
||||
|
@ -45,9 +45,9 @@ public:
|
||||
virtual ~SMESHGUI_MeshOrderMgr();
|
||||
//! Set root mesh object
|
||||
void SetMesh( SMESH::SMESH_Mesh_var& theMesh );
|
||||
//! Check for concurents between submesh objects
|
||||
//! Check for concurrents between submesh objects
|
||||
bool GetMeshOrder();
|
||||
//! Check for concurents between submesh objects
|
||||
//! Check for concurrents between submesh objects
|
||||
bool GetMeshOrder( ListListId& theIds );
|
||||
//! Store submesh priority order
|
||||
bool SetMeshOrder();
|
||||
|
@ -723,7 +723,7 @@ void SMESHGUI_MeshPatternDlg::resetSelInput()
|
||||
|
||||
//=======================================================================
|
||||
// name : SMESHGUI_MeshPatternDlg::onDeactivate
|
||||
// Purpose : SLOT called when dialog must be deativated
|
||||
// Purpose : SLOT called when dialog must be deactivated
|
||||
//=======================================================================
|
||||
void SMESHGUI_MeshPatternDlg::onDeactivate()
|
||||
{
|
||||
|
@ -600,7 +600,7 @@ void SMESHGUI_MultiEditDlg::onSelectionDone()
|
||||
|
||||
//=======================================================================
|
||||
// name : SMESHGUI_MultiEditDlg::onDeactivate
|
||||
// Purpose : SLOT called when dialog must be deativated
|
||||
// Purpose : SLOT called when dialog must be deactivated
|
||||
//=======================================================================
|
||||
void SMESHGUI_MultiEditDlg::onDeactivate()
|
||||
{
|
||||
@ -1628,7 +1628,7 @@ SMESHGUI_SplitVolumesDlg::SMESHGUI_SplitVolumesDlg(SMESHGUI* theModule)
|
||||
gb->setTitle( tr("TARGET_ELEM_TYPE"));
|
||||
}
|
||||
|
||||
myToAllChk->setChecked( true ); //aplly to the whole mesh by default
|
||||
myToAllChk->setChecked( true ); //apply to the whole mesh by default
|
||||
|
||||
bool hasHexa = true;//myMesh->_is_nil() ? false : myMesh->NbHexas();
|
||||
if ( hasHexa )
|
||||
|
@ -538,7 +538,7 @@ void SMESHGUI_OffsetDlg::onTextChange (const QString& theNewText)
|
||||
buttonOk->setEnabled(false);
|
||||
buttonApply->setEnabled(false);
|
||||
|
||||
// hilight entered elements
|
||||
// highlight entered elements
|
||||
SMDS_Mesh* aMesh = 0;
|
||||
if (myActor)
|
||||
aMesh = myActor->GetObject()->GetMesh();
|
||||
|
@ -20,7 +20,7 @@
|
||||
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
//
|
||||
|
||||
// SMESH SMDS : implementaion of Salome mesh data structure
|
||||
// SMESH SMDS : implementation of Salome mesh data structure
|
||||
// File : SMESHGUI_Operation.h
|
||||
// Author : Sergey LITONIN, Open CASCADE S.A.S.
|
||||
//
|
||||
|
@ -247,15 +247,13 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply()
|
||||
|
||||
} catch (const SALOME::SALOME_Exception& S_ex) {
|
||||
SalomeApp_Tools::QtCatchCorbaException(S_ex);
|
||||
myEditCurrentArgument->clear();
|
||||
} catch (...){
|
||||
myEditCurrentArgument->clear();
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
myEditCurrentArgument->clear();
|
||||
if (aResult) {
|
||||
myEditCurrentArgument->clear();
|
||||
mySelector->ClearIndex();
|
||||
SMESH::UpdateView();
|
||||
SMESH::UpdateView( /*withChildrenOfSelected=*/true );
|
||||
SMESHGUI::Modified();
|
||||
}
|
||||
}
|
||||
|
@ -439,7 +439,7 @@ void SMESHGUI_SingleEditDlg::onSelectionDone()
|
||||
|
||||
//=======================================================================
|
||||
// name : onDeactivate()
|
||||
// Purpose : SLOT called when dialog must be deativated
|
||||
// Purpose : SLOT called when dialog must be deactivated
|
||||
//=======================================================================
|
||||
void SMESHGUI_SingleEditDlg::onDeactivate()
|
||||
{
|
||||
|
@ -191,7 +191,7 @@ void SMESHGUI_TransparencyDlg::ClickOnHelp()
|
||||
//=================================================================================
|
||||
// function : SetTransparency()
|
||||
// purpose : Called when value of slider change
|
||||
// : or the first time as initilisation
|
||||
// : or the first time as initialisation
|
||||
//=================================================================================
|
||||
void SMESHGUI_TransparencyDlg::SetTransparency()
|
||||
{
|
||||
|
@ -794,12 +794,13 @@ namespace SMESH
|
||||
return false;
|
||||
}
|
||||
|
||||
void UpdateView(){
|
||||
void UpdateView( bool withChildrenOfSelected )
|
||||
{
|
||||
if ( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()) {
|
||||
LightApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
|
||||
SALOME_ListIO selected; mgr->selectedObjects( selected );
|
||||
|
||||
if( selected.Extent() == 0){
|
||||
if ( selected.Extent() == 0 ) {
|
||||
vtkRenderer* aRenderer = aWnd->getRenderer();
|
||||
VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
|
||||
vtkActorCollection *aCollection = aCopy.GetActors();
|
||||
@ -811,12 +812,36 @@ namespace SMESH
|
||||
break; // avoid multiple warinings if visu failed
|
||||
}
|
||||
}
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
SALOME_ListIteratorOfListIO anIter( selected );
|
||||
for( ; anIter.More(); anIter.Next()){
|
||||
for( ; anIter.More(); anIter.Next())
|
||||
{
|
||||
Handle(SALOME_InteractiveObject) anIO = anIter.Value();
|
||||
if ( !Update(anIO,true) )
|
||||
if ( !Update( anIO, true ))
|
||||
break; // avoid multiple warinings if visu failed
|
||||
|
||||
if ( withChildrenOfSelected ) // update all visible children
|
||||
{
|
||||
QString aFatherID = anIO->getEntry();
|
||||
vtkRenderer* aRenderer = aWnd->getRenderer();
|
||||
VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
|
||||
vtkActorCollection *aCollection = aCopy.GetActors();
|
||||
aCollection->InitTraversal();
|
||||
while ( vtkActor *anAct = aCollection->GetNextActor() ) {
|
||||
if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct )) {
|
||||
if ( anActor->hasIO() && anActor->GetVisibility() )
|
||||
{
|
||||
QString aChildID = anActor->getIO()->getEntry();
|
||||
if ( aChildID.size() > aFatherID.size() &&
|
||||
aChildID.startsWith( aFatherID ))
|
||||
if ( ! Update( anActor->getIO(), true ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RepaintCurrentView();
|
||||
|
@ -120,7 +120,7 @@ SMESHGUI_EXPORT
|
||||
bool UpdateView( EDisplaing, const char* = "" );
|
||||
|
||||
SMESHGUI_EXPORT
|
||||
void UpdateView();
|
||||
void UpdateView( bool withChildrenOfSelected = false );
|
||||
|
||||
SMESHGUI_EXPORT
|
||||
bool UpdateNulData( const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay);
|
||||
|
@ -85,7 +85,7 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
|
||||
myPluginName = atts.value("name");
|
||||
myServerLib = atts.value("server-lib");
|
||||
myClientLib = atts.value("gui-lib");
|
||||
/* It's Need to tranlate lib name for WIN32 or X platform
|
||||
/* It's Need to translate lib name for WIN32 or X platform
|
||||
* (only client lib, because server lib translates in SMESH_Gen_i::createHypothesis
|
||||
* for normal work of *.py files )
|
||||
*/
|
||||
|
@ -7107,7 +7107,7 @@ It is impossible to read point coordinates from file</translation>
|
||||
<name>SMESHGUI_MeshOrderOp</name>
|
||||
<message>
|
||||
<source>SMESH_NO_CONCURENT_MESH</source>
|
||||
<translation>No concurent sub-meshes detected</translation>
|
||||
<translation>No concurrent sub-meshes detected</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -268,14 +268,14 @@ int SMESH_Tree<BND_BOX,NB_CHILDREN>::getHeight(const bool full) const
|
||||
if ( isLeaf() )
|
||||
return 1;
|
||||
|
||||
int heigth = 0;
|
||||
int height = 0;
|
||||
for (int i = 0; i<NB_CHILDREN; i++)
|
||||
{
|
||||
int h = myChildren[i]->getHeight( false );
|
||||
if ( h > heigth )
|
||||
heigth = h;
|
||||
if ( h > height )
|
||||
height = h;
|
||||
}
|
||||
return heigth + 1;
|
||||
return height + 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -5056,7 +5056,7 @@ bool _pyStringFamily::Add( const char* str )
|
||||
|
||||
_strings.erase( itLess, ++itMore );
|
||||
}
|
||||
else // to few string to make a family fot them
|
||||
else // too few string to make a family for them
|
||||
{
|
||||
_strings.insert( itStr, str );
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
|
||||
switch (theStatus) {
|
||||
RETURNCASE( HYP_OK );
|
||||
RETURNCASE( HYP_MISSING );
|
||||
RETURNCASE( HYP_CONCURENT );
|
||||
RETURNCASE( HYP_CONCURRENT );
|
||||
RETURNCASE( HYP_BAD_PARAMETER );
|
||||
RETURNCASE( HYP_HIDDEN_ALGO );
|
||||
RETURNCASE( HYP_HIDING_ALGO );
|
||||
|
@ -87,8 +87,8 @@ ret = mesh.Compute()
|
||||
print ret
|
||||
if ret != 0:
|
||||
log = mesh.GetLog(0) # no erase trace
|
||||
for linelog in log:
|
||||
print linelog
|
||||
# for linelog in log:
|
||||
# print linelog
|
||||
print "Information about the MeshcompShel:"
|
||||
print "Number of nodes : ", mesh.NbNodes()
|
||||
print "Number of edges : ", mesh.NbEdges()
|
||||
|
@ -231,7 +231,7 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
|
||||
reason = hypType + " of the same dimension is already assigned to this shape"
|
||||
elif status == HYP_BAD_DIM :
|
||||
reason = hypType + " mismatches the shape"
|
||||
elif status == HYP_CONCURENT :
|
||||
elif status == HYP_CONCURRENT :
|
||||
reason = "there are concurrent hypotheses on sub-shapes"
|
||||
elif status == HYP_BAD_SUBSHAPE :
|
||||
reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
|
||||
|
@ -207,7 +207,7 @@ public:
|
||||
double constValue = 0) const;
|
||||
/*!
|
||||
* \brief Return nodes in the order they encounter while walking along
|
||||
* the while side or a specified EDGE. For a closed side, the 1st point repeats at end.
|
||||
* the whole side or a specified EDGE. For a closed side, the 1st point repeats at end.
|
||||
* \param iE - index of the EDGE. Default is "all EDGEs".
|
||||
*/
|
||||
std::vector<const SMDS_MeshNode*> GetOrderedNodes( int iE = ALL_EDGES ) const;
|
||||
|
@ -65,10 +65,11 @@
|
||||
#include "Utils_ExceptHandlers.hxx"
|
||||
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/intrusive/circular_list_algorithms.hpp>
|
||||
|
||||
typedef NCollection_Array2<const SMDS_MeshNode*> StdMeshers_Array2OfNode;
|
||||
|
||||
typedef gp_XY gp_UV;
|
||||
typedef gp_XY gp_UV;
|
||||
typedef SMESH_Comment TComm;
|
||||
|
||||
using namespace std;
|
||||
@ -1020,30 +1021,454 @@ bool StdMeshers_Quadrangle_2D::IsApplicable( const TopoDS_Shape & aShape, bool t
|
||||
return ( toCheckAll && nbFoundFaces != 0 );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return true if only two given edges meat at their common vertex
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool twoEdgesMeatAtVertex(const TopoDS_Edge& e1,
|
||||
const TopoDS_Edge& e2,
|
||||
SMESH_Mesh & mesh)
|
||||
{
|
||||
TopoDS_Vertex v;
|
||||
if (!TopExp::CommonVertex(e1, e2, v))
|
||||
return false;
|
||||
TopTools_ListIteratorOfListOfShape ancestIt(mesh.GetAncestors(v));
|
||||
for (; ancestIt.More() ; ancestIt.Next())
|
||||
if (ancestIt.Value().ShapeType() == TopAbs_EDGE)
|
||||
if (!e1.IsSame(ancestIt.Value()) && !e2.IsSame(ancestIt.Value()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief EDGE of a FACE
|
||||
*/
|
||||
struct Edge
|
||||
{
|
||||
TopoDS_Edge myEdge;
|
||||
TopoDS_Vertex my1stVertex;
|
||||
int myIndex;
|
||||
double myAngle; // angle at my1stVertex
|
||||
int myNbSegments; // discretization
|
||||
Edge* myPrev; // preceding EDGE
|
||||
Edge* myNext; // next EDGE
|
||||
|
||||
// traits used by boost::intrusive::circular_list_algorithms
|
||||
typedef Edge node;
|
||||
typedef Edge * node_ptr;
|
||||
typedef const Edge * const_node_ptr;
|
||||
static node_ptr get_next(const_node_ptr n) { return n->myNext; }
|
||||
static void set_next(node_ptr n, node_ptr next) { n->myNext = next; }
|
||||
static node_ptr get_previous(const_node_ptr n) { return n->myPrev; }
|
||||
static void set_previous(node_ptr n, node_ptr prev){ n->myPrev = prev; }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief Four sides of a quadrangle evaluating its quality
|
||||
*/
|
||||
struct QuadQuality
|
||||
{
|
||||
typedef std::set< QuadQuality, QuadQuality > set;
|
||||
|
||||
Edge* myCornerE[4];
|
||||
int myNbSeg [4];
|
||||
|
||||
// quality criteria to minimize
|
||||
int myOppDiff;
|
||||
double myQuartDiff;
|
||||
double mySumAngle;
|
||||
|
||||
// Compute quality criateria and add self to the set of variants
|
||||
//
|
||||
void AddSelf( QuadQuality::set& theVariants )
|
||||
{
|
||||
if ( myCornerE[2] == myCornerE[1] || // exclude invalid variants
|
||||
myCornerE[2] == myCornerE[3] ||
|
||||
myCornerE[0] == myCornerE[3] )
|
||||
return;
|
||||
|
||||
// count nb segments between corners
|
||||
mySumAngle = 0;
|
||||
double totNbSeg = 0;
|
||||
for ( int i1 = 3, i2 = 0; i2 < 4; i1 = i2++ )
|
||||
{
|
||||
myNbSeg[ i1 ] = 0;
|
||||
for ( Edge* e = myCornerE[ i1 ]; e != myCornerE[ i2 ]; e = e->myNext )
|
||||
myNbSeg[ i1 ] += e->myNbSegments;
|
||||
mySumAngle -= myCornerE[ i1 ]->myAngle / M_PI; // [-1,1]
|
||||
totNbSeg += myNbSeg[ i1 ];
|
||||
}
|
||||
|
||||
myOppDiff = ( Abs( myNbSeg[0] - myNbSeg[2] ) +
|
||||
Abs( myNbSeg[1] - myNbSeg[3] ));
|
||||
|
||||
double nbSideIdeal = totNbSeg / 4.;
|
||||
myQuartDiff = -( Min( Min( myNbSeg[0], myNbSeg[1] ),
|
||||
Min( myNbSeg[2], myNbSeg[3] )) / nbSideIdeal );
|
||||
|
||||
theVariants.insert( *this );
|
||||
|
||||
#ifndef _DEBUG_
|
||||
if ( theVariants.size() > 1 ) // erase a worse variant
|
||||
theVariants.erase( ++theVariants.begin() );
|
||||
#endif
|
||||
};
|
||||
|
||||
// first criterion - equality of nbSeg of opposite sides
|
||||
int crit1() const { return myOppDiff; }
|
||||
|
||||
// second criterion - equality of nbSeg of adjacent sides and sharpness of angles
|
||||
double crit2() const { return myQuartDiff + mySumAngle; }
|
||||
|
||||
bool operator () ( const QuadQuality& q1, const QuadQuality& q2) const
|
||||
{
|
||||
if ( q1.crit1() < q2.crit1() )
|
||||
return true;
|
||||
if ( q1.crit1() > q2.crit1() )
|
||||
return false;
|
||||
return q1.crit2() < q2.crit2();
|
||||
}
|
||||
};
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Unite EDGEs to get a required number of sides
|
||||
* \param [in] theNbCorners - the required number of sides
|
||||
* \param [in] theConsiderMesh - to considered only meshed VERTEXes
|
||||
* \param [in] theFaceSide - the FACE EDGEs
|
||||
* \param [out] theVertices - the found corner vertices
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void uniteEdges( const int theNbCorners,
|
||||
const bool theConsiderMesh,
|
||||
const StdMeshers_FaceSide& theFaceSide,
|
||||
const TopoDS_Shape& theBaseVertex,
|
||||
std::vector<TopoDS_Vertex>& theVertices,
|
||||
bool& theHaveConcaveVertices)
|
||||
{
|
||||
// form a circular list of EDGEs
|
||||
std::vector< Edge > edges( theFaceSide.NbEdges() );
|
||||
boost::intrusive::circular_list_algorithms< Edge > circularList;
|
||||
circularList.init_header( &edges[0] );
|
||||
edges[0].myEdge = theFaceSide.Edge( 0 );
|
||||
edges[0].myIndex = 0;
|
||||
edges[0].myNbSegments = 0;
|
||||
for ( int i = 1; i < theFaceSide.NbEdges(); ++i )
|
||||
{
|
||||
edges[ i ].myEdge = theFaceSide.Edge( i );
|
||||
edges[ i ].myIndex = i;
|
||||
edges[ i ].myNbSegments = 0;
|
||||
circularList.link_after( &edges[ i-1 ], &edges[ i ] );
|
||||
}
|
||||
// remove degenerated edges
|
||||
int nbEdges = edges.size();
|
||||
Edge* edge0 = &edges[0];
|
||||
for ( size_t i = 0; i < edges.size(); ++i )
|
||||
if ( SMESH_Algo::isDegenerated( edges[i].myEdge ))
|
||||
{
|
||||
edge0 = circularList.unlink( &edges[i] );
|
||||
--nbEdges;
|
||||
}
|
||||
|
||||
// sort edges by angle
|
||||
std::multimap< double, Edge* > edgeByAngle;
|
||||
int i, iBase = -1, nbConvexAngles = 0, nbSharpAngles = 0;
|
||||
const double angTol = 5. / 180 * M_PI;
|
||||
const double sharpAngle = 0.5 * M_PI - angTol;
|
||||
Edge* e = edge0;
|
||||
for ( i = 0; i < nbEdges; ++i, e = e->myNext )
|
||||
{
|
||||
e->my1stVertex = SMESH_MesherHelper::IthVertex( 0, e->myEdge );
|
||||
if ( e->my1stVertex.IsSame( theBaseVertex ))
|
||||
iBase = e->myIndex;
|
||||
|
||||
e->myAngle = -2 * M_PI;
|
||||
if ( !theConsiderMesh || theFaceSide.VertexNode( e->myIndex ))
|
||||
{
|
||||
e->myAngle = SMESH_MesherHelper::GetAngle( e->myPrev->myEdge, e->myEdge,
|
||||
theFaceSide.Face(), e->my1stVertex );
|
||||
if ( e->myAngle > 2 * M_PI ) // GetAngle() failed
|
||||
e->myAngle *= -1.;
|
||||
}
|
||||
edgeByAngle.insert( std::make_pair( e->myAngle, e ));
|
||||
nbConvexAngles += ( e->myAngle > angTol );
|
||||
nbSharpAngles += ( e->myAngle > sharpAngle );
|
||||
}
|
||||
|
||||
theHaveConcaveVertices = ( nbConvexAngles < nbEdges );
|
||||
|
||||
if ((int) theVertices.size() == theNbCorners )
|
||||
return;
|
||||
|
||||
theVertices.clear();
|
||||
|
||||
if ( !theConsiderMesh || theNbCorners < 4 ||
|
||||
nbConvexAngles <= theNbCorners ||
|
||||
nbSharpAngles == theNbCorners )
|
||||
{
|
||||
if ( nbEdges == theNbCorners ) // return all vertices
|
||||
{
|
||||
for ( e = edge0; (int) theVertices.size() < theNbCorners; e = e->myNext )
|
||||
theVertices.push_back( e->my1stVertex );
|
||||
return;
|
||||
}
|
||||
|
||||
// return corners with maximal angles
|
||||
|
||||
std::set< int > cornerIndices;
|
||||
if ( iBase != -1 )
|
||||
cornerIndices.insert( iBase );
|
||||
|
||||
std::multimap< double, Edge* >::reverse_iterator a2e = edgeByAngle.rbegin();
|
||||
for (; (int) cornerIndices.size() < theNbCorners; ++a2e )
|
||||
cornerIndices.insert( a2e->second->myIndex );
|
||||
|
||||
std::set< int >::iterator i = cornerIndices.begin();
|
||||
for ( ; i != cornerIndices.end(); ++i )
|
||||
theVertices.push_back( edges[ *i ].my1stVertex );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// get nb of segments
|
||||
int totNbSeg = 0; // tatal nb segments
|
||||
std::vector<const SMDS_MeshNode*> nodes;
|
||||
for ( i = 0, e = edge0; i < nbEdges; ++i, e = e->myNext )
|
||||
{
|
||||
nodes.clear();
|
||||
theFaceSide.GetEdgeNodes( e->myIndex, nodes, /*addVertex=*/true, true );
|
||||
if ( nodes.size() == 2 && nodes[0] == nodes[1] ) // all nodes merged
|
||||
{
|
||||
e->myAngle = -1; // to remove
|
||||
}
|
||||
else
|
||||
{
|
||||
e->myNbSegments += nodes.size() - 1;
|
||||
totNbSeg += nodes.size() - 1;
|
||||
}
|
||||
|
||||
// join with the previous edge those edges with concave angles
|
||||
if ( e->myAngle <= 0 )
|
||||
{
|
||||
e->myPrev->myNbSegments += e->myNbSegments;
|
||||
e = circularList.unlink( e )->myPrev;
|
||||
--nbEdges;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( edge0->myNext->myPrev != edge0 ) // edge0 removed, find another edge0
|
||||
for ( size_t i = 0; i < edges.size(); ++i )
|
||||
if ( edges[i].myNext->myPrev == & edges[i] )
|
||||
{
|
||||
edge0 = &edges[i];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// sort different variants by quality
|
||||
|
||||
QuadQuality::set quadVariants;
|
||||
|
||||
// find index of a corner most opposite to corner of edge0
|
||||
int iOpposite0, nbHalf = 0;
|
||||
for ( e = edge0; nbHalf <= totNbSeg / 2; e = e->myNext )
|
||||
nbHalf += e->myNbSegments;
|
||||
iOpposite0 = e->myIndex;
|
||||
|
||||
// compose different variants of quadrangles
|
||||
QuadQuality quad;
|
||||
for ( ; edge0->myIndex != iOpposite0; edge0 = edge0->myNext )
|
||||
{
|
||||
quad.myCornerE[ 0 ] = edge0;
|
||||
|
||||
// find opposite corner 2
|
||||
for ( nbHalf = 0, e = edge0; nbHalf < totNbSeg / 2; e = e->myNext )
|
||||
nbHalf += e->myNbSegments;
|
||||
if ( e == edge0->myNext ) // no space for corner 1
|
||||
e = e->myNext;
|
||||
quad.myCornerE[ 2 ] = e;
|
||||
|
||||
bool moreVariants2 = ( totNbSeg % 2 || nbHalf != totNbSeg / 2 );
|
||||
|
||||
// enumerate different variants of corners 1 and 3
|
||||
for ( Edge* e1 = edge0->myNext; e1 != quad.myCornerE[ 2 ]; e1 = e1->myNext )
|
||||
{
|
||||
quad.myCornerE[ 1 ] = e1;
|
||||
|
||||
// find opposite corner 3
|
||||
for ( nbHalf = 0, e = e1; nbHalf < totNbSeg / 2; e = e->myNext )
|
||||
nbHalf += e->myNbSegments;
|
||||
if ( e == quad.myCornerE[ 2 ] )
|
||||
e = e->myNext;
|
||||
quad.myCornerE[ 3 ] = e;
|
||||
|
||||
bool moreVariants3 = ( totNbSeg % 2 || nbHalf != totNbSeg / 2 );
|
||||
|
||||
quad.AddSelf( quadVariants );
|
||||
|
||||
// another variants
|
||||
if ( moreVariants2 )
|
||||
{
|
||||
quad.myCornerE[ 2 ] = quad.myCornerE[ 2 ]->myPrev;
|
||||
quad.AddSelf( quadVariants );
|
||||
quad.myCornerE[ 2 ] = quad.myCornerE[ 2 ]->myNext;
|
||||
}
|
||||
if ( moreVariants3 )
|
||||
{
|
||||
quad.myCornerE[ 3 ] = quad.myCornerE[ 3 ]->myPrev;
|
||||
quad.AddSelf( quadVariants );
|
||||
|
||||
if ( moreVariants2 )
|
||||
{
|
||||
quad.myCornerE[ 2 ] = quad.myCornerE[ 2 ]->myPrev;
|
||||
quad.AddSelf( quadVariants );
|
||||
quad.myCornerE[ 2 ] = quad.myCornerE[ 2 ]->myNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QuadQuality& bestQuad = *quadVariants.begin();
|
||||
theVertices.resize( 4 );
|
||||
theVertices[ 0 ] = bestQuad.myCornerE[ 0 ]->my1stVertex;
|
||||
theVertices[ 1 ] = bestQuad.myCornerE[ 1 ]->my1stVertex;
|
||||
theVertices[ 2 ] = bestQuad.myCornerE[ 2 ]->my1stVertex;
|
||||
theVertices[ 3 ] = bestQuad.myCornerE[ 3 ]->my1stVertex;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return true if only two given edges meat at their common vertex
|
||||
* \brief Finds vertices at the most sharp face corners
|
||||
* \param [in] theFace - the FACE
|
||||
* \param [in,out] theWire - the ordered edges of the face. It can be modified to
|
||||
* have the first VERTEX of the first EDGE in \a vertices
|
||||
* \param [out] theVertices - the found corner vertices in the order corresponding to
|
||||
* the order of EDGEs in \a theWire
|
||||
* \param [out] theNbDegenEdges - nb of degenerated EDGEs in theFace
|
||||
* \param [in] theConsiderMesh - if \c true, only meshed VERTEXes are considered
|
||||
* as possible corners
|
||||
* \return int - number of quad sides found: 0, 3 or 4
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
static bool twoEdgesMeatAtVertex(const TopoDS_Edge& e1,
|
||||
const TopoDS_Edge& e2,
|
||||
SMESH_Mesh & mesh)
|
||||
int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
||||
SMESH_Mesh & theMesh,
|
||||
std::list<TopoDS_Edge>& theWire,
|
||||
std::vector<TopoDS_Vertex>& theVertices,
|
||||
int & theNbDegenEdges,
|
||||
const bool theConsiderMesh)
|
||||
{
|
||||
TopoDS_Vertex v;
|
||||
if (!TopExp::CommonVertex(e1, e2, v))
|
||||
return false;
|
||||
TopTools_ListIteratorOfListOfShape ancestIt(mesh.GetAncestors(v));
|
||||
for (; ancestIt.More() ; ancestIt.Next())
|
||||
if (ancestIt.Value().ShapeType() == TopAbs_EDGE)
|
||||
if (!e1.IsSame(ancestIt.Value()) && !e2.IsSame(ancestIt.Value()))
|
||||
return false;
|
||||
return true;
|
||||
theNbDegenEdges = 0;
|
||||
|
||||
SMESH_MesherHelper helper( theMesh );
|
||||
if ( myHelper )
|
||||
helper.CopySubShapeInfo( *myHelper );
|
||||
|
||||
StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh,
|
||||
/*isFwd=*/true, /*skipMedium=*/true, &helper );
|
||||
|
||||
// count degenerated EDGEs and possible corner VERTEXes
|
||||
for ( int iE = 0; iE < faceSide.NbEdges(); ++iE )
|
||||
{
|
||||
if ( SMESH_Algo::isDegenerated( faceSide.Edge( iE )))
|
||||
++theNbDegenEdges;
|
||||
else if ( !theConsiderMesh || faceSide.VertexNode( iE ))
|
||||
theVertices.push_back( faceSide.FirstVertex( iE ));
|
||||
}
|
||||
|
||||
// find out required nb of corners (3 or 4)
|
||||
int nbCorners = 4;
|
||||
TopoDS_Shape triaVertex = helper.GetMeshDS()->IndexToShape( myTriaVertexID );
|
||||
if ( !triaVertex.IsNull() &&
|
||||
triaVertex.ShapeType() == TopAbs_VERTEX &&
|
||||
helper.IsSubShape( triaVertex, theFace ) &&
|
||||
theVertices.size() != 4 )
|
||||
nbCorners = 3;
|
||||
else
|
||||
triaVertex.Nullify();
|
||||
|
||||
// check nb of available EDGEs
|
||||
if ( faceSide.NbEdges() < nbCorners )
|
||||
return error(COMPERR_BAD_SHAPE,
|
||||
TComm("Face must have 4 sides but not ") << faceSide.NbEdges() );
|
||||
|
||||
if ( theConsiderMesh )
|
||||
{
|
||||
const int nbSegments = Max( faceSide.NbPoints()-1, faceSide.NbSegments() );
|
||||
if ( nbSegments < nbCorners )
|
||||
return error(COMPERR_BAD_INPUT_MESH, TComm("Too few boundary nodes: ") << nbSegments);
|
||||
}
|
||||
|
||||
if ( nbCorners == 3 )
|
||||
{
|
||||
if ( theVertices.size() < 3 )
|
||||
return error(COMPERR_BAD_SHAPE,
|
||||
TComm("Face must have 3 meshed sides but not ") << theVertices.size() );
|
||||
}
|
||||
else // triaVertex not defined or invalid
|
||||
{
|
||||
if ( theVertices.size() == 3 && theNbDegenEdges == 0 )
|
||||
{
|
||||
if ( myTriaVertexID < 1 )
|
||||
return error(COMPERR_BAD_PARMETERS,
|
||||
"No Base vertex provided for a trilateral geometrical face");
|
||||
|
||||
TComm comment("Invalid Base vertex: ");
|
||||
comment << myTriaVertexID << ", which is not in [ ";
|
||||
comment << helper.GetMeshDS()->ShapeToIndex( faceSide.FirstVertex(0) ) << ", ";
|
||||
comment << helper.GetMeshDS()->ShapeToIndex( faceSide.FirstVertex(1) ) << ", ";
|
||||
comment << helper.GetMeshDS()->ShapeToIndex( faceSide.FirstVertex(2) ) << " ]";
|
||||
return error(COMPERR_BAD_PARMETERS, comment );
|
||||
}
|
||||
if ( theVertices.size() + theNbDegenEdges < 4 )
|
||||
return error(COMPERR_BAD_SHAPE,
|
||||
TComm("Face must have 4 meshed sides but not ") << theVertices.size() );
|
||||
}
|
||||
|
||||
myCheckOri = false;
|
||||
if ( theVertices.size() > 3 )
|
||||
{
|
||||
uniteEdges( nbCorners, theConsiderMesh, faceSide, triaVertex, theVertices, myCheckOri );
|
||||
}
|
||||
|
||||
if ( nbCorners == 3 && !triaVertex.IsSame( theVertices[0] ))
|
||||
{
|
||||
// make theVertices begin from triaVertex
|
||||
for ( size_t i = 0; i < theVertices.size(); ++i )
|
||||
if ( triaVertex.IsSame( theVertices[i] ))
|
||||
{
|
||||
theVertices.erase( theVertices.begin(), theVertices.begin() + i );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
theVertices.push_back( theVertices[i] );
|
||||
}
|
||||
}
|
||||
|
||||
// make theWire begin from the 1st corner vertex
|
||||
while ( !theVertices[0].IsSame( helper.IthVertex( 0, theWire.front() )) ||
|
||||
SMESH_Algo::isDegenerated( theWire.front() ))
|
||||
theWire.splice( theWire.end(), theWire, theWire.begin() );
|
||||
|
||||
return nbCorners;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
*
|
||||
*
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
@ -4253,388 +4678,6 @@ bool StdMeshers_Quadrangle_2D::check()
|
||||
return isOK;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Finds vertices at the most sharp face corners
|
||||
* \param [in] theFace - the FACE
|
||||
* \param [in,out] theWire - the ordered edges of the face. It can be modified to
|
||||
* have the first VERTEX of the first EDGE in \a vertices
|
||||
* \param [out] theVertices - the found corner vertices in the order corresponding to
|
||||
* the order of EDGEs in \a theWire
|
||||
* \param [out] theNbDegenEdges - nb of degenerated EDGEs in theFace
|
||||
* \param [in] theConsiderMesh - if \c true, only meshed VERTEXes are considered
|
||||
* as possible corners
|
||||
* \return int - number of quad sides found: 0, 3 or 4
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
||||
SMESH_Mesh & theMesh,
|
||||
std::list<TopoDS_Edge>& theWire,
|
||||
std::vector<TopoDS_Vertex>& theVertices,
|
||||
int & theNbDegenEdges,
|
||||
const bool theConsiderMesh)
|
||||
{
|
||||
theNbDegenEdges = 0;
|
||||
|
||||
SMESH_MesherHelper helper( theMesh );
|
||||
if ( myHelper )
|
||||
helper.CopySubShapeInfo( *myHelper );
|
||||
StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh,
|
||||
/*isFwd=*/true, /*skipMedium=*/true, &helper );
|
||||
|
||||
// sort theVertices by angle
|
||||
multimap<double, TopoDS_Vertex> vertexByAngle;
|
||||
TopTools_DataMapOfShapeReal angleByVertex;
|
||||
TopoDS_Edge prevE = theWire.back();
|
||||
if ( SMESH_Algo::isDegenerated( prevE ))
|
||||
{
|
||||
list<TopoDS_Edge>::reverse_iterator edge = ++theWire.rbegin();
|
||||
while ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/)
|
||||
++edge;
|
||||
if ( edge == theWire.rend() )
|
||||
return false;
|
||||
prevE = *edge;
|
||||
}
|
||||
list<TopoDS_Edge>::iterator edge = theWire.begin();
|
||||
for ( int iE = 0; edge != theWire.end(); ++edge, ++iE )
|
||||
{
|
||||
if ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/)
|
||||
{
|
||||
++theNbDegenEdges;
|
||||
continue;
|
||||
}
|
||||
if ( !theConsiderMesh || faceSide.VertexNode( iE ))
|
||||
{
|
||||
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
|
||||
double angle = helper.GetAngle( prevE, *edge, theFace, v );
|
||||
vertexByAngle.insert( make_pair( angle, v ));
|
||||
angleByVertex.Bind( v, angle );
|
||||
}
|
||||
prevE = *edge;
|
||||
}
|
||||
|
||||
// find out required nb of corners (3 or 4)
|
||||
int nbCorners = 4;
|
||||
TopoDS_Shape triaVertex = helper.GetMeshDS()->IndexToShape( myTriaVertexID );
|
||||
if ( !triaVertex.IsNull() &&
|
||||
triaVertex.ShapeType() == TopAbs_VERTEX &&
|
||||
helper.IsSubShape( triaVertex, theFace ) &&
|
||||
( vertexByAngle.size() != 4 || vertexByAngle.begin()->first < 5 * M_PI/180. ))
|
||||
nbCorners = 3;
|
||||
else
|
||||
triaVertex.Nullify();
|
||||
|
||||
// check nb of available corners
|
||||
if ( faceSide.NbEdges() < nbCorners )
|
||||
return error(COMPERR_BAD_SHAPE,
|
||||
TComm("Face must have 4 sides but not ") << faceSide.NbEdges() );
|
||||
|
||||
if ( theConsiderMesh )
|
||||
{
|
||||
const int nbSegments = Max( faceSide.NbPoints()-1, faceSide.NbSegments() );
|
||||
if ( nbSegments < nbCorners )
|
||||
return error(COMPERR_BAD_INPUT_MESH, TComm("Too few boundary nodes: ") << nbSegments);
|
||||
}
|
||||
|
||||
if ( nbCorners == 3 )
|
||||
{
|
||||
if ( vertexByAngle.size() < 3 )
|
||||
return error(COMPERR_BAD_SHAPE,
|
||||
TComm("Face must have 3 sides but not ") << vertexByAngle.size() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( vertexByAngle.size() == 3 && theNbDegenEdges == 0 )
|
||||
{
|
||||
if ( myTriaVertexID < 1 )
|
||||
return error(COMPERR_BAD_PARMETERS,
|
||||
"No Base vertex provided for a trilateral geometrical face");
|
||||
|
||||
TComm comment("Invalid Base vertex: ");
|
||||
comment << myTriaVertexID << " its ID is not among [ ";
|
||||
multimap<double, TopoDS_Vertex>::iterator a2v = vertexByAngle.begin();
|
||||
comment << helper.GetMeshDS()->ShapeToIndex( a2v->second ) << ", "; a2v++;
|
||||
comment << helper.GetMeshDS()->ShapeToIndex( a2v->second ) << ", "; a2v++;
|
||||
comment << helper.GetMeshDS()->ShapeToIndex( a2v->second ) << " ]";
|
||||
return error(COMPERR_BAD_PARMETERS, comment );
|
||||
}
|
||||
if ( vertexByAngle.size() + ( theNbDegenEdges > 0 ) < 4 &&
|
||||
vertexByAngle.size() + theNbDegenEdges != 4 )
|
||||
return error(COMPERR_BAD_SHAPE,
|
||||
TComm("Face must have 4 sides but not ") << vertexByAngle.size() );
|
||||
}
|
||||
|
||||
// put all corner vertices in a map
|
||||
TopTools_MapOfShape vMap;
|
||||
if ( nbCorners == 3 )
|
||||
vMap.Add( triaVertex );
|
||||
multimap<double, TopoDS_Vertex>::reverse_iterator a2v = vertexByAngle.rbegin();
|
||||
for ( int iC = 0; a2v != vertexByAngle.rend() && iC < nbCorners; ++a2v, ++iC )
|
||||
vMap.Add( (*a2v).second );
|
||||
|
||||
// check if there are possible variations in choosing corners
|
||||
bool haveVariants = false;
|
||||
if ((int) vertexByAngle.size() > nbCorners )
|
||||
{
|
||||
double lostAngle = a2v->first;
|
||||
double lastAngle = ( --a2v, a2v->first );
|
||||
haveVariants = ( lostAngle * 1.1 >= lastAngle );
|
||||
}
|
||||
|
||||
const double angleTol = 5.* M_PI/180;
|
||||
myCheckOri = ( (int)vertexByAngle.size() > nbCorners ||
|
||||
vertexByAngle.begin()->first < angleTol );
|
||||
|
||||
// make theWire begin from a corner vertex or triaVertex
|
||||
if ( nbCorners == 3 )
|
||||
while ( !triaVertex.IsSame( ( helper.IthVertex( 0, theWire.front() ))) ||
|
||||
SMESH_Algo::isDegenerated( theWire.front() ))
|
||||
theWire.splice( theWire.end(), theWire, theWire.begin() );
|
||||
else
|
||||
while ( !vMap.Contains( helper.IthVertex( 0, theWire.front() )) ||
|
||||
SMESH_Algo::isDegenerated( theWire.front() ))
|
||||
theWire.splice( theWire.end(), theWire, theWire.begin() );
|
||||
|
||||
// fill the result vector and prepare for its refinement
|
||||
theVertices.clear();
|
||||
vector< double > angles;
|
||||
vector< TopoDS_Edge > edgeVec;
|
||||
vector< int > cornerInd, nbSeg;
|
||||
int nbSegTot = 0;
|
||||
angles .reserve( vertexByAngle.size() );
|
||||
edgeVec.reserve( vertexByAngle.size() );
|
||||
nbSeg .reserve( vertexByAngle.size() );
|
||||
cornerInd.reserve( nbCorners );
|
||||
for ( edge = theWire.begin(); edge != theWire.end(); ++edge )
|
||||
{
|
||||
if ( SMESH_Algo::isDegenerated( *edge ))
|
||||
continue;
|
||||
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
|
||||
bool isCorner = vMap.Contains( v );
|
||||
if ( isCorner )
|
||||
{
|
||||
theVertices.push_back( v );
|
||||
cornerInd.push_back( angles.size() );
|
||||
}
|
||||
angles .push_back( angleByVertex.IsBound( v ) ? angleByVertex( v ) : -M_PI );
|
||||
edgeVec.push_back( *edge );
|
||||
if ( theConsiderMesh && haveVariants )
|
||||
{
|
||||
if ( SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( *edge ))
|
||||
nbSeg.push_back( sm->NbNodes() + 1 );
|
||||
else
|
||||
nbSeg.push_back( 0 );
|
||||
nbSegTot += nbSeg.back();
|
||||
}
|
||||
}
|
||||
|
||||
// refine the result vector - make sides equal by length if
|
||||
// there are several equal angles
|
||||
if ( haveVariants )
|
||||
{
|
||||
if ( nbCorners == 3 )
|
||||
angles[0] = 2 * M_PI; // not to move the base triangle VERTEX
|
||||
|
||||
// here we refer to VERTEX'es and EDGEs by indices in angles and edgeVec vectors
|
||||
typedef int TGeoIndex;
|
||||
|
||||
// for each vertex find a vertex till which there are nbSegHalf segments
|
||||
const int nbSegHalf = ( nbSegTot % 2 || nbCorners == 3 ) ? 0 : nbSegTot / 2;
|
||||
vector< TGeoIndex > halfDivider( angles.size(), -1 );
|
||||
int nbHalfDividers = 0;
|
||||
if ( nbSegHalf )
|
||||
{
|
||||
// get min angle of corners
|
||||
double minAngle = 10.;
|
||||
for ( size_t iC = 0; iC < cornerInd.size(); ++iC )
|
||||
minAngle = Min( minAngle, angles[ cornerInd[ iC ]]);
|
||||
|
||||
// find halfDivider's
|
||||
for ( TGeoIndex iV1 = 0; iV1 < TGeoIndex( angles.size() ); ++iV1 )
|
||||
{
|
||||
int nbSegs = 0;
|
||||
TGeoIndex iV2 = iV1;
|
||||
do {
|
||||
nbSegs += nbSeg[ iV2 ];
|
||||
iV2 = helper.WrapIndex( iV2 + 1, nbSeg.size() );
|
||||
} while ( nbSegs < nbSegHalf );
|
||||
|
||||
if ( nbSegs == nbSegHalf &&
|
||||
angles[ iV1 ] + angleTol >= minAngle &&
|
||||
angles[ iV2 ] + angleTol >= minAngle )
|
||||
{
|
||||
halfDivider[ iV1 ] = iV2;
|
||||
++nbHalfDividers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set< TGeoIndex > refinedCorners, treatedCorners;
|
||||
for ( size_t iC = 0; iC < cornerInd.size(); ++iC )
|
||||
{
|
||||
TGeoIndex iV = cornerInd[iC];
|
||||
if ( !treatedCorners.insert( iV ).second )
|
||||
continue;
|
||||
list< TGeoIndex > equVerts; // inds of vertices that can become corners
|
||||
equVerts.push_back( iV );
|
||||
int nbC[2] = { 0, 0 };
|
||||
// find equal angles backward and forward from the iV-th corner vertex
|
||||
for ( int isFwd = 0; isFwd < 2; ++isFwd )
|
||||
{
|
||||
int dV = isFwd ? +1 : -1;
|
||||
int iCNext = helper.WrapIndex( iC + dV, cornerInd.size() );
|
||||
TGeoIndex iVNext = helper.WrapIndex( iV + dV, angles.size() );
|
||||
while ( iVNext != iV )
|
||||
{
|
||||
bool equal = Abs( angles[iV] - angles[iVNext] ) < angleTol;
|
||||
if ( equal )
|
||||
equVerts.insert( isFwd ? equVerts.end() : equVerts.begin(), iVNext );
|
||||
if ( iVNext == cornerInd[ iCNext ])
|
||||
{
|
||||
if ( !equal )
|
||||
{
|
||||
if ( angles[iV] < angles[iVNext] )
|
||||
refinedCorners.insert( iVNext );
|
||||
break;
|
||||
}
|
||||
nbC[ isFwd ]++;
|
||||
treatedCorners.insert( cornerInd[ iCNext ] );
|
||||
iCNext = helper.WrapIndex( iCNext + dV, cornerInd.size() );
|
||||
}
|
||||
iVNext = helper.WrapIndex( iVNext + dV, angles.size() );
|
||||
}
|
||||
if ( iVNext == iV )
|
||||
break; // all angles equal
|
||||
}
|
||||
|
||||
const bool allCornersSame = ( nbC[0] == 3 );
|
||||
if ( allCornersSame && nbHalfDividers > 0 )
|
||||
{
|
||||
// select two halfDivider's as corners
|
||||
TGeoIndex hd1, hd2 = -1;
|
||||
size_t iC2;
|
||||
for ( iC2 = 0; iC2 < cornerInd.size() && hd2 < 0; ++iC2 )
|
||||
{
|
||||
hd1 = cornerInd[ iC2 ];
|
||||
hd2 = halfDivider[ hd1 ];
|
||||
if ( std::find( equVerts.begin(), equVerts.end(), hd2 ) == equVerts.end() )
|
||||
hd2 = -1; // hd2-th vertex can't become a corner
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ( hd2 >= 0 )
|
||||
{
|
||||
angles[ hd1 ] = 2 * M_PI; // make hd1-th vertex no more "equal"
|
||||
angles[ hd2 ] = 2 * M_PI;
|
||||
refinedCorners.insert( hd1 );
|
||||
refinedCorners.insert( hd2 );
|
||||
treatedCorners = refinedCorners;
|
||||
// update cornerInd
|
||||
equVerts.push_front( equVerts.back() );
|
||||
equVerts.push_back( equVerts.front() );
|
||||
list< TGeoIndex >::iterator hdPos =
|
||||
std::find( equVerts.begin(), equVerts.end(), hd2 );
|
||||
if ( hdPos == equVerts.end() ) break;
|
||||
cornerInd[ helper.WrapIndex( iC2 + 0, cornerInd.size()) ] = hd1;
|
||||
cornerInd[ helper.WrapIndex( iC2 + 1, cornerInd.size()) ] = *( --hdPos );
|
||||
cornerInd[ helper.WrapIndex( iC2 + 2, cornerInd.size()) ] = hd2;
|
||||
cornerInd[ helper.WrapIndex( iC2 + 3, cornerInd.size()) ] = *( ++hdPos, ++hdPos );
|
||||
|
||||
theVertices[ 0 ] = helper.IthVertex( 0, edgeVec[ cornerInd[0] ]);
|
||||
theVertices[ 1 ] = helper.IthVertex( 0, edgeVec[ cornerInd[1] ]);
|
||||
theVertices[ 2 ] = helper.IthVertex( 0, edgeVec[ cornerInd[2] ]);
|
||||
theVertices[ 3 ] = helper.IthVertex( 0, edgeVec[ cornerInd[3] ]);
|
||||
iC = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// move corners to make sides equal by length
|
||||
int nbEqualV = equVerts.size();
|
||||
int nbExcessV = nbEqualV - ( 1 + nbC[0] + nbC[1] );
|
||||
if ( nbExcessV > 0 ) // there are nbExcessV vertices that can become corners
|
||||
{
|
||||
// calculate normalized length of each "side" enclosed between neighbor equVerts
|
||||
vector< double > accuLength;
|
||||
double totalLen = 0;
|
||||
vector< TGeoIndex > evVec( equVerts.begin(), equVerts.end() );
|
||||
size_t iEV = 0;
|
||||
TGeoIndex iE = cornerInd[ helper.WrapIndex( iC - nbC[0] - 1, cornerInd.size() )];
|
||||
TGeoIndex iEEnd = cornerInd[ helper.WrapIndex( iC + nbC[1] + 1, cornerInd.size() )];
|
||||
while ((int) accuLength.size() < nbEqualV + int( !allCornersSame ) )
|
||||
{
|
||||
// accumulate length of edges before iEV-th equal vertex
|
||||
accuLength.push_back( totalLen );
|
||||
do {
|
||||
accuLength.back() += SMESH_Algo::EdgeLength( edgeVec[ iE ]);
|
||||
iE = helper.WrapIndex( iE + 1, edgeVec.size());
|
||||
if ( iEV < evVec.size() && iE == evVec[ iEV ] ) {
|
||||
iEV++;
|
||||
break; // equal vertex reached
|
||||
}
|
||||
}
|
||||
while( iE != iEEnd );
|
||||
totalLen = accuLength.back();
|
||||
}
|
||||
accuLength.resize( equVerts.size() );
|
||||
for ( size_t iS = 0; iS < accuLength.size(); ++iS )
|
||||
accuLength[ iS ] /= totalLen;
|
||||
|
||||
// find equVerts most close to the ideal sub-division of all sides
|
||||
int iBestEV = 0;
|
||||
int iCorner = helper.WrapIndex( iC - nbC[0], cornerInd.size() );
|
||||
int nbSides = Min( nbCorners, 2 + nbC[0] + nbC[1] );
|
||||
for ( int iS = 1; iS < nbSides; ++iS, ++iBestEV )
|
||||
{
|
||||
double idealLen = iS / double( nbSides );
|
||||
double d, bestDist = 2.;
|
||||
for ( iEV = iBestEV; iEV < accuLength.size(); ++iEV )
|
||||
{
|
||||
d = Abs( idealLen - accuLength[ iEV ]);
|
||||
|
||||
// take into account presence of a corresponding halfDivider
|
||||
const double cornerWgt = 0.5 / nbSides;
|
||||
const double vertexWgt = 0.25 / nbSides;
|
||||
TGeoIndex hd = halfDivider[ evVec[ iEV ]];
|
||||
if ( hd < 0 )
|
||||
d += vertexWgt;
|
||||
else if( refinedCorners.count( hd ))
|
||||
d -= cornerWgt;
|
||||
else
|
||||
d -= vertexWgt;
|
||||
|
||||
// choose vertex with the best d
|
||||
if ( d < bestDist )
|
||||
{
|
||||
bestDist = d;
|
||||
iBestEV = iEV;
|
||||
}
|
||||
}
|
||||
if ( iBestEV > iS-1 + nbExcessV )
|
||||
iBestEV = iS-1 + nbExcessV;
|
||||
theVertices[ iCorner ] = helper.IthVertex( 0, edgeVec[ evVec[ iBestEV ]]);
|
||||
cornerInd [ iCorner ] = evVec[ iBestEV ];
|
||||
refinedCorners.insert( evVec[ iBestEV ]);
|
||||
iCorner = helper.WrapIndex( iCorner + 1, cornerInd.size() );
|
||||
}
|
||||
|
||||
} // if ( nbExcessV > 0 )
|
||||
else
|
||||
{
|
||||
refinedCorners.insert( cornerInd[ iC ]);
|
||||
}
|
||||
} // loop on cornerInd
|
||||
|
||||
// make theWire begin from the cornerInd[0]-th EDGE
|
||||
while ( !theWire.front().IsSame( edgeVec[ cornerInd[0] ]))
|
||||
theWire.splice( theWire.begin(), theWire, --theWire.end() );
|
||||
|
||||
} // if ( haveVariants )
|
||||
|
||||
return nbCorners;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Constructor of a side of quad
|
||||
|
@ -669,7 +669,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
//! Make mesh on an adge using assigned 1d hyp or default nb of segments
|
||||
//! Make mesh on an edge using assigned 1d hyp or default nb of segments
|
||||
bool ComputeCircularEdge( SMESH_Mesh& aMesh,
|
||||
const StdMeshers_FaceSidePtr& aSide )
|
||||
{
|
||||
@ -697,7 +697,7 @@ public:
|
||||
return ok;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
//! Make mesh on an adge using assigned 1d hyp or default nb of segments
|
||||
//! Make mesh on an edge using assigned 1d hyp or default nb of segments
|
||||
bool EvaluateCircularEdge(SMESH_Mesh& aMesh,
|
||||
const StdMeshers_FaceSidePtr aSide,
|
||||
MapShapeNbElems& aResMap)
|
||||
|
@ -8771,7 +8771,7 @@ void _LayerEdge::ChooseSmooFunction( const set< TGeomID >& concaveVertices,
|
||||
}
|
||||
}
|
||||
|
||||
// // this coice is done only if ( !concaveVertices.empty() ) for Grids/smesh/bugs_19/X1
|
||||
// // this choice is done only if ( !concaveVertices.empty() ) for Grids/smesh/bugs_19/X1
|
||||
// // where the nodes are smoothed too far along a sphere thus creating
|
||||
// // inverted _simplices
|
||||
// double dist[theNbSmooFuns];
|
||||
|
Loading…
Reference in New Issue
Block a user