Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4e3a6d188b | ||
![]() |
6e3eeaa6b3 | ||
![]() |
156112ef20 | ||
![]() |
d3b58de064 | ||
![]() |
de95b32809 | ||
![]() |
9dd9f7684c | ||
![]() |
63567f57a1 | ||
![]() |
d67308f4f8 | ||
![]() |
f55dbc13fb | ||
![]() |
75973dbe64 | ||
![]() |
8db3567826 | ||
![]() |
e60bcaf4a9 | ||
![]() |
49eb5ff195 | ||
![]() |
42a135c4a7 |
@ -41,6 +41,18 @@ ENDIF()
|
||||
SALOME_SETUP_VERSION(9.13.0)
|
||||
MESSAGE(STATUS "Building ${PROJECT_NAME_UC} ${${PROJECT_NAME_UC}_VERSION} from \"${${PROJECT_NAME_UC}_GIT_SHA1}\"")
|
||||
|
||||
|
||||
# Find SalomeBootstrap
|
||||
# ===========
|
||||
SET(SALOMEBOOTSTRAP_ROOT_DIR $ENV{SALOMEBOOTSTRAP_ROOT_DIR} CACHE PATH "Path to the Salome Bootstrap")
|
||||
IF(EXISTS ${SALOMEBOOTSTRAP_ROOT_DIR})
|
||||
FIND_PACKAGE(SalomeBootstrap REQUIRED)
|
||||
ADD_DEFINITIONS(${SALOMEBOOTSTRAP_DEFINITIONS})
|
||||
INCLUDE_DIRECTORIES(${SALOMEBOOTSTRAP_INCLUDE_DIRS})
|
||||
ELSE(EXISTS ${SALOMEBOOTSTRAP_ROOT_DIR})
|
||||
MESSAGE(FATAL_ERROR "We absolutely need a Salome Bootstrap, please define SALOMEBOOTSTRAP_ROOT_DIR")
|
||||
ENDIF(EXISTS ${SALOMEBOOTSTRAP_ROOT_DIR})
|
||||
|
||||
# Find KERNEL
|
||||
# ===========
|
||||
SET(KERNEL_ROOT_DIR $ENV{KERNEL_ROOT_DIR} CACHE PATH "Path to the Salome KERNEL")
|
||||
|
2
README
@ -45,7 +45,7 @@ site:
|
||||
|
||||
* Check Release Notes and Software Requirements of the latest SALOME release at
|
||||
|
||||
<https://www.salome-platform.org/?page_id=15/>
|
||||
<https://github.com/SalomePlatform/.github/wiki/SAT/>
|
||||
|
||||
Note: SALOME Mesh module needs SALOME KERNEL, SALOME GUI and SALOME Geometry as
|
||||
pre-requisites.
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 6.7 KiB |
BIN
doc/gui/images/image88.jpg
Normal file → Executable file
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 12 KiB |
BIN
doc/gui/images/image89.jpg
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
doc/gui/images/reload_mesh_modif_mesh.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
doc/gui/images/reload_mesh_modif_mesh_props.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
doc/gui/images/reload_mesh_orig_mesh.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
doc/gui/images/reload_mesh_result.png
Normal file
After Width: | Height: | Size: 37 KiB |
@ -1,4 +1,5 @@
|
||||
.. _a1d_meshing_hypo_page:
|
||||
.. |larr| unicode:: U+02190 .. LEFTWARDS ARROW
|
||||
|
||||
*********************
|
||||
1D Meshing Hypotheses
|
||||
@ -57,7 +58,7 @@ Adaptive hypothesis
|
||||
Arithmetic Progression hypothesis
|
||||
#################################
|
||||
|
||||
**Arithmetic Progression** hypothesis allows to split edges into segments with a length that changes in arithmetic progression (Lk = Lk-1 + d) beginning from a given starting length and up to a given end length.
|
||||
**Arithmetic Progression** hypothesis allows to split edges into segments with a length that changes in arithmetic progression (L\ :sub:`k`\ |larr| L\ :sub:`k-1`\ + d) beginning from a given starting length and up to a given end length.
|
||||
|
||||
The splitting direction is defined by the orientation of the underlying geometrical edge. **Reverse Edges** list box allows specifying the edges, for which the splitting should be made in the direction opposite to their orientation. This list box is usable only if a geometry object is selected for meshing. In this case it is possible to select edges to be reversed either directly picking them in the 3D viewer or by selecting the edges or groups of edges in the Object Browser. Use
|
||||
**Add** button to add the selected edges to the list.
|
||||
@ -82,7 +83,7 @@ The splitting direction is defined by the orientation of the underlying geometri
|
||||
Geometric Progression hypothesis
|
||||
################################
|
||||
|
||||
**Geometric Progression** hypothesis allows splitting edges into segments with a length that changes in geometric progression (Lk = Lk-1 * d) starting from a given **Start Length** and with a given **Common Ratio**.
|
||||
**Geometric Progression** hypothesis allows splitting edges into segments with a length that changes in geometric progression (L\ :sub:`k`\ |larr| L\ :sub:`k-1`\ * d) starting from a given **Start Length** and with a given **Common Ratio**.
|
||||
|
||||
The splitting direction is defined by the orientation of the underlying geometrical edge.
|
||||
**Reverse Edges** list box allows specifying the edges, for which the splitting should be made in the direction opposite to their orientation. This list box is usable only if a geometry object is selected for meshing. In this case it is possible to select edges to be reversed either directly picking them in the 3D viewer or by selecting the edges or groups of edges in the Object Browser. Use **Add** button to add the selected edges to the list.
|
||||
@ -177,7 +178,7 @@ You can set the type of node distribution for this hypothesis in the **Hypothesi
|
||||
|
||||
**Scale Distribution** - length of segments gradually changes depending on the **Scale Factor**, which is a ratio of the first segment length to the last segment length.
|
||||
|
||||
Length of segments changes in geometric progression with the common ratio (A) depending on the **Scale Factor** (S) and **Number of Segments** (N) as follows: A = S**(1/(N-1)). For an edge of length L, length of the first segment is L * (1 - A)/(1 - A**N)
|
||||
Length of segments changes in geometric progression with the common ratio (A) depending on the **Scale Factor** (S) and **Number of Segments** (N) as follows: A = S\ :sup:`(1/(N-1))`\ . For an edge of length L, length of the first segment is L * (1 - A)/(1 - A\ :sup:`N`\ )
|
||||
|
||||
.. image:: ../images/a-nbsegments2.png
|
||||
:align: center
|
||||
|
@ -210,6 +210,10 @@ When the Preview dialog is closed, the question about the storage of temporarily
|
||||
|
||||
These elements can be kept in the mesh.
|
||||
|
||||
Since the mesh, its submesh(es) and group(s) are now not empty, their **Object Browser** icons will be updated accordingly.
|
||||
|
||||
.. image:: ../images/image89.jpg
|
||||
:align: center
|
||||
|
||||
.. _submesh_order_anchor:
|
||||
|
||||
|
41
doc/gui/input/reload_mesh_from_file.rst
Normal file
@ -0,0 +1,41 @@
|
||||
.. _reload_mesh_from_file_page:
|
||||
|
||||
*******************
|
||||
Reload mesh from file
|
||||
*******************
|
||||
|
||||
This operation allows reload original imported mesh, which was modified by different dedicated tools
|
||||
|
||||
*Reload mesh from file:*
|
||||
|
||||
|
||||
#. Select a mesh(es) (and display it in the 3D Viewer if you are going to pick elements by mouse).
|
||||
#. From popup menu click on the *Reload from file* item
|
||||
|
||||
Each selected mesh will be updated to orignal state with saving display properties
|
||||
|
||||
.. image:: ../images/reload_mesh_orig_mesh.png
|
||||
:align: center
|
||||
|
||||
.. centered::
|
||||
Original mesh
|
||||
|
||||
|
|
||||
|
||||
.. image:: ../images/reload_mesh_modif_mesh.png
|
||||
:align: center
|
||||
|
||||
.. centered::
|
||||
Same mesh after apply "Merge Nodes"
|
||||
|
||||
.. image:: ../images/reload_mesh_modif_mesh_props.png
|
||||
:align: center
|
||||
|
||||
.. centered::
|
||||
Set display properties
|
||||
|
||||
.. image:: ../images/reload_mesh_result.png
|
||||
:align: center
|
||||
|
||||
.. centered::
|
||||
Result after reload mesh
|
@ -258,6 +258,9 @@ module SMESH
|
||||
SMESH_Mesh CreateEmptyMesh()
|
||||
raises ( SALOME::SALOME_Exception );
|
||||
|
||||
SMESH_Mesh ReloadMeshFromFile(in SMESH_Mesh sourceMesh)
|
||||
raises(SALOME::SALOME_Exception);
|
||||
|
||||
/*!
|
||||
* Create Mesh object importing data from given UNV file
|
||||
* (UNV supported version is I-DEAS 10)
|
||||
@ -302,6 +305,7 @@ module SMESH
|
||||
out SMESH::DriverMED_ReadStatus theStatus)
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
|
||||
/*!
|
||||
* Create a dual mesh of a Tetrahedron mesh
|
||||
* \param mesh - TetraHedron mesh to create dual from
|
||||
|
@ -1131,6 +1131,7 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P )
|
||||
if (nbNodes==10) nbNodes=4; // quadratic tetrahedron
|
||||
else if(nbNodes==13) nbNodes=5; // quadratic pyramid
|
||||
else if(nbNodes==15) nbNodes=6; // quadratic pentahedron
|
||||
else if(nbNodes==18) nbNodes=6; // bi-quadratic pentahedron
|
||||
else if(nbNodes==20) nbNodes=8; // quadratic hexahedron
|
||||
else if(nbNodes==27) nbNodes=8; // tri-quadratic hexahedron
|
||||
else return aQuality;
|
||||
|
@ -266,25 +266,25 @@ static int QuadPyram_RE [5][9] = { // REVERSED -> FORWARD (EXTERNAL)
|
||||
static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 };
|
||||
|
||||
/*
|
||||
// + N4
|
||||
// /|\
|
||||
// 9/ | \10
|
||||
// / | \
|
||||
// / | \
|
||||
// N3 +----+----+ N5
|
||||
// | |11 |
|
||||
// | | |
|
||||
// | +13 | QUADRATIC
|
||||
// | | | PENTAHEDRON
|
||||
// 12+ | +14
|
||||
// | | |
|
||||
// | | |
|
||||
// | + N1 |
|
||||
// | / \ |
|
||||
// | 6/ \7 |
|
||||
// | / \ |
|
||||
// |/ \|
|
||||
// N0 +---------+ N2
|
||||
// + N4 +
|
||||
// /|\ /|\
|
||||
// 9/ | \10 + | +
|
||||
// / | \ / | \
|
||||
// / | \ / | \
|
||||
// N3 +----+----+ N5 +----+----+
|
||||
// | |11 | | | |
|
||||
// | | | | | | Central nodes
|
||||
// | +13 | QUADRATIC | 16 + | of bi-quadratic
|
||||
// | | | PENTAHEDRON | + | + | PENTAHEDRON
|
||||
// 12+ | +14 + | 17 +
|
||||
// | | | | 18| |
|
||||
// | | | | | |
|
||||
// | + N1 | | + |
|
||||
// | / \ | | / \ |
|
||||
// | 6/ \7 | | + + |
|
||||
// | / \ | | / \ |
|
||||
// |/ \| |/ \|
|
||||
// N0 +---------+ N2 +---------+
|
||||
// 8
|
||||
*/
|
||||
static int QuadPenta_F [5][9] = { // FORWARD
|
||||
@ -301,6 +301,20 @@ static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL
|
||||
{ 0, 12,3, 11,5, 14,2, 8, 0 }};
|
||||
static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 };
|
||||
|
||||
static int BiQuadPenta_F[5][9] = { // FORWARD
|
||||
{ 0, 6, 1, 7, 2, 8, 0, 0, 0 },
|
||||
{ 3, 11,5, 10,4, 9, 3, 3, 3 },
|
||||
{ 0, 12,3, 9, 4, 13,1, 6, 16}, //!
|
||||
{ 1, 13,4, 10,5, 14,2, 7, 17}, //!
|
||||
{ 0, 8, 2, 14,5, 11,3, 12,18} }; //!
|
||||
static int BiQuadPenta_RE[5][9] = { // REVERSED -> EXTERNAL
|
||||
{ 0, 8, 2, 7, 1, 6, 0, 0, 0 },
|
||||
{ 3, 9, 4, 10,5, 11,3, 3, 3 },
|
||||
{ 0, 6, 1, 13,4, 9, 3, 12,17}, //!
|
||||
{ 1, 7, 2, 14,5, 10,4, 13,16}, //!
|
||||
{ 0, 12,3, 11,5, 14,2, 8, 18} }; //!
|
||||
static int BiQuadPenta_nbN[] = { 6, 6, 9, 9, 9 };
|
||||
|
||||
/*
|
||||
// 13
|
||||
// N5+-----+-----+N6 +-----+-----+
|
||||
@ -634,6 +648,14 @@ void SMDS_VolumeTool::Inverse ()
|
||||
SWAP_NODES( myVolumeNodes, 9, 11 );
|
||||
SWAP_NODES( myVolumeNodes, 13, 14 );
|
||||
break;
|
||||
case 18:
|
||||
SWAP_NODES(myVolumeNodes, 1, 2);
|
||||
SWAP_NODES(myVolumeNodes, 4, 5);
|
||||
SWAP_NODES(myVolumeNodes, 6, 8);
|
||||
SWAP_NODES(myVolumeNodes, 9, 11);
|
||||
SWAP_NODES(myVolumeNodes, 13, 14);
|
||||
SWAP_NODES(myVolumeNodes, 16, 17);
|
||||
break;
|
||||
case 20:
|
||||
SWAP_NODES( myVolumeNodes, 1, 3 );
|
||||
SWAP_NODES( myVolumeNodes, 5, 7 );
|
||||
@ -677,6 +699,7 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const
|
||||
case 10: return QUAD_TETRA;
|
||||
case 13: return QUAD_PYRAM;
|
||||
case 15: return QUAD_PENTA;
|
||||
case 18: return QUAD_PENTA;
|
||||
case 20: return QUAD_HEXA;
|
||||
case 27: return QUAD_HEXA;
|
||||
default: break;
|
||||
@ -862,6 +885,8 @@ double SMDS_VolumeTool::GetSize() const
|
||||
myVolumeNodes[ vtab[i][2] ],
|
||||
myVolumeNodes[ vtab[i][3] ]);
|
||||
}
|
||||
if (!myVolForward && V < 0)
|
||||
V *= -1;
|
||||
}
|
||||
return V;
|
||||
}
|
||||
@ -1705,6 +1730,16 @@ int SMDS_VolumeTool::GetCenterNodeIndex( int faceIndex ) const
|
||||
return faceIndex + 19;
|
||||
}
|
||||
}
|
||||
else if (myAllFacesNbNodes && myVolumeNodes.size() == 18) // element with 18 nodes
|
||||
{
|
||||
switch (faceIndex) {
|
||||
case 2: return 15;
|
||||
case 3: return 16;
|
||||
case 4: return 17;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1727,6 +1762,7 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
|
||||
switch ( myVolumeNodes.size() ) {
|
||||
case 6:
|
||||
case 15:
|
||||
case 18:
|
||||
if ( faceIndex == 0 || faceIndex == 1 )
|
||||
ind = 1 - faceIndex;
|
||||
break;
|
||||
@ -2469,6 +2505,7 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const
|
||||
myMaxFaceNbNodes = sizeof(QuadPyram_F[0])/sizeof(QuadPyram_F[0][0]);
|
||||
break;
|
||||
case 15:
|
||||
case 18:
|
||||
myAllFacesNodeIndices_F = &QuadPenta_F [0][0];
|
||||
//myAllFacesNodeIndices_FE = &QuadPenta_FE[0][0];
|
||||
myAllFacesNodeIndices_RE = &QuadPenta_RE[0][0];
|
||||
@ -2535,7 +2572,8 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes)
|
||||
case 8: return HEXA;
|
||||
case 10: return QUAD_TETRA;
|
||||
case 13: return QUAD_PYRAM;
|
||||
case 15: return QUAD_PENTA;
|
||||
case 15:
|
||||
case 18: return QUAD_PENTA;
|
||||
case 20:
|
||||
case 27: return QUAD_HEXA;
|
||||
case 12: return HEX_PRISM;
|
||||
|
@ -86,6 +86,8 @@
|
||||
namespace fs=boost::filesystem;
|
||||
#endif
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
// maximum stored group name length in MED file
|
||||
#define MAX_MED_GROUP_NAME_LENGTH 80
|
||||
|
||||
@ -713,6 +715,8 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = CheckHypothesesOnSubMeshes(subMesh, anHyp, event);
|
||||
}
|
||||
HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty
|
||||
GetMeshDS()->Modified();
|
||||
@ -1002,6 +1006,78 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const
|
||||
return anHyp;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Iterates hypotesis for all sub-meshes of the given sub-mesh and checks
|
||||
algo state with the given event. The goal is to address hypothesis those are
|
||||
not directly affected by changing of an algorithm of the given sub-shape.
|
||||
It is essential to rebuild propagation chains of such hypotheses, otherwise the chains
|
||||
are being cleared after editing of the algorithm and never rebuilt again.
|
||||
* \param subMesh - the main sub-mesh to check sub-meshes of
|
||||
* \param anHyp - the hypothesis changed on the given sub-mesh, we need to skip it from checking
|
||||
* \param event - the given event
|
||||
* \retval SMESH_Hypothesis::Hypothesis_Status - HYP_OK if no errors found, otherwise the most severe error
|
||||
*/
|
||||
//================================================================================
|
||||
SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh::CheckHypothesesOnSubMeshes(
|
||||
SMESH_subMesh* subMesh,
|
||||
const SMESH_Hypothesis* anHyp,
|
||||
const SMESH_subMesh::algo_event event) const
|
||||
{
|
||||
SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::Hypothesis_Status::HYP_OK;
|
||||
|
||||
// Cache the processed hypotheses for performance reasons.
|
||||
// Given hypothesis is already processed, so should be skipped.
|
||||
std::unordered_set<const SMESH_Hypothesis*> processedHypotheses = { anHyp };
|
||||
|
||||
// Look through sub-meshes of the given sub-mesh
|
||||
SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false, false);
|
||||
while (smIt->more())
|
||||
{
|
||||
const SMESH_subMesh* sm = smIt->next();
|
||||
const SMESH_Algo* algo = sm->GetAlgo();
|
||||
if (!algo)
|
||||
continue;
|
||||
|
||||
const SMESH_HypoFilter* hypoKind = algo->GetCompatibleHypoFilter(false);
|
||||
if (!hypoKind)
|
||||
continue;
|
||||
|
||||
std::list <const SMESHDS_Hypothesis*> usedHyps;
|
||||
if (!GetHypotheses(sm, *hypoKind, usedHyps, true))
|
||||
continue;
|
||||
|
||||
// Look through hypotheses used by algo
|
||||
for (const auto* usedHyp : usedHyps)
|
||||
{
|
||||
SMESH_Hypothesis* hyp = GetHypothesis(usedHyp->GetID());
|
||||
if (hyp == anHyp)
|
||||
continue;
|
||||
|
||||
if (processedHypotheses.find(hyp) != processedHypotheses.end())
|
||||
continue;
|
||||
|
||||
processedHypotheses.insert(hyp); // Cache the hypothesis pointer
|
||||
|
||||
// Hypoteses restricted by Propagation only because of failed tests.
|
||||
// It's ok for now, because this method was created to fix propagation issue.
|
||||
// It should be investigated more if we find similar issues with other hypotheses.
|
||||
const char* hypName = hyp->GetName();
|
||||
if (strcmp(hypName, "Propagation") != 0)
|
||||
continue;
|
||||
|
||||
const SMESH_Hypothesis::Hypothesis_Status ret2 = subMesh->SubMeshesAlgoStateEngine(event, hyp, true);
|
||||
if (ret2 > ret)
|
||||
{
|
||||
ret = ret2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
*
|
||||
|
@ -175,6 +175,11 @@ class SMESH_EXPORT SMESH_Mesh
|
||||
|
||||
SMESH_Hypothesis * GetHypothesis(const int aHypID) const;
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status CheckHypothesesOnSubMeshes(
|
||||
SMESH_subMesh* subMesh,
|
||||
const SMESH_Hypothesis* anHyp,
|
||||
const SMESH_subMesh::algo_event event) const;
|
||||
|
||||
const std::list<SMESHDS_Command*> & GetLog();
|
||||
|
||||
void ClearLog();
|
||||
|
@ -9483,7 +9483,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
|
||||
case SMDSEntity_TriQuad_Hexa:
|
||||
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
|
||||
nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
|
||||
for ( size_t i = 20; i < nodes.size(); ++i ) // rm central nodes
|
||||
for (size_t i = 8; i < nodes.size(); ++i) // rm central nodes from each edge
|
||||
//for (size_t i = 20; i < nodes.size(); ++i) // rm central nodes from each edge
|
||||
if ( nodes[i]->NbInverseElements() == 0 )
|
||||
GetMeshDS()->RemoveFreeNode( nodes[i], /*sm=*/0, /*fromGroups=*/true );
|
||||
break;
|
||||
@ -9496,7 +9497,9 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
|
||||
case SMDSEntity_BiQuad_Penta:
|
||||
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
|
||||
nodes[3], nodes[4], nodes[5], id, theForce3d);
|
||||
for ( size_t i = 15; i < nodes.size(); ++i ) // rm central nodes
|
||||
|
||||
for (size_t i = 6; i < nodes.size(); ++i) // rm central nodes
|
||||
//for ( size_t i = 15; i < nodes.size(); ++i ) // rm central nodes
|
||||
if ( nodes[i]->NbInverseElements() == 0 )
|
||||
GetMeshDS()->RemoveFreeNode( nodes[i], /*sm=*/0, /*fromGroups=*/true );
|
||||
break;
|
||||
@ -13037,15 +13040,58 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
|
||||
if (iQuad)
|
||||
for ( inode = 1; inode < nbFaceNodes; inode += 2)
|
||||
nodes.push_back( nn[inode] ); // add medium nodes
|
||||
int iCenter = vTool.GetCenterNodeIndex(iface); // for HEX27
|
||||
if ( iCenter > 0 )
|
||||
nodes.push_back( vTool.GetNodes()[ iCenter ] );
|
||||
|
||||
if (const SMDS_MeshElement * f = aMesh->FindElement( nodes,
|
||||
SMDSAbs_Face, /*noMedium=*/false ))
|
||||
presentBndElems.push_back( f );
|
||||
// for triangle face for Penta18 (BiQuadratic pentahedron) return -2
|
||||
// because we haven't center node on triangle side, but it's need for create biquadratic face
|
||||
int iCenter = vTool.GetCenterNodeIndex(iface); // for HEX27
|
||||
|
||||
// for triangle faces for Penta18 (BiQuadratic pentahedron) firstly check, exist face or not
|
||||
// if not - create node in middle face
|
||||
if (iCenter == -2)
|
||||
{
|
||||
SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
|
||||
bool isFound = false;
|
||||
while (itF->more())
|
||||
{
|
||||
const SMDS_MeshElement* e = itF->next();
|
||||
int nbNodesToCheck = e->NbNodes();
|
||||
if (nbNodesToCheck == (int)nodes.size() + 1)
|
||||
{
|
||||
for (size_t i = 1; e && i < nodes.size() - 1; ++i)
|
||||
{
|
||||
int nodeIndex = e->GetNodeIndex(nodes[i]);
|
||||
if (nodeIndex < 0 || nodeIndex >= nbNodesToCheck)
|
||||
e = 0;
|
||||
}
|
||||
if (e)
|
||||
{
|
||||
presentBndElems.push_back(e);
|
||||
isFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFound)
|
||||
{
|
||||
SMESH_MesherHelper aHelper(*myMesh);
|
||||
double bc[3];
|
||||
vTool.GetFaceBaryCenter(iface, bc[0], bc[1], bc[2]);
|
||||
auto aNodeC = aHelper.AddNode(bc[0], bc[1], bc[2]);
|
||||
nodes.push_back(aNodeC);
|
||||
missingBndElems.push_back(nodes);
|
||||
}
|
||||
}
|
||||
else
|
||||
missingBndElems.push_back( nodes );
|
||||
{
|
||||
if (iCenter > 0)
|
||||
nodes.push_back(vTool.GetNodes()[iCenter]);
|
||||
|
||||
if (const SMDS_MeshElement* f = aMesh->FindElement(nodes,
|
||||
SMDSAbs_Face, /*noMedium=*/false))
|
||||
presentBndElems.push_back(f);
|
||||
else
|
||||
missingBndElems.push_back(nodes);
|
||||
}
|
||||
|
||||
if ( targetMesh != myMesh )
|
||||
{
|
||||
|
@ -35,7 +35,8 @@ using namespace std;
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
SMESHDS_Script::SMESHDS_Script(bool theIsEmbeddedMode):
|
||||
myIsEmbeddedMode(theIsEmbeddedMode)
|
||||
myIsEmbeddedMode(theIsEmbeddedMode),
|
||||
myIsModified(true)
|
||||
{
|
||||
//cerr << "=========================== myIsEmbeddedMode " << myIsEmbeddedMode << endl;
|
||||
}
|
||||
|
@ -86,6 +86,8 @@ class SMESHDS_EXPORT SMESHDS_SubMesh : public SMDS_ElementHolder
|
||||
virtual void tmpClear();
|
||||
virtual void add( const SMDS_MeshElement* element );
|
||||
virtual void compact() {}
|
||||
// Commented out to avoid SMESH_netgen_runner_1D2D3D test failure
|
||||
// virtual void clear() override { Clear(); }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -122,6 +122,9 @@
|
||||
|
||||
#include "SMESH_version.h"
|
||||
|
||||
#include "SMESHDS_Mesh.hxx"
|
||||
#include "SMESH_Mesh.hxx"
|
||||
|
||||
#include "SMESH_Actor.h"
|
||||
#include "SMESH_ActorUtils.h"
|
||||
#include "SMESH_Client.hxx"
|
||||
@ -221,6 +224,8 @@ namespace
|
||||
|
||||
void ExportMeshToFile(int theCommandID);
|
||||
|
||||
void ReloadMeshFromFile(int theCommandID);
|
||||
|
||||
void SetDisplayMode(int theCommandID, VTK::MarkerMap& theMarkerMap);
|
||||
|
||||
void SetDisplayEntity(int theCommandID);
|
||||
@ -410,9 +415,6 @@ namespace
|
||||
{
|
||||
_PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] );
|
||||
if ( aMeshSO ) {
|
||||
_PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
|
||||
_PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" );
|
||||
aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
|
||||
if ( theCommandID == SMESHOp::OpImportUNV ) // mesh names aren't taken from the file for UNV import
|
||||
SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() );
|
||||
|
||||
@ -1079,6 +1081,84 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Reload selected mesh from file a file
|
||||
*/
|
||||
//================================================================================
|
||||
void ReloadMeshFromFile(int theCommandID)
|
||||
{
|
||||
LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
|
||||
SALOME_ListIO selected;
|
||||
if (aSel)
|
||||
aSel->selectedObjects(selected);
|
||||
|
||||
QList< QPair< SMESH::SMESH_IDSource_var, QString > > aMeshList;
|
||||
QList< QPair< SMESH::SMESH_IDSource_var, QString > >::iterator aMeshIter;
|
||||
SALOME_ListIteratorOfListIO It(selected);
|
||||
|
||||
// Iterate by all selected
|
||||
for (; It.More(); It.Next())
|
||||
{
|
||||
Handle(SALOME_InteractiveObject) anIObject = It.Value();
|
||||
SMESH::SMESH_IDSource_var aMeshItem =
|
||||
SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(anIObject);
|
||||
|
||||
if (aMeshItem->_is_nil()) {
|
||||
SUIT_MessageBox::warning(SMESHGUI::desktop(),
|
||||
QObject::tr("SMESH_WRN_WARNING"),
|
||||
QObject::tr("SMESH_BAD_MESH_SELECTION"));
|
||||
continue;
|
||||
}
|
||||
|
||||
SMESH::SMESH_Mesh_var aMeshByIO = SMESH::GetMeshByIO(anIObject);
|
||||
SMESH::SelectionProxy aMesh = SMESH::SelectionProxy(aMeshItem);
|
||||
SMESH::MedInfo anInfo = aMesh.medFileInfo();
|
||||
if (!anInfo.isValid())
|
||||
continue;
|
||||
|
||||
SMESH::ListOfGroups aGroups = *aMeshByIO->GetGroups();
|
||||
for (int i = 0; i < aGroups.length(); ++i)
|
||||
{
|
||||
auto X = aGroups[i];
|
||||
_PTR(SObject) aGroupSObject = SMESH::FindSObject(X);
|
||||
SMESH_Actor* anActor = SMESH::FindActorByEntry(aGroupSObject->GetID().c_str());
|
||||
SMESH::smIdType_array aMeshInfo = *X->GetMeshInfo();
|
||||
|
||||
if (anActor)
|
||||
{
|
||||
vtkTypeBool isVisib = anActor->GetVisibility();
|
||||
SMESH::UpdateView(!isVisib ? SMESH::eDisplay : SMESH::eErase, aGroupSObject->GetID().c_str());
|
||||
}
|
||||
else
|
||||
SMESH::UpdateView(SMESH::eErase, aGroupSObject->GetID().c_str());
|
||||
}
|
||||
|
||||
SMESH::mesh_array_var aMeshes = new SMESH::mesh_array;
|
||||
{
|
||||
// re-import mesh
|
||||
SMESH::SMESH_Mesh_var aReloadedMesh = SMESHGUI::GetSMESHGen()->ReloadMeshFromFile(aMeshByIO);
|
||||
|
||||
QStringList anEntryList;
|
||||
|
||||
_PTR(SObject) aMeshSO = SMESH::FindSObject(aReloadedMesh);
|
||||
if (aMeshSO) {
|
||||
anEntryList.append(aMeshSO->GetID().c_str());
|
||||
}
|
||||
SMESHGUI::GetSMESHGUI()->updateObjBrowser();
|
||||
if (LightApp_Application* anApp =
|
||||
dynamic_cast<LightApp_Application*>(SUIT_Session::session()->activeApplication()))
|
||||
anApp->browseObjects(anEntryList);
|
||||
}
|
||||
|
||||
SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(aMeshItem);
|
||||
QString aMeshName = anIObject->getName();
|
||||
aMeshList.append(QPair< SMESH::SMESH_IDSource_var, QString >(aMeshItem, aMeshName));
|
||||
|
||||
}
|
||||
SMESH::UpdateView();
|
||||
}
|
||||
|
||||
inline void InverseEntityMode(unsigned int& theOutputMode,
|
||||
unsigned int theMode)
|
||||
{
|
||||
@ -2691,7 +2771,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
|
||||
::ImportMeshesFromFile(GetSMESHGen(),theCommandID);
|
||||
break;
|
||||
}
|
||||
|
||||
case SMESHOp::OpReloadFromFile:
|
||||
{
|
||||
if (isStudyLocked()) break;
|
||||
::ReloadMeshFromFile(theCommandID);
|
||||
break;
|
||||
}
|
||||
case SMESHOp::OpFileInformation:
|
||||
{
|
||||
SALOME_ListIO selected;
|
||||
@ -3484,7 +3569,6 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SMESHOp::OpFindElementByPoint:
|
||||
{
|
||||
startOperation( theCommandID );
|
||||
@ -4320,6 +4404,7 @@ void SMESHGUI::initialize( CAM_Application* app )
|
||||
//createSMESHAction( SMESHOp::OpStdInfo, "STD_INFO", "ICON_STD_INFO" );
|
||||
//createSMESHAction( SMESHOp::OpWhatIs, "WHAT_IS", "ICON_WHAT_IS" ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
|
||||
createSMESHAction( SMESHOp::OpFindElementByPoint, "FIND_ELEM", "ICON_FIND_ELEM" );
|
||||
createSMESHAction( SMESHOp::OpReloadFromFile, "RELOAD_FROM_FILE");
|
||||
//update
|
||||
createSMESHAction( SMESHOp::OpFreeNode, "FREE_NODE", "ICON_FREE_NODE", 0, true );
|
||||
createSMESHAction( SMESHOp::OpEqualNode, "EQUAL_NODE", "ICON_EQUAL_NODE", 0, true );
|
||||
@ -4932,6 +5017,7 @@ void SMESHGUI::initialize( CAM_Application* app )
|
||||
createPopupItem( SMESHOp::OpFileInformation, OB, mesh, "&& selcount=1 && isImported" );
|
||||
createPopupItem( SMESHOp::OpMeshInformation, OB, mesh_part );
|
||||
createPopupItem( SMESHOp::OpFindElementByPoint,OB, mesh_group, "&& selcount=1 && " + hasElems );
|
||||
createPopupItem( SMESHOp::OpReloadFromFile, OB, mesh, "&& isImported");
|
||||
createPopupItem( SMESHOp::OpOverallMeshQuality,OB, mesh_part );
|
||||
popupMgr()->insert( separator(), -1, 0 );
|
||||
createPopupItem( SMESHOp::OpCreateGroup, OB, mesh, "&& selcount=1" );
|
||||
|
@ -94,6 +94,7 @@ namespace SMESHOp {
|
||||
OpWhatIs = 2101, // MENU MESH - MESH ELEMENT INFORMATION
|
||||
OpStdInfo = 2102, // MENU MESH - MESH STANDARD INFORMATION
|
||||
OpFindElementByPoint = 2103, // MENU MESH - FIND ELEMENT BY POINT
|
||||
OpReloadFromFile = 2104, // MENU MESH - RELOAD MESH FROM FILE
|
||||
OpUpdate = 2200, // POPUP MENU - UPDATE
|
||||
// Controls -----------------------//--------------------------------
|
||||
OpFreeNode = 3000, // MENU CONTROLS - FREE NODES
|
||||
|
@ -272,6 +272,10 @@
|
||||
<source>MEN_ADV_INFO</source>
|
||||
<translation>Mesh Information</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MEN_RELOAD_FROM_FILE</source>
|
||||
<translation>Reload from file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MEN_ALL</source>
|
||||
<translation>All</translation>
|
||||
@ -3332,6 +3336,10 @@ Use Display Entity menu command to show them.
|
||||
<source>STB_ADV_INFO</source>
|
||||
<translation>Show base information about the mesh object</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>STB_RELOAD_FROM_FILE</source>
|
||||
<translation>Reload original mesh from file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>STB_ALL</source>
|
||||
<translation>All</translation>
|
||||
@ -4072,6 +4080,10 @@ Use Display Entity menu command to show them.
|
||||
<source>TOP_ADV_INFO</source>
|
||||
<translation>Mesh Information</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TOP_RELOAD_FROM_FILE</source>
|
||||
<translation>Reload from file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TOP_ALL</source>
|
||||
<translation>All</translation>
|
||||
|
@ -268,6 +268,10 @@
|
||||
<source>MEN_ADV_INFO</source>
|
||||
<translation>Informations sur le maillage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MEN_RELOAD_FROM_FILE</source>
|
||||
<translation>Reload from file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MEN_ALL</source>
|
||||
<translation>Tous</translation>
|
||||
@ -3331,6 +3335,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher.
|
||||
<source>STB_ALL</source>
|
||||
<translation>Tous</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>STB_RELOAD_FROM_FILE</source>
|
||||
<translation>Reload original mesh from file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>STB_AREA</source>
|
||||
<translation>Aire</translation>
|
||||
@ -4067,6 +4075,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher.
|
||||
<source>TOP_ADV_INFO</source>
|
||||
<translation>Informations sur le maillage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TOP_RELOAD_FROM_FILE</source>
|
||||
<translation>Reload from file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TOP_ALL</source>
|
||||
<translation>Tous</translation>
|
||||
|
@ -251,6 +251,10 @@
|
||||
<source>MEN_ADV_INFO</source>
|
||||
<translation>メッシュに関する情報</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MEN_RELOAD_FROM_FILE</source>
|
||||
<translation>Reload from file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MEN_ALL</source>
|
||||
<translation>すべて</translation>
|
||||
@ -2979,6 +2983,10 @@ pip install meshio[all]</translation>
|
||||
<source>STB_ADV_INFO</source>
|
||||
<translation>メッシュ上の基本的な情報を得る</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>STB_RELOAD_FROM_FILE</source>
|
||||
<translation>Reload original mesh from file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>STB_ALL</source>
|
||||
<translation>すべて</translation>
|
||||
@ -3663,6 +3671,10 @@ pip install meshio[all]</translation>
|
||||
<source>TOP_ADV_INFO</source>
|
||||
<translation>メッシュに関する情報</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TOP_RELOAD_FROM_FILE</source>
|
||||
<translation>Reload from file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TOP_ALL</source>
|
||||
<translation>すべて</translation>
|
||||
|
@ -23,6 +23,7 @@ INCLUDE_DIRECTORIES(
|
||||
${KERNEL_INCLUDE_DIRS}
|
||||
${OpenCASCADE_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${SALOMEBOOTSTRAP_INCLUDE_DIRS}
|
||||
${PROJECT_SOURCE_DIR}/src/SMDS
|
||||
)
|
||||
|
||||
@ -38,6 +39,7 @@ SET(_link_LIBRARIES
|
||||
${OpenCASCADE_FoundationClasses_LIBRARIES}
|
||||
${OpenCASCADE_ModelingData_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
SALOMEException
|
||||
SMDS
|
||||
)
|
||||
|
||||
|
@ -1013,6 +1013,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
|
||||
{
|
||||
// there are methods to convert:
|
||||
// CreateMesh( shape )
|
||||
// ReloadMesh( shape )
|
||||
// Concatenate( [mesh1, ...], ... )
|
||||
// CreateHypothesis( theHypType, theLibName )
|
||||
// Compute( mesh, geom )
|
||||
@ -1067,6 +1068,13 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
|
||||
Handle(_pyMesh) mesh = new _pyMesh( theCommand, entries.front() );
|
||||
AddObject( mesh );
|
||||
}
|
||||
if (method == "ReloadMeshFromFile")
|
||||
{
|
||||
std::cout << "WhatIS" << std::endl;
|
||||
Handle(_pyMesh) mesh = new _pyMesh(theCommand, theCommand->GetResultValue());
|
||||
AddObject(mesh);
|
||||
return;
|
||||
}
|
||||
|
||||
// CreateHypothesis()
|
||||
if ( method == "CreateHypothesis" )
|
||||
|
@ -153,6 +153,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <QStringList>
|
||||
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/serialization/list.hpp>
|
||||
@ -1330,6 +1331,61 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh()
|
||||
return mesh._retn();
|
||||
}
|
||||
|
||||
SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ReloadMeshFromFile(SMESH::SMESH_Mesh_ptr theMesh)
|
||||
{
|
||||
SMESH::mesh_array_var aMeshes = new SMESH::mesh_array;
|
||||
|
||||
SMESH::MedFileInfo* aMedInfo = theMesh->GetMEDFileInfo();
|
||||
|
||||
// Get file path and re-import mesh
|
||||
QString aPath = QString(aMedInfo->fileName);
|
||||
QStringList aSplit = aPath.split('.');
|
||||
QStringList anEntryList;
|
||||
|
||||
auto aStudy = getStudyServant();
|
||||
|
||||
SMESH::SMESH_Mesh_ptr aNewMesh;
|
||||
|
||||
SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*> (theMesh->GetMeshPtr());
|
||||
aMesh->GetMeshDS()->ClearMesh();
|
||||
|
||||
if (aSplit.last() == "cgns")
|
||||
{
|
||||
SMESH::DriverMED_ReadStatus res;
|
||||
aMeshes = ReloadMeshesFromCGNS(aPath.toUtf8().constData(), theMesh, res);
|
||||
|
||||
aNewMesh = aMeshes[0];
|
||||
|
||||
}
|
||||
else if (aSplit.last().contains("stl", Qt::CaseSensitivity::CaseInsensitive))
|
||||
{
|
||||
aNewMesh = ReloadMeshesFromSTL(aPath.toUtf8().constData(), theMesh);
|
||||
}
|
||||
else if (aSplit.last().contains("unv", Qt::CaseSensitivity::CaseInsensitive))
|
||||
{
|
||||
aNewMesh = ReloadMeshesFromUNV(aPath.toUtf8().constData(), theMesh);
|
||||
}
|
||||
else if (aSplit.last().contains("mesh", Qt::CaseSensitivity::CaseInsensitive))
|
||||
{
|
||||
SMESH::ComputeError_var res;
|
||||
aNewMesh = ReloadMeshesFromGMF(aPath.toUtf8().constData(), theMesh, true, res.out());
|
||||
}
|
||||
else if (aSplit.last().contains("med", Qt::CaseSensitivity::CaseInsensitive))
|
||||
{
|
||||
SMESH::DriverMED_ReadStatus res;
|
||||
aMeshes = ReloadMeshesFromMED(aPath.toUtf8().constData(), theMesh, res);
|
||||
|
||||
aNewMesh = aMeshes[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// MeshIO
|
||||
}
|
||||
|
||||
theMesh = SMESH::SMESH_Mesh::_duplicate(aNewMesh);
|
||||
return theMesh;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
//================================================================================
|
||||
@ -1401,12 +1457,15 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
|
||||
checkFileReadable( theFileName );
|
||||
|
||||
SMESH::SMESH_Mesh_var aMesh = createMesh();
|
||||
|
||||
string aFileName;
|
||||
|
||||
// publish mesh in the study
|
||||
if ( CanPublishInStudy( aMesh ) ) {
|
||||
SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
|
||||
aStudyBuilder->NewCommand(); // There is a transaction
|
||||
SALOMEDS::SObject_wrap aSO = PublishMesh( aMesh.in(), aFileName.c_str() );
|
||||
SALOMEDS::SObject_wrap aSO =
|
||||
PublishMesh( aMesh.in(), aFileName.c_str(), "ICON_SMESH_TREE_MESH_IMPORTED" );
|
||||
aStudyBuilder->CommitCommand();
|
||||
if ( !aSO->_is_nil() ) {
|
||||
// Update Python script
|
||||
@ -1425,6 +1484,36 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
|
||||
return aMesh._retn();
|
||||
}
|
||||
|
||||
SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ReloadMeshesFromUNV(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh)
|
||||
{
|
||||
Unexpect aCatch(SALOME_SalomeException);
|
||||
|
||||
checkFileReadable(theFileName);
|
||||
|
||||
string aFileName;
|
||||
// publish mesh in the study
|
||||
if (CanPublishInStudy(sourceMesh)) {
|
||||
SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
|
||||
aStudyBuilder->NewCommand(); // There is a transaction
|
||||
SALOMEDS::SObject_wrap aSO = PublishMesh(sourceMesh, aFileName.c_str());
|
||||
aStudyBuilder->CommitCommand();
|
||||
if (!aSO->_is_nil()) {
|
||||
// Update Python script
|
||||
TPythonDump(this) << aSO << " = " << this << ".ReloadMeshesFromUNV(r'" << theFileName << "')";
|
||||
}
|
||||
}
|
||||
|
||||
SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>(GetServant(sourceMesh).in());
|
||||
ASSERT(aServant);
|
||||
aServant->ImportUNVFile(theFileName);
|
||||
|
||||
// Dump creation of groups
|
||||
SMESH::ListOfGroups_var groups = aServant->GetGroups();
|
||||
|
||||
aServant->GetImpl().GetMeshDS()->Modified();
|
||||
return sourceMesh;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* SMESH_Gen_i::CreateMeshFromMED
|
||||
@ -1438,13 +1527,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char*
|
||||
{
|
||||
checkFileReadable( theFileName );
|
||||
|
||||
#ifdef WIN32
|
||||
char bname[ _MAX_FNAME ];
|
||||
_splitpath( theFileName, NULL, NULL, bname, NULL );
|
||||
string aFileName = bname;
|
||||
#else
|
||||
string aFileName = basename( const_cast<char *>( theFileName ));
|
||||
#endif
|
||||
// Retrieve mesh names from the file
|
||||
DriverMED_R_SMESHDS_Mesh myReader;
|
||||
myReader.SetFile( theFileName );
|
||||
@ -1481,7 +1563,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char*
|
||||
// publish mesh in the study
|
||||
SALOMEDS::SObject_wrap aSO;
|
||||
if ( CanPublishInStudy( mesh ) )
|
||||
aSO = PublishMesh( mesh.in(), meshName.c_str() );
|
||||
aSO = PublishMesh( mesh.in(), meshName.c_str(), "ICON_SMESH_TREE_MESH_IMPORTED" );
|
||||
|
||||
// Python Dump
|
||||
if ( !aSO->_is_nil() ) {
|
||||
@ -1515,6 +1597,92 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char*
|
||||
return aResult._retn();
|
||||
}
|
||||
|
||||
SMESH::mesh_array* SMESH_Gen_i::ReloadMeshesFromMED(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh, SMESH::DriverMED_ReadStatus& theStatus)
|
||||
{
|
||||
SMESH::ListOfGroups anOldGroups = *sourceMesh->GetGroups();
|
||||
checkFileReadable(theFileName);
|
||||
|
||||
#ifdef WIN32
|
||||
char bname[_MAX_FNAME];
|
||||
_splitpath(theFileName, NULL, NULL, bname, NULL);
|
||||
string aFileName = bname;
|
||||
#else
|
||||
string aFileName = basename(const_cast<char*>(theFileName));
|
||||
#endif
|
||||
// Retrieve mesh names from the file
|
||||
DriverMED_R_SMESHDS_Mesh myReader;
|
||||
myReader.SetFile(theFileName);
|
||||
myReader.SetMeshId(-1);
|
||||
Driver_Mesh::Status aStatus;
|
||||
list<string> aNames = myReader.GetMeshNames(aStatus);
|
||||
SMESH::mesh_array_var aResult = new SMESH::mesh_array();
|
||||
theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
|
||||
|
||||
{ // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
|
||||
|
||||
// Python Dump
|
||||
TPythonDump aPythonDump(this);
|
||||
aPythonDump << "([";
|
||||
|
||||
if (theStatus == SMESH::DRS_OK)
|
||||
{
|
||||
SALOMEDS::StudyBuilder_var aStudyBuilder;
|
||||
aStudyBuilder = getStudyServant()->NewBuilder();
|
||||
aStudyBuilder->NewCommand(); // There is a transaction
|
||||
|
||||
aResult->length(aNames.size());
|
||||
int i = 0;
|
||||
|
||||
// Iterate through all meshes and create mesh objects
|
||||
for (const std::string& meshName : aNames)
|
||||
{
|
||||
// Python Dump
|
||||
if (i > 0) aPythonDump << ", ";
|
||||
|
||||
// publish mesh in the study
|
||||
SALOMEDS::SObject_wrap aSO;
|
||||
if (CanPublishInStudy(sourceMesh))
|
||||
aSO = PublishMesh(sourceMesh, meshName.c_str());
|
||||
|
||||
// Python Dump
|
||||
if (!aSO->_is_nil()) {
|
||||
aPythonDump << aSO;
|
||||
}
|
||||
else {
|
||||
aPythonDump << "mesh_" << i;
|
||||
}
|
||||
|
||||
// Read mesh data (groups are published automatically by ImportMEDFile())
|
||||
SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>(GetServant(sourceMesh).in());
|
||||
ASSERT(meshServant);
|
||||
SMESH::DriverMED_ReadStatus status1 =
|
||||
meshServant->ImportMEDFile(theFileName, meshName.c_str());
|
||||
if (status1 > theStatus)
|
||||
theStatus = status1;
|
||||
|
||||
for (unsigned int i = 0; i < anOldGroups.length(); ++i)
|
||||
{
|
||||
//auto X = anOldGroups[i];
|
||||
sourceMesh->RemoveGroup(anOldGroups[i]);
|
||||
}
|
||||
aResult[i++] = SMESH::SMESH_Mesh::_duplicate(sourceMesh);
|
||||
|
||||
meshServant->GetImpl().GetMeshDS()->Modified();
|
||||
}
|
||||
if (!aStudyBuilder->_is_nil())
|
||||
aStudyBuilder->CommitCommand();
|
||||
}
|
||||
|
||||
// Update Python script
|
||||
aPythonDump << "], status) = " << this << ".ReloadMeshesFromMED( r'" << theFileName << "' )";
|
||||
}
|
||||
// Dump creation of groups
|
||||
for (CORBA::ULong i = 0; i < aResult->length(); ++i)
|
||||
SMESH::ListOfGroups_var groups = aResult[i]->GetGroups();
|
||||
|
||||
return aResult._retn();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* SMESH_Gen_i::CreateMeshFromSTL
|
||||
@ -1529,7 +1697,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
|
||||
checkFileReadable( theFileName );
|
||||
|
||||
SMESH::SMESH_Mesh_var aMesh = createMesh();
|
||||
//string aFileName;
|
||||
|
||||
#ifdef WIN32
|
||||
char bname[ _MAX_FNAME ];
|
||||
_splitpath( theFileName, NULL, NULL, bname, NULL );
|
||||
@ -1537,11 +1705,13 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
|
||||
#else
|
||||
string aFileName = basename( const_cast<char *>(theFileName) );
|
||||
#endif
|
||||
|
||||
// publish mesh in the study
|
||||
if ( CanPublishInStudy( aMesh ) ) {
|
||||
SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
|
||||
aStudyBuilder->NewCommand(); // There is a transaction
|
||||
SALOMEDS::SObject_wrap aSO = PublishInStudy( SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() );
|
||||
SALOMEDS::SObject_wrap aSO =
|
||||
PublishMesh( aMesh.in(), aFileName.c_str(), "ICON_SMESH_TREE_MESH_IMPORTED" );
|
||||
aStudyBuilder->CommitCommand();
|
||||
if ( !aSO->_is_nil() ) {
|
||||
// Update Python script
|
||||
@ -1556,6 +1726,37 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
|
||||
return aMesh._retn();
|
||||
}
|
||||
|
||||
SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ReloadMeshesFromSTL(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh)
|
||||
{
|
||||
Unexpect aCatch(SALOME_SalomeException);
|
||||
checkFileReadable(theFileName);
|
||||
|
||||
#ifdef WIN32
|
||||
char bname[_MAX_FNAME];
|
||||
_splitpath(theFileName, NULL, NULL, bname, NULL);
|
||||
string aFileName = bname;
|
||||
#else
|
||||
string aFileName = basename(const_cast<char*>(theFileName));
|
||||
#endif
|
||||
// publish mesh in the study
|
||||
if (CanPublishInStudy(sourceMesh)) {
|
||||
SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
|
||||
aStudyBuilder->NewCommand(); // There is a transaction
|
||||
SALOMEDS::SObject_wrap aSO = PublishInStudy(SALOMEDS::SObject::_nil(), sourceMesh, aFileName.c_str());
|
||||
aStudyBuilder->CommitCommand();
|
||||
if (!aSO->_is_nil()) {
|
||||
// Update Python script
|
||||
TPythonDump(this) << aSO << " = " << this << ".ReloadMeshFromSTL(r'" << theFileName << "')";
|
||||
}
|
||||
}
|
||||
|
||||
SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>(GetServant(sourceMesh).in());
|
||||
ASSERT(aServant);
|
||||
aServant->ImportSTLFile(theFileName);
|
||||
aServant->GetImpl().GetMeshDS()->Modified();
|
||||
return sourceMesh;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Create meshes and import data from the CGSN file
|
||||
@ -1616,7 +1817,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char*
|
||||
// publish mesh in the study
|
||||
SALOMEDS::SObject_wrap aSO;
|
||||
if ( CanPublishInStudy( mesh ) )
|
||||
aSO = PublishMesh( mesh.in(), meshName.c_str() );
|
||||
aSO = PublishMesh( mesh.in(), meshName.c_str(), "ICON_SMESH_TREE_MESH_IMPORTED" );
|
||||
|
||||
// Python Dump
|
||||
if ( !aSO->_is_nil() ) {
|
||||
@ -1641,6 +1842,85 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char*
|
||||
return aResult._retn();
|
||||
}
|
||||
|
||||
SMESH::mesh_array* SMESH_Gen_i::ReloadMeshesFromCGNS(const char* theFileName,
|
||||
SMESH::SMESH_Mesh_ptr sourceMesh,
|
||||
SMESH::DriverMED_ReadStatus& theStatus)
|
||||
{
|
||||
Unexpect aCatch(SALOME_SalomeException);
|
||||
checkFileReadable(theFileName);
|
||||
|
||||
SMESH::mesh_array_var aResult = new SMESH::mesh_array();
|
||||
|
||||
#ifdef WITH_CGNS
|
||||
// Retrieve nb meshes from the file
|
||||
DriverCGNS_Read myReader;
|
||||
myReader.SetFile(theFileName);
|
||||
Driver_Mesh::Status aStatus;
|
||||
int nbMeshes = myReader.GetNbMeshes(aStatus);
|
||||
theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
|
||||
|
||||
aResult->length(nbMeshes);
|
||||
|
||||
{ // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
|
||||
|
||||
// Python Dump
|
||||
TPythonDump aPythonDump(this);
|
||||
aPythonDump << "([";
|
||||
|
||||
if (theStatus == SMESH::DRS_OK)
|
||||
{
|
||||
SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
|
||||
aStudyBuilder->NewCommand(); // There is a transaction
|
||||
|
||||
int i = 0;
|
||||
|
||||
// Iterate through all meshes and create mesh objects
|
||||
for (; i < nbMeshes; ++i)
|
||||
{
|
||||
// Python Dump
|
||||
if (i > 0) aPythonDump << ", ";
|
||||
|
||||
// create mesh
|
||||
aResult[i] = SMESH::SMESH_Mesh::_duplicate(sourceMesh);
|
||||
|
||||
// Read mesh data (groups are published automatically by ImportMEDFile())
|
||||
SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>(GetServant(sourceMesh).in());
|
||||
ASSERT(meshServant);
|
||||
string meshName;
|
||||
SMESH::DriverMED_ReadStatus status1 =
|
||||
meshServant->ImportCGNSFile(theFileName, i, meshName);
|
||||
if (status1 > theStatus)
|
||||
theStatus = status1;
|
||||
|
||||
meshServant->GetImpl().GetMeshDS()->Modified();
|
||||
// publish mesh in the study
|
||||
SALOMEDS::SObject_wrap aSO;
|
||||
if (CanPublishInStudy(sourceMesh))
|
||||
aSO = PublishMesh(sourceMesh, meshName.c_str());
|
||||
|
||||
// Python Dump
|
||||
if (!aSO->_is_nil()) {
|
||||
aPythonDump << aSO;
|
||||
}
|
||||
else {
|
||||
aPythonDump << "mesh_" << i;
|
||||
}
|
||||
}
|
||||
aStudyBuilder->CommitCommand();
|
||||
}
|
||||
|
||||
aPythonDump << "], status) = " << this << ".ReloadMeshesFromCGNS(r'" << theFileName << "')";
|
||||
}
|
||||
// Dump creation of groups
|
||||
for (CORBA::ULong i = 0; i < aResult->length(); ++i)
|
||||
SMESH::ListOfGroups_var groups = aResult[i]->GetGroups();
|
||||
#else
|
||||
THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
|
||||
#endif
|
||||
|
||||
return aResult._retn();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Create a mesh and import data from a GMF file
|
||||
@ -1667,7 +1947,8 @@ SMESH_Gen_i::CreateMeshesFromGMF( const char* theFileName,
|
||||
if ( CanPublishInStudy( aMesh ) ) {
|
||||
SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
|
||||
aStudyBuilder->NewCommand(); // There is a transaction
|
||||
SALOMEDS::SObject_wrap aSO = PublishInStudy( SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() );
|
||||
SALOMEDS::SObject_wrap aSO =
|
||||
PublishMesh( aMesh.in(), aFileName.c_str(), "ICON_SMESH_TREE_MESH_IMPORTED" );
|
||||
aStudyBuilder->CommitCommand();
|
||||
if ( !aSO->_is_nil() ) {
|
||||
// Update Python script
|
||||
@ -1683,6 +1964,38 @@ SMESH_Gen_i::CreateMeshesFromGMF( const char* theFileName,
|
||||
return aMesh._retn();
|
||||
}
|
||||
|
||||
SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ReloadMeshesFromGMF(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh, CORBA::Boolean theMakeRequiredGroups, SMESH::ComputeError_out theError)
|
||||
{
|
||||
Unexpect aCatch(SALOME_SalomeException);
|
||||
checkFileReadable(theFileName);
|
||||
|
||||
#ifdef WIN32
|
||||
char bname[_MAX_FNAME];
|
||||
_splitpath(theFileName, NULL, NULL, bname, NULL);
|
||||
string aFileName = bname;
|
||||
#else
|
||||
string aFileName = basename(const_cast<char*>(theFileName));
|
||||
#endif
|
||||
// publish mesh in the study
|
||||
if (CanPublishInStudy(sourceMesh)) {
|
||||
SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
|
||||
aStudyBuilder->NewCommand(); // There is a transaction
|
||||
SALOMEDS::SObject_wrap aSO = PublishInStudy(SALOMEDS::SObject::_nil(), sourceMesh, aFileName.c_str());
|
||||
aStudyBuilder->CommitCommand();
|
||||
if (!aSO->_is_nil()) {
|
||||
// Update Python script
|
||||
TPythonDump(this) << "(" << aSO << ", error) = " << this << ".ReloadMeshesFromGMF(r'"
|
||||
<< theFileName << "', "
|
||||
<< theMakeRequiredGroups << " )";
|
||||
}
|
||||
}
|
||||
SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>(GetServant(sourceMesh).in());
|
||||
ASSERT(aServant);
|
||||
theError = aServant->ImportGMFFile(theFileName, theMakeRequiredGroups);
|
||||
aServant->GetImpl().GetMeshDS()->Modified();
|
||||
return sourceMesh;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Create a mesh and import data from any file supported by meshio library
|
||||
@ -1737,7 +2050,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMESHIO(const char* theFileName,
|
||||
// publish mesh in the study
|
||||
SALOMEDS::SObject_wrap aSO;
|
||||
if (CanPublishInStudy(mesh))
|
||||
aSO = PublishMesh(mesh.in(), meshName.c_str());
|
||||
aSO = PublishMesh(mesh.in(), meshName.c_str(), "ICON_SMESH_TREE_MESH_IMPORTED");
|
||||
|
||||
// Save SO to use in a python dump
|
||||
sobjects.emplace_back(aSO);
|
||||
@ -1769,6 +2082,82 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMESHIO(const char* theFileName,
|
||||
return aResult._retn();
|
||||
}
|
||||
|
||||
SMESH::mesh_array* SMESH_Gen_i::ReloadMeshesFromMESHIO(const char* theFileName, SMESH::SMESH_Mesh_ptr sourceMesh, SMESH::DriverMED_ReadStatus& theStatus)
|
||||
{
|
||||
Unexpect aCatch(SALOME_SalomeException);
|
||||
checkFileReadable(theFileName);
|
||||
|
||||
MESSAGE("Import part with meshio through an intermediate MED file");
|
||||
|
||||
// Create an object that holds a temp file name and
|
||||
// removes the file when goes out of scope.
|
||||
SMESH_Meshio meshio;
|
||||
const QString tempFileName = meshio.CreateTempFileName(theFileName);
|
||||
|
||||
// Convert temp file into a target one with meshio command
|
||||
meshio.Convert(theFileName, tempFileName);
|
||||
|
||||
// We don't need a python dump from SMESH_Gen_i::CreateMeshesFromMED(), so
|
||||
// we can't use this method as is here. The followed code is an edited part of
|
||||
// copy pasted CreateMeshesFromMED().
|
||||
|
||||
// Retrieve mesh names from the file
|
||||
DriverMED_R_SMESHDS_Mesh myReader;
|
||||
myReader.SetFile(tempFileName.toStdString());
|
||||
myReader.SetMeshId(-1);
|
||||
Driver_Mesh::Status aStatus;
|
||||
list<string> aNames = myReader.GetMeshNames(aStatus);
|
||||
SMESH::mesh_array_var aResult = new SMESH::mesh_array();
|
||||
theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
|
||||
|
||||
if (theStatus == SMESH::DRS_OK)
|
||||
{
|
||||
SALOMEDS::StudyBuilder_var aStudyBuilder;
|
||||
aStudyBuilder = getStudyServant()->NewBuilder();
|
||||
aStudyBuilder->NewCommand(); // There is a transaction
|
||||
|
||||
aResult->length(aNames.size());
|
||||
std::vector<SALOMEDS::SObject_wrap> sobjects;
|
||||
int i = 0;
|
||||
|
||||
// Iterate through all meshes and create mesh objects
|
||||
for (const std::string& meshName : aNames)
|
||||
{
|
||||
// publish mesh in the study
|
||||
SALOMEDS::SObject_wrap aSO;
|
||||
if (CanPublishInStudy(sourceMesh))
|
||||
aSO = PublishMesh(sourceMesh, meshName.c_str());
|
||||
|
||||
// Save SO to use in a python dump
|
||||
sobjects.emplace_back(aSO);
|
||||
|
||||
// Read mesh data (groups are published automatically by ImportMEDFile())
|
||||
SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>(GetServant(sourceMesh).in());
|
||||
ASSERT(meshServant);
|
||||
SMESH::DriverMED_ReadStatus status1 =
|
||||
meshServant->ImportMEDFile(tempFileName.toUtf8().data(), meshName.c_str());
|
||||
if (status1 > theStatus)
|
||||
theStatus = status1;
|
||||
|
||||
aResult[i++] = SMESH::SMESH_Mesh::_duplicate(sourceMesh);
|
||||
meshServant->GetImpl().GetMeshDS()->Modified();
|
||||
}
|
||||
|
||||
if (!aStudyBuilder->_is_nil())
|
||||
aStudyBuilder->CommitCommand();
|
||||
|
||||
// Python dump
|
||||
const std::string functionName = std::string(".ReloadMeshesFromMESHIO(r'") + theFileName + "')";
|
||||
functionToPythonDump(this, functionName, sobjects);
|
||||
}
|
||||
|
||||
// Dump creation of groups
|
||||
for (CORBA::ULong i = 0; i < aResult->length(); ++i)
|
||||
SMESH::ListOfGroups_var groups = aResult[i]->GetGroups();
|
||||
|
||||
return aResult._retn();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* SMESH_Gen_i::IsReadyToCompute
|
||||
|
@ -237,29 +237,54 @@ public:
|
||||
// Create empty mesh
|
||||
SMESH::SMESH_Mesh_ptr CreateEmptyMesh();
|
||||
|
||||
SMESH::SMESH_Mesh_ptr ReloadMeshFromFile(SMESH::SMESH_Mesh_ptr theMesh);
|
||||
|
||||
// Create a mesh and import data from an UNV file
|
||||
SMESH::SMESH_Mesh_ptr CreateMeshesFromUNV( const char* theFileName );
|
||||
|
||||
SMESH::SMESH_Mesh_ptr ReloadMeshesFromUNV(const char* theFileName,
|
||||
SMESH::SMESH_Mesh_ptr sourceMesh);
|
||||
|
||||
// Create mesh(es) and import data from MED file
|
||||
SMESH::mesh_array* CreateMeshesFromMED( const char* theFileName,
|
||||
SMESH::DriverMED_ReadStatus& theStatus );
|
||||
|
||||
SMESH::mesh_array* ReloadMeshesFromMED(const char* theFileName,
|
||||
SMESH::SMESH_Mesh_ptr sourceMesh,
|
||||
SMESH::DriverMED_ReadStatus& theStatus);
|
||||
|
||||
// Create a mesh and import data from a STL file
|
||||
SMESH::SMESH_Mesh_ptr CreateMeshesFromSTL( const char* theFileName );
|
||||
|
||||
SMESH::SMESH_Mesh_ptr ReloadMeshesFromSTL(const char* theFileName,
|
||||
SMESH::SMESH_Mesh_ptr sourceMesh);
|
||||
|
||||
// Create mesh(es) and import data from CGNS file
|
||||
SMESH::mesh_array* CreateMeshesFromCGNS( const char* theFileName,
|
||||
SMESH::DriverMED_ReadStatus& theStatus );
|
||||
|
||||
SMESH::mesh_array* ReloadMeshesFromCGNS(const char* theFileName,
|
||||
SMESH::SMESH_Mesh_ptr sourceMesh,
|
||||
SMESH::DriverMED_ReadStatus& theStatus);
|
||||
|
||||
// Create a mesh and import data from a GMF file
|
||||
SMESH::SMESH_Mesh_ptr CreateMeshesFromGMF( const char* theFileName,
|
||||
CORBA::Boolean theMakeRequiredGroups,
|
||||
SMESH::ComputeError_out theError);
|
||||
|
||||
SMESH::SMESH_Mesh_ptr ReloadMeshesFromGMF(const char* theFileName,
|
||||
SMESH::SMESH_Mesh_ptr sourceMesh,
|
||||
CORBA::Boolean theMakeRequiredGroups,
|
||||
SMESH::ComputeError_out theError);
|
||||
|
||||
// Create a mesh and import data from any file supported by meshio library
|
||||
SMESH::mesh_array* CreateMeshesFromMESHIO(const char* theFileName,
|
||||
SMESH::DriverMED_ReadStatus& theStatus);
|
||||
|
||||
SMESH::mesh_array* ReloadMeshesFromMESHIO(const char* theFileName,
|
||||
SMESH::SMESH_Mesh_ptr sourceMesh,
|
||||
SMESH::DriverMED_ReadStatus& theStatus);
|
||||
|
||||
// Create dual mesh of a tetrahedron mesh
|
||||
SMESH::SMESH_Mesh_ptr CreateDualMesh(SMESH::SMESH_IDSource_ptr meshPart,
|
||||
const char* meshName,
|
||||
@ -524,7 +549,8 @@ public:
|
||||
// publishing methods
|
||||
SALOMEDS::SComponent_ptr PublishComponent();
|
||||
SALOMEDS::SObject_ptr PublishMesh (SMESH::SMESH_Mesh_ptr theMesh,
|
||||
const char* theName = 0);
|
||||
const char* theName = 0,
|
||||
const char* thePixMap = 0);
|
||||
SALOMEDS::SObject_ptr PublishHypothesis (SMESH::SMESH_Hypothesis_ptr theHyp,
|
||||
const char* theName = 0);
|
||||
SALOMEDS::SObject_ptr PublishSubMesh (SMESH::SMESH_Mesh_ptr theMesh,
|
||||
@ -536,6 +562,7 @@ public:
|
||||
GEOM::GEOM_Object_ptr theShapeObject,
|
||||
const char* theName = 0);
|
||||
void UpdateIcons(SMESH::SMESH_Mesh_ptr theMesh);
|
||||
void UpdateGroupIcon(SMESH::SMESH_GroupBase_ptr theGroup);
|
||||
void HighLightInvalid(CORBA::Object_ptr theObject, bool isInvalid);
|
||||
bool IsInvalid(SALOMEDS::SObject_ptr theObject);
|
||||
bool AddHypothesisToShape(SMESH::SMESH_Mesh_ptr theMesh,
|
||||
|
@ -607,7 +607,8 @@ SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent()
|
||||
//=======================================================================
|
||||
|
||||
SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SMESH::SMESH_Mesh_ptr theMesh,
|
||||
const char* theName)
|
||||
const char* theName,
|
||||
const char* thePixMap)
|
||||
{
|
||||
if ( !myIsEnablePublish )
|
||||
return SALOMEDS::SObject::_nil();
|
||||
@ -631,7 +632,8 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SMESH::SMESH_Mesh_ptr theMesh,
|
||||
else
|
||||
aTag++;
|
||||
|
||||
aMeshSO = publish( theMesh, father, aTag, "ICON_SMESH_TREE_MESH_WARN" );
|
||||
aMeshSO = publish( theMesh, father, aTag,
|
||||
thePixMap ? thePixMap : "ICON_SMESH_TREE_MESH_WARN" );
|
||||
if ( aMeshSO->_is_nil() )
|
||||
return aMeshSO._retn();
|
||||
}
|
||||
@ -977,18 +979,13 @@ void SMESH_Gen_i::UpdateIcons( SMESH::SMESH_Mesh_ptr theMesh )
|
||||
if ( idSrc->_is_nil() )
|
||||
continue;
|
||||
|
||||
SMESH::SMESH_GroupBase_var grp = SMESH::SMESH_GroupBase::_narrow( obj );
|
||||
SMESH::SMESH_GroupOnFilter_var gof = SMESH::SMESH_GroupOnFilter::_narrow( obj );
|
||||
const bool isGroup = !grp->_is_nil();
|
||||
const bool isGroupOnFilter = !gof->_is_nil();
|
||||
|
||||
bool isEmpty = ( mesh_i->NbNodes() == 0 );
|
||||
if ( !isEmpty )
|
||||
{
|
||||
if ( isGroupOnFilter ) // GetTypes() can be very long on GroupOnFilter!
|
||||
{
|
||||
SMESH::smIdType_array_var nbByType = mesh_i->GetNbElementsByType();
|
||||
isEmpty = ( nbByType[ grp->GetType() ] == 0 );
|
||||
SMESH::SMESH_GroupBase_var grp = SMESH::SMESH_GroupBase::_narrow( obj );
|
||||
if ( !grp->_is_nil() ) {
|
||||
UpdateGroupIcon(grp);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1013,15 +1010,44 @@ void SMESH_Gen_i::UpdateIcons( SMESH::SMESH_Mesh_ptr theMesh )
|
||||
|
||||
if ( isEmpty )
|
||||
SetPixMap( so, "ICON_SMESH_TREE_MESH_WARN");
|
||||
else if ( !isGroup )
|
||||
else
|
||||
SetPixMap( so, "ICON_SMESH_TREE_MESH" );
|
||||
|
||||
} // loop on sub-meshes or groups
|
||||
} // loop on roots
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UpdateGroupIcon
|
||||
//purpose : update icon of a group
|
||||
//=======================================================================
|
||||
|
||||
void SMESH_Gen_i::UpdateGroupIcon( SMESH::SMESH_GroupBase_ptr theGroup )
|
||||
{
|
||||
SALOMEDS::SObject_wrap so = ObjectToSObject( theGroup );
|
||||
if ( so->_is_nil() )
|
||||
return;
|
||||
|
||||
SMESH::SMESH_GroupOnFilter_var gof = SMESH::SMESH_GroupOnFilter::_narrow( theGroup );
|
||||
const bool isGroupOnFilter = !gof->_is_nil();
|
||||
|
||||
bool isEmpty = false;
|
||||
if ( isGroupOnFilter ) // GetTypes() can be very long on GroupOnFilter!
|
||||
{
|
||||
SMESH::smIdType_array_var nbByType = theGroup->GetMesh()->GetNbElementsByType();
|
||||
isEmpty = ( nbByType[ theGroup->GetType() ] == 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
isEmpty = ( theGroup->Size() == 0 );
|
||||
}
|
||||
|
||||
if ( isEmpty )
|
||||
SetPixMap( so, "ICON_SMESH_TREE_MESH_WARN");
|
||||
else if ( isGroupOnFilter )
|
||||
SetPixMap( so, "ICON_SMESH_TREE_GROUP_ON_FILTER" );
|
||||
else
|
||||
SetPixMap( so, "ICON_SMESH_TREE_GROUP" );
|
||||
|
||||
} // loop on sub-meshes or groups
|
||||
} // loop on roots
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@ -261,16 +261,19 @@ void SMESH_Group_i::Clear()
|
||||
if ( myPreMeshInfo )
|
||||
myPreMeshInfo->FullLoadFromFile();
|
||||
|
||||
SMESH::SMESH_Group_var me = _this();
|
||||
|
||||
// Update Python script
|
||||
SMESH::TPythonDump() << SMESH::SMESH_Group_var(_this()) << ".Clear()";
|
||||
SMESH::TPythonDump() << me << ".Clear()";
|
||||
|
||||
// Clear the group
|
||||
SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
|
||||
if (aGroupDS) {
|
||||
aGroupDS->Clear();
|
||||
return;
|
||||
}
|
||||
SMESH_Gen_i* aGen = GetMeshServant()->GetGen();
|
||||
aGen->UpdateGroupIcon(me);
|
||||
Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@ -301,20 +304,28 @@ SMESH::smIdType SMESH_Group_i::Add( const SMESH::smIdType_array& theIDs )
|
||||
if ( myPreMeshInfo )
|
||||
myPreMeshInfo->FullLoadFromFile();
|
||||
|
||||
SMESH::SMESH_Group_var me = _this();
|
||||
|
||||
// Update Python script
|
||||
SMESH::TPythonDump() << "nbAdd = " << SMESH::SMESH_Group_var(_this()) << ".Add( " << theIDs << " )";
|
||||
SMESH::TPythonDump() << "nbAdd = " << me << ".Add( " << theIDs << " )";
|
||||
|
||||
// Add elements to the group
|
||||
SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
|
||||
if (aGroupDS) {
|
||||
bool wasEmpty = aGroupDS->IsEmpty();
|
||||
int nbAdd = 0;
|
||||
for ( CORBA::ULong i = 0; i < theIDs.length(); i++) {
|
||||
int anID = (int) theIDs[i];
|
||||
if ( aGroupDS->Add( anID ))
|
||||
nbAdd++;
|
||||
}
|
||||
if ( nbAdd )
|
||||
if ( nbAdd ) {
|
||||
Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
|
||||
if (wasEmpty) {
|
||||
SMESH_Gen_i* aGen = GetMeshServant()->GetGen();
|
||||
aGen->UpdateGroupIcon(me);
|
||||
}
|
||||
}
|
||||
return nbAdd;
|
||||
}
|
||||
MESSAGE("attempt to add elements to a vague group");
|
||||
@ -332,9 +343,10 @@ SMESH::smIdType SMESH_Group_i::Remove( const SMESH::smIdType_array& theIDs )
|
||||
if ( myPreMeshInfo )
|
||||
myPreMeshInfo->FullLoadFromFile();
|
||||
|
||||
SMESH::SMESH_Group_var me = _this();
|
||||
|
||||
// Update Python script
|
||||
SMESH::TPythonDump() << "nbDel = " << SMESH::SMESH_Group_var(_this())
|
||||
<< ".Remove( " << theIDs << " )";
|
||||
SMESH::TPythonDump() << "nbDel = " << me << ".Remove( " << theIDs << " )";
|
||||
|
||||
// Remove elements from the group
|
||||
SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
|
||||
@ -345,8 +357,13 @@ SMESH::smIdType SMESH_Group_i::Remove( const SMESH::smIdType_array& theIDs )
|
||||
if ( aGroupDS->Remove( anID ))
|
||||
nbDel++;
|
||||
}
|
||||
if ( nbDel )
|
||||
if ( nbDel ) {
|
||||
Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
|
||||
if (aGroupDS->IsEmpty()) {
|
||||
SMESH_Gen_i* aGen = GetMeshServant()->GetGen();
|
||||
aGen->UpdateGroupIcon(me);
|
||||
}
|
||||
}
|
||||
return nbDel;
|
||||
}
|
||||
MESSAGE("attempt to remove elements from a vague group");
|
||||
@ -361,24 +378,27 @@ SMESH::smIdType SMESH_Group_i::Remove( const SMESH::smIdType_array& theIDs )
|
||||
|
||||
typedef bool (SMESHDS_Group::*TFunChangeGroup)(const smIdType);
|
||||
|
||||
CORBA::Long
|
||||
ChangeByPredicate( SMESH::Predicate_i* thePredicate,
|
||||
CORBA::Long ChangeByPredicate( SMESH::Predicate_i* thePredicate,
|
||||
SMESHDS_GroupBase* theGroupBase,
|
||||
SMESH::NotifyerAndWaiter* theGroupImpl,
|
||||
SMESH_GroupBase_i* theGroup,
|
||||
TFunChangeGroup theFun)
|
||||
{
|
||||
CORBA::Long aNb = 0;
|
||||
if(SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>(theGroupBase)){
|
||||
if (SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>(theGroupBase)) {
|
||||
SMESH::Controls::Filter::TIdSequence aSequence;
|
||||
const SMDS_Mesh* aMesh = theGroupBase->GetMesh();
|
||||
SMESH::Filter_i::GetElementsId(thePredicate,aMesh,aSequence);
|
||||
|
||||
CORBA::Long i = 0, iEnd = aSequence.size();
|
||||
for(; i < iEnd; i++)
|
||||
if((aGroupDS->*theFun)(aSequence[i]))
|
||||
for (; i < iEnd; i++)
|
||||
if ((aGroupDS->*theFun)(aSequence[i]))
|
||||
aNb++;
|
||||
if ( aNb )
|
||||
theGroupImpl->Modified();
|
||||
if ( aNb ) {
|
||||
theGroup->Modified();
|
||||
SMESH_Gen_i* aGen = theGroup->GetMeshServant()->GetGen();
|
||||
SMESH::SMESH_GroupBase_var aGroup = theGroup->_this();
|
||||
aGen->UpdateGroupIcon(aGroup);
|
||||
}
|
||||
return aNb;
|
||||
}
|
||||
return aNb;
|
||||
@ -428,11 +448,16 @@ SMESH::smIdType SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource )
|
||||
aGroupDS->SMDSGroup().Add( elemIt->next() );
|
||||
}
|
||||
|
||||
// Update Python script
|
||||
pd << "nbAdd = " << SMESH::SMESH_Group_var(_this()) << ".AddFrom( " << theSource << " )";
|
||||
SMESH::SMESH_Group_var me = _this();
|
||||
|
||||
if ( prevNb != Size() )
|
||||
// Update Python script
|
||||
pd << "nbAdd = " << me << ".AddFrom( " << theSource << " )";
|
||||
|
||||
if ( prevNb != Size() ) {
|
||||
SMESH_Gen_i* aGen = GetMeshServant()->GetGen();
|
||||
aGen->UpdateGroupIcon(me);
|
||||
Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
|
||||
}
|
||||
|
||||
return Size() - prevNb;
|
||||
}
|
||||
@ -830,17 +855,18 @@ void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
|
||||
myFilter->SetMesh( SMESH::SMESH_Mesh::_nil() ); // to UnRegister() the mesh
|
||||
}
|
||||
|
||||
SMESH_Gen_i* aGen = GetMeshServant()->GetGen();
|
||||
SMESH::SMESH_GroupOnFilter_var me = _this();
|
||||
|
||||
if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
|
||||
{
|
||||
grDS->SetPredicate( GetPredicate( myFilter ));
|
||||
aGen->UpdateGroupIcon(me);
|
||||
Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
|
||||
}
|
||||
|
||||
SMESH::SMESH_GroupOnFilter_var me = _this();
|
||||
|
||||
// mark the group valid after edition
|
||||
GetMeshServant()->GetGen()->HighLightInvalid( me, false );
|
||||
|
||||
aGen->HighLightInvalid( me, false );
|
||||
|
||||
SMESH::TPythonDump()<< me <<".SetFilter( "<< theFilter <<" )";
|
||||
}
|
||||
@ -1078,4 +1104,3 @@ void SMESH_GroupOnFilter_i::OnBaseObjModified(NotifyerAndWaiter* /*filter*/, boo
|
||||
if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
|
||||
grDS->SetPredicate( GetPredicate( myFilter )); // group resets its cache
|
||||
}
|
||||
|
||||
|
@ -1414,6 +1414,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr
|
||||
resGroupDS->SMDSGroup().Add( e );
|
||||
}
|
||||
}
|
||||
|
||||
GetGen()->UpdateGroupIcon(aResGrp);
|
||||
|
||||
// Update Python script
|
||||
pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
|
||||
<< theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
|
||||
@ -1500,6 +1503,8 @@ SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
|
||||
resGroupDS->SMDSGroup().Add( e );
|
||||
}
|
||||
|
||||
GetGen()->UpdateGroupIcon(aResGrp);
|
||||
|
||||
// Update Python script
|
||||
pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
|
||||
<< ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
|
||||
@ -1561,6 +1566,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr
|
||||
resGroupDS->SMDSGroup().Add( e );
|
||||
}
|
||||
}
|
||||
|
||||
GetGen()->UpdateGroupIcon(aResGrp);
|
||||
|
||||
// Update Python script
|
||||
pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
|
||||
<< theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
|
||||
@ -1661,6 +1669,8 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
|
||||
resGroupDS->SMDSGroup().Add( e );
|
||||
}
|
||||
|
||||
GetGen()->UpdateGroupIcon(aResGrp);
|
||||
|
||||
// Update Python script
|
||||
pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
|
||||
<< ".CutListOfGroups( " << theMainGroups << ", "
|
||||
@ -3473,7 +3483,6 @@ void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
|
||||
|
||||
void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
|
||||
{
|
||||
MESSAGE("SMESH_Mesh_i::SetImpl");
|
||||
_impl = impl;
|
||||
if ( _impl )
|
||||
_impl->SetCallUp( new TCallUp_i(this));
|
||||
@ -3487,7 +3496,6 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
|
||||
|
||||
::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
|
||||
{
|
||||
MESSAGE("SMESH_Mesh_i::GetImpl()");
|
||||
return *_impl;
|
||||
}
|
||||
|
||||
|
@ -675,6 +675,14 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
|
||||
global notebook
|
||||
notebook = salome_notebook.NoteBook( theIsEnablePublish )
|
||||
|
||||
def ReloadMeshFromFile(self, theMesh):
|
||||
"""
|
||||
Desc for method,
|
||||
"""
|
||||
|
||||
aSmeshMesh = SMESH._objref_SMESH_Gen.ReloadMeshFromFile(self, theMesh)
|
||||
aMesh = Mesh(self, self.geompyD, aSmeshMesh)
|
||||
return aMesh
|
||||
|
||||
def CreateMeshesFromUNV( self,theFileName ):
|
||||
"""
|
||||
|
@ -230,7 +230,7 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh,
|
||||
}
|
||||
|
||||
// remove free nodes
|
||||
if ( /*SMESHDS_SubMesh * smDS = */meshDS->MeshElements( helper.GetSubShapeID() ))
|
||||
//if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( helper.GetSubShapeID() ))
|
||||
{
|
||||
std::vector< const SMDS_MeshNode* > nodesToRemove;
|
||||
// get intersection nodes
|
||||
|
@ -579,6 +579,14 @@ namespace {
|
||||
case HAS_PROPAG_HYP: { // propag hyp on this submesh
|
||||
// --------------------------------------------------------
|
||||
switch ( event ) {
|
||||
case SMESH_subMesh::ADD_FATHER_ALGO:
|
||||
{
|
||||
DBGMSG("HAS_PROPAG_HYP propagation to ADD_FATHER_ALGO " << subMesh->GetId());
|
||||
|
||||
// Rebuild propagation chain after an algo was added on father submesh
|
||||
buildPropagationChain(subMesh);
|
||||
break;
|
||||
}
|
||||
case SMESH_subMesh::REMOVE_HYP:
|
||||
case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp
|
||||
if ( isPropagHyp && !getProagationHyp( subMesh ))
|
||||
|
@ -492,6 +492,105 @@ static void compensateError(double a1, double an,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief adjust internal node parameters so that the last segment length == an,
|
||||
* and by distributing the error for the total length of curve segments
|
||||
* in relation to the target length computed from the current parameters
|
||||
* \param a1 - the first segment length
|
||||
* \param an - the last segment length
|
||||
* \param U1 - the first edge parameter
|
||||
* \param Un - the last edge parameter
|
||||
* \param length - the edge length
|
||||
* \param C3d - the edge curve
|
||||
* \param theParams - internal node parameters to adjust
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
static void distributeError(double a1, double an,
|
||||
double U1, double Un,
|
||||
double length,
|
||||
Adaptor3d_Curve& C3d,
|
||||
list<double> & theParams)
|
||||
{
|
||||
// Compute the error of the total length based in the current curve parameters
|
||||
double tol = Min( Precision::Confusion(), 0.01 * Min(a1, an) );
|
||||
double totalLength = 0.0;
|
||||
double prevParam = U1;
|
||||
list<double> segLengths;
|
||||
list<double>::iterator itU = theParams.begin();
|
||||
for ( ; itU != theParams.end(); ++itU )
|
||||
{
|
||||
// Compute the curve length between two adjacent parameters and sum them up
|
||||
double curLength = GCPnts_AbscissaPoint::Length(C3d, prevParam, *itU, tol);
|
||||
segLengths.push_back(curLength);
|
||||
totalLength += curLength;
|
||||
prevParam = *itU;
|
||||
}
|
||||
// Calculate the error between the total length of all segments based on given parameters
|
||||
// and the target length of the edge itself
|
||||
double error = totalLength - length;
|
||||
// Compute the sum of all internal segments (= total computed length minus the length of
|
||||
// the start and end segments)
|
||||
double midLength = totalLength - (a1 + an);
|
||||
|
||||
// We only need to distribute the error, if the current parametrization is not correct,
|
||||
// and if there are multiple internal segments
|
||||
smIdType nPar = theParams.size();
|
||||
if ( a1 + an <= length && nPar > 1 && fabs(error) > tol )
|
||||
{
|
||||
// Update the length of each internal segment (start and end length are given and not changed)
|
||||
double newTotalLength = 0.0;
|
||||
double newLength;
|
||||
double relError = error / midLength;
|
||||
list<double> newSegLengths;
|
||||
list<double>::iterator itL = segLengths.begin();
|
||||
for ( ; itL != segLengths.end(); ++itL )
|
||||
{
|
||||
// Do not update, but copy the first and the last segment lengths
|
||||
newLength = *itL;
|
||||
if (itL != segLengths.begin() && itL != --segLengths.end())
|
||||
{
|
||||
newLength -= newLength * relError;
|
||||
}
|
||||
newSegLengths.push_back(newLength);
|
||||
newTotalLength += newLength;
|
||||
}
|
||||
bool reverse = ( U1 > Un );
|
||||
|
||||
// Update the parameters of the curve based on the new lengths
|
||||
double curveLength, tol2, U;
|
||||
double prevU = U1;
|
||||
itU = theParams.begin();
|
||||
itL = newSegLengths.begin();
|
||||
for ( ; itU != theParams.end(); ++itU, ++itL )
|
||||
{
|
||||
curveLength = (reverse ? -(*itL) : *itL);
|
||||
tol2 = Min( Precision::Confusion(), fabs(curveLength) / 100. );
|
||||
GCPnts_AbscissaPoint Discret( tol2, C3d, curveLength, prevU );
|
||||
if ( !Discret.IsDone() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
U = Discret.Parameter();
|
||||
|
||||
double sign = reverse ? -1 : 1;
|
||||
if ( sign*U1 < sign*U && sign*U < sign*Un )
|
||||
{
|
||||
*itU = U;
|
||||
}
|
||||
else
|
||||
{
|
||||
*itU = (sign*U >= sign*Un ? Un : U1);
|
||||
break;
|
||||
}
|
||||
prevU = U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Class used to clean mesh on edges when 0D hyp modified.
|
||||
@ -1042,8 +1141,9 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh,
|
||||
return error ( SMESH_Comment("Invalid segment lengths (")<<a1<<" and "<<an<<") "<<
|
||||
"for an edge of length "<<theLength);
|
||||
|
||||
double q = ( an - a1 ) / ( 2 *theLength/( a1 + an ) - 1 );
|
||||
int n = int(fabs(q) > numeric_limits<double>::min() ? ( 1+( an-a1 )/q ) : ( 1+theLength/a1 ));
|
||||
// Compute first the number of segments and then the arithmetic increment based on that number
|
||||
int n = static_cast<int>(2 * theLength / ( a1 + an ) + 0.5);
|
||||
double q = (n > 1 ? ( an - a1 ) / (n - 1) : 0.0);
|
||||
|
||||
double U1 = theReverse ? l : f;
|
||||
double Un = theReverse ? f : l;
|
||||
@ -1054,19 +1154,23 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh,
|
||||
eltSize = -eltSize;
|
||||
q = -q;
|
||||
}
|
||||
while ( n-- > 0 && eltSize * ( Un - U1 ) > 0 ) {
|
||||
for (int i=0; i<n; i++) {
|
||||
// computes a point on a curve <theC3d> at the distance <eltSize>
|
||||
// from the point of parameter <param>.
|
||||
GCPnts_AbscissaPoint Discret( tol, theC3d, eltSize, param );
|
||||
if ( !Discret.IsDone() ) break;
|
||||
param = Discret.Parameter();
|
||||
if ( param > f && param < l )
|
||||
theParams.push_back( param );
|
||||
else
|
||||
break;
|
||||
eltSize += q;
|
||||
}
|
||||
compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
|
||||
|
||||
distributeError( a1, an, U1, Un, theLength, theC3d, theParams );
|
||||
|
||||
// Do not include the parameter for the start or end of an edge in the list of parameters
|
||||
// NOTE: it is required to correctly distribute the error
|
||||
if (fabs(theParams.front() - U1) < tol) theParams.pop_front();
|
||||
if (fabs(theParams.back() - Un) < tol) theParams.pop_back();
|
||||
|
||||
if ( theReverse ) theParams.reverse(); // NPAL18025
|
||||
|
||||
return true;
|
||||
|
@ -1867,26 +1867,30 @@ bool _ViscousBuilder2D::shrink()
|
||||
Geom2dAdaptor_Curve edgeCurve( pcurve, Min( uf, ul ), Max( uf, ul ));
|
||||
Geom2dAdaptor_Curve seg2Curve( seg2Line );
|
||||
Geom2dInt_GInter curveInt( edgeCurve, seg2Curve, 1e-7, 1e-7 );
|
||||
isConvex = ( curveInt.IsDone() && !curveInt.IsEmpty() );
|
||||
if ( isConvex ) {
|
||||
/* convex VERTEX */
|
||||
length1D = Abs( u - curveInt.Point( 1 ).ParamOnFirst() );
|
||||
double maxDist2d = 2 * L2->_lEdges[ iLSeg2 ]._length2D;
|
||||
isConvex = ( length1D < maxDist2d * len1dTo2dRatio );
|
||||
/* |L seg2
|
||||
|
||||
// In the older version length2D was set to this value only inside the !convex if block
|
||||
// But it seems that length2D can be set here anyway, because if not set valid value of length2D here,
|
||||
// it will be calculated later using length1D, and it can be not valid in cases if length1D is too large or too small.
|
||||
length2D = L2->_lEdges[iFSeg2]._length2D;
|
||||
|
||||
/* convex VERTEX
|
||||
* L seg2
|
||||
* | o---o---
|
||||
* | / |
|
||||
* |/ | L2
|
||||
* x------x--- */
|
||||
}
|
||||
if ( !isConvex ) { /* concave VERTEX */ /* o-----o---
|
||||
/* concave VERTEX
|
||||
* o-----o---
|
||||
* \ |
|
||||
* \ | L2
|
||||
* x--x---
|
||||
* /
|
||||
* L / */
|
||||
length2D = L2->_lEdges[ iFSeg2 ]._length2D;
|
||||
//if ( L2->_advancable ) continue;
|
||||
isConvex = ( curveInt.IsDone() && !curveInt.IsEmpty() );
|
||||
if ( isConvex )
|
||||
{
|
||||
length1D = Abs( u - curveInt.Point( 1 ).ParamOnFirst() );
|
||||
length2D = Max(length2D, length1D / len1dTo2dRatio);
|
||||
}
|
||||
}
|
||||
else // L2 is advancable but in the face adjacent by L
|
||||
|
@ -117,3 +117,30 @@ try:
|
||||
except Exception as e:
|
||||
salome_pluginsmanager.logger.info('ERROR: TopIIVolMesh plug-in is unavailable: {}'.format(e))
|
||||
pass
|
||||
|
||||
import sys
|
||||
import importlib
|
||||
import importlib.util
|
||||
|
||||
smesh_pyplugin_dir = os.getenv("SMESH_PYPLUGIN_DIR")
|
||||
if smesh_pyplugin_dir:
|
||||
plugin_dirs = smesh_pyplugin_dir.split(":")
|
||||
# reverse plugin_dirs list to call smesh python plugin in good order
|
||||
plugin_dirs.reverse()
|
||||
for plg_dir in plugin_dirs:
|
||||
if os.path.exists(plg_dir):
|
||||
sys.path.insert(0, plg_dir)
|
||||
#for filename in sorted(
|
||||
# filter(lambda x: os.path.isfile(os.path.join(plg_dir, x)),
|
||||
# os.listdir(plg_dir))):
|
||||
for filename in os.listdir(plg_dir):
|
||||
if filename.endswith(".py"):
|
||||
f = os.path.join(plg_dir, filename)
|
||||
try:
|
||||
module_name = os.path.splitext(os.path.basename(f))[0]
|
||||
_specs = importlib.util.find_spec(module_name)
|
||||
_module = importlib.util.module_from_spec(_specs)
|
||||
_specs.loader.exec_module(_module)
|
||||
_module.init()
|
||||
except:
|
||||
print("Can not load python plugin from {}".format(plg_dir))
|
||||
|
81
test/SMESH_algo_switch_box.py
Executable file
@ -0,0 +1,81 @@
|
||||
# Tests that switching of algorithms back and forth does not lead to errors
|
||||
|
||||
import salome
|
||||
salome.salome_init()
|
||||
|
||||
from salome.geom import geomBuilder
|
||||
|
||||
import SMESH
|
||||
from salome.smesh import smeshBuilder
|
||||
|
||||
# Create a box
|
||||
geompy = geomBuilder.New()
|
||||
|
||||
O = geompy.MakeVertex(0, 0, 0)
|
||||
OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
|
||||
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
|
||||
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
|
||||
Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
|
||||
edge = geompy.CreateGroup(Box_1, geompy.ShapeType["EDGE"])
|
||||
geompy.UnionIDs(edge, [26])
|
||||
[edge] = geompy.GetExistingSubObjects(Box_1, False)
|
||||
geompy.addToStudy( O, 'O' )
|
||||
geompy.addToStudy( OX, 'OX' )
|
||||
geompy.addToStudy( OY, 'OY' )
|
||||
geompy.addToStudy( OZ, 'OZ' )
|
||||
geompy.addToStudy( Box_1, 'Box_1' )
|
||||
geompy.addToStudyInFather( Box_1, edge, 'edge' )
|
||||
|
||||
# Create a mesh from the box and a sub-mesh from an edge
|
||||
smesh = smeshBuilder.New()
|
||||
Mesh_1 = smesh.Mesh(Box_1,'Mesh_1')
|
||||
Regular_1D = Mesh_1.Segment()
|
||||
Number_of_Segments_1 = Regular_1D.NumberOfSegments(15)
|
||||
Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE)
|
||||
Hexa_3D = Mesh_1.Hexahedron(algo=smeshBuilder.Hexa)
|
||||
edge_1 = Mesh_1.GroupOnGeom(edge,'edge',SMESH.EDGE)
|
||||
Regular_1D_1 = Mesh_1.Segment(geom=edge)
|
||||
Number_of_Segments_2 = Regular_1D_1.NumberOfSegments(2)
|
||||
Propagation_of_1D_Hyp = Regular_1D_1.Propagation()
|
||||
|
||||
# Compute initial mesh
|
||||
Mesh_1.Compute()
|
||||
Mesh_1.CheckCompute()
|
||||
Sub_mesh_1 = Regular_1D_1.GetSubMesh()
|
||||
|
||||
# Get the number of faces in the mesh
|
||||
num_faces_before = Mesh_1.NbFaces()
|
||||
print('Number of faces before switching: %d' % num_faces_before)
|
||||
|
||||
# Switch to composite segment algorithm and compute the mesh
|
||||
status = Mesh_1.RemoveHypothesis(Regular_1D)
|
||||
CompositeSegment_1D = Mesh_1.Segment(algo=smeshBuilder.COMPOSITE)
|
||||
Mesh_1.AddHypothesis(CompositeSegment_1D)
|
||||
isDone = Mesh_1.Compute()
|
||||
Mesh_1.CheckCompute() # if propagation doesn't work it already fails here
|
||||
|
||||
# Switch back to regular segment algorithm and compute the mesh
|
||||
status = Mesh_1.RemoveHypothesis(CompositeSegment_1D)
|
||||
Mesh_1.AddHypothesis(Regular_1D)
|
||||
Mesh_1.Compute()
|
||||
Mesh_1.CheckCompute()
|
||||
|
||||
# Get the number of faces in the mesh
|
||||
num_faces_after = Mesh_1.NbFaces()
|
||||
print('Number of faces after switching: %d' % num_faces_after)
|
||||
assert num_faces_before == num_faces_after, 'Number of faces before and after switching should be the same'
|
||||
|
||||
## Set names of Mesh objects
|
||||
smesh.SetName(CompositeSegment_1D.GetAlgorithm(), 'CompositeSegment_1D')
|
||||
smesh.SetName(Number_of_Segments_1, 'Number of Segments_1')
|
||||
smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1')
|
||||
smesh.SetName(Number_of_Segments_2, 'Number of Segments_2')
|
||||
smesh.SetName(edge_1, 'edge')
|
||||
smesh.SetName(Hexa_3D.GetAlgorithm(), 'Hexa_3D')
|
||||
smesh.SetName(Sub_mesh_1, 'Sub-mesh_1')
|
||||
smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
|
||||
smesh.SetName(Propagation_of_1D_Hyp, 'Propagation of 1D Hyp. on Opposite Edges_1')
|
||||
smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D')
|
||||
|
||||
if salome.sg.hasDesktop():
|
||||
salome.sg.updateObjBrowser()
|
80
test/SMESH_algo_switch_face.py
Executable file
@ -0,0 +1,80 @@
|
||||
# Tests that switching of algorithms back and forth does not lead to errors
|
||||
|
||||
import salome
|
||||
salome.salome_init()
|
||||
|
||||
from salome.geom import geomBuilder
|
||||
|
||||
import SMESH
|
||||
from salome.smesh import smeshBuilder
|
||||
|
||||
# Create a simple face
|
||||
geompy = geomBuilder.New()
|
||||
|
||||
O = geompy.MakeVertex(0, 0, 0)
|
||||
OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
|
||||
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
|
||||
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
|
||||
Face_1 = geompy.MakeFaceHW(100, 100, 1)
|
||||
edge = geompy.CreateGroup(Face_1, geompy.ShapeType['EDGE'])
|
||||
geompy.UnionIDs(edge, [6])
|
||||
[edge] = geompy.GetExistingSubObjects(Face_1, False)
|
||||
geompy.addToStudy( O, 'O' )
|
||||
geompy.addToStudy( OX, 'OX' )
|
||||
geompy.addToStudy( OY, 'OY' )
|
||||
geompy.addToStudy( OZ, 'OZ' )
|
||||
geompy.addToStudy( Face_1, 'Face_1' )
|
||||
geompy.addToStudyInFather( Face_1, edge, 'edge' )
|
||||
|
||||
# Create a mesh from the face and a sub-mesh from an edge
|
||||
smesh = smeshBuilder.New()
|
||||
|
||||
Mesh_1 = smesh.Mesh(Face_1,'Mesh_1')
|
||||
Regular_1D = Mesh_1.Segment()
|
||||
Number_of_Segments_1 = Regular_1D.NumberOfSegments(3)
|
||||
Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE)
|
||||
edge_1 = Mesh_1.GroupOnGeom(edge,'edge',SMESH.EDGE)
|
||||
Regular_1D_1 = Mesh_1.Segment(geom=edge)
|
||||
Number_of_Segments_2 = Regular_1D_1.NumberOfSegments(2)
|
||||
Propagation_of_1D_Hyp = Regular_1D_1.Propagation()
|
||||
|
||||
# Compute initial mesh
|
||||
Mesh_1.Compute()
|
||||
Mesh_1.CheckCompute()
|
||||
Sub_mesh_1 = Regular_1D_1.GetSubMesh()
|
||||
|
||||
# Get the number of faces in the mesh
|
||||
num_faces_before = Mesh_1.NbFaces()
|
||||
print('Number of faces before switching: %d' % num_faces_before)
|
||||
|
||||
# Switch to composite segment algorithm and compute the mesh
|
||||
status = Mesh_1.RemoveHypothesis(Regular_1D)
|
||||
CompositeSegment_1D = smesh.CreateHypothesis('CompositeSegment_1D')
|
||||
Mesh_1.AddHypothesis(CompositeSegment_1D)
|
||||
Mesh_1.Compute()
|
||||
Mesh_1.CheckCompute()
|
||||
|
||||
# Switch back to regular segment algorithm and compute the mesh
|
||||
status = Mesh_1.RemoveHypothesis(CompositeSegment_1D)
|
||||
Mesh_1.AddHypothesis(Regular_1D)
|
||||
Mesh_1.Compute()
|
||||
Mesh_1.CheckCompute()
|
||||
|
||||
# Get the number of faces in the mesh
|
||||
num_faces_after = Mesh_1.NbFaces()
|
||||
print('Number of faces after switching: %d' % num_faces_after)
|
||||
assert num_faces_before == num_faces_after, 'Number of faces before and after switching should be the same'
|
||||
|
||||
## Set names of Mesh objects
|
||||
smesh.SetName(CompositeSegment_1D, 'CompositeSegment_1D')
|
||||
smesh.SetName(Number_of_Segments_1, 'Number of Segments_1')
|
||||
smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1')
|
||||
smesh.SetName(Number_of_Segments_2, 'Number of Segments_2')
|
||||
smesh.SetName(edge_1, 'edge')
|
||||
smesh.SetName(Sub_mesh_1, 'Sub-mesh_1')
|
||||
smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
|
||||
smesh.SetName(Propagation_of_1D_Hyp, 'Propagation of 1D Hyp. on Opposite Edges_1')
|
||||
smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D')
|
||||
|
||||
if salome.sg.hasDesktop():
|
||||
salome.sg.updateObjBrowser()
|
@ -109,6 +109,8 @@ SET(GOOD_TESTS
|
||||
ex31_dimGroup.py
|
||||
PAL_MESH_043_2D.py
|
||||
SMESH_AdvancedEditor.py
|
||||
SMESH_algo_switch_box.py
|
||||
SMESH_algo_switch_face.py
|
||||
SMESH_blocks.py
|
||||
SMESH_box.py
|
||||
SMESH_BuildCompound.py
|
||||
|