mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-26 14:40:33 +05:00
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:
parent
f15b6ceb9f
commit
67909c435c
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
*/
|
||||
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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 );
|
||||
|
@ -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) ))
|
||||
|
Loading…
Reference in New Issue
Block a user