IPAL52868: Confusing error message when computing an imported mesh w/o algo assigned

IPAL52888: Pattern Mapping fails to load from a face just after study loading
This commit is contained in:
eap 2015-10-05 14:51:57 +03:00
parent f15b6ceb9f
commit 67909c435c
19 changed files with 563 additions and 348 deletions

View File

@ -14,10 +14,10 @@ of several dimensions.
<li>For meshing of 1D entities (<b>edges</b>):</li>
\anchor a1d_algos_anchor
<ul>
<li><em>Wire Discretization</em> meshing algorithm - splits an edge into a
<li><b>Wire Discretization</b> meshing algorithm - splits an edge into a
number of mesh segments following an 1D hypothesis.
</li>
<li><em>Composite Side Discretization</em> algorithm - allows to apply a 1D
<li><b>Composite Side Discretization</b> algorithm - allows to apply a 1D
hypothesis to a whole side of a geometrical face even if it is
composed of several edges provided that they form C1 curve in all
faces of the main shape.</li>
@ -26,7 +26,7 @@ number of mesh segments following an 1D hypothesis.
<li>For meshing of 2D entities (<b>faces</b>):</li>
<ul>
<li><em>Triangle (Mefisto)</em> meshing algorithm - splits faces
<li><b>Triangle (Mefisto)</b> meshing algorithm - splits faces
into triangular elements.</li>
<li>\subpage quad_ijk_algo_page "Quadrangle (Mapping)" meshing
algorithm - splits faces into quadrangular elements.</li>
@ -39,12 +39,12 @@ number of mesh segments following an 1D hypothesis.
<li>For meshing of 3D entities (<b>solid objects</b>):</li>
<ul>
<li><em>Hexahedron (i,j,k)</em> meshing algorithm - solids are
<li><b>Hexahedron (i,j,k)</b> meshing algorithm - solids are
split into hexahedral elements thus forming a structured 3D
mesh. The algorithm requires that 2D mesh generated on a solid could
be considered as a mesh of a box, i.e. there should be six nodes shared
by three quadrangles and the rest nodes should be shared by four
quadrangles.
be considered as a mesh of a box, i.e. there should be eight nodes
shared by three quadrangles and the rest nodes should be shared by
four quadrangles.
\image html hexa_ijk_mesh.png "Structured mesh generated by Hexahedron (i,j,k) on a solid bound by 16 faces"
</li>
@ -59,25 +59,25 @@ number of mesh segments following an 1D hypothesis.
\image html image126.gif "Example of a hexahedral 3D mesh"
</ul>
Some 3D meshing algorithms, such as Hexahedron(i,j,k) and some
commercial ones, also can generate 3D meshes from 2D meshes, working
without geometrical objects.
Some 3D meshing algorithms, such as Hexahedron(i,j,k) also can
generate 3D meshes from 2D meshes, working without geometrical
objects.
There is also a number of more specific algorithms:
<ul>
<li>\subpage prism_3d_algo_page "for meshing prismatic 3D shapes"</li>
<li>\subpage quad_from_ma_algo_page "for meshing faces with sinuous borders"</li>
<li> <em>Polygon per Face</em> meshing algorithm - generates one mesh
<li>\subpage prism_3d_algo_page "for meshing prismatic 3D shapes with hexahedra and prisms"</li>
<li>\subpage quad_from_ma_algo_page "for quadrangle meshing of faces with sinuous borders"</li>
<li> <b>Polygon per Face</b> meshing algorithm - generates one mesh
face (either a triangle, a quadrangle or a polygon) per a geometrical
face using all nodes from the face boundary.</li>
<li>\subpage projection_algos_page "for meshing by projection of another mesh"</li>
<li>\subpage import_algos_page "for meshing by importing elements from another mesh"</li>
<li>\subpage radial_prism_algo_page "for meshing geometrical objects with cavities"</li>
<li>\subpage radial_quadrangle_1D2D_algo_page "for meshing special faces (circles and parts of circles)"</li>
<li>\subpage radial_prism_algo_page "for meshing 3D geometrical objects with cavities with hexahedra and prisms"</li>
<li>\subpage radial_quadrangle_1D2D_algo_page "for quadrangle meshing of disks and parts of disks"</li>
<li>\subpage use_existing_page "Use Edges to be Created Manually" and
\ref use_existing_page "Use Faces to be Created Manually" algorithms can be
used to create a 1D or a 2D mesh in a python script.</li>
<li>\subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"</li>
\ref use_existing_page "Use Faces to be Created Manually" algorithms can be
used to create a 1D or a 2D mesh in a python script.</li>
<li>\subpage segments_around_vertex_algo_page "for defining the length of mesh segments around certain vertices"</li>
</ul>
\ref constructing_meshes_page "Constructing meshes" page describes in

View File

@ -149,7 +149,7 @@ Alternatively, it is possible to select <b>Refine selected mesh elements</b>
check-box and apply the pattern to
<ul>
<li> One or several <b>Mesh volumes</b> instead of a geometric 3D object</li>
<li> and select two /b Nodes instead of vertices.</li>
<li> and select two \b Nodes instead of vertices.</li>
</ul>
Additionally it is possible to:
<ul>

View File

@ -3,15 +3,20 @@
\page segments_around_vertex_algo_page Segments around Vertex
\n <b>Segments around Vertex</b> algorithm is considered to be a 0D meshing
algorithm, but, of course, it doesn't mesh nodes. It allows to define
the local size of the elements in the neighborhood of a certain
node. If we choose an object of higher dimension, it applies to all
its tops, i.e. corners of a box. The 0D algorithm combines with the
algorithms of higher dimensions, but it is not necessarily required
for their successful implementation.
algorithm, but, of course, it doesn't mesh vertices. It allows to define
the local size of the segments in the neighborhood of a certain
vertex. If we assign this algorithm to a geometrical object of higher
dimension, it applies to all its vertices.
This algorithm allows only one hypothesis.
Length of segments near vertex is defined by <b> Length Near
Vertex </b> hypothesis.
This hypothesis is used by \ref a1d_algos_anchor "Wire Discretization" or
\ref a1d_algos_anchor "Composite Side Discretization" algorithms as
follows: a geometrical edge is discretized according to a 1D
hypotheses and then nodes near vertices are modified to assure the
segment length required by <b> Length Near Vertex </b> hypothesis.
\image html lengthnearvertex.png
*/
*/

View File

@ -943,7 +943,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh,
if ( !hasAlgo ) {
ret = false;
theErrors.push_back( TAlgoStateError() );
theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, 1, true );
theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, theMesh.HasShapeToMesh() ? 1 : 3, true );
}
return ret;

View File

@ -4816,7 +4816,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem,
else if(nbSame==1) {
// ---> pyramid + pentahedron - can not be created since it is needed
// additional middle node at the center of face
INFOS( " Sweep for face " << elem->GetID() << " can not be created" );
//INFOS( " Sweep for face " << elem->GetID() << " can not be created" );
return;
}
else if( nbSame == 2 ) {
@ -11666,7 +11666,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
}
else
{
INFOS("Quadratic multiple joints not implemented");
//INFOS("Quadratic multiple joints not implemented");
// TODO quadratic nodes
}
}

View File

@ -1822,12 +1822,12 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
SMESH_Hypothesis::Hypothesis_Status hyp_status;
algo = GetAlgo();
if(algo && !aResMap.count(this) )
if( algo && !aResMap.count( this ))
{
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (!ret) return false;
if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary())
if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary() )
{
// check submeshes needed
bool subMeshEvaluated = true;
@ -1845,8 +1845,23 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
return false;
}
_computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
ret = algo->Evaluate((*_father), _subShape, aResMap);
if ( IsMeshComputed() )
{
vector<int> & nbEntities = aResMap[ this ];
nbEntities.resize( SMDSEntity_Last, 0 );
if ( SMESHDS_SubMesh* sm = GetSubMeshDS() )
{
nbEntities[ SMDSEntity_Node ] = sm->NbNodes();
SMDS_ElemIteratorPtr elemIt = sm->GetElements();
while ( elemIt->more() )
nbEntities[ elemIt->next()->GetEntityType() ]++;
}
}
else
{
ret = algo->Evaluate((*_father), _subShape, aResMap);
}
aResMap.insert( make_pair( this,vector<int>(0)));
}

View File

@ -4336,35 +4336,35 @@ void SMESHGUI::initialize( CAM_Application* app )
hasFacesOrVolumes("(({'Face'} in elemTypes) || ({'Volume'} in elemTypes)) ");
createPopupItem( SMESHOp::OpFileInformation, OB, mesh, "&& selcount=1 && isImported" );
createPopupItem( SMESHOp::OpCreateSubMesh, OB, mesh, "&& isComputable");
createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, mesh, "&& isComputable");
createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, subMesh, "&& isComputable" );
createPopupItem( SMESHOp::OpCreateSubMesh, OB, mesh, "&& hasGeomReference");
createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, mesh );
createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, subMesh, "&& hasGeomReference" );
createPopupItem( SMESHOp::OpEditGroup, OB, group );
createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" );
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( SMESHOp::OpCompute, OB, mesh, "&& isComputable" );
createPopupItem( SMESHOp::OpPreCompute, OB, mesh, "&& isComputable && isPreComputable" );
createPopupItem( SMESHOp::OpPreCompute, OB, mesh, "&& isPreComputable" );
createPopupItem( SMESHOp::OpEvaluate, OB, mesh, "&& isComputable" );
createPopupItem( SMESHOp::OpMeshOrder, OB, mesh, "&& isComputable" );
createPopupItem( SMESHOp::OpMeshOrder, OB, mesh, "&& isComputable && hasGeomReference" );
createPopupItem( SMESHOp::OpUpdate, OB, mesh_part );
createPopupItem( SMESHOp::OpMeshInformation, OB, mesh_part );
createPopupItem( SMESHOp::OpFindElementByPoint, OB, mesh_group );
createPopupItem( SMESHOp::OpOverallMeshQuality, OB, mesh_part );
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( SMESHOp::OpCreateGroup, OB, mesh );
createPopupItem( SMESHOp::OpCreateGeometryGroup, OB, mesh );
createPopupItem( SMESHOp::OpCreateGeometryGroup, OB, mesh, "&& hasGeomReference" );
createPopupItem( SMESHOp::OpConstructGroup, OB, subMesh );
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( SMESHOp::OpEditHypothesis, OB, hypo);
createPopupItem( SMESHOp::OpUnassign, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( SMESHOp::OpClearMesh, OB, mesh );
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( SMESHOp::OpConvertMeshToQuadratic, OB, mesh + " " + subMesh ); // convert to quadratic
createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh + " " + group, // create 2D mesh from 3D
"&& dim>=2");
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( SMESHOp::OpClearMesh, OB, mesh );
popupMgr()->insert( separator(), -1, 0 );
QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
QString multiple_non_empty = QString( " && %1>0 && numberOfNodes>0" ).arg( dc );

View File

@ -1728,13 +1728,14 @@ void SMESHGUI_PrecomputeOp::initDialog()
void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
QMap<int,int>& theModeMap)
{
_PTR(SObject) aHypRoot;
if ( !theMesh ) return;
_PTR(SObject) aHypFolder;
_PTR(GenericAttribute) anAttr;
int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
if ( theMesh && theMesh->FindSubObject( aPart, aHypRoot ) )
if ( theMesh->FindSubObject( aPart, aHypFolder ) )
{
_PTR(ChildIterator) anIter =
SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
SMESH::GetActiveStudyDocument()->NewChildIterator( aHypFolder );
for ( ; anIter->More(); anIter->Next() )
{
_PTR(SObject) anObj = anIter->Value();
@ -1743,16 +1744,16 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
anObj = aRefObj;
else
continue;
if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
{
CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
if ( CORBA::is_nil( aVar ) )
continue;
SMESH::SMESH_Algo_var algo;
for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
{
SMESH::SMESH_Algo_var algo;
switch(dim) {
case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
@ -1760,7 +1761,56 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
default: break;
}
if ( !algo->_is_nil() )
{
theModeMap[ dim ] = 0;
if ( theModeMap.size() == 3 )
return;
break;
}
}
}
}
}
// check sub-meshes
for ( aPart = SMESH::Tag_SubMeshOnEdge; aPart < SMESH::Tag_LastSubMesh; ++aPart )
{
if ( !theMesh->FindSubObject( aPart, aHypFolder ))
continue;
_PTR(ChildIterator) anIter =
SMESH::GetActiveStudyDocument()->NewChildIterator( aHypFolder );
for ( anIter->InitEx(true); anIter->More(); anIter->Next() )
{
_PTR(SObject) anObj = anIter->Value();
_PTR(SObject) aRefObj;
if ( anObj->ReferencedObject( aRefObj ) )
anObj = aRefObj;
else
continue;
if ( anObj->FindAttribute( anAttr, "AttributeName" ))
{
CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
if ( CORBA::is_nil( aVar ) )
continue;
SMESH::SMESH_Algo_var algo;
for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
{
switch(dim) {
case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
case SMESH::DIM_3D: algo = SMESH::SMESH_3D_Algo::_narrow( aVar ); break;
default: break;
}
if ( !algo->_is_nil() )
{
theModeMap[ dim ] = 0;
if ( theModeMap.size() == 3 )
return;
break;
}
}
}
}

View File

@ -34,6 +34,7 @@
#include "SMESHGUI_IdValidator.h"
#include "SMESHGUI_FilterDlg.h"
#include <SMESH_TypeFilter.hxx>
#include <SMESH_Actor.h>
#include <SMDS_Mesh.hxx>
@ -208,14 +209,18 @@ void SMESHGUI_RemoveNodesDlg::Init()
connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
connect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)),
SLOT(onTextChange(const QString&)));
this, SLOT (onTextChange(const QString&)));
SMESH::SetPointRepresentation(true);
mySelectionMgr->clearFilters();
mySelectionMgr->installFilter( new SMESH_TypeFilter( SMESH::IDSOURCE ));
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(NodeSelection);
SelectionIntoArgument();
//SelectionIntoArgument();
mySelectionMgr->setSelectedObjects( SALOME_ListIO() );
}
//=================================================================================
@ -412,16 +417,16 @@ void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument()
myBusy = true;
myEditCurrentArgument->setText(aString);
myBusy = false;
// OK
myNbOkNodes = nbNodes;
} // if (nbNodes > 0)
} // if (myActor)
} // if (!myMesh->_is_nil())
} // if (nbSel == 1)
updateButtons();
updateButtons();
}
//=================================================================================
@ -474,6 +479,9 @@ void SMESHGUI_RemoveNodesDlg::ActivateThisDialog()
mySMESHGUI->SetActiveDialogBox((QDialog*)this); // ??
mySelectionMgr->clearFilters();
mySelectionMgr->installFilter( new SMESH_TypeFilter( SMESH::IDSOURCE ));
SMESH::SetPointRepresentation(true);
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(NodeSelection);

View File

@ -128,7 +128,7 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
else if ( p=="displayMode" ) val = QVariant( displayMode( ind ) );
else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) );
else if ( p=="isPreComputable" ) val = QVariant( isPreComputable( ind ) );
else if ( p=="hasReference" ) val = QVariant( hasReference( ind ) );
else if ( p=="hasGeomReference" ) val = QVariant( hasGeomReference( ind ) );
else if ( p=="isImported" ) val = QVariant( isImported( ind ) );
else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
else if ( p=="groupType" ) val = QVariant( groupType( ind ) );
@ -492,62 +492,58 @@ int SMESHGUI_Selection::dim( int ind ) const
//=======================================================================
//function : isComputable
//purpose :
//purpose : return true for a ready-to-compute mesh
//=======================================================================
QVariant SMESHGUI_Selection::isComputable( int ind ) const
{
if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Mesh" )
{
QMap<int,int> modeMap;
_PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
CORBA::Object_var obj = SMESH::SObjectToObject( so, SMESH::GetActiveStudyDocument() );
if( !CORBA::is_nil( obj ) ) {
SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
if ( !CORBA::is_nil( mesh ) ) {
if ( mesh->HasShapeToMesh() ) {
GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
return QVariant( !shape->_is_nil() );
}
else
{
return QVariant( mesh->NbFaces() !=0 );
}
}
else
{
GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
return QVariant( !shape->_is_nil() );
}
}
SMESHGUI_PrecomputeOp::getAssignedAlgos( so, modeMap );
return QVariant( modeMap.size() > 0 );
}
return QVariant( false );
}
//=======================================================================
//function : isPreComputable
//purpose :
//purpose : returns true for a mesh with algorithms
//=======================================================================
QVariant SMESHGUI_Selection::isPreComputable( int ind ) const
{
if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Mesh" )
{
QMap<int,int> modeMap;
_PTR(SObject) pMesh = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
SMESHGUI_PrecomputeOp::getAssignedAlgos( pMesh, modeMap );
return QVariant( modeMap.size() > 1 );
int maxDim = dim( ind );
if ( maxDim < 2 ) // we can preview 1D or 2D
{
QMap<int,int> modeMap;
_PTR(SObject) pMesh = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
SMESHGUI_PrecomputeOp::getAssignedAlgos( pMesh, modeMap );
if ( modeMap.size() > 1 )
return QVariant( ( modeMap.contains( SMESH::DIM_3D )) ||
( modeMap.contains( SMESH::DIM_2D ) && maxDim < 1 ));
}
}
return QVariant( false );
}
//=======================================================================
//function : hasReference
//purpose :
//function : hasGeomReference
//purpose : returns true for a mesh or sub-mesh on geometry
//=======================================================================
QVariant SMESHGUI_Selection::hasReference( int ind ) const
QVariant SMESHGUI_Selection::hasGeomReference( int ind ) const
{
return QVariant( isReference( ind ) );
if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
{
_PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
return QVariant( !shape->_is_nil() );
}
return QVariant( false );
}
//=======================================================================

View File

@ -58,7 +58,7 @@ public:
virtual int dim( int ) const;
virtual QVariant isComputable( int ) const;
virtual QVariant isPreComputable( int ) const;
virtual QVariant hasReference( int ) const;
virtual QVariant hasGeomReference( int ) const;
virtual QVariant isVisible( int ) const;
virtual QString quadratic2DMode( int ) const;

View File

@ -96,6 +96,9 @@ namespace
: _p0(p0), _p1(p1), _geomEdgeInd(iE) {}
InSegment() : _p0(0), _p1(0), _geomEdgeInd(0) {}
const InPoint& point0() const { return *_p0; }
const InPoint& point1() const { return *_p1; }
inline bool isConnected( const TVDEdge* edge );
inline bool isExternal( const TVDEdge* edge );
@ -258,8 +261,9 @@ namespace boost {
namespace
{
const int theNoBrachID = 0; // std::numeric_limits<int>::max();
double theScale[2]; // scale used in bndSegsToMesh()
const int theNoBrachID = 0;
double theScale[2]; // scale used in bndSegsToMesh()
const size_t theNoEdgeID = std::numeric_limits<size_t>::max() / 1000;
// -------------------------------------------------------------------------------------
/*!
@ -277,17 +281,18 @@ namespace
};
// -------------------------------------------------------------------------------------
/*!
* \brief A segment on EDGE, used to create BndPoints
* \brief Segment of EDGE, used to create BndPoints
*/
struct BndSeg
{
InSegment* _inSeg;
const TVDEdge* _edge;
double _uLast;
BndSeg* _prev; // previous BndSeg in FACE boundary
int _branchID; // negative ID means reverse direction
BndSeg( InSegment* seg, const TVDEdge* edge, double u ):
_inSeg(seg), _edge(edge), _uLast(u), _branchID( theNoBrachID ) {}
_inSeg(seg), _edge(edge), _uLast(u), _prev(0), _branchID( theNoBrachID ) {}
void setIndexToEdge( size_t id )
{
@ -298,21 +303,39 @@ namespace
size_t geomEdge() const { return _inSeg->_geomEdgeInd; }
void setBranch( int branchID, vector< BndSeg >& bndSegs )
static BndSeg* getBndSegOfEdge( const TVDEdge* edge,
vector< vector< BndSeg > >& bndSegsPerEdge )
{
BndSeg* seg = 0;
if ( edge )
{
size_t oppSegIndex = SMESH_MAT2d::Branch::getBndSegment( edge );
size_t oppEdgeIndex = SMESH_MAT2d::Branch::getGeomEdge ( edge );
if ( oppEdgeIndex < bndSegsPerEdge.size() &&
oppSegIndex < bndSegsPerEdge[ oppEdgeIndex ].size() )
{
seg = & bndSegsPerEdge[ oppEdgeIndex ][ oppSegIndex ];
}
}
return seg;
}
void setBranch( int branchID, vector< vector< BndSeg > >& bndSegsPerEdge )
{
_branchID = branchID;
if ( _edge ) // pass branch to an opposite BndSeg
{
size_t oppSegIndex = SMESH_MAT2d::Branch::getBndSegment( _edge->twin() );
if ( oppSegIndex < bndSegs.size() && bndSegs[ oppSegIndex ]._branchID == theNoBrachID )
bndSegs[ oppSegIndex ]._branchID = -branchID;
}
// pass branch to an opposite BndSeg
if ( _edge )
if ( BndSeg* oppSeg = getBndSegOfEdge( _edge->twin(), bndSegsPerEdge ))
{
if ( oppSeg->_branchID == theNoBrachID )
oppSeg->_branchID = -branchID;
}
}
bool hasOppositeEdge( const size_t noEdgeID )
bool hasOppositeEdge()
{
if ( !_edge ) return false;
return ( _inSeg->getGeomEdge( _edge->twin()->cell() ) != noEdgeID );
return ( _inSeg->getGeomEdge( _edge->twin()->cell() ) != theNoEdgeID );
}
// check a next segment in CW order
@ -352,6 +375,35 @@ namespace
return false;
}
}; // struct BndSeg
// -------------------------------------------------------------------------------------
/*!
* \brief Iterator
*/
struct BranchIterator
{
int _i, _size;
const std::vector<const TVDEdge*> & _edges;
bool _closed;
BranchIterator(const std::vector<const TVDEdge*> & edges, int i )
:_i( i ), _size( edges.size() ), _edges( edges )
{
_closed = ( edges[0]->vertex1() == edges.back()->vertex0() ); // closed branch
}
const TVDEdge* operator++() { ++_i; return edge(); }
const TVDEdge* operator--() { --_i; return edge(); }
bool operator<( const BranchIterator& other ) { return _i < other._i; }
BranchIterator& operator=( const BranchIterator& other ) { _i = other._i; return *this; }
void set(int i) { _i = i; }
int index() const { return _i; }
int indexMod() const { return ( _i + _size ) % _size; }
const TVDEdge* edge() const {
return _closed ? _edges[ indexMod() ] : ( _i < 0 || _i >= _size ) ? 0 : _edges[ _i ];
}
const TVDEdge* edgePrev() { --_i; const TVDEdge* e = edge(); ++_i; return e; }
const TVDEdge* edgeNext() { ++_i; const TVDEdge* e = edge(); --_i; return e; }
};
//================================================================================
@ -670,22 +722,25 @@ namespace
*/
//================================================================================
void updateJoinedBranch( vector< const TVDEdge* > & branchEdges,
const size_t newID,
vector< BndSeg > & bndSegs,
const bool reverse)
void updateJoinedBranch( vector< const TVDEdge* > & branchEdges,
const size_t newID,
vector< vector< BndSeg > > & bndSegs,
const bool reverse)
{
BndSeg *seg1, *seg2;
if ( reverse )
{
for ( size_t i = 0; i < branchEdges.size(); ++i )
{
size_t seg1 = SMESH_MAT2d::Branch::getBndSegment( branchEdges[i] );
size_t seg2 = SMESH_MAT2d::Branch::getBndSegment( branchEdges[i]->twin() );
bndSegs[ seg1 ]._branchID /= bndSegs[ seg1 ].branchID();
bndSegs[ seg2 ]._branchID /= bndSegs[ seg2 ].branchID();
bndSegs[ seg1 ]._branchID *= -newID;
bndSegs[ seg2 ]._branchID *= -newID;
branchEdges[i] = branchEdges[i]->twin();
if (( seg1 = BndSeg::getBndSegOfEdge( branchEdges[i], bndSegs )) &&
( seg2 = BndSeg::getBndSegOfEdge( branchEdges[i]->twin(), bndSegs )))
{
seg1->_branchID /= seg1->branchID();
seg2->_branchID /= seg2->branchID();
seg1->_branchID *= -newID;
seg2->_branchID *= -newID;
branchEdges[i] = branchEdges[i]->twin();
}
}
std::reverse( branchEdges.begin(), branchEdges.end() );
}
@ -693,12 +748,14 @@ namespace
{
for ( size_t i = 0; i < branchEdges.size(); ++i )
{
size_t seg1 = SMESH_MAT2d::Branch::getBndSegment( branchEdges[i] );
size_t seg2 = SMESH_MAT2d::Branch::getBndSegment( branchEdges[i]->twin() );
bndSegs[ seg1 ]._branchID /= bndSegs[ seg1 ].branchID();
bndSegs[ seg2 ]._branchID /= bndSegs[ seg2 ].branchID();
bndSegs[ seg1 ]._branchID *= newID;
bndSegs[ seg2 ]._branchID *= newID;
if (( seg1 = BndSeg::getBndSegOfEdge( branchEdges[i], bndSegs )) &&
( seg2 = BndSeg::getBndSegOfEdge( branchEdges[i]->twin(), bndSegs )))
{
seg1->_branchID /= seg1->branchID();
seg2->_branchID /= seg2->branchID();
seg1->_branchID *= newID;
seg2->_branchID *= newID;
}
}
}
}
@ -723,9 +780,7 @@ namespace
vector< const SMESH_MAT2d::BranchEnd* >& branchPnt,
SMESH_MAT2d::Boundary& boundary )
{
const size_t noEdgeID = inSegments.size() + 1; // ID of non-existent geom EDGE
// Associate MA cells with inSegments
// Associate MA cells with geom EDGEs
for (TVD::const_cell_iterator it = vd.cells().begin(); it != vd.cells().end(); ++it)
{
const TVDCell* cell = &(*it);
@ -737,7 +792,7 @@ namespace
}
else
{
InSegment::setGeomEdgeToCell( cell, noEdgeID );
InSegment::setGeomEdgeToCell( cell, theNoEdgeID );
}
}
@ -806,7 +861,7 @@ namespace
{
if ( edge->is_primary() ) break; // this should not happen
const TVDEdge* edge2 = edge->twin(); // we are in a neighbor cell, add MA edges to inPnt
if ( inSeg.getGeomEdge( edge2->cell() ) != noEdgeID )
if ( inSeg.getGeomEdge( edge2->cell() ) != theNoEdgeID )
break; // cell of an InSegment
bool hasInfinite = false;
list< const TVDEdge* > pointEdges;
@ -840,63 +895,96 @@ namespace
if ( inPoints.front() == inPoints.back() /*&& !inPoints[0]._edges.empty()*/ )
{
inPntChecked[0] = false; // do not use the 1st point twice
//InSegment::setGeomEdgeToCell( inPoints[0]._edges.back()->cell(), noEdgeID );
//InSegment::setGeomEdgeToCell( inPoints[0]._edges.back()->cell(), theNoEdgeID );
inPoints[0]._edges.clear();
}
// Divide InSegment's into BndSeg's (so that each BndSeg corresponds to one MA edge)
vector< BndSeg > bndSegs;
bndSegs.reserve( inSegments.size() * 3 );
list< const TVDEdge* >::reverse_iterator e;
for ( size_t i = 0; i < inSegments.size(); ++i )
vector< vector< BndSeg > > bndSegsPerEdge( boundary.nbEdges() ); // all BndSeg's
{
InSegment& inSeg = inSegments[i];
vector< BndSeg > bndSegs; // bndSeg's of a current EDGE
size_t prevGeomEdge = theNoEdgeID;
// segments around 1st concave point
size_t ip0 = inSeg._p0->index( inPoints );
if ( inPntChecked[ ip0 ] )
for ( e = inSeg._p0->_edges.rbegin(); e != inSeg._p0->_edges.rend(); ++e )
bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p0->_param ));
inPntChecked[ ip0 ] = false;
list< const TVDEdge* >::reverse_iterator e;
for ( size_t i = 0; i < inSegments.size(); ++i )
{
InSegment& inSeg = inSegments[i];
// segments of InSegment's
const size_t nbMaEdges = inSeg._edges.size();
switch ( nbMaEdges ) {
case 0: // "around" circle center
bndSegs.push_back( BndSeg( &inSeg, 0, inSeg._p1->_param )); break;
case 1:
bndSegs.push_back( BndSeg( &inSeg, inSeg._edges.back(), inSeg._p1->_param )); break;
default:
gp_XY inSegDir( inSeg._p1->_a - inSeg._p0->_a,
inSeg._p1->_b - inSeg._p0->_b );
const double inSegLen2 = inSegDir.SquareModulus();
e = inSeg._edges.rbegin();
for ( size_t iE = 1; iE < nbMaEdges; ++e, ++iE )
if ( inSeg._geomEdgeInd != prevGeomEdge )
{
gp_XY toMA( (*e)->vertex0()->x() - inSeg._p0->_a,
(*e)->vertex0()->y() - inSeg._p0->_b );
double r = toMA * inSegDir / inSegLen2;
double u = r * inSeg._p1->_param + ( 1. - r ) * inSeg._p0->_param;
bndSegs.push_back( BndSeg( &inSeg, *e, u ));
if ( !bndSegs.empty() )
bndSegsPerEdge[ prevGeomEdge ].swap( bndSegs );
prevGeomEdge = inSeg._geomEdgeInd;
}
bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p1->_param ));
}
// segments around 2nd concave point
size_t ip1 = inSeg._p1->index( inPoints );
if ( inPntChecked[ ip1 ] )
for ( e = inSeg._p1->_edges.rbegin(); e != inSeg._p1->_edges.rend(); ++e )
// segments around 1st concave point
size_t ip0 = inSeg._p0->index( inPoints );
if ( inPntChecked[ ip0 ] )
for ( e = inSeg._p0->_edges.rbegin(); e != inSeg._p0->_edges.rend(); ++e )
bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p0->_param ));
inPntChecked[ ip0 ] = false;
// segments of InSegment's
const size_t nbMaEdges = inSeg._edges.size();
switch ( nbMaEdges ) {
case 0: // "around" circle center
bndSegs.push_back( BndSeg( &inSeg, 0, inSeg._p1->_param )); break;
case 1:
bndSegs.push_back( BndSeg( &inSeg, inSeg._edges.back(), inSeg._p1->_param )); break;
default:
gp_XY inSegDir( inSeg._p1->_a - inSeg._p0->_a,
inSeg._p1->_b - inSeg._p0->_b );
const double inSegLen2 = inSegDir.SquareModulus();
e = inSeg._edges.rbegin();
for ( size_t iE = 1; iE < nbMaEdges; ++e, ++iE )
{
gp_XY toMA( (*e)->vertex0()->x() - inSeg._p0->_a,
(*e)->vertex0()->y() - inSeg._p0->_b );
double r = toMA * inSegDir / inSegLen2;
double u = r * inSeg._p1->_param + ( 1. - r ) * inSeg._p0->_param;
bndSegs.push_back( BndSeg( &inSeg, *e, u ));
}
bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p1->_param ));
inPntChecked[ ip1 ] = false;
}
// segments around 2nd concave point
size_t ip1 = inSeg._p1->index( inPoints );
if ( inPntChecked[ ip1 ] )
for ( e = inSeg._p1->_edges.rbegin(); e != inSeg._p1->_edges.rend(); ++e )
bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p1->_param ));
inPntChecked[ ip1 ] = false;
}
if ( !bndSegs.empty() )
bndSegsPerEdge[ prevGeomEdge ].swap( bndSegs );
}
// make TVDEdge's know it's BndSeg to enable passing branchID to
// an opposite BndSeg in BndSeg::setBranch()
for ( size_t i = 0; i < bndSegs.size(); ++i )
bndSegs[i].setIndexToEdge( i );
// prepare to MA branch search
for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
{
// 1) make TVDEdge's know it's BndSeg to enable passing branchID to
// an opposite BndSeg in BndSeg::setBranch(); geom EDGE ID is known from TVDCell
// 2) connect bndSegs via BndSeg::_prev
bndSegsToMesh( bndSegs ); // debug: visually check found MA edges
vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
if ( bndSegs.empty() ) continue;
for ( size_t i = 1; i < bndSegs.size(); ++i )
{
bndSegs[i]._prev = & bndSegs[i-1];
bndSegs[i].setIndexToEdge( i );
}
// look for the last bndSeg of previous EDGE to set bndSegs[0]._prev
const InPoint& p0 = bndSegs[0]._inSeg->point0();
for ( size_t iE2 = 0; iE2 < bndSegsPerEdge.size(); ++iE2 )
if ( p0 == bndSegsPerEdge[ iE2 ].back()._inSeg->point1() )
{
bndSegs[0]._prev = & bndSegsPerEdge[ iE2 ].back();
break;
}
bndSegs[0].setIndexToEdge( 0 );
}
//bndSegsToMesh( bndSegsPerEdge ); // debug: visually check found MA edges
// Find TVDEdge's of Branches and associate them with bndSegs
@ -907,71 +995,67 @@ namespace
map< const TVDVertex*, SMESH_MAT2d::BranchEndType > endType;
int branchID = 1; // we code orientation as branchID sign
branchEdges.resize( branchID + 1 );
branchEdges.resize( branchID );
size_t i1st = 0;
while ( i1st < bndSegs.size() && !bndSegs[i1st].hasOppositeEdge( noEdgeID ))
++i1st;
bndSegs[i1st].setBranch( branchID, bndSegs ); // set to the i-th and to the opposite bndSeg
branchEdges[ branchID ].push_back( bndSegs[i1st]._edge );
for ( size_t i = i1st+1; i < bndSegs.size(); ++i )
for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
{
if ( bndSegs[i].branchID() )
vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
for ( size_t i = 0; i < bndSegs.size(); ++i )
{
branchID = bndSegs[i]._branchID; // with sign
if ( bndSegs[i]._branchID == -bndSegs[i-1]._branchID &&
bndSegs[i]._edge )
if ( bndSegs[i].branchID() )
{
SMESH_MAT2d::BranchEndType type =
( bndSegs[i]._inSeg->isConnected( bndSegs[i]._edge ) ?
SMESH_MAT2d::BE_ON_VERTEX :
SMESH_MAT2d::BE_END );
endType.insert( make_pair( bndSegs[i]._edge->vertex1(), type ));
if ( bndSegs[i]._prev &&
bndSegs[i]._branchID == -bndSegs[i]._prev->_branchID &&
bndSegs[i]._edge )
{
SMESH_MAT2d::BranchEndType type =
( bndSegs[i]._inSeg->isConnected( bndSegs[i]._edge ) ?
SMESH_MAT2d::BE_ON_VERTEX :
SMESH_MAT2d::BE_END );
endType.insert( make_pair( bndSegs[i]._edge->vertex1(), type ));
}
continue;
}
continue;
}
if ( !bndSegs[i-1].isSameBranch( bndSegs[i] ))
{
branchEdges.resize(( branchID = branchEdges.size()) + 1 );
if ( bndSegs[i]._edge )
endType.insert( make_pair( bndSegs[i]._edge->vertex1(),
SMESH_MAT2d::BE_BRANCH_POINT ));
}
bndSegs[i].setBranch( branchID, bndSegs ); // set to i-th and to the opposite bndSeg
if ( bndSegs[i].hasOppositeEdge( noEdgeID ))
branchEdges[ bndSegs[i].branchID() ].push_back( bndSegs[i]._edge );
}
// define BranchEndType of the first TVDVertex
if ( bndSegs.front()._branchID == -bndSegs.back()._branchID )
{
if ( bndSegs[0]._edge )
{
SMESH_MAT2d::BranchEndType type =
( bndSegs[0]._inSeg->isConnected( bndSegs[0]._edge ) ?
SMESH_MAT2d::BE_ON_VERTEX :
SMESH_MAT2d::BE_END );
endType.insert( make_pair( bndSegs[0]._edge->vertex1(), type ));
}
else if ( bndSegs.back()._edge )
{
SMESH_MAT2d::BranchEndType type =
( bndSegs.back()._inSeg->isConnected( bndSegs.back()._edge ) ?
SMESH_MAT2d::BE_ON_VERTEX :
SMESH_MAT2d::BE_END );
endType.insert( make_pair( bndSegs.back()._edge->vertex0(), type ));
if ( !bndSegs[i]._prev &&
!bndSegs[i].hasOppositeEdge() )
continue;
if ( !bndSegs[i]._prev ||
!bndSegs[i]._prev->isSameBranch( bndSegs[i] ))
{
branchEdges.resize(( branchID = branchEdges.size()) + 1 );
if ( bndSegs[i]._edge && bndSegs[i]._prev )
endType.insert( make_pair( bndSegs[i]._edge->vertex1(), SMESH_MAT2d::BE_BRANCH_POINT ));
}
else if ( bndSegs[i]._prev->_branchID )
{
branchID = bndSegs[i]._prev->_branchID; // with sign
}
else if ( bndSegs[i]._edge && // 1st bndSeg of a WIRE
bndSegs[i]._inSeg->isConnected( bndSegs[i]._edge ))
{
branchEdges.resize(( branchID = branchEdges.size()) + 1 );
if ( bndSegs[i]._inSeg->point0() == bndSegs[i]._edge->vertex1() )
endType.insert( make_pair( bndSegs[i]._edge->vertex1(), SMESH_MAT2d::BE_ON_VERTEX ));
else
endType.insert( make_pair( bndSegs[i]._edge->vertex0(), SMESH_MAT2d::BE_ON_VERTEX ));
}
bndSegs[i].setBranch( branchID, bndSegsPerEdge ); // set to i-th and to the opposite bndSeg
if ( bndSegs[i].hasOppositeEdge() )
branchEdges[ bndSegs[i].branchID() ].push_back( bndSegs[i]._edge );
}
}
// join the 1st and the last branch edges if it is the same branch
if ( bndSegs.back().branchID() != bndSegs.front().branchID() &&
bndSegs.back().isSameBranch( bndSegs.front() ))
{
vector<const TVDEdge*> & br1 = branchEdges[ bndSegs.front().branchID() ];
vector<const TVDEdge*> & br2 = branchEdges[ bndSegs.back().branchID() ];
br1.insert( br1.begin(), br2.begin(), br2.end() );
br2.clear();
}
// if ( bndSegs.back().branchID() != bndSegs.front().branchID() &&
// bndSegs.back().isSameBranch( bndSegs.front() ))
// {
// vector<const TVDEdge*> & br1 = branchEdges[ bndSegs.front().branchID() ];
// vector<const TVDEdge*> & br2 = branchEdges[ bndSegs.back().branchID() ];
// br1.insert( br1.begin(), br2.begin(), br2.end() );
// br2.clear();
// }
// remove branches ending at BE_ON_VERTEX
@ -1010,34 +1094,38 @@ namespace
if ( !v0 && !v1 )
continue;
size_t iBrToJoin = 0;
for ( size_t iB2 = 1; iB2 < branchEdges.size(); ++iB2 )
for ( int isV0 = 0; isV0 < 2; ++isV0 )
{
if ( branchEdges[iB2].empty() || isBranchRemoved[iB2] || iB == iB2 )
continue;
const TVDVertex* v02 = branchEdges[iB2][0]->vertex1();
const TVDVertex* v12 = branchEdges[iB2].back()->vertex0();
if ( v0 == v02 || v0 == v12 || v1 == v02 || v1 == v12 )
const TVDVertex* v = isV0 ? v0 : v1;
size_t iBrToJoin = 0;
for ( size_t iB2 = 1; iB2 < branchEdges.size(); ++iB2 )
{
if ( iBrToJoin > 0 )
if ( branchEdges[iB2].empty() || isBranchRemoved[iB2] || iB == iB2 )
continue;
const TVDVertex* v02 = branchEdges[iB2][0]->vertex1();
const TVDVertex* v12 = branchEdges[iB2].back()->vertex0();
if ( v == v02 || v == v12 )
{
iBrToJoin = 0;
break; // more than 2 not removed branches meat at a TVDVertex
if ( iBrToJoin > 0 )
{
iBrToJoin = 0;
break; // more than 2 not removed branches meat at a TVDVertex
}
iBrToJoin = iB2;
}
iBrToJoin = iB2;
}
}
if ( iBrToJoin > 0 )
{
vector<const TVDEdge*>& branch = branchEdges[ iBrToJoin ];
const TVDVertex* v02 = branch[0]->vertex1();
const TVDVertex* v12 = branch.back()->vertex0();
updateJoinedBranch( branch, iB, bndSegs, /*reverse=*/(v0 == v02 || v1 == v12 ));
if ( v0 == v02 || v0 == v12 )
branchEdges[iB].insert( branchEdges[iB].begin(), branch.begin(), branch.end() );
else
branchEdges[iB].insert( branchEdges[iB].end(), branch.begin(), branch.end() );
branch.clear();
if ( iBrToJoin > 0 )
{
vector<const TVDEdge*>& branch = branchEdges[ iBrToJoin ];
const TVDVertex* v02 = branch[0]->vertex1();
const TVDVertex* v12 = branch.back()->vertex0();
updateJoinedBranch( branch, iB, bndSegsPerEdge, /*reverse=*/(v0 == v02 || v1 == v12 ));
if ( v0 == v02 || v0 == v12 )
branchEdges[iB].insert( branchEdges[iB].begin(), branch.begin(), branch.end() );
else
branchEdges[iB].insert( branchEdges[iB].end(), branch.begin(), branch.end() );
branch.clear();
}
}
} // loop on branchEdges
} // if ( ignoreCorners )
@ -1064,36 +1152,31 @@ namespace
// Fill in BndPoints of each EDGE of the boundary
size_t iSeg = 0;
//size_t iSeg = 0;
int edgeInd = -1, dInd = 0;
while ( iSeg < bndSegs.size() )
for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
{
const size_t geomID = bndSegs[ iSeg ].geomEdge();
SMESH_MAT2d::BndPoints & bndPoints = boundary.getPoints( geomID );
size_t nbSegs = 0;
for ( size_t i = iSeg; i < bndSegs.size() && geomID == bndSegs[ i ].geomEdge(); ++i )
++nbSegs;
size_t iSegEnd = iSeg + nbSegs;
vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
SMESH_MAT2d::BndPoints & bndPoints = boundary.getPoints( iE );
// make TVDEdge know an index of bndSegs within BndPoints
for ( size_t i = iSeg; i < iSegEnd; ++i )
for ( size_t i = 0; i < bndSegs.size(); ++i )
if ( bndSegs[i]._edge )
SMESH_MAT2d::Branch::setBndSegment( i - iSeg, bndSegs[i]._edge );
SMESH_MAT2d::Branch::setBndSegment( i, bndSegs[i]._edge );
// parameters on EDGE
bndPoints._params.reserve( nbSegs + 1 );
bndPoints._params.push_back( bndSegs[ iSeg ]._inSeg->_p0->_param );
bndPoints._params.reserve( bndSegs.size() + 1 );
bndPoints._params.push_back( bndSegs[ 0 ]._inSeg->_p0->_param );
for ( size_t i = iSeg; i < iSegEnd; ++i )
for ( size_t i = 0; i < bndSegs.size(); ++i )
bndPoints._params.push_back( bndSegs[ i ]._uLast );
// MA edges
bndPoints._maEdges.reserve( nbSegs );
bndPoints._maEdges.reserve( bndSegs.size() );
for ( size_t i = iSeg; i < iSegEnd; ++i )
for ( size_t i = 0; i < bndSegs.size(); ++i )
{
const size_t brID = bndSegs[ i ].branchID();
const SMESH_MAT2d::Branch* br = branchByID[ brID ];
@ -1136,9 +1219,6 @@ namespace
bndPoints._maEdges.push_back( make_pair( br, ( 1 + edgeInd ) * dInd ));
} // loop on bndSegs of an EDGE
iSeg = iSegEnd;
} // loop on all bndSegs to construct Boundary
// Initialize branches
@ -1352,7 +1432,7 @@ bool SMESH_MAT2d::Boundary::moveToClosestEdgeEnd( BoundaryPoint& bp ) const
return false;
const BndPoints& points = _pointsPerEdge[ bp._edgeIndex ];
if ( bp._param - points._params[0] < points._params.back() - bp._param )
if ( Abs( bp._param - points._params[0]) < Abs( points._params.back() - bp._param ))
bp._param = points._params[0];
else
bp._param = points._params.back();
@ -1658,7 +1738,7 @@ bool SMESH_MAT2d::Branch::addDivPntForConcaVertex( std::vector< std::size_t >&
std::vector< BranchPoint >& divPoints,
const vector<const TVDEdge*>& maEdges,
const vector<const TVDEdge*>& maEdgesTwin,
size_t & i) const
int & i) const
{
// if there is a concave vertex between EDGEs
// then position of a dividing BranchPoint is undefined, it is somewhere
@ -1670,11 +1750,13 @@ bool SMESH_MAT2d::Branch::addDivPntForConcaVertex( std::vector< std::size_t >&
BranchPoint divisionPnt;
divisionPnt._branch = this;
BranchIterator iCur( maEdges, i );
size_t ie1 = getGeomEdge( maEdges [i] );
size_t ie2 = getGeomEdge( maEdgesTwin[i] );
size_t iSeg1 = getBndSegment( maEdges[ i-1 ] );
size_t iSeg2 = getBndSegment( maEdges[ i ] );
size_t iSeg1 = getBndSegment( iCur.edgePrev() );
size_t iSeg2 = getBndSegment( iCur.edge() );
bool isConcaPrev = _boundary->isConcaveSegment( edgeIDs1.back(), iSeg1 );
bool isConcaNext = _boundary->isConcaveSegment( ie1, iSeg2 );
if ( !isConcaNext && !isConcaPrev )
@ -1682,46 +1764,48 @@ bool SMESH_MAT2d::Branch::addDivPntForConcaVertex( std::vector< std::size_t >&
bool isConcaveV = false;
int iPrev = i-1, iNext = i;
const TVDEdge* maE;
BranchIterator iPrev( maEdges, i ), iNext( maEdges, i );
--iPrev;
if ( isConcaNext ) // all null-length segments follow
{
// look for a VERTEX of the opposite EDGE
++iNext; // end of null-length segments
while ( iNext < maEdges.size() )
// iNext - next after all null-length segments
while ( maE = ++iNext )
{
iSeg2 = getBndSegment( maEdges[ iNext ] );
if ( _boundary->isConcaveSegment( ie1, iSeg2 ))
++iNext;
else
iSeg2 = getBndSegment( maE );
if ( !_boundary->isConcaveSegment( ie1, iSeg2 ))
break;
}
bool vertexFound = false;
for ( size_t iE = i+1; iE < iNext; ++iE )
for ( ++iCur; iCur < iNext; ++iCur )
{
ie2 = getGeomEdge( maEdgesTwin[iE] );
ie2 = getGeomEdge( maEdgesTwin[ iCur.indexMod() ] );
if ( ie2 != edgeIDs2.back() )
{
// opposite VERTEX found
divisionPnt._iEdge = iE;
divisionPnt._iEdge = iCur.indexMod();
divisionPnt._edgeParam = 0;
divPoints.push_back( divisionPnt );
edgeIDs1.push_back( ie1 );
edgeIDs2.push_back( ie2 );
vertexFound = true;
}
}
}
if ( vertexFound )
{
iPrev = i = --iNext; // not to add a BP in the moddle
--iNext;
iPrev = iNext; // not to add a BP in the moddle
i = iNext.indexMod();
isConcaveV = true;
}
}
else if ( isConcaPrev )
{
// all null-length segments passed, find their beginning
while ( iPrev-1 >= 0 )
while ( maE = iPrev.edgePrev() )
{
iSeg1 = getBndSegment( maEdges[ iPrev-1 ] );
iSeg1 = getBndSegment( maE );
if ( _boundary->isConcaveSegment( edgeIDs1.back(), iSeg1 ))
--iPrev;
else
@ -1729,17 +1813,18 @@ bool SMESH_MAT2d::Branch::addDivPntForConcaVertex( std::vector< std::size_t >&
}
}
if ( iPrev < i-1 || iNext > i )
if ( iPrev.index() < i-1 || iNext.index() > i )
{
// no VERTEX on the opposite EDGE, put the Branch Point in the middle
double par1 = _params[ iPrev+1 ], par2 = _params[ iNext ];
divisionPnt._iEdge = iPrev.indexMod();
++iPrev;
double par1 = _params[ iPrev.indexMod() ], par2 = _params[ iNext.indexMod() ];
double midPar = 0.5 * ( par1 + par2 );
divisionPnt._iEdge = iPrev;
while ( _params[ divisionPnt._iEdge + 1 ] < midPar )
++divisionPnt._iEdge;
for ( ; _params[ iPrev.indexMod() ] < midPar; ++iPrev )
divisionPnt._iEdge = iPrev.indexMod();
divisionPnt._edgeParam =
( _params[ divisionPnt._iEdge + 1 ] - midPar ) /
( _params[ divisionPnt._iEdge + 1 ] - _params[ divisionPnt._iEdge ] );
( _params[ iPrev.indexMod() ] - midPar ) /
( _params[ iPrev.indexMod() ] - _params[ divisionPnt._iEdge ] );
divPoints.push_back( divisionPnt );
isConcaveV = true;
}
@ -1767,50 +1852,74 @@ void SMESH_MAT2d::Branch::getOppositeGeomEdges( std::vector< std::size_t >& edge
edgeIDs2.clear();
divPoints.clear();
edgeIDs1.push_back( getGeomEdge( _maEdges[0] ));
edgeIDs2.push_back( getGeomEdge( _maEdges[0]->twin() ));
std::vector<const TVDEdge*> twins( _maEdges.size() );
for ( size_t i = 0; i < _maEdges.size(); ++i )
twins[i] = _maEdges[i]->twin();
BranchIterator maIter ( _maEdges, 0 );
BranchIterator twIter ( twins, 0 );
// size_t lastConcaE1 = _boundary.nbEdges();
// size_t lastConcaE2 = _boundary.nbEdges();
// if ( maIter._closed ) // closed branch
// {
// edgeIDs1.push_back( getGeomEdge( _maEdges.back() ));
// edgeIDs2.push_back( getGeomEdge( _maEdges.back()->twin() ));
// }
// else
{
edgeIDs1.push_back( getGeomEdge( maIter.edge() ));
edgeIDs2.push_back( getGeomEdge( twIter.edge() ));
}
BranchPoint divisionPnt;
divisionPnt._branch = this;
for ( size_t i = 0; i < _maEdges.size(); ++i )
for ( ++maIter, ++twIter; maIter.index() < _maEdges.size(); ++maIter, ++twIter )
{
size_t ie1 = getGeomEdge( _maEdges[i] );
size_t ie2 = getGeomEdge( _maEdges[i]->twin() );
if ( edgeIDs1.back() != ie1 || edgeIDs2.back() != ie2 )
size_t ie1 = getGeomEdge( maIter.edge() );
size_t ie2 = getGeomEdge( twIter.edge() );
bool otherE1 = ( edgeIDs1.back() != ie1 );
bool otherE2 = ( edgeIDs2.back() != ie2 );
if ( !otherE1 && !otherE2 && maIter._closed )
{
int iSegPrev1 = getBndSegment( maIter.edgePrev() );
int iSegCur1 = getBndSegment( maIter.edge() );
otherE1 = Abs( iSegPrev1 - iSegCur1 ) != 1;
int iSegPrev2 = getBndSegment( twIter.edgePrev() );
int iSegCur2 = getBndSegment( twIter.edge() );
otherE2 = Abs( iSegPrev2 - iSegCur2 ) != 1;
}
if ( otherE1 || otherE2 )
{
bool isConcaveV = false;
if ( edgeIDs1.back() != ie1 && edgeIDs2.back() == ie2 )
if ( otherE1 && !otherE2 )
{
isConcaveV = addDivPntForConcaVertex( edgeIDs1, edgeIDs2, divPoints, _maEdges, twins, i );
isConcaveV = addDivPntForConcaVertex( edgeIDs1, edgeIDs2, divPoints,
_maEdges, twins, maIter._i );
}
if ( edgeIDs1.back() == ie1 && edgeIDs2.back() != ie2 )
if ( !otherE1 && otherE2 )
{
isConcaveV = addDivPntForConcaVertex( edgeIDs2, edgeIDs1, divPoints, twins, _maEdges, i );
isConcaveV = addDivPntForConcaVertex( edgeIDs2, edgeIDs1, divPoints,
twins, _maEdges, maIter._i );
}
if ( isConcaveV )
{
ie1 = getGeomEdge( _maEdges[i] );
ie2 = getGeomEdge( _maEdges[i]->twin() );
ie1 = getGeomEdge( maIter.edge() );
ie2 = getGeomEdge( twIter.edge() );
}
if (( !isConcaveV ) ||
( edgeIDs1.back() != ie1 || edgeIDs2.back() != ie2 ))
if ( !isConcaveV || otherE1 || otherE2 )
{
edgeIDs1.push_back( ie1 );
edgeIDs2.push_back( ie2 );
}
if ( divPoints.size() < edgeIDs1.size() - 1 )
{
divisionPnt._iEdge = i;
divisionPnt._iEdge = maIter.index();
divisionPnt._edgeParam = 0;
divPoints.push_back( divisionPnt );
}

View File

@ -138,7 +138,7 @@ namespace SMESH_MAT2d
std::vector< BranchPoint >& divPoints,
const std::vector<const TVDEdge*>& maEdges,
const std::vector<const TVDEdge*>& maEdgesTwin,
size_t & i) const;
int & i) const;
// association of _maEdges with boundary segments is stored in this way:
// index of an EDGE: TVDEdge->cell()->color()

View File

@ -510,7 +510,6 @@ FunctorType Length2D_i::GetFunctorType()
SMESH::Length2D::Values* Length2D_i::GetValues()
{
INFOS("Length2D_i::GetValues");
SMESH::Controls::Length2D::TValues aValues;
(dynamic_cast<SMESH::Controls::Length2D*>(myFunctorPtr.get()))->GetValues( aValues );
@ -530,7 +529,6 @@ SMESH::Length2D::Values* Length2D_i::GetValues()
aValue.myPnt2 = aVal.myPntId[ 1 ];
}
INFOS("Length2D_i::GetValuess~");
return aResult._retn();
}
@ -581,7 +579,6 @@ FunctorType MultiConnection2D_i::GetFunctorType()
SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
{
INFOS("MultiConnection2D_i::GetValues");
SMESH::Controls::MultiConnection2D::MValues aValues;
(dynamic_cast<SMESH::Controls::MultiConnection2D*>(myFunctorPtr.get()))->GetValues( aValues );
@ -601,7 +598,6 @@ SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
aValue.myNbConnects = (*anIter).second;
}
INFOS("Multiconnection2D_i::GetValuess~");
return aResult._retn();
}
@ -1218,7 +1214,6 @@ FreeEdges_i::FreeEdges_i()
SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
{
INFOS("FreeEdges_i::GetBorders");
SMESH::Controls::FreeEdges::TBorders aBorders;
myFreeEdgesPtr->GetBoreders( aBorders );
@ -1237,8 +1232,6 @@ SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
aBorder.myPnt1 = aBord.myPntId[ 0 ];
aBorder.myPnt2 = aBord.myPntId[ 1 ];
}
INFOS("FreeEdges_i::GetBorders~");
return aResult._retn();
}

View File

@ -268,7 +268,6 @@ GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine() {
SMESH_Gen_i::SMESH_Gen_i()
{
INFOS( "SMESH_Gen_i::SMESH_Gen_i : default constructor" );
}
//=============================================================================
@ -1876,9 +1875,9 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
try {
// get mesh servant
SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
meshServant->Load();
ASSERT( meshServant );
if ( meshServant ) {
meshServant->Load();
// NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
meshServant->CheckGeomModif();
// get local TopoDS_Shape
@ -2157,6 +2156,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
ASSERT( meshServant );
if ( meshServant ) {
meshServant->Load();
// NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
meshServant->CheckGeomModif();
// get local TopoDS_Shape
@ -2178,7 +2178,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
{
SMESH_subMesh* sm = anIt->first;
SMESH_ComputeErrorPtr& error = sm->GetComputeError();
const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape());
const SMESH_Algo* algo = sm->GetAlgo();
if ( (algo && !error.get()) || error->IsOK() )
error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo));
}
@ -2965,8 +2965,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
const char* theURL,
bool isMultiFile )
{
INFOS( "SMESH_Gen_i::Save" );
// ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
// san -- in case <myCurrentStudy> differs from theComponent's study,
// use that of the component
@ -3908,7 +3906,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
if ( !isMultiFile )
SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
INFOS( "SMESH_Gen_i::Save() completed" );
return aStreamFile._retn();
}
@ -3975,8 +3972,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
const char* theURL,
bool isMultiFile )
{
INFOS( "SMESH_Gen_i::Load" );
if ( theComponent->GetStudy()->StudyId() != GetCurrentStudyID() )
SetCurrentStudy( theComponent->GetStudy() );
@ -3993,11 +3988,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
TCollection_AsciiString tmpDir =
( char* )( isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir().c_str() );
INFOS( "THE URL++++++++++++++" );
INFOS( theURL );
INFOS( "THE TMP PATH+++++++++" );
INFOS( tmpDir );
// Convert the stream into sequence of files to process
SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
tmpDir.ToCString(),
@ -4844,7 +4834,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
}
}
INFOS( "SMESH_Gen_i::Load completed" );
return true;
}

View File

@ -4700,6 +4700,14 @@ SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
}
}
// cout << endl << "INIT" << endl;
// for ( size_t i = 0; i < tmp0Delems.size(); ++i )
// {
// cout << i << " ";
// if ( i % 3 == 0 ) cout << "^ ";
// tmp0Delems[i]->GetNode(0)->Print( cout );
// }
SMESH_TRY;
::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
@ -4722,6 +4730,20 @@ SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
continue;
// TIDSortedElemSet emptySet, avoidSet;
// if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, emptySet, avoidSet))
// {
// cout << "WRONG 2nd 1" << endl;
// n0->Print( cout );
// n1->Print( cout );
// }
// if ( !SMESH_MeshAlgos::FindFaceInSet( n3, n4, emptySet, avoidSet))
// {
// cout << "WRONG 2nd 2" << endl;
// n3->Print( cout );
// n4->Print( cout );
// }
if ( !isBordToBord )
{
n1 = n2; // at border-to-side sewing only last side node (n1) is needed
@ -4735,6 +4757,13 @@ SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
groupSewed = ( res == ok );
isBordToBord = false;
// cout << endl << "SEWED GROUP " << i << " PART " << iN / 3 << endl;
// for ( size_t t = 0; t < tmp0Delems.size(); ++t )
// {
// cout << t << " ";
// if ( t % 3 == 0 ) cout << "^ ";
// tmp0Delems[t]->GetNode(0)->Print( cout );
// }
}
i0D += nodes.size();
nbSewed += groupSewed;

View File

@ -83,28 +83,31 @@ SMESH::SMESH_Pattern_ptr SMESH_Gen_i::GetPattern()
//=======================================================================
SMESH_Pattern_i::SMESH_Pattern_i( SMESH_Gen_i* theGen_i ):
myGen( theGen_i )
myGen( theGen_i )
{
}
//=======================================================================
//function : getMesh
//purpose :
//purpose :
//=======================================================================
::SMESH_Mesh* SMESH_Pattern_i::getMesh( SMESH::SMESH_Mesh_ptr & theMesh )
{
SMESH_Mesh_i* anImplPtr =
SMESH_Mesh_i* anImplPtr =
dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
if ( anImplPtr )
{
anImplPtr->Load();
return & anImplPtr->GetImpl();
}
return 0;
}
//=======================================================================
//function : LoadFromFile
//purpose :
//purpose :
//=======================================================================
CORBA::Boolean SMESH_Pattern_i::LoadFromFile(const char* theFileContents)

View File

@ -1022,23 +1022,23 @@ namespace
*/
//================================================================================
bool projectVertices( SMESH_MesherHelper& theHelper,
const SMESH_MAT2d::MedialAxis& theMA,
const vector< SMESH_MAT2d::BranchPoint >& theDivPoints,
const vector< std::size_t > & theEdgeIDs1,
const vector< std::size_t > & theEdgeIDs2,
const vector< bool >& theIsEdgeComputed,
TMAPar2NPoints & thePointsOnE,
SinuousFace& theSinuFace)
bool projectVertices( SMESH_MesherHelper& theHelper,
const SMESH_MAT2d::MedialAxis& theMA,
vector< SMESH_MAT2d::BranchPoint >& theDivPoints,
const vector< std::size_t > & theEdgeIDs1,
const vector< std::size_t > & theEdgeIDs2,
const vector< bool >& theIsEdgeComputed,
TMAPar2NPoints & thePointsOnE,
SinuousFace& theSinuFace)
{
SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
const vector<TopoDS_Edge>& theSinuEdges = theSinuFace._sinuEdges;
const vector< TopoDS_Edge >& theSinuEdges = theSinuFace._sinuEdges;
const vector< Handle(Geom_Curve) >& theCurves = theSinuFace._sinuCurves;
double uMA;
SMESH_MAT2d::BoundaryPoint bp[2];
const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
{
// add to thePointsOnE NodePoint's of ends of theSinuEdges
if ( !branch.getBoundaryPoints( 0., bp[0], bp[1] ) ||
!theMA.getBoundary().moveToClosestEdgeEnd( bp[0] )) return false;
@ -1048,17 +1048,18 @@ namespace
findVertexAndNode( np0, theSinuEdges, meshDS );
findVertexAndNode( np1, theSinuEdges, meshDS );
thePointsOnE.insert( make_pair( -0.1, make_pair( np0, np1 )));
}
if ( !theSinuFace.IsRing() )
{
if ( !branch.getBoundaryPoints( 1., bp[0], bp[1] ) ||
!theMA.getBoundary().moveToClosestEdgeEnd( bp[0] ) ||
!theMA.getBoundary().moveToClosestEdgeEnd( bp[1] )) return false;
np0 = bp[0]; np1 = bp[1];
NodePoint np0( bp[0] ), np1( bp[1] );
findVertexAndNode( np0, theSinuEdges, meshDS );
findVertexAndNode( np1, theSinuEdges, meshDS );
thePointsOnE.insert( make_pair( 1.1, make_pair( np0, np1)));
}
// project theDivPoints
if ( theDivPoints.empty() )
@ -1087,7 +1088,7 @@ namespace
if ( isVertex[0] && isVertex[1] )
continue;
const size_t iVert = isVertex[0] ? 0 : 1;
const size_t iNode = 1 - iVert;
const size_t iNode = 1 - iVert;
bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
if ( !isOppComputed )
@ -1275,6 +1276,16 @@ namespace
np = &get( u2NPnext->second, iSide );
u1 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
if ( u0 == u1 )
{
if ( np->_node ) --u2NPprev;
else ++u2NPnext;
np = &get( u2NPprev->second, iSide );
u0 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
np = &get( u2NPnext->second, iSide );
u1 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
}
// distribute points and create nodes
double du = ( u1 - u0 ) / ( sameU2NP.size() + 1 );
double u = u0 + du;
@ -1352,8 +1363,8 @@ namespace
TMAPar2NPoints::const_iterator u2NPdist, u2NP = thePointsOnEdges.begin();
for ( ; u2NP != thePointsOnEdges.end(); ++u2NP )
{
SMESH_TNodeXYZ xyz( u2NP->second.first._node );
dist = xyz.SquareDistance( u2NP->second.second._node );
SMESH_TNodeXYZ xyz( u2NP->second.first._node ); // node out
dist = xyz.SquareDistance( u2NP->second.second._node );// node in
if ( dist > maxDist )
{
u2NPdist = u2NP;
@ -1400,6 +1411,8 @@ namespace
theFace._quad->side[ 2 ] = theFace._quad->side[ 0 ];
// rotate the IN side if opposite nodes of IN and OUT sides don't match
if ( theFace._quad->side[ 1 ].GetUVPtStruct().empty() )
return false;
const SMDS_MeshNode * nIn0 = theFace._quad->side[ 1 ].First().node;
if ( nIn0 != nIn )
{
@ -1418,6 +1431,10 @@ namespace
uvsNew.insert( uvsNew.end(), uvsIn.begin() + i, uvsIn.end() );
uvsNew.insert( uvsNew.end(), uvsIn.begin() + 1, uvsIn.begin() + i + 1);
theFace._quad->side[ 1 ] = StdMeshers_FaceSide::New( uvsNew );
if ( theFace._quad->side[ 1 ].NbPoints() !=
theFace._quad->side[ 3 ].NbPoints())
return false;
}
} // if ( theShortEdges[0].empty() )
@ -1902,6 +1919,7 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::computeQuads( SMESH_MesherHelper& theHe
// create quadrangles
bool ok;
theHelper.SetElementsOnShape( true );
if ( nbNodesShort0 == nbNodesShort1 )
ok = StdMeshers_Quadrangle_2D::computeQuadDominant( *theHelper.GetMesh(),
theQuad->face, theQuad );

View File

@ -3848,7 +3848,7 @@ void StdMeshers_Quadrangle_2D::updateDegenUV(FaceQuadStruct::Ptr quad)
// Set number of nodes on a degenerated side to be same as on an opposite side
// ----------------------------------------------------------------------------
for ( unsigned i = 0; i < quad->side.size(); ++i )
for ( size_t i = 0; i < quad->side.size(); ++i )
{
StdMeshers_FaceSidePtr degSide = quad->side[i];
if ( !myHelper->IsDegenShape( degSide->EdgeID(0) ))