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> <li>For meshing of 1D entities (<b>edges</b>):</li>
\anchor a1d_algos_anchor \anchor a1d_algos_anchor
<ul> <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. number of mesh segments following an 1D hypothesis.
</li> </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 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 composed of several edges provided that they form C1 curve in all
faces of the main shape.</li> 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> <li>For meshing of 2D entities (<b>faces</b>):</li>
<ul> <ul>
<li><em>Triangle (Mefisto)</em> meshing algorithm - splits faces <li><b>Triangle (Mefisto)</b> meshing algorithm - splits faces
into triangular elements.</li> into triangular elements.</li>
<li>\subpage quad_ijk_algo_page "Quadrangle (Mapping)" meshing <li>\subpage quad_ijk_algo_page "Quadrangle (Mapping)" meshing
algorithm - splits faces into quadrangular elements.</li> 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> <li>For meshing of 3D entities (<b>solid objects</b>):</li>
<ul> <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 split into hexahedral elements thus forming a structured 3D
mesh. The algorithm requires that 2D mesh generated on a solid could 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 be considered as a mesh of a box, i.e. there should be eight nodes
by three quadrangles and the rest nodes should be shared by four shared by three quadrangles and the rest nodes should be shared by
quadrangles. four quadrangles.
\image html hexa_ijk_mesh.png "Structured mesh generated by Hexahedron (i,j,k) on a solid bound by 16 faces" \image html hexa_ijk_mesh.png "Structured mesh generated by Hexahedron (i,j,k) on a solid bound by 16 faces"
</li> </li>
@ -59,25 +59,25 @@ number of mesh segments following an 1D hypothesis.
\image html image126.gif "Example of a hexahedral 3D mesh" \image html image126.gif "Example of a hexahedral 3D mesh"
</ul> </ul>
Some 3D meshing algorithms, such as Hexahedron(i,j,k) and some Some 3D meshing algorithms, such as Hexahedron(i,j,k) also can
commercial ones, also can generate 3D meshes from 2D meshes, working generate 3D meshes from 2D meshes, working without geometrical
without geometrical objects. objects.
There is also a number of more specific algorithms: There is also a number of more specific algorithms:
<ul> <ul>
<li>\subpage prism_3d_algo_page "for meshing prismatic 3D shapes"</li> <li>\subpage prism_3d_algo_page "for meshing prismatic 3D shapes with hexahedra and prisms"</li>
<li>\subpage quad_from_ma_algo_page "for meshing faces with sinuous borders"</li> <li>\subpage quad_from_ma_algo_page "for quadrangle meshing of faces with sinuous borders"</li>
<li> <em>Polygon per Face</em> meshing algorithm - generates one mesh <li> <b>Polygon per Face</b> meshing algorithm - generates one mesh
face (either a triangle, a quadrangle or a polygon) per a geometrical face (either a triangle, a quadrangle or a polygon) per a geometrical
face using all nodes from the face boundary.</li> face using all nodes from the face boundary.</li>
<li>\subpage projection_algos_page "for meshing by projection of another mesh"</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 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_prism_algo_page "for meshing 3D geometrical objects with cavities with hexahedra and prisms"</li>
<li>\subpage radial_quadrangle_1D2D_algo_page "for meshing special faces (circles and parts of circles)"</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 <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 \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> 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> <li>\subpage segments_around_vertex_algo_page "for defining the length of mesh segments around certain vertices"</li>
</ul> </ul>
\ref constructing_meshes_page "Constructing meshes" page describes in \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 check-box and apply the pattern to
<ul> <ul>
<li> One or several <b>Mesh volumes</b> instead of a geometric 3D object</li> <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> </ul>
Additionally it is possible to: Additionally it is possible to:
<ul> <ul>

View File

@ -3,15 +3,20 @@
\page segments_around_vertex_algo_page Segments around Vertex \page segments_around_vertex_algo_page Segments around Vertex
\n <b>Segments around Vertex</b> algorithm is considered to be a 0D meshing \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 algorithm, but, of course, it doesn't mesh vertices. It allows to define
the local size of the elements in the neighborhood of a certain the local size of the segments in the neighborhood of a certain
node. If we choose an object of higher dimension, it applies to all vertex. If we assign this algorithm to a geometrical object of higher
its tops, i.e. corners of a box. The 0D algorithm combines with the dimension, it applies to all its vertices.
algorithms of higher dimensions, but it is not necessarily required
for their successful implementation.
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 \image html lengthnearvertex.png
*/
*/

View File

@ -943,7 +943,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh,
if ( !hasAlgo ) { if ( !hasAlgo ) {
ret = false; ret = false;
theErrors.push_back( TAlgoStateError() ); 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; return ret;

View File

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

View File

@ -1822,12 +1822,12 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
SMESH_Hypothesis::Hypothesis_Status hyp_status; SMESH_Hypothesis::Hypothesis_Status hyp_status;
algo = GetAlgo(); algo = GetAlgo();
if(algo && !aResMap.count(this) ) if( algo && !aResMap.count( this ))
{ {
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (!ret) return false; if (!ret) return false;
if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary()) if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary() )
{ {
// check submeshes needed // check submeshes needed
bool subMeshEvaluated = true; bool subMeshEvaluated = true;
@ -1845,8 +1845,23 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
return false; return false;
} }
_computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo); _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))); 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)) "); hasFacesOrVolumes("(({'Face'} in elemTypes) || ({'Volume'} in elemTypes)) ");
createPopupItem( SMESHOp::OpFileInformation, OB, mesh, "&& selcount=1 && isImported" ); createPopupItem( SMESHOp::OpFileInformation, OB, mesh, "&& selcount=1 && isImported" );
createPopupItem( SMESHOp::OpCreateSubMesh, OB, mesh, "&& isComputable"); createPopupItem( SMESHOp::OpCreateSubMesh, OB, mesh, "&& hasGeomReference");
createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, mesh, "&& isComputable"); createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, mesh );
createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, subMesh, "&& isComputable" ); createPopupItem( SMESHOp::OpEditMeshOrSubMesh, OB, subMesh, "&& hasGeomReference" );
createPopupItem( SMESHOp::OpEditGroup, OB, group ); createPopupItem( SMESHOp::OpEditGroup, OB, group );
createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" ); createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" );
popupMgr()->insert( separator(), -1, 0 ); popupMgr()->insert( separator(), -1, 0 );
createPopupItem( SMESHOp::OpCompute, OB, mesh, "&& isComputable" ); 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::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::OpUpdate, OB, mesh_part );
createPopupItem( SMESHOp::OpMeshInformation, OB, mesh_part ); createPopupItem( SMESHOp::OpMeshInformation, OB, mesh_part );
createPopupItem( SMESHOp::OpFindElementByPoint, OB, mesh_group ); createPopupItem( SMESHOp::OpFindElementByPoint, OB, mesh_group );
createPopupItem( SMESHOp::OpOverallMeshQuality, OB, mesh_part ); createPopupItem( SMESHOp::OpOverallMeshQuality, OB, mesh_part );
popupMgr()->insert( separator(), -1, 0 ); popupMgr()->insert( separator(), -1, 0 );
createPopupItem( SMESHOp::OpCreateGroup, OB, mesh ); createPopupItem( SMESHOp::OpCreateGroup, OB, mesh );
createPopupItem( SMESHOp::OpCreateGeometryGroup, OB, mesh ); createPopupItem( SMESHOp::OpCreateGeometryGroup, OB, mesh, "&& hasGeomReference" );
createPopupItem( SMESHOp::OpConstructGroup, OB, subMesh ); createPopupItem( SMESHOp::OpConstructGroup, OB, subMesh );
popupMgr()->insert( separator(), -1, 0 ); popupMgr()->insert( separator(), -1, 0 );
createPopupItem( SMESHOp::OpEditHypothesis, OB, hypo); createPopupItem( SMESHOp::OpEditHypothesis, OB, hypo);
createPopupItem( SMESHOp::OpUnassign, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS createPopupItem( SMESHOp::OpUnassign, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS
popupMgr()->insert( separator(), -1, 0 ); 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::OpConvertMeshToQuadratic, OB, mesh + " " + subMesh ); // convert to quadratic
createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh + " " + group, // create 2D mesh from 3D createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh + " " + group, // create 2D mesh from 3D
"&& dim>=2"); "&& dim>=2");
popupMgr()->insert( separator(), -1, 0 ); 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 only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
QString multiple_non_empty = QString( " && %1>0 && 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, void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
QMap<int,int>& theModeMap) QMap<int,int>& theModeMap)
{ {
_PTR(SObject) aHypRoot; if ( !theMesh ) return;
_PTR(SObject) aHypFolder;
_PTR(GenericAttribute) anAttr; _PTR(GenericAttribute) anAttr;
int aPart = SMESH::Tag_RefOnAppliedAlgorithms; int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
if ( theMesh && theMesh->FindSubObject( aPart, aHypRoot ) ) if ( theMesh->FindSubObject( aPart, aHypFolder ) )
{ {
_PTR(ChildIterator) anIter = _PTR(ChildIterator) anIter =
SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot ); SMESH::GetActiveStudyDocument()->NewChildIterator( aHypFolder );
for ( ; anIter->More(); anIter->Next() ) for ( ; anIter->More(); anIter->Next() )
{ {
_PTR(SObject) anObj = anIter->Value(); _PTR(SObject) anObj = anIter->Value();
@ -1743,16 +1744,16 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
anObj = aRefObj; anObj = aRefObj;
else else
continue; continue;
if ( anObj->FindAttribute( anAttr, "AttributeName" ) ) if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
{ {
CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject(); CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
if ( CORBA::is_nil( aVar ) ) if ( CORBA::is_nil( aVar ) )
continue; continue;
SMESH::SMESH_Algo_var algo;
for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ ) for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
{ {
SMESH::SMESH_Algo_var algo;
switch(dim) { switch(dim) {
case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break; 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_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
@ -1760,7 +1761,56 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
default: break; default: break;
} }
if ( !algo->_is_nil() ) if ( !algo->_is_nil() )
{
theModeMap[ dim ] = 0; 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_IdValidator.h"
#include "SMESHGUI_FilterDlg.h" #include "SMESHGUI_FilterDlg.h"
#include <SMESH_TypeFilter.hxx>
#include <SMESH_Actor.h> #include <SMESH_Actor.h>
#include <SMDS_Mesh.hxx> #include <SMDS_Mesh.hxx>
@ -208,14 +209,18 @@ void SMESHGUI_RemoveNodesDlg::Init()
connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView())); connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
connect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView())); connect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)), connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)),
SLOT(onTextChange(const QString&))); this, SLOT (onTextChange(const QString&)));
SMESH::SetPointRepresentation(true); SMESH::SetPointRepresentation(true);
mySelectionMgr->clearFilters();
mySelectionMgr->installFilter( new SMESH_TypeFilter( SMESH::IDSOURCE ));
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(NodeSelection); aViewWindow->SetSelectionMode(NodeSelection);
SelectionIntoArgument(); //SelectionIntoArgument();
mySelectionMgr->setSelectedObjects( SALOME_ListIO() );
} }
//================================================================================= //=================================================================================
@ -412,16 +417,16 @@ void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument()
myBusy = true; myBusy = true;
myEditCurrentArgument->setText(aString); myEditCurrentArgument->setText(aString);
myBusy = false; myBusy = false;
// OK // OK
myNbOkNodes = nbNodes; myNbOkNodes = nbNodes;
} // if (nbNodes > 0) } // if (nbNodes > 0)
} // if (myActor) } // if (myActor)
} // if (!myMesh->_is_nil()) } // if (!myMesh->_is_nil())
} // if (nbSel == 1) } // if (nbSel == 1)
updateButtons(); updateButtons();
} }
//================================================================================= //=================================================================================
@ -474,6 +479,9 @@ void SMESHGUI_RemoveNodesDlg::ActivateThisDialog()
mySMESHGUI->SetActiveDialogBox((QDialog*)this); // ?? mySMESHGUI->SetActiveDialogBox((QDialog*)this); // ??
mySelectionMgr->clearFilters();
mySelectionMgr->installFilter( new SMESH_TypeFilter( SMESH::IDSOURCE ));
SMESH::SetPointRepresentation(true); SMESH::SetPointRepresentation(true);
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(NodeSelection); 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=="displayMode" ) val = QVariant( displayMode( ind ) );
else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) ); else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) );
else if ( p=="isPreComputable" ) val = QVariant( isPreComputable( 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=="isImported" ) val = QVariant( isImported( ind ) );
else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) ); else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
else if ( p=="groupType" ) val = QVariant( groupType( ind ) ); else if ( p=="groupType" ) val = QVariant( groupType( ind ) );
@ -492,62 +492,58 @@ int SMESHGUI_Selection::dim( int ind ) const
//======================================================================= //=======================================================================
//function : isComputable //function : isComputable
//purpose : //purpose : return true for a ready-to-compute mesh
//======================================================================= //=======================================================================
QVariant SMESHGUI_Selection::isComputable( int ind ) const 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() ); _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
CORBA::Object_var obj = SMESH::SObjectToObject( so, SMESH::GetActiveStudyDocument() ); SMESHGUI_PrecomputeOp::getAssignedAlgos( so, modeMap );
if( !CORBA::is_nil( obj ) ) { return QVariant( modeMap.size() > 0 );
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() );
}
}
} }
return QVariant( false ); return QVariant( false );
} }
//======================================================================= //=======================================================================
//function : isPreComputable //function : isPreComputable
//purpose : //purpose : returns true for a mesh with algorithms
//======================================================================= //=======================================================================
QVariant SMESHGUI_Selection::isPreComputable( int ind ) const 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; int maxDim = dim( ind );
_PTR(SObject) pMesh = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() ); if ( maxDim < 2 ) // we can preview 1D or 2D
SMESHGUI_PrecomputeOp::getAssignedAlgos( pMesh, modeMap ); {
return QVariant( modeMap.size() > 1 ); 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 ); return QVariant( false );
} }
//======================================================================= //=======================================================================
//function : hasReference //function : hasGeomReference
//purpose : //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 int dim( int ) const;
virtual QVariant isComputable( int ) const; virtual QVariant isComputable( int ) const;
virtual QVariant isPreComputable( int ) const; virtual QVariant isPreComputable( int ) const;
virtual QVariant hasReference( int ) const; virtual QVariant hasGeomReference( int ) const;
virtual QVariant isVisible( int ) const; virtual QVariant isVisible( int ) const;
virtual QString quadratic2DMode( int ) const; virtual QString quadratic2DMode( int ) const;

View File

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

View File

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

View File

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

View File

@ -268,7 +268,6 @@ GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine() {
SMESH_Gen_i::SMESH_Gen_i() 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 { try {
// get mesh servant // get mesh servant
SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() ); SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
meshServant->Load();
ASSERT( meshServant ); ASSERT( meshServant );
if ( meshServant ) { if ( meshServant ) {
meshServant->Load();
// NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
meshServant->CheckGeomModif(); meshServant->CheckGeomModif();
// get local TopoDS_Shape // 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() ); SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
ASSERT( meshServant ); ASSERT( meshServant );
if ( meshServant ) { if ( meshServant ) {
meshServant->Load();
// NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
meshServant->CheckGeomModif(); meshServant->CheckGeomModif();
// get local TopoDS_Shape // 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_subMesh* sm = anIt->first;
SMESH_ComputeErrorPtr& error = sm->GetComputeError(); 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() ) if ( (algo && !error.get()) || error->IsOK() )
error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo)); 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, const char* theURL,
bool isMultiFile ) bool isMultiFile )
{ {
INFOS( "SMESH_Gen_i::Save" );
// ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() ) // ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
// san -- in case <myCurrentStudy> differs from theComponent's study, // san -- in case <myCurrentStudy> differs from theComponent's study,
// use that of the component // use that of the component
@ -3908,7 +3906,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
if ( !isMultiFile ) if ( !isMultiFile )
SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
INFOS( "SMESH_Gen_i::Save() completed" );
return aStreamFile._retn(); return aStreamFile._retn();
} }
@ -3975,8 +3972,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
const char* theURL, const char* theURL,
bool isMultiFile ) bool isMultiFile )
{ {
INFOS( "SMESH_Gen_i::Load" );
if ( theComponent->GetStudy()->StudyId() != GetCurrentStudyID() ) if ( theComponent->GetStudy()->StudyId() != GetCurrentStudyID() )
SetCurrentStudy( theComponent->GetStudy() ); SetCurrentStudy( theComponent->GetStudy() );
@ -3993,11 +3988,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
TCollection_AsciiString tmpDir = TCollection_AsciiString tmpDir =
( char* )( isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir().c_str() ); ( 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 // Convert the stream into sequence of files to process
SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream, SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
tmpDir.ToCString(), tmpDir.ToCString(),
@ -4844,7 +4834,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
} }
} }
INFOS( "SMESH_Gen_i::Load completed" );
return true; 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_TRY;
::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK; ::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 ) if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
continue; 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 ) if ( !isBordToBord )
{ {
n1 = n2; // at border-to-side sewing only last side node (n1) is needed 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 ); groupSewed = ( res == ok );
isBordToBord = false; 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(); i0D += nodes.size();
nbSewed += groupSewed; 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 ): SMESH_Pattern_i::SMESH_Pattern_i( SMESH_Gen_i* theGen_i ):
myGen( theGen_i ) myGen( theGen_i )
{ {
} }
//======================================================================= //=======================================================================
//function : getMesh //function : getMesh
//purpose : //purpose :
//======================================================================= //=======================================================================
::SMESH_Mesh* SMESH_Pattern_i::getMesh( SMESH::SMESH_Mesh_ptr & theMesh ) ::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() ); dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
if ( anImplPtr ) if ( anImplPtr )
{
anImplPtr->Load();
return & anImplPtr->GetImpl(); return & anImplPtr->GetImpl();
}
return 0; return 0;
} }
//======================================================================= //=======================================================================
//function : LoadFromFile //function : LoadFromFile
//purpose : //purpose :
//======================================================================= //=======================================================================
CORBA::Boolean SMESH_Pattern_i::LoadFromFile(const char* theFileContents) CORBA::Boolean SMESH_Pattern_i::LoadFromFile(const char* theFileContents)

View File

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