22483: EDF 2772 SMESH: Define several 3D viscous layer hypotheses on the same Geometry
BIN
doc/salome/gui/SMESH/images/analyticdensity.png
Normal file
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 32 KiB |
BIN
doc/salome/gui/SMESH/images/createmesh-inv2.png
Executable file → Normal file
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 34 KiB |
BIN
doc/salome/gui/SMESH/images/createmesh-inv3.png
Executable file → Normal file
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 31 KiB |
BIN
doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png
Executable file → Normal file
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 33 KiB |
BIN
doc/salome/gui/SMESH/images/distributionwithtabledensity.png
Executable file → Normal file
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 33 KiB |
BIN
doc/salome/gui/SMESH/images/image10.jpg
Executable file → Normal file
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 11 KiB |
@ -183,28 +183,48 @@ You can set the type of distribution for this hypothesis in the
|
||||
<br><b>Equidistant Distribution</b> - all segments will have the same
|
||||
length, you define only the <b>Number of Segments</b>.
|
||||
|
||||
<br><b>Scale Distribution</b> - length of segments gradually changes depending on the <b>Scale Factor</b>, which is a ratio of the first segment length to the last segment length.
|
||||
<br><b>Scale Distribution</b> - length of segments gradually changes
|
||||
depending on the <b>Scale Factor</b>, which is a ratio of the first
|
||||
segment length to the last segment length.<br>
|
||||
Length of segments changes in geometric progression with the common
|
||||
ratio (A) depending on the <b>Scale Factor</b> (S) and <b>Number of
|
||||
Segments</b> (N) as follows: <code> A = S**(1/(N-1))</code>. For an
|
||||
edge of length L, length of the first segment is
|
||||
<code>L * (1 - A)/(1 - A**N)</code>.
|
||||
|
||||
|
||||
\image html a-nbsegments2.png
|
||||
|
||||
<br><b>Distribution with Analytic Density</b> - you input the formula,
|
||||
which will rule the change of length of segments and the module shows
|
||||
in the plot the density function curve in red and the node
|
||||
distribution as blue crosses.
|
||||
|
||||
\image html distributionwithanalyticdensity.png
|
||||
|
||||
<br>
|
||||
\anchor analyticdensity_anchor
|
||||
The node distribution is computed so that to have the density function
|
||||
integral on the range between two nodes equal for all segments.
|
||||
\image html analyticdensity.png
|
||||
|
||||
<br><b>Distribution with Table Density</b> - you input a number of
|
||||
pairs <b>t - F(t)</b>, where \b t ranges from 0 to 1, and the module computes the
|
||||
formula, which will rule the change of length of segments and shows
|
||||
the curve in the plot. You can select the <b>Conversion mode</b> from
|
||||
\b Exponent and <b>Cut negative</b>.
|
||||
in the plot the density function curve in red and the node
|
||||
distribution as blue crosses. The node distribution is computed the
|
||||
same way as for
|
||||
\ref analyticdensity_anchor "Distribution with Analytic Density". You
|
||||
can select the <b>Conversion mode</b> from\b Exponent and <b>Cut
|
||||
negative</b>.
|
||||
|
||||
\image html distributionwithtabledensity.png
|
||||
|
||||
<br><b>Distribution with Analytic Density</b> - you input the formula,
|
||||
which will rule the change of length of segments and the module shows
|
||||
the curve in the plot.
|
||||
|
||||
\image html distributionwithanalyticdensity.png
|
||||
|
||||
<b>See Also</b> a sample TUI Script of a
|
||||
\ref tui_deflection_1d "Defining Number of Segments" hypothesis
|
||||
operation.
|
||||
|
||||
|
||||
<br>
|
||||
\anchor start_and_end_length_anchor
|
||||
<h2>Start and End Length hypothesis</h2>
|
||||
|
@ -93,7 +93,7 @@ computations.
|
||||
and edges, just hide the mesh to avoid this. To avoid a long wait when a
|
||||
geometry with many faces (or edges) is displayed, the number of faces
|
||||
(edges) shown at a time is limited by the value of "Sub-shapes
|
||||
preview chunk size" preference (in Preferences/Mesh/General tab).<br>
|
||||
preview chunk size" preference (in Preferences/Mesh/General tab).
|
||||
|
||||
If faces/edges without layers are specified, the element layers are
|
||||
not constructed on geometrical faces shared by several solids in 3D
|
||||
@ -106,6 +106,15 @@ computations.
|
||||
possibly being internal faces/edges within the whole model.
|
||||
\image html viscous_layers_on_submesh.png 2D viscous layers constructed on boundary edges of a sub-mesh on a disk face.
|
||||
|
||||
If you use \b several hypotheses to define viscous layers on faces of
|
||||
one solid, keep in mind the following. Each hypothesis defines a set
|
||||
of faces with viscous layers (even if you specify faces without
|
||||
layers). The sets of faces with viscous layers defined by several
|
||||
hypotheses should not intersect, else the module won't add an
|
||||
hypothesis that is incompatible with another one. <br>
|
||||
Also you can't define different number of layers on adjacent faces
|
||||
of a solid.<br>
|
||||
This logic is also valid for the 2D hypothesis.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
@ -29,9 +29,13 @@
|
||||
\image html createmesh-inv.png
|
||||
<br>
|
||||
</li>
|
||||
<li>Select <b>Mesh Type</b> in the corresponding list from <b>Any, Hexahedral, Tetrahedral, Triangular </b> and \b Quadrilateral (there can be less items for lower dimensions).
|
||||
<li> To filter off irrelevant meshing algorithms, you can
|
||||
select <b>Mesh Type</b> in the corresponding list from <b>Any,
|
||||
Hexahedral, Tetrahedral, Triangular </b> and \b Quadrilateral (there
|
||||
can be less items for the geometry of lower dimensions).
|
||||
|
||||
Selection of a mesh type hides any algorithms that are not able to create elements of this type.</li>
|
||||
Selection of a mesh type hides all meshing algorithms that can not
|
||||
generate elements of this type.</li>
|
||||
|
||||
<li>Apply \subpage basic_meshing_algos_page "meshing algorithms" and
|
||||
\subpage about_hypo_page "hypotheses" which will be used to compute
|
||||
@ -42,7 +46,8 @@
|
||||
dimension of the CAD model (geometry) the algorithms listed on
|
||||
this page affect and the maximal dimension of elements the algorithms
|
||||
generate. For example, \b 3D page lists the algorithms that affect
|
||||
3D geometrical objects (solids).
|
||||
3D geometrical objects (solids) and generate 3D mesh elements
|
||||
(tetrahedra, hexahedra etc.)
|
||||
|
||||
\note
|
||||
- Some page(s) can be disabled if the source geometrical
|
||||
@ -65,7 +70,6 @@
|
||||
it is "Mesh_1". Then select the geometrical object you wish to
|
||||
mesh in the Object Browser and click "Select" button near \b Geometry
|
||||
field (if the name of the object has not yet appeared in \b Geometry field).
|
||||
|
||||
<center>
|
||||
\image html image120.png
|
||||
<em>"Select" button</em>
|
||||
@ -74,21 +78,22 @@
|
||||
Now you can define 3D Algorithm and 3D Hypotheses, which will be
|
||||
applied to the solids of your geometrical object. Click the <em>"Add
|
||||
Hypothesis"</em> button to add a hypothesis.
|
||||
|
||||
<center>
|
||||
\image html image121.png
|
||||
<em>"Add Hypothesis" button</em>
|
||||
</center>
|
||||
Click the <em>"Plus"</em> button to enable adding more additional hypotheses.
|
||||
|
||||
Click the <em>"Edit Hypothesis"</em> button to change the values for the
|
||||
current hypothesis.
|
||||
|
||||
<center>
|
||||
\image html image122.png
|
||||
<em>"Edit Hypothesis" button</em>
|
||||
</center>
|
||||
|
||||
Most 2D and 3D algorithms can work without hypotheses using default meshing parameters. Some algorithms do not require any hypotheses. After selection of an algorithm "Hypothesis" field of
|
||||
Most 2D and 3D algorithms can work without hypotheses using
|
||||
default meshing parameters. Some algorithms do not require any
|
||||
hypotheses. After selection of an algorithm "Hypothesis" field of
|
||||
the dialog can contain:
|
||||
<ul>
|
||||
<li> <em>\<Default\></em> if the algorithm can work using default
|
||||
@ -111,6 +116,9 @@
|
||||
choice of hypotheses and lower dimension algorithms depends on
|
||||
the higher dimension algorithm.
|
||||
|
||||
If you wish you can select different algorithms and/or hypotheses
|
||||
for meshing some parts of your CAD model by \ref constructing_submeshes_page.
|
||||
|
||||
Some algorithms generate mesh of several dimensions, while others
|
||||
produce mesh of only one dimension. In the latter case there must
|
||||
be one Algorithm and zero or several
|
||||
@ -128,8 +136,9 @@
|
||||
|
||||
It contains:
|
||||
<ul>
|
||||
<li>a mesh name (<em>Mesh_mechanic</em>);
|
||||
<li>a reference to the geometrical object on the basis of
|
||||
which the mesh has been constructed;</li>
|
||||
which the mesh has been constructed (\a mechanic);</li>
|
||||
<li><b>Applied hypotheses</b> folder containing the references
|
||||
to the hypotheses applied at the construction of the mesh;</li>
|
||||
<li><b>Applied algorithms</b> folder containing the references
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
\page constructing_submeshes_page Constructing sub-meshes
|
||||
|
||||
Sub-mesh is a mesh on a geometrical sub-object created with algorithms
|
||||
Sub-mesh is a mesh on a geometrical sub-object created with meshing algorithms
|
||||
and/or hypotheses other than the algorithms and hypotheses assigned to
|
||||
the parent mesh on the parent geometrical object.
|
||||
|
||||
@ -52,7 +52,7 @@ The following dialog box will appear:
|
||||
\par
|
||||
It allows to define the \b Name, the parent \b Mesh and the \b
|
||||
Geometry (e.g. a face if the parent mesh has been built on box) of the
|
||||
sub-mesh. You can define algorithms and hypotheses in the same way as
|
||||
sub-mesh. You can select meshing algorithms and hypotheses in the same way as
|
||||
in \ref constructing_meshes_page "Create mesh" menu.
|
||||
|
||||
\par
|
||||
@ -93,11 +93,13 @@ displayed as follows:
|
||||
\par
|
||||
It contains:
|
||||
<ul>
|
||||
<li>a reference to the geometrical object on the basis of which the sub-mesh has been constructed;</li>
|
||||
<li>a sub-mesh name (\a SubMeshFace1)
|
||||
<li>a reference to the geometrical object on the basis of which the
|
||||
sub-mesh has been constructed (<em>Cylindrical Face_1</em>);</li>
|
||||
<li><b>Applied hypotheses</b> folder containing the references to the
|
||||
hypotheses applied to the construction of the sub-mesh;</li>
|
||||
hypotheses selected at the construction of the sub-mesh;</li>
|
||||
<li><b>Applied algorithms</b> folder containing the references to the
|
||||
algorithms applied to the construction of the sub-mesh.</li>
|
||||
algorithms selected at the construction of the sub-mesh.</li>
|
||||
</ul>
|
||||
|
||||
<br><b>See Also</b> a sample TUI Script of a
|
||||
|
@ -40,29 +40,24 @@ the following ways:
|
||||
mesh. For this, turn on the <b>Select All</b> check box. In this mode
|
||||
all controls, which allow selecting the entities in other ways, are
|
||||
disabled.</li>
|
||||
<li>By applying the Filter. The <b>Set filter</b> button allows to
|
||||
define the filter for selection of the elements for your group. See more
|
||||
about filters on the
|
||||
\ref selection_filter_library_page "Selection filter library" page.<br>
|
||||
If the <b>Enable manual edition</b> check box is turned off, the
|
||||
filter entirely defines the group contents. In this mode, the filter is
|
||||
applied to all elements of the mesh. If there are no entities
|
||||
corresponding to the filter, the \b Apply button is disabled.<br>
|
||||
If the <b>Enable manual edition</b> check box is turned on, the defined
|
||||
filter can be used to for selection of entities for the group.</li>
|
||||
<li>By choosing entities manually with the mouse in the 3D Viewer. For
|
||||
this, turn on the <b>Enable manual edition</b> check box. You can
|
||||
click on an element in the 3D viewer and it will be highlighted. After
|
||||
that click the \b Add button and the ID of this element will be
|
||||
added to the list.</li>
|
||||
<li>By adding entities from either a submesh or an existing
|
||||
added to the list.<br>
|
||||
The <b>Set filter</b> button allows to define the filter for
|
||||
selection of the elements for your group. See more about filters on
|
||||
the \ref selection_filter_library_page "Selection filter library"
|
||||
page.</li>
|
||||
<li>By adding entities from either a sub-mesh or an existing
|
||||
group. For this, turn on the <b>Enable manual edition</b> check
|
||||
box. <b>Select from</b> set of fields allows to select a submesh or
|
||||
box. <b>Select from</b> set of fields allows to select a sub-mesh or
|
||||
a group of the appropriate type.</li>
|
||||
</ul>
|
||||
In the <b>manual edition</b> mode you can
|
||||
<ul>
|
||||
<li>click the \b Remove button to remove the selected elements from the list</li>
|
||||
<li>click the \b Remove button to remove the selected list items from
|
||||
the list.</li>
|
||||
<li>click the <b>Sort List</b> button to sort the list of IDs of
|
||||
mesh elements.</li>
|
||||
</ul>
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
\page editing_meshes_page Editing Meshes
|
||||
|
||||
\n After you have created a mesh or submesh with definite applied
|
||||
hypotheses and algorithms you can edit your mesh by \b assigning new
|
||||
hypotheses and algorithms or \b unassigning the applied hypotheses and
|
||||
algorithms. The editing proceeds in the same way as <b>Mesh
|
||||
Creation</b>.
|
||||
\n After you have created a mesh or sub-mesh with definite applied
|
||||
meshing algorithms and hypotheses you can edit your mesh by \b assigning other
|
||||
algorithms and/or hypotheses or \b unassigning the applied hypotheses and
|
||||
algorithms. The editing proceeds in the same way as
|
||||
\ref create_mesh_anchor "Mesh Creation".
|
||||
|
||||
\image html createmesh-inv3.png
|
||||
|
||||
|
@ -215,7 +215,8 @@ module SMESH
|
||||
HYP_BAD_DIM, // bad dimension
|
||||
HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its sub-shape, nor a group
|
||||
HYP_BAD_GEOMETRY, // geometry mismatches algorithm's expectation
|
||||
HYP_NEED_SHAPE // algorithm can work on shape only
|
||||
HYP_NEED_SHAPE, // algorithm can work on shape only
|
||||
HYP_INCOMPAT_HYPS // several additional hypotheses are incompatible one with other
|
||||
};
|
||||
|
||||
/*!
|
||||
@ -508,24 +509,22 @@ module SMESH
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
/*!
|
||||
* Add hypothesis to the mesh, under a particular Sub-shape
|
||||
* Add hypothesis to the mesh, under a particular sub-shape
|
||||
* (or the main shape itself)
|
||||
* The Add method is only used to prepare the build of the mesh and store
|
||||
* This method is only used to prepare the build of the mesh and store
|
||||
* the algorithms and associated parameters.
|
||||
* Actual job of mesh the shape is done by MESH_Gen.
|
||||
* Actual job of meshing the shape is done by SMESH_Gen::Compute()
|
||||
* @params
|
||||
* - aSubShape : sub-shape obtained by a shape explode in GEOM
|
||||
* - aSubObject : sub-shape obtained by a shape explode in GEOM
|
||||
* (or main shape)
|
||||
* - anHyp : hypothesis object
|
||||
* - anHyp : an hypothesis object
|
||||
* @return
|
||||
* - OK if the hypothesis is compatible with the sub-shape
|
||||
* (and all previous hypothesis on the sub-shape)
|
||||
* - NOK if the hypothesis is not compatible with the sub-shape
|
||||
* (or one previous hypothesis on the sub-shape)
|
||||
* raises exception if hypothesis has not been created
|
||||
* - An enum item explaining what's up
|
||||
* - anErrorText: an optional textual description of a problem (if any)
|
||||
*/
|
||||
Hypothesis_Status AddHypothesis(in GEOM::GEOM_Object aSubObject,
|
||||
in SMESH_Hypothesis anHyp)
|
||||
in SMESH_Hypothesis anHyp,
|
||||
out string anErrorText)
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
/*!
|
||||
|
@ -44,6 +44,8 @@ SET(SMESH_RESOURCES_FILES
|
||||
mesh_hypo_segment.png
|
||||
mesh_hypo_volume.png
|
||||
mesh_hypo_edit.png
|
||||
mesh_plus.png
|
||||
mesh_minus.png
|
||||
mesh_info.png
|
||||
advanced_mesh_info.png
|
||||
standard_mesh_info.png
|
||||
|
BIN
resources/mesh_minus.png
Normal file
After Width: | Height: | Size: 529 B |
BIN
resources/mesh_plus.png
Normal file
After Width: | Height: | Size: 598 B |
@ -138,6 +138,8 @@ class SMESH_EXPORT SMESH_Algo : public SMESH_Hypothesis
|
||||
* \param aShape - the shape
|
||||
* \param aStatus - check result
|
||||
* \retval bool - true if hypothesis is well defined
|
||||
*
|
||||
* Textual description of a problem can be stored in _comment field.
|
||||
*/
|
||||
virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
|
||||
const TopoDS_Shape& aShape,
|
||||
|
@ -63,7 +63,8 @@ public:
|
||||
HYP_BAD_DIM, // bad dimension
|
||||
HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its sub-shape, nor a group
|
||||
HYP_BAD_GEOMETRY, // shape geometry mismatches algorithm's expectation
|
||||
HYP_NEED_SHAPE // algorithm can work on shape only
|
||||
HYP_NEED_SHAPE, // algorithm can work on shape only
|
||||
HYP_INCOMPAT_HYPS // several additional hypotheses are incompatible one with other
|
||||
};
|
||||
static bool IsStatusFatal(Hypothesis_Status theStatus)
|
||||
{ return theStatus >= HYP_UNKNOWN_FATAL; }
|
||||
|
@ -602,11 +602,15 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName,
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status
|
||||
SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
|
||||
int anHypId ) throw(SALOME_Exception)
|
||||
int anHypId,
|
||||
std::string* anError ) throw(SALOME_Exception)
|
||||
{
|
||||
Unexpect aCatch(SalomeException);
|
||||
if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
|
||||
|
||||
if ( anError )
|
||||
anError->clear();
|
||||
|
||||
SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
|
||||
if ( !subMesh || !subMesh->GetId())
|
||||
return SMESH_Hypothesis::HYP_BAD_SUBSHAPE;
|
||||
@ -633,11 +637,14 @@ SMESH_Hypothesis::Hypothesis_Status
|
||||
|
||||
// shape
|
||||
|
||||
bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
|
||||
bool isAlgo = ( anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO );
|
||||
int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP;
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
|
||||
|
||||
if ( anError && SMESH_Hypothesis::IsStatusFatal(ret) && subMesh->GetComputeError() )
|
||||
*anError = subMesh->GetComputeError()->myComment;
|
||||
|
||||
// sub-shapes
|
||||
if ( !SMESH_Hypothesis::IsStatusFatal(ret) &&
|
||||
anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
|
||||
@ -645,9 +652,19 @@ SMESH_Hypothesis::Hypothesis_Status
|
||||
event = isAlgo ? SMESH_subMesh::ADD_FATHER_ALGO : SMESH_subMesh::ADD_FATHER_HYP;
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status ret2 =
|
||||
subMesh->SubMeshesAlgoStateEngine(event, anHyp);
|
||||
subMesh->SubMeshesAlgoStateEngine(event, anHyp, /*exitOnFatal=*/true);
|
||||
if (ret2 > ret)
|
||||
{
|
||||
ret = ret2;
|
||||
if ( SMESH_Hypothesis::IsStatusFatal( ret ))
|
||||
{
|
||||
if ( anError && subMesh->GetComputeError() )
|
||||
*anError = subMesh->GetComputeError()->myComment;
|
||||
// remove anHyp
|
||||
event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
|
||||
subMesh->AlgoStateEngine(event, anHyp);
|
||||
}
|
||||
}
|
||||
|
||||
// check concurent hypotheses on ancestors
|
||||
if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
|
||||
@ -892,17 +909,20 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh,
|
||||
const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
|
||||
const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
|
||||
for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
|
||||
if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) &&
|
||||
( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
|
||||
hypTypes.insert( (*hyp)->GetName() ).second )
|
||||
{
|
||||
const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
|
||||
if (( aFilter.IsOk( h, aSubShape )) &&
|
||||
( h->IsAuxiliary() || !mainHypFound ) &&
|
||||
( h->IsAuxiliary() || hypTypes.insert( h->GetName() ).second ))
|
||||
{
|
||||
aHypList.push_back( *hyp );
|
||||
nbHyps++;
|
||||
if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
|
||||
if ( !h->IsAuxiliary() )
|
||||
mainHypFound = true;
|
||||
if ( assignedTo ) assignedTo->push_back( aSubShape );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get hypos from ancestors of aSubShape
|
||||
if ( andAncestors )
|
||||
@ -918,18 +938,21 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh,
|
||||
const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
|
||||
const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
|
||||
for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
|
||||
if (( aFilter.IsOk( cSMESH_Hyp( *hyp ), curSh )) &&
|
||||
( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
|
||||
( hypTypes.insert( (*hyp)->GetName() ).second ))
|
||||
{
|
||||
const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
|
||||
if (( aFilter.IsOk( h, curSh )) &&
|
||||
( h->IsAuxiliary() || !mainHypFound ) &&
|
||||
( h->IsAuxiliary() || hypTypes.insert( h->GetName() ).second ))
|
||||
{
|
||||
aHypList.push_back( *hyp );
|
||||
nbHyps++;
|
||||
if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() )
|
||||
if ( !h->IsAuxiliary() )
|
||||
mainHypFound = true;
|
||||
if ( assignedTo ) assignedTo->push_back( curSh );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nbHyps;
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ public:
|
||||
bool theMakeRequiredGroups = true );
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status
|
||||
AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId)
|
||||
AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId, std::string* error=0)
|
||||
throw(SALOME_Exception);
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status
|
||||
|
@ -670,11 +670,17 @@ bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis,
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Treats modification of hypotheses definition
|
||||
* \param [in] event - what happens
|
||||
* \param [in] anHyp - a hypothesis
|
||||
* \return SMESH_Hypothesis::Hypothesis_Status - a treatment result.
|
||||
*
|
||||
* Optional description of a problematic situation (if any) can be retrieved
|
||||
* via GetComputeError().
|
||||
*/
|
||||
//=============================================================================
|
||||
//================================================================================
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status
|
||||
SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
|
||||
@ -753,7 +759,7 @@ SMESH_Hypothesis::Hypothesis_Status
|
||||
if ( ! CanAddHypothesis( anHyp )) // check dimension
|
||||
return SMESH_Hypothesis::HYP_BAD_DIM;
|
||||
|
||||
if ( /*!anHyp->IsAuxiliary() &&*/ getSimilarAttached( _subShape, anHyp ) )
|
||||
if ( !anHyp->IsAuxiliary() && getSimilarAttached( _subShape, anHyp ) )
|
||||
return SMESH_Hypothesis::HYP_ALREADY_EXIST;
|
||||
|
||||
if ( !meshDS->AddHypothesis(_subShape, anHyp))
|
||||
@ -782,6 +788,9 @@ SMESH_Hypothesis::Hypothesis_Status
|
||||
if (!isApplicableHyp)
|
||||
return ret; // not applicable hypotheses do not change algo state
|
||||
|
||||
if (( algo = GetAlgo()))
|
||||
algo->InitComputeError();
|
||||
|
||||
switch (_algoState)
|
||||
{
|
||||
|
||||
@ -1114,6 +1123,11 @@ SMESH_Hypothesis::Hypothesis_Status
|
||||
}
|
||||
}
|
||||
|
||||
if ( _algo ) { // get an error description set by _algo->CheckHypothesis()
|
||||
_computeError = _algo->GetComputeError();
|
||||
_algo->InitComputeError();
|
||||
}
|
||||
|
||||
bool stateChange = ( _algoState != oldAlgoState );
|
||||
|
||||
if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK
|
||||
@ -1213,14 +1227,24 @@ void SMESH_subMesh::setAlgoState(algo_state state)
|
||||
_algoState = state;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Send an event to sub-meshes
|
||||
* \param [in] event - the event
|
||||
* \param [in] anHyp - an hypothesis
|
||||
* \param [in] exitOnFatal - to stop iteration on sub-meshes if a sub-mesh
|
||||
* reports a fatal result
|
||||
* \return SMESH_Hypothesis::Hypothesis_Status - the worst result
|
||||
*
|
||||
* Optional description of a problematic situation (if any) can be retrieved
|
||||
* via GetComputeError().
|
||||
*/
|
||||
//=============================================================================
|
||||
//================================================================================
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status
|
||||
SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
|
||||
SMESH_Hypothesis * anHyp)
|
||||
SMESH_Hypothesis * anHyp,
|
||||
bool exitOnFatal)
|
||||
{
|
||||
SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK;
|
||||
//EAP: a wire (dim==1) should notify edges (dim==1)
|
||||
@ -1229,10 +1253,16 @@ SMESH_Hypothesis::Hypothesis_Status
|
||||
{
|
||||
SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
|
||||
while ( smIt->more() ) {
|
||||
SMESH_Hypothesis::Hypothesis_Status ret2 =
|
||||
smIt->next()->AlgoStateEngine(event, anHyp);
|
||||
SMESH_subMesh* sm = smIt->next();
|
||||
SMESH_Hypothesis::Hypothesis_Status ret2 = sm->AlgoStateEngine(event, anHyp);
|
||||
if ( ret2 > ret )
|
||||
{
|
||||
ret = ret2;
|
||||
_computeError = sm->_computeError;
|
||||
sm->_computeError.reset();
|
||||
if ( exitOnFatal && SMESH_Hypothesis::IsStatusFatal( ret ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -218,10 +218,10 @@ public:
|
||||
AlgoStateEngine(int event, SMESH_Hypothesis * anHyp);
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status
|
||||
SubMeshesAlgoStateEngine(int event, SMESH_Hypothesis * anHyp);
|
||||
SubMeshesAlgoStateEngine(int event, SMESH_Hypothesis * anHyp, bool exitOnFatal=false);
|
||||
|
||||
algo_state GetAlgoState() const { return _algoState; }
|
||||
compute_state GetComputeState() const { return _computeState; };
|
||||
compute_state GetComputeState() const { return _computeState; }
|
||||
SMESH_ComputeErrorPtr& GetComputeError() { return _computeError; }
|
||||
|
||||
void DumpAlgoState(bool isMain);
|
||||
|
@ -103,3 +103,14 @@ bool SMESHDS_Hypothesis::operator==(const SMESHDS_Hypothesis& other) const
|
||||
((SMESHDS_Hypothesis*)&other)->SaveTo(otherSave);
|
||||
return mySave.str() == otherSave.str();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Compare types of hypotheses
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool SMESHDS_Hypothesis::IsSameName( const SMESHDS_Hypothesis& other) const
|
||||
{
|
||||
return _name == other._name;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ class SMESHDS_EXPORT SMESHDS_Hypothesis
|
||||
virtual std::ostream & SaveTo(std::ostream & save)=0;
|
||||
virtual std::istream & LoadFrom(std::istream & load)=0;
|
||||
|
||||
bool IsSameName( const SMESHDS_Hypothesis& other) const;
|
||||
virtual bool operator==(const SMESHDS_Hypothesis& other) const;
|
||||
bool operator!=(const SMESHDS_Hypothesis& other) const { return !(*this==other); }
|
||||
|
||||
|
@ -93,19 +93,23 @@ namespace SMESH
|
||||
|
||||
void processHypothesisStatus(const int theHypStatus,
|
||||
SMESH::SMESH_Hypothesis_ptr theHyp,
|
||||
const bool theIsAddition)
|
||||
const bool theIsAddition,
|
||||
const char* theError = 0)
|
||||
{
|
||||
if (theHypStatus > SMESH::HYP_OK) {
|
||||
// get Hyp name
|
||||
QString aHypName ("NULL Hypothesis");
|
||||
if (!CORBA::is_nil(theHyp)) {
|
||||
_PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
|
||||
if (Shyp)
|
||||
if (Shyp) {
|
||||
// name in study
|
||||
aHypName = Shyp->GetName().c_str();
|
||||
else
|
||||
}
|
||||
else {
|
||||
// label in xml file
|
||||
aHypName = GetHypothesisData(theHyp->GetName())->Label;
|
||||
CORBA::String_var hypType = theHyp->GetName();
|
||||
aHypName = GetHypothesisData( hypType.in() )->Label;
|
||||
}
|
||||
}
|
||||
|
||||
// message
|
||||
@ -116,12 +120,22 @@ namespace SMESH
|
||||
else
|
||||
aMsg = (isFatal ? "SMESH_CANT_RM_HYP" : "SMESH_RM_HYP_WRN");
|
||||
|
||||
aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName) +
|
||||
aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName);
|
||||
|
||||
if ( theError && theError[0] )
|
||||
{
|
||||
aMsg += theError;
|
||||
}
|
||||
else
|
||||
{
|
||||
QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data());
|
||||
|
||||
if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) // PAL18501
|
||||
aMsg = aMsg.arg( GetHypothesisData(theHyp->GetName())->Dim[0] );
|
||||
|
||||
if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) { // PAL18501
|
||||
CORBA::String_var hypType = theHyp->GetName();
|
||||
if ( HypothesisData* hd = GetHypothesisData( hypType.in() ))
|
||||
aMsg = aMsg.arg( hd->Dim[0] );
|
||||
}
|
||||
}
|
||||
SUIT_MessageBox::warning(SMESHGUI::desktop(),
|
||||
QObject::tr("SMESH_WRN_WARNING"),
|
||||
aMsg);
|
||||
@ -520,7 +534,8 @@ namespace SMESH
|
||||
_PTR(SObject) SM = SMESH::FindSObject(aMesh);
|
||||
GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM);
|
||||
try {
|
||||
res = aMesh->AddHypothesis(aShapeObject, aHyp);
|
||||
CORBA::String_var error;
|
||||
res = aMesh->AddHypothesis(aShapeObject, aHyp, error.out());
|
||||
if (res < SMESH::HYP_UNKNOWN_FATAL) {
|
||||
_PTR(SObject) aSH = SMESH::FindSObject(aHyp);
|
||||
if (SM && aSH) {
|
||||
@ -529,7 +544,7 @@ namespace SMESH
|
||||
}
|
||||
if (res > SMESH::HYP_OK) {
|
||||
wc.suspend();
|
||||
processHypothesisStatus(res, aHyp, true);
|
||||
processHypothesisStatus(res, aHyp, true, error.in() );
|
||||
wc.resume();
|
||||
}
|
||||
}
|
||||
@ -554,8 +569,10 @@ namespace SMESH
|
||||
SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
|
||||
_PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
|
||||
GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
|
||||
if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) {
|
||||
res = aMesh->AddHypothesis(aShapeObject, aHyp);
|
||||
if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil())
|
||||
{
|
||||
CORBA::String_var error;
|
||||
res = aMesh->AddHypothesis( aShapeObject, aHyp, error.out() );
|
||||
if (res < SMESH::HYP_UNKNOWN_FATAL) {
|
||||
_PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
|
||||
if (meshSO)
|
||||
@ -563,7 +580,7 @@ namespace SMESH
|
||||
}
|
||||
if (res > SMESH::HYP_OK) {
|
||||
wc.suspend();
|
||||
processHypothesisStatus(res, aHyp, true);
|
||||
processHypothesisStatus( res, aHyp, true, error.in() );
|
||||
wc.resume();
|
||||
}
|
||||
}
|
||||
|
@ -32,16 +32,19 @@
|
||||
#include <SUIT_ResourceMgr.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QVBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QTabWidget>
|
||||
#include <QGroupBox>
|
||||
#include <QToolButton>
|
||||
#include <QComboBox>
|
||||
#include <QMenu>
|
||||
#include <QCursor>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QMenu>
|
||||
#include <QPushButton>
|
||||
#include <QTabWidget>
|
||||
#include <QToolButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <Standard_Integer.hxx>
|
||||
|
||||
#define SPACING 6
|
||||
#define MARGIN 11
|
||||
@ -65,19 +68,21 @@ SMESHGUI_MeshTab::SMESHGUI_MeshTab( QWidget* theParent )
|
||||
SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
|
||||
QIcon aCreateIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_HYPO" ) ) );
|
||||
QIcon aEditIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_HYPO_EDIT" ) ) );
|
||||
QIcon aPlusIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_PLUS" ) ) );
|
||||
QIcon aMinusIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_MINUS" ) ) );
|
||||
|
||||
// Algorifm
|
||||
QLabel* anAlgoLbl = new QLabel( tr( "ALGORITHM" ), this );
|
||||
myHyp[ Algo ] = new QComboBox( this );
|
||||
myHypCombo[ Algo ] = new QComboBox( this );
|
||||
|
||||
// Hypothesis
|
||||
QLabel* aHypLbl = new QLabel( tr( "HYPOTHESIS" ), this );
|
||||
myHyp[ MainHyp ] = new QComboBox( this );
|
||||
myHyp[ MainHyp ]->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
|
||||
myCreateHyp[ MainHyp ] = new QToolButton( this );
|
||||
myCreateHyp[ MainHyp ]->setIcon( aCreateIcon );
|
||||
myEditHyp[ MainHyp ] = new QToolButton( this );
|
||||
myEditHyp[ MainHyp ]->setIcon( aEditIcon );
|
||||
myHypCombo[ MainHyp ] = new QComboBox( this );
|
||||
myHypCombo[ MainHyp ]->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
|
||||
myCreateHypBtn[ MainHyp ] = new QToolButton( this );
|
||||
myCreateHypBtn[ MainHyp ]->setIcon( aCreateIcon );
|
||||
myEditHypBtn[ MainHyp ] = new QToolButton( this );
|
||||
myEditHypBtn[ MainHyp ]->setIcon( aEditIcon );
|
||||
|
||||
// Line
|
||||
QFrame* aLine = new QFrame( this );
|
||||
@ -85,12 +90,20 @@ SMESHGUI_MeshTab::SMESHGUI_MeshTab( QWidget* theParent )
|
||||
|
||||
// Add. hypothesis
|
||||
QLabel* anAddHypLbl = new QLabel( tr( "ADD_HYPOTHESIS" ), this );
|
||||
myHyp[ AddHyp ] = new QComboBox( this );
|
||||
myHyp[ AddHyp ]->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
|
||||
myCreateHyp[ AddHyp ] = new QToolButton( this );
|
||||
myCreateHyp[ AddHyp ]->setIcon( aCreateIcon );
|
||||
myEditHyp[ AddHyp ] = new QToolButton( this );
|
||||
myEditHyp[ AddHyp ]->setIcon( aEditIcon );
|
||||
myHypCombo[ AddHyp ] = new QComboBox( this );
|
||||
myHypCombo[ AddHyp ]->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
|
||||
myCreateHypBtn[ AddHyp ] = new QToolButton( this );
|
||||
myCreateHypBtn[ AddHyp ]->setIcon( aCreateIcon );
|
||||
myEditHypBtn[ AddHyp ] = new QToolButton( this );
|
||||
myEditHypBtn[ AddHyp ]->setIcon( aEditIcon );
|
||||
myEditHypBtn[ MoreAddHyp ] = new QToolButton( this );
|
||||
myEditHypBtn[ MoreAddHyp ]->setIcon( aEditIcon );
|
||||
|
||||
myAddHypList = new QListWidget( this );
|
||||
myMoreAddHypBtn = new QToolButton( this );
|
||||
myMoreAddHypBtn->setIcon( aPlusIcon );
|
||||
myLessAddHypBtn = new QToolButton( this );
|
||||
myLessAddHypBtn->setIcon( aMinusIcon );
|
||||
|
||||
// Fill layout
|
||||
QGridLayout* aLay = new QGridLayout( this );
|
||||
@ -98,26 +111,35 @@ SMESHGUI_MeshTab::SMESHGUI_MeshTab( QWidget* theParent )
|
||||
aLay->setSpacing( SPACING );
|
||||
|
||||
aLay->addWidget( anAlgoLbl, 0, 0 );
|
||||
aLay->addWidget( myHyp[ Algo ], 0, 1 );
|
||||
aLay->addWidget( myHypCombo[ Algo ], 0, 1 );
|
||||
aLay->addWidget( aHypLbl, 1, 0 );
|
||||
aLay->addWidget( myHyp[ MainHyp ], 1, 1 );
|
||||
aLay->addWidget( myCreateHyp[ MainHyp ], 1, 2 );
|
||||
aLay->addWidget( myEditHyp[ MainHyp ], 1, 3 );
|
||||
aLay->addWidget( myHypCombo[ MainHyp ], 1, 1 );
|
||||
aLay->addWidget( myCreateHypBtn[ MainHyp ], 1, 2 );
|
||||
aLay->addWidget( myEditHypBtn[ MainHyp ], 1, 3 );
|
||||
aLay->addWidget( aLine, 2, 0, 1, 4 );
|
||||
aLay->addWidget( anAddHypLbl, 3, 0 );
|
||||
aLay->addWidget( myHyp[ AddHyp ], 3, 1 );
|
||||
aLay->addWidget( myCreateHyp[ AddHyp ], 3, 2 );
|
||||
aLay->addWidget( myEditHyp[ AddHyp ], 3, 3 );
|
||||
aLay->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ), 4, 0 );
|
||||
aLay->addWidget( myHypCombo[ AddHyp ], 3, 1 );
|
||||
aLay->addWidget( myCreateHypBtn[ AddHyp ], 3, 2 );
|
||||
aLay->addWidget( myEditHypBtn[ AddHyp ], 3, 3 );
|
||||
aLay->addWidget( myAddHypList, 4, 1, 2, 1 );
|
||||
aLay->addWidget( myMoreAddHypBtn, 4, 2 );
|
||||
aLay->addWidget( myEditHypBtn[ MoreAddHyp ], 4, 3 );
|
||||
aLay->addWidget( myLessAddHypBtn, 5, 2 );
|
||||
aLay->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ), 6, 0 );
|
||||
|
||||
// Connect signals and slots
|
||||
for ( int i = MainHyp; i <= AddHyp; i++ )
|
||||
{
|
||||
connect( myCreateHyp[ i ], SIGNAL( clicked() ) , SLOT( onCreateHyp() ) );
|
||||
connect( myEditHyp[ i ] , SIGNAL( clicked() ) , SLOT( onEditHyp() ) );
|
||||
connect( myHyp[ i ] , SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
|
||||
connect( myCreateHypBtn[ i ], SIGNAL( clicked() ) , SLOT( onCreateHyp() ) );
|
||||
connect( myEditHypBtn[ i ] , SIGNAL( clicked() ) , SLOT( onEditHyp() ) );
|
||||
connect( myHypCombo[ i ] , SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
|
||||
}
|
||||
connect( myHyp[ Algo ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
|
||||
connect( myHypCombo[ Algo ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
|
||||
|
||||
connect( myAddHypList, SIGNAL( currentRowChanged( int ) ), SLOT( onHyp( int ) ) );
|
||||
connect( myEditHypBtn[ MoreAddHyp ], SIGNAL( clicked() ), SLOT( onEditHyp() ) );
|
||||
connect( myMoreAddHypBtn, SIGNAL( clicked() ), SLOT( onMoreAddHyp() ));
|
||||
connect( myLessAddHypBtn, SIGNAL( clicked() ), SLOT( onLessAddHyp() ));
|
||||
|
||||
// Initialize controls
|
||||
|
||||
@ -135,6 +157,49 @@ SMESHGUI_MeshTab::~SMESHGUI_MeshTab()
|
||||
{
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Adds an item in a control corresponding to \a type
|
||||
* \param [in] txt - item text
|
||||
* \param [in] type - HypType
|
||||
* \param [in] index - index of item in a list of items
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void SMESHGUI_MeshTab::addItem( const QString& txt, const int type, const int index )
|
||||
{
|
||||
if ( type <= AddHyp )
|
||||
{
|
||||
myHypCombo[ type ]->addItem( txt, QVariant( index ));
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem( txt, myAddHypList );
|
||||
item->setData( Qt::UserRole, QVariant( index ));
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Returns index of hyp of a given type
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
int SMESHGUI_MeshTab::getCurrentIndex( const int type, const bool curByType ) const
|
||||
{
|
||||
if ( type <= AddHyp )
|
||||
{
|
||||
return myHypCombo[ type ]->itemData( myHypCombo[ type ]->currentIndex() ).toInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
int row = curByType ? ( type - AddHyp - 1 ) : myAddHypList->currentRow();
|
||||
if ( QListWidgetItem* item = myAddHypList->item( row ))
|
||||
return item->data( Qt::UserRole ).toInt();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Sets available hypothesis or algorithms
|
||||
@ -146,25 +211,26 @@ SMESHGUI_MeshTab::~SMESHGUI_MeshTab()
|
||||
//================================================================================
|
||||
void SMESHGUI_MeshTab::setAvailableHyps( const int theId, const QStringList& theHyps )
|
||||
{
|
||||
myAvailableHyps[ theId ] = theHyps;
|
||||
myAvailableHypTypes[ theId ] = theHyps;
|
||||
|
||||
bool enable = ! theHyps.isEmpty();
|
||||
if ( theId == Algo ) // fill list of algos
|
||||
{
|
||||
myHyp[ Algo ]->clear();
|
||||
myHypCombo[ Algo ]->clear();
|
||||
if ( enable )
|
||||
{
|
||||
myHyp[ Algo ]->addItem( tr( "NONE" ) );
|
||||
myHyp[ Algo ]->addItems( theHyps );
|
||||
myHyp[ Algo ]->setCurrentIndex( 0 );
|
||||
addItem( tr( "NONE"), Algo, 0 );
|
||||
for ( int i = 0, nbHyp = theHyps.count(); i < nbHyp; ++i )
|
||||
addItem( theHyps[i], Algo, i+1 );
|
||||
myHypCombo[ Algo ]->setCurrentIndex( 0 );
|
||||
}
|
||||
}
|
||||
else // enable buttons
|
||||
{
|
||||
myCreateHyp[ theId ]->setEnabled( enable );
|
||||
myEditHyp [ theId ]->setEnabled( false );
|
||||
myCreateHypBtn[ theId ]->setEnabled( enable );
|
||||
myEditHypBtn [ theId ]->setEnabled( false );
|
||||
}
|
||||
myHyp[ theId ]->setEnabled( enable );
|
||||
myHypCombo[ theId ]->setEnabled( enable );
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@ -172,7 +238,7 @@ void SMESHGUI_MeshTab::setAvailableHyps( const int theId, const QStringList& the
|
||||
* \brief Sets existing hypothesis
|
||||
* \param theId - identifier of hypothesis (main or additional, see HypType enumeration)
|
||||
* \param theHyps - list of available hypothesis names
|
||||
* \param theDefaultAvlbl - \c true means that the algorithm can with w/o hypothesis
|
||||
* \param theDefaultAvlbl - \c true means that the algorithm can work w/o hypothesis
|
||||
* with some default parameters
|
||||
*
|
||||
* Sets existing main or additional hypothesis for this tab
|
||||
@ -184,17 +250,25 @@ void SMESHGUI_MeshTab::setExistingHyps( const int theId,
|
||||
{
|
||||
if ( theId != Algo )
|
||||
{
|
||||
bool enable = ! myAvailableHyps[ theId ].isEmpty();
|
||||
myHyp[ theId ]->clear();
|
||||
bool enable = ! myAvailableHypTypes[ theId ].isEmpty();
|
||||
myHypCombo[ theId ]->clear();
|
||||
if ( enable )
|
||||
{
|
||||
QString none = tr( theDefaultAvlbl ? "DEFAULT" : ( theId == AddHyp ) ? "NONE" : "NONE" );
|
||||
myHyp[ theId ]->addItem( none );
|
||||
myHyp[ theId ]->addItems( theHyps );
|
||||
myHyp[ theId ]->setCurrentIndex( 0 );
|
||||
addItem( none, theId, 0 );
|
||||
for ( int i = 0, nbHyp = theHyps.count(); i < nbHyp; ++i )
|
||||
addItem( theHyps[i], theId, i+1 );
|
||||
myHypCombo[ theId ]->setCurrentIndex( 0 );
|
||||
}
|
||||
myHypCombo [ theId ]->setEnabled( enable );
|
||||
myEditHypBtn[ theId ]->setEnabled( false );
|
||||
if ( theId == AddHyp )
|
||||
{
|
||||
myAddHypList->clear();
|
||||
myEditHypBtn[ MoreAddHyp ]->setEnabled( false );
|
||||
myMoreAddHypBtn->setEnabled( false );
|
||||
myLessAddHypBtn->setEnabled( false );
|
||||
}
|
||||
myHyp [ theId ]->setEnabled( enable );
|
||||
myEditHyp[ theId ]->setEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,10 +284,15 @@ void SMESHGUI_MeshTab::setExistingHyps( const int theId,
|
||||
//================================================================================
|
||||
void SMESHGUI_MeshTab::addHyp( const int theId, const QString& theHyp )
|
||||
{
|
||||
myHyp[ theId ]->addItem( theHyp );
|
||||
myHyp[ theId ]->setCurrentIndex( myHyp[ theId ]->count() - 1 );
|
||||
myEditHyp[ theId ]->setEnabled( true );
|
||||
myHyp[ theId ]->setEnabled( true );
|
||||
int index = myHypCombo[ theId ]->count();
|
||||
if ( theId == AddHyp )
|
||||
index += myAddHypList->count();
|
||||
addItem( theHyp, theId, index );
|
||||
myHypCombo[ theId ]->setCurrentIndex( myHypCombo[ theId ]->count() - 1 );
|
||||
myEditHypBtn[ theId ]->setEnabled( true );
|
||||
myHypCombo[ theId ]->setEnabled( true );
|
||||
if ( theId == AddHyp )
|
||||
myMoreAddHypBtn->setEnabled( true );
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@ -226,13 +305,13 @@ void SMESHGUI_MeshTab::addHyp( const int theId, const QString& theHyp )
|
||||
* Renames hypothesis
|
||||
*/
|
||||
//================================================================================
|
||||
void SMESHGUI_MeshTab::renameHyp( const int theId,
|
||||
const int theIndex,
|
||||
const QString& theNewName )
|
||||
{
|
||||
if ( theIndex > 0 && theIndex < myHyp[ theId ]->count() )
|
||||
myHyp[ theId ]->setItemText( theIndex, theNewName );
|
||||
}
|
||||
// void SMESHGUI_MeshTab::renameHyp( const int theId,
|
||||
// const int theIndex,
|
||||
// const QString& theNewName )
|
||||
// {
|
||||
// if ( theIndex > 0 && theIndex < myHypCombo[ theId ]->count() )
|
||||
// myHypCombo[ theId ]->setItemText( theIndex, theNewName );
|
||||
// }
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
@ -245,11 +324,30 @@ void SMESHGUI_MeshTab::renameHyp( const int theId,
|
||||
//================================================================================
|
||||
void SMESHGUI_MeshTab::setCurrentHyp( const int theId, const int theIndex )
|
||||
{
|
||||
if ( theIndex >= 0 && theIndex < myHyp[ theId ]->count() )
|
||||
if ( theId <= AddHyp )
|
||||
{
|
||||
myHyp[ theId ]->setCurrentIndex( theIndex );
|
||||
if ( myEditHyp[ theId ] )
|
||||
myEditHyp[ theId ]->setEnabled( theIndex > 0 );
|
||||
if ( theIndex >= 0 && theIndex < myHypCombo[ theId ]->count() )
|
||||
{
|
||||
myHypCombo[ theId ]->setCurrentIndex( theIndex );
|
||||
if ( myEditHypBtn[ theId ] )
|
||||
myEditHypBtn[ theId ]->setEnabled( theIndex > 0 );
|
||||
if ( theId == AddHyp )
|
||||
myMoreAddHypBtn ->setEnabled( theIndex > 0 );
|
||||
}
|
||||
}
|
||||
else // more than one additional hyp assigned
|
||||
{
|
||||
// move a hyp from myHypCombo[ AddHyp ] to myAddHypList
|
||||
for ( int i = 1, nb = myHypCombo[ AddHyp ]->count(); i < nb; ++i )
|
||||
{
|
||||
int curIndex = myHypCombo[ AddHyp ]->itemData( i ).toInt();
|
||||
if ( theIndex == curIndex )
|
||||
{
|
||||
addItem( myHypCombo[ AddHyp ]->itemText( i ), theId, theIndex );
|
||||
myHypCombo[ AddHyp ]->removeItem( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,11 +358,26 @@ void SMESHGUI_MeshTab::setCurrentHyp( const int theId, const int theIndex )
|
||||
* \retval int - index of current hypothesis
|
||||
*
|
||||
* Gets current hypothesis
|
||||
* Use theId > AddHyp to get more than selected addetional hyps (see nbAddHypTypes()).
|
||||
*/
|
||||
//================================================================================
|
||||
int SMESHGUI_MeshTab::currentHyp( const int theId ) const
|
||||
{
|
||||
return myHyp[ theId ]->currentIndex();
|
||||
return getCurrentIndex( theId, /*curByType=*/true );
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Returns nb of selected supplementary additional hypotheses
|
||||
*
|
||||
* Access to their indices is via currentHyp( AddHyp + i ) where i is within the
|
||||
* range 0 <= i < this->nbAddHypTypes()
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
int SMESHGUI_MeshTab::nbAddHypTypes() const
|
||||
{
|
||||
return myAddHypList->count();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@ -277,12 +390,12 @@ int SMESHGUI_MeshTab::currentHyp( const int theId ) const
|
||||
//================================================================================
|
||||
void SMESHGUI_MeshTab::onCreateHyp()
|
||||
{
|
||||
bool isMainHyp = sender() == myCreateHyp[ MainHyp ];
|
||||
bool isMainHyp = ( sender() == myCreateHypBtn[ MainHyp ]);
|
||||
|
||||
QMenu aPopup( this );
|
||||
|
||||
QStringList aHypNames = isMainHyp ?
|
||||
myAvailableHyps[ MainHyp ] : myAvailableHyps[ AddHyp ];
|
||||
myAvailableHypTypes[ MainHyp ] : myAvailableHypTypes[ AddHyp ];
|
||||
|
||||
QList<QAction*> actions;
|
||||
for ( int i = 0, n = aHypNames.count(); i < n; i++ )
|
||||
@ -304,8 +417,12 @@ void SMESHGUI_MeshTab::onCreateHyp()
|
||||
void SMESHGUI_MeshTab::onEditHyp()
|
||||
{
|
||||
const QObject* aSender = sender();
|
||||
int aHypType = aSender == myEditHyp[ MainHyp ] ? MainHyp : AddHyp;
|
||||
emit editHyp( aHypType, myHyp[ aHypType ]->currentIndex() - 1 ); // - 1 because there is NONE on the top
|
||||
int aHypType = MainHyp;
|
||||
for ( ; aHypType <= MoreAddHyp; ++aHypType )
|
||||
if ( aSender == myEditHypBtn[ aHypType ])
|
||||
break;
|
||||
emit editHyp( Min( aHypType, AddHyp ),
|
||||
getCurrentIndex( aHypType ) - 1 ); // - 1 because there is NONE on the top
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@ -320,11 +437,66 @@ void SMESHGUI_MeshTab::onEditHyp()
|
||||
void SMESHGUI_MeshTab::onHyp( int theIndex )
|
||||
{
|
||||
const QObject* aSender = sender();
|
||||
if ( aSender == myHyp[ Algo ] )
|
||||
if ( aSender == myHypCombo[ Algo ] )
|
||||
{
|
||||
emit selectAlgo( theIndex - 1 ); // - 1 because there is NONE on the top
|
||||
else {
|
||||
int anIndex = aSender == myHyp[ MainHyp ] ? MainHyp : AddHyp;
|
||||
myEditHyp[ anIndex ]->setEnabled( theIndex > 0 );
|
||||
}
|
||||
else if ( aSender == myAddHypList )
|
||||
{
|
||||
myEditHypBtn[ MoreAddHyp ]->setEnabled( theIndex >= 0 );
|
||||
myLessAddHypBtn ->setEnabled( theIndex >= 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
int type = ( aSender == myHypCombo[ MainHyp ] ? MainHyp : AddHyp );
|
||||
myEditHypBtn[ type ]->setEnabled( theIndex > 0 );
|
||||
|
||||
if ( type == AddHyp )
|
||||
myMoreAddHypBtn ->setEnabled( theIndex > 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Adds a current additional hyp to myAddHypList
|
||||
*
|
||||
* SLOT called when myMoreAddHypBtn ("plus") clicked
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void SMESHGUI_MeshTab::onMoreAddHyp()
|
||||
{
|
||||
int hypIndex = currentHyp( AddHyp );
|
||||
if ( hypIndex > 0 )
|
||||
{
|
||||
// move a hyp from myHypCombo[ AddHyp ] to myAddHypList
|
||||
int comboIndex = myHypCombo[ AddHyp ]->currentIndex();
|
||||
addItem( myHypCombo[ AddHyp ]->itemText( comboIndex ), MoreAddHyp, hypIndex );
|
||||
|
||||
myHypCombo[ AddHyp ]->removeItem( comboIndex );
|
||||
myHypCombo[ AddHyp ]->setCurrentIndex( 0 );
|
||||
|
||||
myMoreAddHypBtn->setEnabled( false );
|
||||
myEditHypBtn[ AddHyp ]->setEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Removes a current additional hyp from myAddHypList
|
||||
*
|
||||
* SLOT called when myLessAddHypBtn ("minus") clicked
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void SMESHGUI_MeshTab::onLessAddHyp()
|
||||
{
|
||||
if ( QListWidgetItem * item = myAddHypList->currentItem() )
|
||||
{
|
||||
// move a hyp from myAddHypList to myHypCombo[ AddHyp ]
|
||||
int hypIndex = item->data( Qt::UserRole ).toInt();
|
||||
addItem( item->text(), AddHyp, hypIndex );
|
||||
delete item;//myAddHypList->takeItem( myAddHypList->currentRow() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,9 +511,9 @@ void SMESHGUI_MeshTab::reset()
|
||||
{
|
||||
for ( int i = Algo; i <= AddHyp; i++ )
|
||||
{
|
||||
myHyp[ i ]->setCurrentIndex( 0 );
|
||||
if ( myEditHyp[ i ] )
|
||||
myEditHyp[ i ]->setEnabled( false );
|
||||
myHypCombo[ i ]->setCurrentIndex( 0 );
|
||||
if ( myEditHypBtn[ i ] )
|
||||
myEditHypBtn[ i ]->setEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,12 @@
|
||||
#include <QMap>
|
||||
|
||||
class SMESHGUI_MeshTab;
|
||||
class QTabWidget;
|
||||
class QComboBox;
|
||||
class QToolButton;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
class QComboBox;
|
||||
class QListWidget;
|
||||
class QMenu;
|
||||
class QTabWidget;
|
||||
class QToolButton;
|
||||
|
||||
/*!
|
||||
* \brief Dialog for mech creation or editing
|
||||
@ -112,7 +113,10 @@ public:
|
||||
{
|
||||
Algo = 0, //!< algorithms
|
||||
MainHyp, //!< main hypothesis
|
||||
AddHyp //!< additional hypothesis
|
||||
AddHyp, //!< additional hypothesis
|
||||
MoreAddHyp //! since several additional hypothesis are possible, the 2-nd, 3-d etc
|
||||
// additional hypotheses are coded as being of HypType (AddHyp + 1), (AddHyp + 2) etc.
|
||||
// Nb of HypType's after MainHyp is returned by SMESHGUI_MeshTab::nbAddHypTypes()
|
||||
};
|
||||
|
||||
public:
|
||||
@ -122,9 +126,10 @@ public:
|
||||
void setAvailableHyps( const int, const QStringList& );
|
||||
void setExistingHyps( const int, const QStringList&, bool=false);
|
||||
void addHyp( const int, const QString& );
|
||||
void renameHyp( const int, const int, const QString& );
|
||||
//void renameHyp( const int, const int, const QString& );
|
||||
void setCurrentHyp( const int, const int );
|
||||
int currentHyp( const int ) const;
|
||||
int nbAddHypTypes() const;
|
||||
void reset();
|
||||
|
||||
signals:
|
||||
@ -139,14 +144,24 @@ private slots:
|
||||
void onCreateHyp();
|
||||
void onEditHyp();
|
||||
void onHyp( int );
|
||||
void onMoreAddHyp();
|
||||
void onLessAddHyp();
|
||||
|
||||
private:
|
||||
QMap<int, QComboBox*> myHyp;
|
||||
QMap<int, QToolButton*> myCreateHyp;
|
||||
QMap<int, QToolButton*> myEditHyp;
|
||||
|
||||
QMap<int, QStringList> myAvailableHyps;
|
||||
QMap<int, QStringList> myExistingHyps;
|
||||
void addItem( const QString& txt, const int type, const int index );
|
||||
int getCurrentIndex( const int type, const bool curByType=false) const;
|
||||
|
||||
QMap<int, QStringList> myAvailableHypTypes;
|
||||
|
||||
QMap<int, QComboBox*> myHypCombo;
|
||||
QMap<int, QToolButton*> myCreateHypBtn;
|
||||
QMap<int, QToolButton*> myEditHypBtn;
|
||||
|
||||
QToolButton* myMoreAddHypBtn;
|
||||
QToolButton* myLessAddHypBtn;
|
||||
QListWidget* myAddHypList; // 2-nd, etc. additional hyps
|
||||
|
||||
};
|
||||
|
||||
#endif // SMESHGUI_MESHDLG_H
|
||||
|
@ -610,8 +610,8 @@ void SMESHGUI_MeshOp::selectionDone()
|
||||
myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->hide();
|
||||
myDlg->updateGeometry();
|
||||
myDlg->adjustSize();
|
||||
readMesh();
|
||||
myIsMesh = submeshVar->_is_nil();
|
||||
readMesh();
|
||||
}
|
||||
else
|
||||
myDlg->reset();
|
||||
@ -873,7 +873,11 @@ void SMESHGUI_MeshOp::availableHyps( const int theDim,
|
||||
* \param theAlgoData - to select hypos able to be used by this algo (optional)
|
||||
*
|
||||
* Gets existing (i.e. already created) hypotheses or algorithm in accordance with
|
||||
* input parameters
|
||||
* input parameters.
|
||||
*
|
||||
* WARNING: when using this method to get hyps existing in Mesh component,
|
||||
* call availableHyps() before in order to get only hyps of available types
|
||||
* that was filtered by availableHyps()
|
||||
*/
|
||||
//================================================================================
|
||||
void SMESHGUI_MeshOp::existingHyps( const int theDim,
|
||||
@ -881,7 +885,7 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
|
||||
_PTR(SObject) theFather,
|
||||
QStringList& theHyps,
|
||||
THypList& theHypList,
|
||||
HypothesisData* theAlgoData)
|
||||
HypothesisData* theAlgoData) const
|
||||
{
|
||||
// Clear hypoheses list
|
||||
theHyps.clear();
|
||||
@ -890,20 +894,21 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
|
||||
if ( !theFather )
|
||||
return;
|
||||
|
||||
const bool isAux = ( theHypType == AddHyp );
|
||||
|
||||
_PTR(SObject) aHypRoot;
|
||||
_PTR(GenericAttribute) anAttr;
|
||||
_PTR(AttributeName) aName;
|
||||
_PTR(AttributeIOR) anIOR;
|
||||
|
||||
bool isMesh = !_CAST( SComponent, theFather );
|
||||
const bool isMesh = !_CAST( SComponent, theFather );
|
||||
int aPart = -1;
|
||||
if ( isMesh )
|
||||
aPart = theHypType == Algo ? SMESH::Tag_RefOnAppliedAlgorithms : SMESH::Tag_RefOnAppliedHypothesis;
|
||||
else
|
||||
aPart = theHypType == Algo ? SMESH::Tag_AlgorithmsRoot : SMESH::Tag_HypothesisRoot;
|
||||
|
||||
const bool isAux = ( theHypType == AddHyp );
|
||||
const bool allHyps = ( !isMesh && theHypType != Algo && theDim > -1);
|
||||
|
||||
if ( theFather->FindSubObject( aPart, aHypRoot ) )
|
||||
{
|
||||
_PTR(ChildIterator) anIter =
|
||||
@ -933,7 +938,8 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
|
||||
if ( !aData) continue;
|
||||
if (( theDim == -1 || aData->Dim.contains( theDim ) ) &&
|
||||
( isCompatible ( theAlgoData, aData, theHypType )) &&
|
||||
( theHypType == Algo || isAux == aData->IsAuxOrNeedHyp ))
|
||||
( theHypType == Algo || isAux == aData->IsAuxOrNeedHyp ) &&
|
||||
( !allHyps || myAvailableHypData[theDim][theHypType].count(aData) ))
|
||||
{
|
||||
std::string aHypName = aName->Value();
|
||||
theHyps.append( aHypName.c_str() );
|
||||
@ -1173,6 +1179,8 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim,
|
||||
|
||||
myDim = theDim;
|
||||
myType = theType;
|
||||
|
||||
// get a unique hyp name
|
||||
QStringList aHypNames;
|
||||
TDim2Type2HypList::const_iterator aDimIter = myExistingHyps.begin();
|
||||
for ( ; aDimIter != myExistingHyps.end(); aDimIter++) {
|
||||
@ -1481,13 +1489,14 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
|
||||
{
|
||||
if ( !isAccessibleDim( dim ))
|
||||
continue;
|
||||
for ( int type = MainHyp; type < NbHypTypes; type++ )
|
||||
for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(dim); dlgType++ )
|
||||
{
|
||||
const int type = Min( dlgType, AddHyp );
|
||||
myAvailableHypData[ dim ][ type ].clear();
|
||||
QStringList anAvailable, anExisting;
|
||||
|
||||
HypothesisData* curAlgo = algoByDim[ dim ];
|
||||
int hypIndex = currentHyp( dim, type );
|
||||
int hypIndex = currentHyp( dim, dlgType );
|
||||
|
||||
SMESH::SMESH_Hypothesis_var curHyp;
|
||||
if ( hypIndex >= 0 && hypIndex < myExistingHyps[ dim ][ type ].count() )
|
||||
@ -1521,8 +1530,8 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
|
||||
if ( !isCompatible( curAlgo, hypData, type ))
|
||||
curHyp = SMESH::SMESH_Hypothesis::_nil();
|
||||
}
|
||||
existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo);
|
||||
availableHyps( dim, type, anAvailable, myAvailableHypData[ dim ][ type ], curAlgo);
|
||||
existingHyps( dim, type, pObj, anExisting, myExistingHyps[ dim ][ type ], curAlgo);
|
||||
defaulHypAvlbl = (type == MainHyp && !curAlgo->IsAuxOrNeedHyp );
|
||||
}
|
||||
// set list of hypotheses
|
||||
@ -1701,14 +1710,19 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
|
||||
SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ) );
|
||||
}
|
||||
|
||||
for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ ) {
|
||||
for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
|
||||
{
|
||||
if ( !isAccessibleDim( aDim )) continue;
|
||||
|
||||
// assign hypotheses
|
||||
for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ ) {
|
||||
int aHypIndex = currentHyp( aDim, aHypType );
|
||||
if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() ) {
|
||||
SMESH::SMESH_Hypothesis_var aHypVar = myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first;
|
||||
for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(aDim); dlgType++ )
|
||||
{
|
||||
const int aHypIndex = currentHyp( aDim, dlgType );
|
||||
const int aHypType = Min( dlgType, AddHyp );
|
||||
if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
|
||||
{
|
||||
SMESH::SMESH_Hypothesis_var aHypVar =
|
||||
myExistingHyps[ aDim ][ aHypType ][ aHypIndex ].first;
|
||||
if ( !aHypVar->_is_nil() )
|
||||
SMESH::AddHypothesisOnMesh( aMeshVar, aHypVar );
|
||||
}
|
||||
@ -1838,9 +1852,10 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList
|
||||
if ( !anAlgoVar->_is_nil() )
|
||||
SMESH::AddHypothesisOnSubMesh( aSubMeshVar, anAlgoVar );
|
||||
// assign hypotheses
|
||||
for ( int aHypType = MainHyp; aHypType <= AddHyp; aHypType++ )
|
||||
for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(aDim); dlgType++ )
|
||||
{
|
||||
int aHypIndex = currentHyp( aDim, aHypType );
|
||||
const int aHypIndex = currentHyp( aDim, dlgType );
|
||||
const int aHypType = Min( dlgType, AddHyp );
|
||||
if ( aHypIndex >= 0 && aHypIndex < myExistingHyps[ aDim ][ aHypType ].count() )
|
||||
{
|
||||
SMESH::SMESH_Hypothesis_var aHypVar =
|
||||
@ -1876,6 +1891,36 @@ int SMESHGUI_MeshOp::currentHyp( const int theDim, const int theHypType ) const
|
||||
return myDlg->tab( theDim )->currentHyp( theHypType ) - 1;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Checks if a hypothesis is selected
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool SMESHGUI_MeshOp::isSelectedHyp( int theDim, int theHypType, int theIndex) const
|
||||
{
|
||||
if ( theHypType < AddHyp ) // only one hyp can be selected
|
||||
return currentHyp( theDim, theHypType ) == theIndex;
|
||||
|
||||
for ( int dlgHypType = AddHyp; dlgHypType < nbDlgHypTypes( theDim ); ++dlgHypType )
|
||||
if ( currentHyp( theDim, dlgHypType ) == theIndex )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Returns nb of HypType's taking into account possible several
|
||||
* selected additional hypotheses which are coded as additional HypType's.
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
int SMESHGUI_MeshOp::nbDlgHypTypes( const int dim ) const
|
||||
{
|
||||
return NbHypTypes + myDlg->tab( dim )->nbAddHypTypes();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Returns true if hypotheses of given dim can be assigned
|
||||
@ -2095,23 +2140,26 @@ void SMESHGUI_MeshOp::readMesh()
|
||||
{
|
||||
// get hypotheses
|
||||
existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
|
||||
// find index of requered hypothesis among existing ones for this dimension and type
|
||||
int aHypIndex = -1;
|
||||
if ( myObjHyps[ dim ][ hypType ].count() > 0 ) {
|
||||
aHypIndex = find( myObjHyps[ dim ][ hypType ].first().first,
|
||||
for ( int i = 0, nb = myObjHyps[ dim ][ hypType ].count(); i < nb; ++i )
|
||||
{
|
||||
// find index of required hypothesis among existing ones for this dimension and type
|
||||
int aHypIndex = find( myObjHyps[ dim ][ hypType ][ i ].first,
|
||||
myExistingHyps[ dim ][ hypType ] );
|
||||
if ( aHypIndex < 0 ) {
|
||||
// assigned hypothesis is incompatible with the algorithm
|
||||
if ( currentHyp( dim, Algo ) < 0 )
|
||||
{ // none algo selected; it is edition for sure, of submesh maybe
|
||||
hypWithoutAlgo = true;
|
||||
myExistingHyps[ dim ][ hypType ].push_back( myObjHyps[ dim ][ hypType ].first() );
|
||||
myExistingHyps[ dim ][ hypType ].push_back( myObjHyps[ dim ][ hypType ][ i ] );
|
||||
anExisting.push_back( myObjHyps[ dim ][ hypType ][ i ].second );
|
||||
aHypIndex = myExistingHyps[ dim ][ hypType ].count() - 1;
|
||||
myDlg->tab( dim )->setExistingHyps( hypType, anExisting );
|
||||
}
|
||||
}
|
||||
setCurrentHyp( dim, hypType + i, aHypIndex );
|
||||
|
||||
if ( hypType == MainHyp ) break; // only one main hyp allowed
|
||||
}
|
||||
setCurrentHyp( dim, hypType, aHypIndex );
|
||||
}
|
||||
}
|
||||
// make available other hyps of same type as one without algo
|
||||
@ -2249,37 +2297,38 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
|
||||
myObjHyps[ dim ][ Algo ].append( THypItem( anAlgoVar, aName) );
|
||||
}
|
||||
|
||||
// assign hypotheses
|
||||
// remove deselected hypotheses
|
||||
for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
|
||||
{
|
||||
int aNewHypIndex = currentHyp( dim, hypType );
|
||||
int anOldHypIndex = -1;
|
||||
|
||||
// remove old hypotheses
|
||||
if ( myObjHyps[ dim ][ hypType ].count() > 0 )
|
||||
for ( int i = 0, nb = myObjHyps[ dim ][ hypType ].count(); i < nb; ++i )
|
||||
{
|
||||
anOldHypIndex = find( myObjHyps[ dim ][ hypType ].first().first,
|
||||
myExistingHyps[ dim ][ hypType ] );
|
||||
if ( aNewHypIndex != anOldHypIndex || // different hyps
|
||||
anOldHypIndex == -1 ) // hyps of different algos
|
||||
SMESH::SMESH_Hypothesis_var hyp = myObjHyps[ dim ][ hypType ][ i ].first;
|
||||
int hypIndex = this->find( hyp, myExistingHyps[ dim ][ hypType ]);
|
||||
if ( !isSelectedHyp( dim, hypType, hypIndex ) && !hyp->_is_nil() )
|
||||
{
|
||||
SMESH::RemoveHypothesisOrAlgorithmOnMesh
|
||||
( pObj, myObjHyps[ dim ][ hypType ].first().first );
|
||||
myObjHyps[ dim ][ hypType ].clear();
|
||||
SMESH::RemoveHypothesisOrAlgorithmOnMesh( pObj, hyp );
|
||||
}
|
||||
}
|
||||
}
|
||||
// assign newly selected hypotheses
|
||||
for ( int dlgType = MainHyp; dlgType < nbDlgHypTypes(dim); dlgType++ )
|
||||
{
|
||||
const int curIndex = currentHyp( dim, dlgType );
|
||||
const int hypType = Min( dlgType, AddHyp );
|
||||
if ( curIndex >= 0 && curIndex < myExistingHyps[ dim ][ hypType ].count() )
|
||||
{
|
||||
SMESH::SMESH_Hypothesis_var hyp = myExistingHyps[ dim ][ hypType ][ curIndex ].first;
|
||||
|
||||
// assign new hypotheses
|
||||
if ( aNewHypIndex != anOldHypIndex && aNewHypIndex > -1 )
|
||||
bool isAssigned = ( this->find( hyp, myObjHyps[ dim ][ hypType ]) >= 0 );
|
||||
if ( !isAssigned )
|
||||
{
|
||||
if ( isMesh )
|
||||
SMESH::AddHypothesisOnMesh
|
||||
(aMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first );
|
||||
SMESH::AddHypothesisOnMesh (aMeshVar, hyp );
|
||||
else if ( !aSubMeshVar->_is_nil() )
|
||||
SMESH::AddHypothesisOnSubMesh
|
||||
( aSubMeshVar, myExistingHyps[ dim ][ hypType ][ aNewHypIndex ].first );
|
||||
SMESH::AddHypothesisOnSubMesh ( aSubMeshVar, hyp );
|
||||
}
|
||||
// reread all hypotheses of mesh if necessary
|
||||
}
|
||||
// reread all hypotheses of mesh
|
||||
QStringList anExisting;
|
||||
existingHyps( dim, hypType, pObj, anExisting, myObjHyps[ dim ][ hypType ] );
|
||||
}
|
||||
|
@ -96,12 +96,12 @@ private:
|
||||
QStringList&,
|
||||
THypDataList&,
|
||||
HypothesisData* = 0 ) const;
|
||||
static void existingHyps( const int,
|
||||
void existingHyps( const int,
|
||||
const int,
|
||||
_PTR(SObject),
|
||||
QStringList&,
|
||||
THypList&,
|
||||
HypothesisData* = 0 );
|
||||
HypothesisData* = 0 ) const;
|
||||
HypothesisData* hypData( const int,
|
||||
const int,
|
||||
const int ); // access to myAvailableHypData
|
||||
@ -117,6 +117,8 @@ private:
|
||||
bool askUser=false);
|
||||
|
||||
int currentHyp( const int, const int ) const;
|
||||
bool isSelectedHyp( int, int, int ) const;
|
||||
int nbDlgHypTypes( const int ) const;
|
||||
bool isAccessibleDim( const int ) const;
|
||||
void setCurrentHyp( const int, const int, const int );
|
||||
void setDefaultName( const QString& prefix="" ) const;
|
||||
@ -135,7 +137,9 @@ private:
|
||||
void createMeshTypeList( QStringList& );
|
||||
void setAvailableMeshType( const QStringList& );
|
||||
void setFilteredAlgoData( const int, const int );
|
||||
|
||||
private:
|
||||
|
||||
SMESHGUI_MeshDlg* myDlg;
|
||||
SMESHGUI_ShapeByMeshOp* myShapeByMeshOp;
|
||||
bool myToCreate;
|
||||
|
@ -299,6 +299,14 @@
|
||||
<source>ICON_HYPO_EDIT</source>
|
||||
<translation>mesh_hypo_edit.png</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ICON_PLUS</source>
|
||||
<translation>mesh_plus.png</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ICON_MINUS</source>
|
||||
<translation>mesh_minus.png</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ICON_INTERSECT</source>
|
||||
<translation>mesh_intersectGroups.png</translation>
|
||||
|
@ -549,6 +549,7 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
|
||||
RETURNCASE( HYP_BAD_SUBSHAPE );
|
||||
RETURNCASE( HYP_BAD_GEOMETRY );
|
||||
RETURNCASE( HYP_NEED_SHAPE );
|
||||
RETURNCASE( HYP_INCOMPAT_HYPS );
|
||||
default:;
|
||||
}
|
||||
return SMESH::HYP_UNKNOWN_FATAL;
|
||||
@ -564,33 +565,31 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp)
|
||||
SMESH::Hypothesis_Status
|
||||
SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp,
|
||||
CORBA::String_out anErrorText)
|
||||
throw(SALOME::SALOME_Exception)
|
||||
{
|
||||
Unexpect aCatch(SALOME_SalomeException);
|
||||
if ( _preMeshInfo )
|
||||
_preMeshInfo->ForgetOrLoad();
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
|
||||
std::string error;
|
||||
SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
|
||||
anErrorText = error.c_str();
|
||||
|
||||
SMESH::SMESH_Mesh_var mesh( _this() );
|
||||
if ( !SMESH_Hypothesis::IsStatusFatal(status) )
|
||||
{
|
||||
SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
|
||||
_gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp );
|
||||
_gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
|
||||
}
|
||||
if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
|
||||
|
||||
// Update Python script
|
||||
//if(_impl->HasShapeToMesh())
|
||||
{
|
||||
TPythonDump() << "status = " << mesh << ".AddHypothesis( "
|
||||
<< aSubShapeObject << ", " << anHyp << " )";
|
||||
}
|
||||
// else {
|
||||
// TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )";
|
||||
// }
|
||||
<< aSubShape << ", " << anHyp << " )";
|
||||
|
||||
return ConvertHypothesisStatus(status);
|
||||
}
|
||||
@ -602,12 +601,13 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr
|
||||
//=============================================================================
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status
|
||||
SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp)
|
||||
SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp,
|
||||
std::string* anErrorText)
|
||||
{
|
||||
if(MYDEBUG) MESSAGE("addHypothesis");
|
||||
|
||||
if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
|
||||
if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
|
||||
THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
|
||||
|
||||
if (CORBA::is_nil( anHyp ))
|
||||
@ -619,22 +619,28 @@ SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
TopoDS_Shape myLocSubShape;
|
||||
//use PseudoShape in case if mesh has no shape
|
||||
if(HasShapeToMesh())
|
||||
myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
|
||||
myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
|
||||
else
|
||||
myLocSubShape = _impl->GetShapeToMesh();
|
||||
|
||||
const int hypId = anHyp->GetId();
|
||||
status = _impl->AddHypothesis(myLocSubShape, hypId);
|
||||
if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
|
||||
std::string error;
|
||||
status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
|
||||
if ( !SMESH_Hypothesis::IsStatusFatal(status) )
|
||||
{
|
||||
_mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
|
||||
anHyp->Register();
|
||||
// assure there is a corresponding submesh
|
||||
if ( !_impl->IsMainShape( myLocSubShape )) {
|
||||
int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
|
||||
if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
|
||||
SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject ));
|
||||
SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
|
||||
}
|
||||
}
|
||||
else if ( anErrorText )
|
||||
{
|
||||
*anErrorText = error;
|
||||
}
|
||||
}
|
||||
catch(SALOME_Exception & S_ex)
|
||||
{
|
||||
@ -649,7 +655,7 @@ SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp)
|
||||
throw(SALOME::SALOME_Exception)
|
||||
{
|
||||
@ -657,18 +663,18 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS
|
||||
if ( _preMeshInfo )
|
||||
_preMeshInfo->ForgetOrLoad();
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
|
||||
SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
|
||||
SMESH::SMESH_Mesh_var mesh = _this();
|
||||
|
||||
if ( !SMESH_Hypothesis::IsStatusFatal(status) )
|
||||
{
|
||||
SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
|
||||
_gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp );
|
||||
_gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
|
||||
}
|
||||
// Update Python script
|
||||
if(_impl->HasShapeToMesh())
|
||||
TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
|
||||
<< aSubShapeObject << ", " << anHyp << " )";
|
||||
<< aSubShape << ", " << anHyp << " )";
|
||||
else
|
||||
TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
|
||||
<< anHyp << " )";
|
||||
@ -683,12 +689,12 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS
|
||||
//=============================================================================
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status
|
||||
SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp)
|
||||
{
|
||||
if(MYDEBUG) MESSAGE("removeHypothesis()");
|
||||
|
||||
if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
|
||||
if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
|
||||
THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
|
||||
|
||||
if (CORBA::is_nil( anHyp ))
|
||||
@ -700,7 +706,7 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
TopoDS_Shape myLocSubShape;
|
||||
//use PseudoShape in case if mesh has no shape
|
||||
if( _impl->HasShapeToMesh() )
|
||||
myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject );
|
||||
myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
|
||||
else
|
||||
myLocSubShape = _impl->GetShapeToMesh();
|
||||
|
||||
@ -726,18 +732,18 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
//=============================================================================
|
||||
|
||||
SMESH::ListOfHypothesis *
|
||||
SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
|
||||
SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
|
||||
throw(SALOME::SALOME_Exception)
|
||||
{
|
||||
Unexpect aCatch(SALOME_SalomeException);
|
||||
if (MYDEBUG) MESSAGE("GetHypothesisList");
|
||||
if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
|
||||
if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
|
||||
THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
|
||||
|
||||
SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
|
||||
|
||||
try {
|
||||
TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
|
||||
TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
|
||||
if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
|
||||
myLocSubShape = _impl->GetShapeToMesh();
|
||||
const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
|
||||
@ -803,18 +809,18 @@ SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Excepti
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
|
||||
const char* theName )
|
||||
throw(SALOME::SALOME_Exception)
|
||||
{
|
||||
Unexpect aCatch(SALOME_SalomeException);
|
||||
if (CORBA::is_nil(aSubShapeObject))
|
||||
if (CORBA::is_nil(aSubShape))
|
||||
THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
|
||||
|
||||
SMESH::SMESH_subMesh_var subMesh;
|
||||
SMESH::SMESH_Mesh_var aMesh = _this();
|
||||
try {
|
||||
TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
|
||||
TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
|
||||
|
||||
//Get or Create the SMESH_subMesh object implementation
|
||||
|
||||
@ -830,16 +836,16 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap
|
||||
|
||||
// create a new subMesh object servant if there is none for the shape
|
||||
if ( subMesh->_is_nil() )
|
||||
subMesh = createSubMesh( aSubShapeObject );
|
||||
subMesh = createSubMesh( aSubShape );
|
||||
if ( _gen_i->CanPublishInStudy( subMesh ))
|
||||
{
|
||||
SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
|
||||
SALOMEDS::SObject_wrap aSO =
|
||||
_gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName );
|
||||
_gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
|
||||
if ( !aSO->_is_nil()) {
|
||||
// Update Python script
|
||||
TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
|
||||
<< aSubShapeObject << ", '" << theName << "' )";
|
||||
<< aSubShape << ", '" << theName << "' )";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -863,7 +869,7 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
|
||||
if ( theSubMesh->_is_nil() )
|
||||
return;
|
||||
|
||||
GEOM::GEOM_Object_var aSubShapeObject;
|
||||
GEOM::GEOM_Object_var aSubShape;
|
||||
SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
|
||||
if ( !aStudy->_is_nil() ) {
|
||||
// Remove submesh's SObject
|
||||
@ -875,10 +881,10 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
|
||||
anObj->ReferencedObject( aRef.inout() ))
|
||||
{
|
||||
CORBA::Object_var obj = aRef->GetObject();
|
||||
aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
|
||||
aSubShape = GEOM::GEOM_Object::_narrow( obj );
|
||||
}
|
||||
// if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
|
||||
// aSubShapeObject = theSubMesh->GetSubShape();
|
||||
// if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
|
||||
// aSubShape = theSubMesh->GetSubShape();
|
||||
|
||||
SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
|
||||
builder->RemoveObjectWithChildren( anSO );
|
||||
@ -888,7 +894,7 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
|
||||
}
|
||||
}
|
||||
|
||||
if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
|
||||
if ( removeSubMesh( theSubMesh, aSubShape.in() ))
|
||||
if ( _preMeshInfo )
|
||||
_preMeshInfo->ForgetOrLoad();
|
||||
|
||||
|
@ -86,21 +86,22 @@ public:
|
||||
void ClearSubMesh(CORBA::Long ShapeID)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
|
||||
SMESH::Hypothesis_Status AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
SMESH::Hypothesis_Status AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp,
|
||||
CORBA::String_out anErrorText)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
|
||||
SMESH::Hypothesis_Status RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
|
||||
SMESH::Hypothesis_Status RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
|
||||
SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
|
||||
SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
|
||||
SMESH::submesh_array* GetSubMeshes()
|
||||
throw (SALOME::SALOME_Exception);
|
||||
|
||||
SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, const char* theName)
|
||||
SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Object_ptr aSubShape, const char* theName)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
|
||||
void RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
|
||||
@ -404,10 +405,11 @@ public:
|
||||
|
||||
// Internal methods not available through CORBA
|
||||
// They are called by corresponding interface methods
|
||||
SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp);
|
||||
SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp,
|
||||
std::string* anErrorText=0);
|
||||
|
||||
SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
|
||||
SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
|
||||
SMESH::SMESH_Hypothesis_ptr anHyp);
|
||||
|
||||
static SMESH::Hypothesis_Status
|
||||
|
@ -207,12 +207,15 @@ def GetName(obj):
|
||||
raise RuntimeError, "Null or invalid object"
|
||||
|
||||
## Prints error message if a hypothesis was not assigned.
|
||||
def TreatHypoStatus(status, hypName, geomName, isAlgo):
|
||||
def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
|
||||
if isAlgo:
|
||||
hypType = "algorithm"
|
||||
else:
|
||||
hypType = "hypothesis"
|
||||
pass
|
||||
reason = ""
|
||||
if hasattr( status, "__getitem__" ):
|
||||
status,reason = status[0],status[1]
|
||||
if status == HYP_UNKNOWN_FATAL :
|
||||
reason = "for unknown reason"
|
||||
elif status == HYP_INCOMPATIBLE :
|
||||
@ -235,17 +238,24 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo):
|
||||
elif status == HYP_HIDING_ALGO:
|
||||
reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
|
||||
elif status == HYP_NEED_SHAPE:
|
||||
reason = "Algorithm can't work without shape"
|
||||
reason = "algorithm can't work without shape"
|
||||
elif status == HYP_INCOMPAT_HYPS:
|
||||
pass
|
||||
else:
|
||||
return
|
||||
hypName = '"' + hypName + '"'
|
||||
geomName= '"' + geomName+ '"'
|
||||
if status < HYP_UNKNOWN_FATAL and not geomName =='""':
|
||||
print hypName, "was assigned to", geomName,"but", reason
|
||||
elif not geomName == '""':
|
||||
print hypName, "was not assigned to",geomName,":", reason
|
||||
where = geomName
|
||||
if where:
|
||||
where = '"%s"' % geomName
|
||||
if mesh:
|
||||
meshName = GetName( mesh )
|
||||
if meshName and meshName != NO_NAME:
|
||||
where = '"%s" in "%s"' % ( geomName, meshName )
|
||||
if status < HYP_UNKNOWN_FATAL and where:
|
||||
print '"%s" was assigned to %s but %s' %( hypName, where, reason )
|
||||
elif where:
|
||||
print '"%s" was not assigned to %s : %s' %( hypName, where, reason )
|
||||
else:
|
||||
print hypName, "was not assigned:", reason
|
||||
print '"%s" was not assigned : %s' %( hypName, reason )
|
||||
pass
|
||||
|
||||
## Private method. Add geom (sub-shape of the main shape) into the study if not yet there
|
||||
@ -1592,7 +1602,7 @@ class Mesh:
|
||||
if geom:
|
||||
geom_name = geom.GetName()
|
||||
isAlgo = hyp._narrow( SMESH_Algo )
|
||||
TreatHypoStatus( status, hyp_name, geom_name, isAlgo )
|
||||
TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
|
||||
return status
|
||||
|
||||
## Return True if an algorithm of hypothesis is assigned to a given shape
|
||||
@ -1878,7 +1888,7 @@ class Mesh:
|
||||
# @param UnaryOp FT_LogicalNOT or FT_Undefined
|
||||
# @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
|
||||
# FT_LyingOnGeom, FT_CoplanarFaces criteria
|
||||
# @return SMESH_Group
|
||||
# @return SMESH_GroupOnFilter
|
||||
# @ingroup l2_grps_create
|
||||
def MakeGroup(self,
|
||||
groupName,
|
||||
@ -1895,7 +1905,7 @@ class Mesh:
|
||||
## Creates a mesh group by the given criterion
|
||||
# @param groupName the name of the mesh group
|
||||
# @param Criterion the instance of Criterion class
|
||||
# @return SMESH_Group
|
||||
# @return SMESH_GroupOnFilter
|
||||
# @ingroup l2_grps_create
|
||||
def MakeGroupByCriterion(self, groupName, Criterion):
|
||||
aFilterMgr = self.smeshpyD.CreateFilterManager()
|
||||
@ -1910,7 +1920,7 @@ class Mesh:
|
||||
## Creates a mesh group by the given criteria (list of criteria)
|
||||
# @param groupName the name of the mesh group
|
||||
# @param theCriteria the list of criteria
|
||||
# @return SMESH_Group
|
||||
# @return SMESH_GroupOnFilter
|
||||
# @ingroup l2_grps_create
|
||||
def MakeGroupByCriteria(self, groupName, theCriteria):
|
||||
aFilterMgr = self.smeshpyD.CreateFilterManager()
|
||||
@ -1923,12 +1933,13 @@ class Mesh:
|
||||
## Creates a mesh group by the given filter
|
||||
# @param groupName the name of the mesh group
|
||||
# @param theFilter the instance of Filter class
|
||||
# @return SMESH_Group
|
||||
# @return SMESH_GroupOnFilter
|
||||
# @ingroup l2_grps_create
|
||||
def MakeGroupByFilter(self, groupName, theFilter):
|
||||
group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
|
||||
theFilter.SetMesh( self.mesh )
|
||||
group.AddFrom( theFilter )
|
||||
#group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
|
||||
#theFilter.SetMesh( self.mesh )
|
||||
#group.AddFrom( theFilter )
|
||||
group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
|
||||
return group
|
||||
|
||||
## Removes a group
|
||||
|
@ -214,7 +214,7 @@ class Mesh_Algorithm:
|
||||
|
||||
## Private method
|
||||
def Hypothesis (self, hyp, args=[], so="libStdMeshersEngine.so",
|
||||
UseExisting=0, CompareMethod=""):
|
||||
UseExisting=0, CompareMethod="", toAdd=True):
|
||||
from salome.smesh.smeshBuilder import TreatHypoStatus, GetName
|
||||
hypo = None
|
||||
if UseExisting:
|
||||
@ -243,8 +243,9 @@ class Mesh_Algorithm:
|
||||
geomName=""
|
||||
if self.geom:
|
||||
geomName = GetName(self.geom)
|
||||
if toAdd:
|
||||
status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
|
||||
TreatHypoStatus( status, GetName(hypo), geomName, 0 )
|
||||
TreatHypoStatus( status, GetName(hypo), geomName, 0, self.mesh )
|
||||
return hypo
|
||||
|
||||
## Returns entry of the shape to mesh in the study
|
||||
@ -275,11 +276,13 @@ class Mesh_Algorithm:
|
||||
if faces and isinstance( faces[0], geomBuilder.GEOM._objref_GEOM_Object ):
|
||||
faces = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in faces ]
|
||||
hyp = self.Hypothesis("ViscousLayers",
|
||||
[thickness, numberOfLayers, stretchFactor, faces])
|
||||
[thickness, numberOfLayers, stretchFactor, faces, isFacesToIgnore],
|
||||
toAdd=False)
|
||||
hyp.SetTotalThickness(thickness)
|
||||
hyp.SetNumberLayers(numberOfLayers)
|
||||
hyp.SetStretchFactor(stretchFactor)
|
||||
hyp.SetFaces(faces, isFacesToIgnore)
|
||||
self.mesh.AddHypothesis( hyp, self.geom )
|
||||
return hyp
|
||||
|
||||
## Defines "ViscousLayers2D" hypothesis to give parameters of layers of quadrilateral
|
||||
@ -303,12 +306,13 @@ class Mesh_Algorithm:
|
||||
if edges and isinstance( edges[0], geomBuilder.GEOM._objref_GEOM_Object ):
|
||||
edges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in edges ]
|
||||
hyp = self.Hypothesis("ViscousLayers2D",
|
||||
[thickness, numberOfLayers, stretchFactor,
|
||||
edges, isEdgesToIgnore])
|
||||
[thickness, numberOfLayers, stretchFactor, edges, isEdgesToIgnore],
|
||||
toAdd=False)
|
||||
hyp.SetTotalThickness(thickness)
|
||||
hyp.SetNumberLayers(numberOfLayers)
|
||||
hyp.SetStretchFactor(stretchFactor)
|
||||
hyp.SetEdges(edges, isEdgesToIgnore)
|
||||
self.mesh.AddHypothesis( hyp, self.geom )
|
||||
return hyp
|
||||
|
||||
## Transform a list of either edges or tuples (edge, 1st_vertex_of_edge)
|
||||
|
@ -1012,7 +1012,8 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace,
|
||||
SMESH_Mesh & theMesh,
|
||||
const bool theIgnoreMediumNodes,
|
||||
TError & theError,
|
||||
SMESH_ProxyMesh::Ptr theProxyMesh)
|
||||
SMESH_ProxyMesh::Ptr theProxyMesh,
|
||||
const bool theCheckVertexNodes)
|
||||
{
|
||||
list< TopoDS_Edge > edges, internalEdges;
|
||||
list< int > nbEdgesInWires;
|
||||
@ -1037,6 +1038,7 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace,
|
||||
// as StdMeshers_FaceSide::GetUVPtStruct() requires
|
||||
if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676
|
||||
{
|
||||
if ( theCheckVertexNodes )
|
||||
while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
|
||||
theMesh.GetMeshDS()))
|
||||
{
|
||||
|
@ -141,7 +141,8 @@ public:
|
||||
SMESH_Mesh & theMesh,
|
||||
const bool theIgnoreMediumNodes,
|
||||
TError & theError,
|
||||
SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr());
|
||||
SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr(),
|
||||
const bool theCheckVertexNodes=true);
|
||||
/*!
|
||||
* \brief Change orientation of side geometry
|
||||
*/
|
||||
|
@ -124,23 +124,17 @@ bool StdMeshers_Hexa_3D::CheckHypothesis
|
||||
return true;
|
||||
}
|
||||
|
||||
// only StdMeshers_ViscousLayers can be used
|
||||
aStatus = HYP_OK;
|
||||
for ( ; h != hyps.end(); ++h )
|
||||
{
|
||||
string hypName = (*h)->GetName();
|
||||
if ( find( _compatibleHypothesis.begin(),_compatibleHypothesis.end(),hypName )
|
||||
!= _compatibleHypothesis.end() )
|
||||
{
|
||||
_viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h );
|
||||
if ( !(_viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h )))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
aStatus = HYP_INCOMPATIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !_viscousLayersHyp )
|
||||
aStatus = HYP_INCOMPATIBLE;
|
||||
else
|
||||
error( _viscousLayersHyp->CheckHypothesis( aMesh, aShape, aStatus ));
|
||||
|
||||
return aStatus == HYP_OK;
|
||||
}
|
||||
|
@ -122,6 +122,9 @@ bool StdMeshers_MEFISTO_2D::CheckHypothesis
|
||||
_edgeLength = 0;
|
||||
_maxElementArea = 0;
|
||||
|
||||
if ( !error( StdMeshers_ViscousLayers2D::CheckHypothesis( aMesh, aShape, aStatus )))
|
||||
return false;
|
||||
|
||||
list <const SMESHDS_Hypothesis * >::const_iterator itl;
|
||||
const SMESHDS_Hypothesis *theHyp;
|
||||
|
||||
|
@ -114,7 +114,17 @@ TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh& the
|
||||
return PropagationMgr::GetSource( theMesh.GetSubMeshContaining( theEdge ),
|
||||
isPropagOfDistribution);
|
||||
}
|
||||
|
||||
const SMESH_HypoFilter& StdMeshers_Propagation::GetFilter()
|
||||
{
|
||||
static SMESH_HypoFilter propagHypFilter;
|
||||
if ( propagHypFilter.IsEmpty() )
|
||||
{
|
||||
propagHypFilter.
|
||||
Init( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ())).
|
||||
Or ( SMESH_HypoFilter::HasName( StdMeshers_PropagOfDistribution::GetName ()));
|
||||
}
|
||||
return propagHypFilter;
|
||||
}
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// PROPAGATION MANAGEMENT
|
||||
@ -226,14 +236,8 @@ namespace {
|
||||
*/
|
||||
const SMESH_Hypothesis* getProagationHyp (SMESH_subMesh* theSubMesh)
|
||||
{
|
||||
static SMESH_HypoFilter propagHypFilter;
|
||||
if ( propagHypFilter.IsEmpty() )
|
||||
{
|
||||
propagHypFilter.
|
||||
Init( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ())).
|
||||
Or ( SMESH_HypoFilter::HasName( StdMeshers_PropagOfDistribution::GetName ()));
|
||||
}
|
||||
return theSubMesh->GetFather()->GetHypothesis( theSubMesh, propagHypFilter, true );
|
||||
return theSubMesh->GetFather()->GetHypothesis
|
||||
( theSubMesh, StdMeshers_Propagation::GetFilter(), true );
|
||||
}
|
||||
//================================================================================
|
||||
/*!
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include <TopoDS_Edge.hxx>
|
||||
|
||||
class SMESH_HypoFilter;
|
||||
|
||||
// =======================================================================
|
||||
/*!
|
||||
@ -53,6 +54,12 @@ class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis
|
||||
|
||||
static std::string GetName ();
|
||||
|
||||
/*!
|
||||
* \brief Returns a filter selecting both StdMeshers_Propagation and
|
||||
* StdMeshers_PropagOfDistribution hypotheses
|
||||
*/
|
||||
static const SMESH_HypoFilter& GetFilter();
|
||||
|
||||
/*!
|
||||
* \brief Set EventListener managing propagation of hypotheses
|
||||
* \param subMesh - edge submesh to set event listener on
|
||||
|
@ -199,7 +199,9 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis
|
||||
}
|
||||
}
|
||||
|
||||
return isOk;
|
||||
error( StdMeshers_ViscousLayers2D::CheckHypothesis( aMesh, aShape, aStatus ));
|
||||
|
||||
return aStatus == HYP_OK;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -127,13 +127,18 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh& aMesh,
|
||||
const list <const SMESHDS_Hypothesis * > & hyps =
|
||||
GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false);
|
||||
|
||||
const SMESH_HypoFilter & propagFilter = StdMeshers_Propagation::GetFilter();
|
||||
|
||||
// find non-auxiliary hypothesis
|
||||
const SMESHDS_Hypothesis *theHyp = 0;
|
||||
set< string > propagTypes;
|
||||
list <const SMESHDS_Hypothesis * >::const_iterator h = hyps.begin();
|
||||
for ( ; h != hyps.end(); ++h ) {
|
||||
if ( static_cast<const SMESH_Hypothesis*>(*h)->IsAuxiliary() ) {
|
||||
if ( strcmp( "QuadraticMesh", (*h)->GetName() ) == 0 )
|
||||
_quadraticMesh = true;
|
||||
if ( propagFilter.IsOk( static_cast< const SMESH_Hypothesis*>( *h ), aShape ))
|
||||
propagTypes.insert( (*h)->GetName() );
|
||||
}
|
||||
else {
|
||||
if ( !theHyp )
|
||||
@ -293,11 +298,48 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh& aMesh,
|
||||
ASSERT(_adaptiveHyp);
|
||||
_hypType = ADAPTIVE;
|
||||
_onlyUnaryInput = false;
|
||||
aStatus = SMESH_Hypothesis::HYP_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
return ( _hypType != NONE );
|
||||
if ( propagTypes.size() > 1 && aStatus == HYP_OK )
|
||||
{
|
||||
// detect concurrent Propagation hyps
|
||||
_usedHypList.clear();
|
||||
list< TopoDS_Shape > assignedTo;
|
||||
if ( aMesh.GetHypotheses( aShape, propagFilter, _usedHypList, true, &assignedTo ) > 1 )
|
||||
{
|
||||
// find most simple shape and a hyp on it
|
||||
int simpleShape = TopAbs_COMPOUND;
|
||||
const SMESHDS_Hypothesis* localHyp = 0;
|
||||
list< TopoDS_Shape >::iterator shape = assignedTo.begin();
|
||||
list< const SMESHDS_Hypothesis *>::iterator hyp = _usedHypList.begin();
|
||||
for ( ; shape != assignedTo.end(); ++shape )
|
||||
if ( shape->ShapeType() > simpleShape )
|
||||
{
|
||||
simpleShape = shape->ShapeType();
|
||||
localHyp = (*hyp);
|
||||
}
|
||||
// check if there a different hyp on simpleShape
|
||||
shape = assignedTo.begin();
|
||||
hyp = _usedHypList.begin();
|
||||
for ( ; hyp != _usedHypList.end(); ++hyp, ++shape )
|
||||
if ( shape->ShapeType() == simpleShape &&
|
||||
!localHyp->IsSameName( **hyp ))
|
||||
{
|
||||
aStatus = HYP_INCOMPAT_HYPS;
|
||||
return error( SMESH_Comment("Hypotheses of both \"")
|
||||
<< StdMeshers_Propagation::GetName() << "\" and \""
|
||||
<< StdMeshers_PropagOfDistribution::GetName()
|
||||
<< "\" types can't be applied to the same edge");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ( aStatus == SMESH_Hypothesis::HYP_OK );
|
||||
}
|
||||
|
||||
static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
|
||||
|
@ -355,6 +355,7 @@ namespace VISCOUS_3D
|
||||
bool IsOnEdge() const { return _2neibors; }
|
||||
gp_XYZ Copy( _LayerEdge& other, SMESH_MesherHelper& helper );
|
||||
void SetCosin( double cosin );
|
||||
int NbSteps() const { return _pos.size() - 1; } // nb inlation steps
|
||||
};
|
||||
struct _LayerEdgeCmp
|
||||
{
|
||||
@ -414,6 +415,36 @@ namespace VISCOUS_3D
|
||||
bool CheckPrisms() const;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
* \brief Layers parameters got by averaging several hypotheses
|
||||
*/
|
||||
struct AverageHyp
|
||||
{
|
||||
AverageHyp( const StdMeshers_ViscousLayers* hyp = 0 )
|
||||
:_nbLayers(0), _nbHyps(0), _thickness(0), _stretchFactor(0)
|
||||
{
|
||||
Add( hyp );
|
||||
}
|
||||
void Add( const StdMeshers_ViscousLayers* hyp )
|
||||
{
|
||||
if ( hyp )
|
||||
{
|
||||
_nbHyps++;
|
||||
_nbLayers = hyp->GetNumberLayers();
|
||||
//_thickness += hyp->GetTotalThickness();
|
||||
_thickness = Max( _thickness, hyp->GetTotalThickness() );
|
||||
_stretchFactor += hyp->GetStretchFactor();
|
||||
}
|
||||
}
|
||||
double GetTotalThickness() const { return _thickness; /*_nbHyps ? _thickness / _nbHyps : 0;*/ }
|
||||
double GetStretchFactor() const { return _nbHyps ? _stretchFactor / _nbHyps : 0; }
|
||||
int GetNumberLayers() const { return _nbLayers; }
|
||||
private:
|
||||
int _nbLayers, _nbHyps;
|
||||
double _thickness, _stretchFactor;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
typedef map< const SMDS_MeshNode*, _LayerEdge*, TIDCompare > TNode2Edge;
|
||||
@ -424,12 +455,15 @@ namespace VISCOUS_3D
|
||||
*/
|
||||
struct _SolidData
|
||||
{
|
||||
typedef const StdMeshers_ViscousLayers* THyp;
|
||||
TopoDS_Shape _solid;
|
||||
const StdMeshers_ViscousLayers* _hyp;
|
||||
TopoDS_Shape _hypShape;
|
||||
TGeomID _index; // SOLID id
|
||||
_MeshOfSolid* _proxyMesh;
|
||||
list< THyp > _hyps;
|
||||
list< TopoDS_Shape > _hypShapes;
|
||||
map< TGeomID, THyp > _face2hyp; // filled if _hyps.size() > 1
|
||||
set< TGeomID > _reversedFaceIds;
|
||||
set<TGeomID> _ignoreFaceIds; // WOL FACEs and FACEs of other SOLIDS
|
||||
set< TGeomID > _ignoreFaceIds; // WOL FACEs and FACEs of other SOLIDs
|
||||
|
||||
double _stepSize, _stepSizeCoeff, _geomSize;
|
||||
const SMDS_MeshNode* _stepSizeNodes[2];
|
||||
@ -439,7 +473,7 @@ namespace VISCOUS_3D
|
||||
// map to find _n2eMap of another _SolidData by a shrink shape shared by two _SolidData's
|
||||
map< TGeomID, TNode2Edge* > _s2neMap;
|
||||
// edges of _n2eMap. We keep same data in two containers because
|
||||
// iteration over the map is 5 time longer than over the vector
|
||||
// iteration over the map is 5 times longer than over the vector
|
||||
vector< _LayerEdge* > _edges;
|
||||
|
||||
// key: an id of shape (EDGE or VERTEX) shared by a FACE with
|
||||
@ -462,15 +496,16 @@ namespace VISCOUS_3D
|
||||
vector< int > _endEdgeOnShape;
|
||||
int _nbShapesToSmooth;
|
||||
|
||||
// data of averaged StdMeshers_ViscousLayers parameters for each shape with _LayerEdge's
|
||||
vector< AverageHyp > _hypOnShape;
|
||||
double _maxThickness; // of all _hyps
|
||||
double _minThickness; // of all _hyps
|
||||
|
||||
double _epsilon; // precision for SegTriaInter()
|
||||
|
||||
TGeomID _index; // SOLID id, for debug
|
||||
|
||||
_SolidData(const TopoDS_Shape& s=TopoDS_Shape(),
|
||||
const StdMeshers_ViscousLayers* h=0,
|
||||
const TopoDS_Shape& hs=TopoDS_Shape(),
|
||||
_MeshOfSolid* m=0)
|
||||
:_solid(s), _hyp(h), _hypShape(hs), _proxyMesh(m) {}
|
||||
:_solid(s), _proxyMesh(m) {}
|
||||
~_SolidData();
|
||||
|
||||
Handle(Geom_Curve) CurveForSmooth( const TopoDS_Edge& E,
|
||||
@ -496,7 +531,7 @@ namespace VISCOUS_3D
|
||||
iEnd = _endEdgeOnShape[ end ];
|
||||
}
|
||||
|
||||
bool GetShapeEdges(const TGeomID shapeID, size_t& edgeEnd, int* iBeg=0, int* iEnd=0 ) const;
|
||||
bool GetShapeEdges(const TGeomID shapeID, size_t& iEdgeEnd, int* iBeg=0, int* iEnd=0 ) const;
|
||||
|
||||
void AddShapesToSmooth( const set< TGeomID >& shapeIDs );
|
||||
};
|
||||
@ -563,6 +598,9 @@ namespace VISCOUS_3D
|
||||
// does it's job
|
||||
SMESH_ComputeErrorPtr Compute(SMESH_Mesh& mesh,
|
||||
const TopoDS_Shape& shape);
|
||||
// check validity of hypotheses
|
||||
SMESH_ComputeErrorPtr CheckHypotheses( SMESH_Mesh& mesh,
|
||||
const TopoDS_Shape& shape );
|
||||
|
||||
// restore event listeners used to clear an inferior dim sub-mesh modified by viscous layers
|
||||
void RestoreListeners();
|
||||
@ -573,7 +611,11 @@ namespace VISCOUS_3D
|
||||
private:
|
||||
|
||||
bool findSolidsWithLayers();
|
||||
bool findFacesWithLayers();
|
||||
bool findFacesWithLayers(const bool onlyWith=false);
|
||||
void getIgnoreFaces(const TopoDS_Shape& solid,
|
||||
const StdMeshers_ViscousLayers* hyp,
|
||||
const TopoDS_Shape& hypShape,
|
||||
set<TGeomID>& ignoreFaces);
|
||||
bool makeLayer(_SolidData& data);
|
||||
bool setEdgeData(_LayerEdge& edge, const set<TGeomID>& subIds,
|
||||
SMESH_MesherHelper& helper, _SolidData& data);
|
||||
@ -832,6 +874,27 @@ bool StdMeshers_ViscousLayers::SetParametersByMesh(const SMESH_Mesh* theMesh,
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
} // --------------------------------------------------------------------------------
|
||||
SMESH_ComputeErrorPtr
|
||||
StdMeshers_ViscousLayers::CheckHypothesis(SMESH_Mesh& theMesh,
|
||||
const TopoDS_Shape& theShape,
|
||||
SMESH_Hypothesis::Hypothesis_Status& theStatus)
|
||||
{
|
||||
VISCOUS_3D::_ViscousBuilder bulder;
|
||||
SMESH_ComputeErrorPtr err = bulder.CheckHypotheses( theMesh, theShape );
|
||||
if ( err && !err->IsOK() )
|
||||
theStatus = SMESH_Hypothesis::HYP_INCOMPAT_HYPS;
|
||||
else
|
||||
theStatus = SMESH_Hypothesis::HYP_OK;
|
||||
|
||||
return err;
|
||||
}
|
||||
// --------------------------------------------------------------------------------
|
||||
bool StdMeshers_ViscousLayers::IsShapeWithLayers(int shapeIndex) const
|
||||
{
|
||||
bool isIn =
|
||||
( std::find( _shapeIds.begin(), _shapeIds.end(), shapeIndex ) != _shapeIds.end() );
|
||||
return IsToIgnoreShapes() ? !isIn : isIn;
|
||||
}
|
||||
// END StdMeshers_ViscousLayers hypothesis
|
||||
//================================================================================
|
||||
@ -1313,6 +1376,34 @@ SMESH_ComputeErrorPtr _ViscousBuilder::Compute(SMESH_Mesh& theMesh,
|
||||
return _error;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Check validity of hypotheses
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
SMESH_ComputeErrorPtr _ViscousBuilder::CheckHypotheses( SMESH_Mesh& mesh,
|
||||
const TopoDS_Shape& shape )
|
||||
{
|
||||
_mesh = & mesh;
|
||||
|
||||
if ( _ViscousListener::GetSolidMesh( _mesh, shape, /*toCreate=*/false))
|
||||
return SMESH_ComputeErrorPtr(); // everything already computed
|
||||
|
||||
|
||||
findSolidsWithLayers();
|
||||
bool ok = findFacesWithLayers();
|
||||
|
||||
// remove _MeshOfSolid's of _SolidData's
|
||||
for ( size_t i = 0; i < _sdVec.size(); ++i )
|
||||
_ViscousListener::RemoveSolidMesh( _mesh, _sdVec[i]._solid );
|
||||
|
||||
if ( !ok )
|
||||
return _error;
|
||||
|
||||
return SMESH_ComputeErrorPtr();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Finds SOLIDs to compute using viscous layers. Fills _sdVec
|
||||
@ -1336,21 +1427,27 @@ bool _ViscousBuilder::findSolidsWithLayers()
|
||||
// TODO: check if algo is hidden
|
||||
const list <const SMESHDS_Hypothesis *> & allHyps =
|
||||
algo->GetUsedHypothesis(*_mesh, allSolids(i), /*ignoreAuxiliary=*/false);
|
||||
_SolidData* soData = 0;
|
||||
list< const SMESHDS_Hypothesis *>::const_iterator hyp = allHyps.begin();
|
||||
const StdMeshers_ViscousLayers* viscHyp = 0;
|
||||
for ( ; hyp != allHyps.end() && !viscHyp; ++hyp )
|
||||
viscHyp = dynamic_cast<const StdMeshers_ViscousLayers*>( *hyp );
|
||||
if ( viscHyp )
|
||||
for ( ; hyp != allHyps.end(); ++hyp )
|
||||
if ( viscHyp = dynamic_cast<const StdMeshers_ViscousLayers*>( *hyp ))
|
||||
{
|
||||
TopoDS_Shape hypShape;
|
||||
filter.Init( filter.Is( viscHyp ));
|
||||
_mesh->GetHypothesis( allSolids(i), filter, true, &hypShape );
|
||||
|
||||
if ( !soData )
|
||||
{
|
||||
_MeshOfSolid* proxyMesh = _ViscousListener::GetSolidMesh( _mesh,
|
||||
allSolids(i),
|
||||
/*toCreate=*/true);
|
||||
_sdVec.push_back( _SolidData( allSolids(i), viscHyp, hypShape, proxyMesh ));
|
||||
_sdVec.back()._index = getMeshDS()->ShapeToIndex( allSolids(i));
|
||||
_sdVec.push_back( _SolidData( allSolids(i), proxyMesh ));
|
||||
soData = & _sdVec.back();
|
||||
soData->_index = getMeshDS()->ShapeToIndex( allSolids(i));
|
||||
}
|
||||
soData->_hyps.push_back( viscHyp );
|
||||
soData->_hypShapes.push_back( hypShape );
|
||||
}
|
||||
}
|
||||
if ( _sdVec.empty() )
|
||||
@ -1366,7 +1463,7 @@ bool _ViscousBuilder::findSolidsWithLayers()
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool _ViscousBuilder::findFacesWithLayers()
|
||||
bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith)
|
||||
{
|
||||
SMESH_MesherHelper helper( *_mesh );
|
||||
TopExp_Explorer exp;
|
||||
@ -1377,56 +1474,99 @@ bool _ViscousBuilder::findFacesWithLayers()
|
||||
{
|
||||
solids.Add( _sdVec[i]._solid );
|
||||
|
||||
vector<TGeomID> ids = _sdVec[i]._hyp->GetBndShapes();
|
||||
if ( _sdVec[i]._hyp->IsToIgnoreShapes() ) // FACEs to ignore are given
|
||||
// get faces to ignore defined by each hyp
|
||||
typedef const StdMeshers_ViscousLayers* THyp;
|
||||
typedef std::pair< set<TGeomID>, THyp > TFacesOfHyp;
|
||||
list< TFacesOfHyp > ignoreFacesOfHyps;
|
||||
list< THyp >::iterator hyp = _sdVec[i]._hyps.begin();
|
||||
list< TopoDS_Shape >::iterator hypShape = _sdVec[i]._hypShapes.begin();
|
||||
for ( ; hyp != _sdVec[i]._hyps.end(); ++hyp, ++hypShape )
|
||||
{
|
||||
for ( size_t ii = 0; ii < ids.size(); ++ii )
|
||||
{
|
||||
const TopoDS_Shape& s = getMeshDS()->IndexToShape( ids[ii] );
|
||||
if ( !s.IsNull() && s.ShapeType() == TopAbs_FACE )
|
||||
_sdVec[i]._ignoreFaceIds.insert( ids[ii] );
|
||||
}
|
||||
}
|
||||
else // FACEs with layers are given
|
||||
{
|
||||
exp.Init( _sdVec[i]._solid, TopAbs_FACE );
|
||||
for ( ; exp.More(); exp.Next() )
|
||||
{
|
||||
TGeomID faceInd = getMeshDS()->ShapeToIndex( exp.Current() );
|
||||
if ( find( ids.begin(), ids.end(), faceInd ) == ids.end() )
|
||||
_sdVec[i]._ignoreFaceIds.insert( faceInd );
|
||||
}
|
||||
ignoreFacesOfHyps.push_back( TFacesOfHyp( set<TGeomID>(), *hyp ));
|
||||
getIgnoreFaces( _sdVec[i]._solid, *hyp, *hypShape, ignoreFacesOfHyps.back().first );
|
||||
}
|
||||
|
||||
// ignore internal FACEs if inlets and outlets are specified
|
||||
// fill _SolidData::_face2hyp and check compatibility of hypotheses
|
||||
const int nbHyps = _sdVec[i]._hyps.size();
|
||||
if ( nbHyps > 1 )
|
||||
{
|
||||
TopTools_IndexedDataMapOfShapeListOfShape solidsOfFace;
|
||||
if ( _sdVec[i]._hyp->IsToIgnoreShapes() )
|
||||
TopExp::MapShapesAndAncestors( _sdVec[i]._hypShape,
|
||||
TopAbs_FACE, TopAbs_SOLID, solidsOfFace);
|
||||
// check if two hypotheses define different parameters for the same FACE
|
||||
list< TFacesOfHyp >::iterator igFacesOfHyp;
|
||||
for ( exp.Init( _sdVec[i]._solid, TopAbs_FACE ); exp.More(); exp.Next() )
|
||||
{
|
||||
const TGeomID faceID = getMeshDS()->ShapeToIndex( exp.Current() );
|
||||
THyp hyp = 0;
|
||||
igFacesOfHyp = ignoreFacesOfHyps.begin();
|
||||
for ( ; igFacesOfHyp != ignoreFacesOfHyps.end(); ++igFacesOfHyp )
|
||||
if ( ! igFacesOfHyp->first.count( faceID ))
|
||||
{
|
||||
if ( hyp )
|
||||
return error(SMESH_Comment("Several hypotheses define "
|
||||
"Viscous Layers on the face #") << faceID );
|
||||
hyp = igFacesOfHyp->second;
|
||||
}
|
||||
if ( hyp )
|
||||
_sdVec[i]._face2hyp.insert( make_pair( faceID, hyp ));
|
||||
else
|
||||
_sdVec[i]._ignoreFaceIds.insert( faceID );
|
||||
}
|
||||
|
||||
// check if two hypotheses define different number of viscous layers for
|
||||
// adjacent faces of a solid
|
||||
set< int > nbLayersSet;
|
||||
igFacesOfHyp = ignoreFacesOfHyps.begin();
|
||||
for ( ; igFacesOfHyp != ignoreFacesOfHyps.end(); ++igFacesOfHyp )
|
||||
{
|
||||
nbLayersSet.insert( igFacesOfHyp->second->GetNumberLayers() );
|
||||
}
|
||||
if ( nbLayersSet.size() > 1 )
|
||||
{
|
||||
for ( exp.Init( _sdVec[i]._solid, TopAbs_EDGE ); exp.More(); exp.Next() )
|
||||
{
|
||||
PShapeIteratorPtr fIt = helper.GetAncestors( exp.Current(), *_mesh, TopAbs_FACE );
|
||||
THyp hyp1 = 0, hyp2 = 0;
|
||||
while( const TopoDS_Shape* face = fIt->next() )
|
||||
{
|
||||
const TGeomID faceID = getMeshDS()->ShapeToIndex( *face );
|
||||
map< TGeomID, THyp >::iterator f2h = _sdVec[i]._face2hyp.find( faceID );
|
||||
if ( f2h != _sdVec[i]._face2hyp.end() )
|
||||
{
|
||||
( hyp1 ? hyp2 : hyp1 ) = f2h->second;
|
||||
}
|
||||
}
|
||||
if ( hyp1 && hyp2 &&
|
||||
hyp1->GetNumberLayers() != hyp2->GetNumberLayers() )
|
||||
{
|
||||
return error("Two hypotheses define different number of "
|
||||
"viscous layers on adjacent faces");
|
||||
}
|
||||
}
|
||||
}
|
||||
} // if ( nbHyps > 1 )
|
||||
else
|
||||
{
|
||||
_sdVec[i]._ignoreFaceIds.swap( ignoreFacesOfHyps.back().first );
|
||||
}
|
||||
|
||||
// fill _SolidData::_reversedFaceIds
|
||||
{
|
||||
exp.Init( _sdVec[i]._solid.Oriented( TopAbs_FORWARD ), TopAbs_FACE );
|
||||
for ( ; exp.More(); exp.Next() )
|
||||
{
|
||||
const TopoDS_Face& face = TopoDS::Face( exp.Current() );
|
||||
if ( helper.NbAncestors( face, *_mesh, TopAbs_SOLID ) < 2 )
|
||||
continue;
|
||||
|
||||
const TGeomID faceInd = getMeshDS()->ShapeToIndex( face );
|
||||
if ( _sdVec[i]._hyp->IsToIgnoreShapes() )
|
||||
const TGeomID faceID = getMeshDS()->ShapeToIndex( face );
|
||||
if ( //!sdVec[i]._ignoreFaceIds.count( faceID ) && ???????
|
||||
helper.NbAncestors( face, *_mesh, TopAbs_SOLID ) > 1 &&
|
||||
helper.IsReversedSubMesh( face ))
|
||||
{
|
||||
int nbSolids = solidsOfFace.FindFromKey( face ).Extent();
|
||||
if ( nbSolids > 1 )
|
||||
_sdVec[i]._ignoreFaceIds.insert( faceInd );
|
||||
_sdVec[i]._reversedFaceIds.insert( faceID );
|
||||
}
|
||||
}
|
||||
}
|
||||
} // loop on _sdVec
|
||||
|
||||
if ( helper.IsReversedSubMesh( face ))
|
||||
{
|
||||
_sdVec[i]._reversedFaceIds.insert( faceInd );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( onlyWith ) // is called to check hypotheses compatibility only
|
||||
return true;
|
||||
|
||||
// Find faces to shrink mesh on (solution 2 in issue 0020832);
|
||||
TopTools_IndexedMapOfShape shapes;
|
||||
@ -1642,6 +1782,60 @@ bool _ViscousBuilder::findFacesWithLayers()
|
||||
return true;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Finds FACEs w/o layers for a given SOLID by an hypothesis
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void _ViscousBuilder::getIgnoreFaces(const TopoDS_Shape& solid,
|
||||
const StdMeshers_ViscousLayers* hyp,
|
||||
const TopoDS_Shape& hypShape,
|
||||
set<TGeomID>& ignoreFaceIds)
|
||||
{
|
||||
TopExp_Explorer exp;
|
||||
|
||||
vector<TGeomID> ids = hyp->GetBndShapes();
|
||||
if ( hyp->IsToIgnoreShapes() ) // FACEs to ignore are given
|
||||
{
|
||||
for ( size_t ii = 0; ii < ids.size(); ++ii )
|
||||
{
|
||||
const TopoDS_Shape& s = getMeshDS()->IndexToShape( ids[ii] );
|
||||
if ( !s.IsNull() && s.ShapeType() == TopAbs_FACE )
|
||||
ignoreFaceIds.insert( ids[ii] );
|
||||
}
|
||||
}
|
||||
else // FACEs with layers are given
|
||||
{
|
||||
exp.Init( solid, TopAbs_FACE );
|
||||
for ( ; exp.More(); exp.Next() )
|
||||
{
|
||||
TGeomID faceInd = getMeshDS()->ShapeToIndex( exp.Current() );
|
||||
if ( find( ids.begin(), ids.end(), faceInd ) == ids.end() )
|
||||
ignoreFaceIds.insert( faceInd );
|
||||
}
|
||||
}
|
||||
|
||||
// ignore internal FACEs if inlets and outlets are specified
|
||||
if ( hyp->IsToIgnoreShapes() )
|
||||
{
|
||||
TopTools_IndexedDataMapOfShapeListOfShape solidsOfFace;
|
||||
TopExp::MapShapesAndAncestors( hypShape,
|
||||
TopAbs_FACE, TopAbs_SOLID, solidsOfFace);
|
||||
|
||||
for ( exp.Init( solid, TopAbs_FACE ); exp.More(); exp.Next() )
|
||||
{
|
||||
const TopoDS_Face& face = TopoDS::Face( exp.Current() );
|
||||
if ( SMESH_MesherHelper::NbAncestors( face, *_mesh, TopAbs_SOLID ) < 2 )
|
||||
continue;
|
||||
|
||||
int nbSolids = solidsOfFace.FindFromKey( face ).Extent();
|
||||
if ( nbSolids > 1 )
|
||||
ignoreFaceIds.insert( getMeshDS()->ShapeToIndex( face ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Create the inner surface of the viscous layer and prepare data for infation
|
||||
@ -1940,7 +2134,6 @@ void _ViscousBuilder::limitStepSize( _SolidData& data, const double minSize )
|
||||
void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
|
||||
{
|
||||
const int nbTestPnt = 5; // on a FACE sub-shape
|
||||
const double minCurvature = 0.9 / data._hyp->GetTotalThickness();
|
||||
|
||||
BRepLProp_SLProps surfProp( 2, 1e-6 );
|
||||
SMESH_MesherHelper helper( *_mesh );
|
||||
@ -1975,6 +2168,7 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
|
||||
else
|
||||
continue;
|
||||
// check concavity and curvature and limit data._stepSize
|
||||
const double minCurvature = 0.9 / data._hypOnShape[ edgesEnd ].GetTotalThickness();
|
||||
int nbLEdges = iEnd - iBeg;
|
||||
int iStep = Max( 1, nbLEdges / nbTestPnt );
|
||||
for ( ; iBeg < iEnd; iBeg += iStep )
|
||||
@ -2069,7 +2263,16 @@ bool _ViscousBuilder::sortEdges( _SolidData& data,
|
||||
{
|
||||
// define allowed thickness
|
||||
computeGeomSize( data ); // compute data._geomSize
|
||||
const double tgtThick = Min( 0.5 * data._geomSize, data._hyp->GetTotalThickness() );
|
||||
|
||||
data._maxThickness = 0;
|
||||
data._minThickness = 1e100;
|
||||
list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin();
|
||||
for ( ; hyp != data._hyps.end(); ++hyp )
|
||||
{
|
||||
data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() );
|
||||
data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() );
|
||||
}
|
||||
const double tgtThick = /*Min( 0.5 * data._geomSize, */data._maxThickness;
|
||||
|
||||
// Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's
|
||||
// boundry inclined to the shape at a sharp angle
|
||||
@ -2200,6 +2403,45 @@ bool _ViscousBuilder::sortEdges( _SolidData& data,
|
||||
//eVec.clear();
|
||||
}
|
||||
|
||||
// compute average StdMeshers_ViscousLayers parameters for each shape
|
||||
|
||||
data._hypOnShape.clear();
|
||||
if ( data._hyps.size() == 1 )
|
||||
{
|
||||
data._hypOnShape.resize( data._endEdgeOnShape.size(), AverageHyp( data._hyps.back() ));
|
||||
}
|
||||
else
|
||||
{
|
||||
data._hypOnShape.resize( data._endEdgeOnShape.size() );
|
||||
map< TGeomID, const StdMeshers_ViscousLayers* >::iterator f2hyp;
|
||||
for ( size_t i = 0; i < data._endEdgeOnShape.size(); ++i )
|
||||
{
|
||||
int iEnd = data._endEdgeOnShape[i];
|
||||
_LayerEdge* LE = data._edges[ iEnd-1 ];
|
||||
TGeomID iShape = LE->_nodes[0]->getshapeId();
|
||||
const TopoDS_Shape& S = getMeshDS()->IndexToShape( iShape );
|
||||
if ( S.ShapeType() == TopAbs_FACE )
|
||||
{
|
||||
if (( f2hyp = data._face2hyp.find( iShape )) != data._face2hyp.end() )
|
||||
{
|
||||
data._hypOnShape[ i ].Add( f2hyp->second );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PShapeIteratorPtr fIt = SMESH_MesherHelper::GetAncestors( S, *_mesh, TopAbs_FACE );
|
||||
while ( const TopoDS_Shape* face = fIt->next() )
|
||||
{
|
||||
TGeomID faceID = getMeshDS()->ShapeToIndex( *face );
|
||||
if (( f2hyp = data._face2hyp.find( faceID )) != data._face2hyp.end() )
|
||||
{
|
||||
data._hypOnShape[ i ].Add( f2hyp->second );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -2912,9 +3154,9 @@ bool _ViscousBuilder::inflate(_SolidData& data)
|
||||
if ( data._stepSize > 0.3 * data._geomSize )
|
||||
limitStepSize( data, 0.3 * data._geomSize );
|
||||
|
||||
const double tgtThick = data._hyp->GetTotalThickness();
|
||||
if ( data._stepSize > tgtThick )
|
||||
limitStepSize( data, tgtThick );
|
||||
const double tgtThick = data._maxThickness;
|
||||
if ( data._stepSize > data._minThickness )
|
||||
limitStepSize( data, data._minThickness );
|
||||
|
||||
if ( data._stepSize < 1. )
|
||||
data._epsilon = data._stepSize * 1e-7;
|
||||
@ -2923,21 +3165,26 @@ bool _ViscousBuilder::inflate(_SolidData& data)
|
||||
|
||||
double avgThick = 0, curThick = 0, distToIntersection = Precision::Infinite();
|
||||
int nbSteps = 0, nbRepeats = 0;
|
||||
while ( 1.01 * avgThick < tgtThick )
|
||||
int iBeg, iEnd, iS;
|
||||
while ( avgThick < 0.99 )
|
||||
{
|
||||
// new target length
|
||||
curThick += data._stepSize;
|
||||
if ( curThick > tgtThick )
|
||||
{
|
||||
curThick = tgtThick + ( tgtThick-avgThick ) * nbRepeats;
|
||||
curThick = tgtThick + tgtThick*( 1.-avgThick ) * nbRepeats;
|
||||
nbRepeats++;
|
||||
}
|
||||
|
||||
// Elongate _LayerEdge's
|
||||
dumpFunction(SMESH_Comment("inflate")<<data._index<<"_step"<<nbSteps); // debug
|
||||
for ( size_t i = 0; i < data._edges.size(); ++i )
|
||||
for ( iBeg = 0, iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
|
||||
{
|
||||
data._edges[i]->SetNewLength( curThick, helper );
|
||||
const double shapeCurThick = Min( curThick, data._hypOnShape[ iS ].GetTotalThickness() );
|
||||
for ( iEnd = data._endEdgeOnShape[ iS ]; iBeg < iEnd; ++iBeg )
|
||||
{
|
||||
data._edges[iBeg]->SetNewLength( shapeCurThick, helper );
|
||||
}
|
||||
}
|
||||
dumpFunctionEnd();
|
||||
|
||||
@ -2962,16 +3209,22 @@ bool _ViscousBuilder::inflate(_SolidData& data)
|
||||
|
||||
// Evaluate achieved thickness
|
||||
avgThick = 0;
|
||||
for ( size_t i = 0; i < data._edges.size(); ++i )
|
||||
avgThick += data._edges[i]->_len;
|
||||
for ( iBeg = 0, iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
|
||||
{
|
||||
const double shapeTgtThick = data._hypOnShape[ iS ].GetTotalThickness();
|
||||
for ( iEnd = data._endEdgeOnShape[ iS ]; iBeg < iEnd; ++iBeg )
|
||||
{
|
||||
avgThick += Min( 1., data._edges[iBeg]->_len / shapeTgtThick );
|
||||
}
|
||||
}
|
||||
avgThick /= data._edges.size();
|
||||
debugMsg( "-- Thickness " << avgThick << " reached" );
|
||||
debugMsg( "-- Thickness " << avgThick*100 << "% reached" );
|
||||
|
||||
if ( distToIntersection < avgThick*1.5 )
|
||||
if ( distToIntersection < tgtThick*avgThick*1.5 )
|
||||
{
|
||||
debugMsg( "-- Stop inflation since "
|
||||
<< " distToIntersection( "<<distToIntersection<<" ) < avgThick( "
|
||||
<< avgThick << " ) * 1.5" );
|
||||
<< tgtThick*avgThick << " ) * 1.5" );
|
||||
break;
|
||||
}
|
||||
// new step size
|
||||
@ -2980,12 +3233,12 @@ bool _ViscousBuilder::inflate(_SolidData& data)
|
||||
data._stepSize = data._stepSizeCoeff *
|
||||
SMESH_TNodeXYZ(data._stepSizeNodes[0]).Distance(data._stepSizeNodes[1]);
|
||||
|
||||
} // while ( 1.01 * avgThick < tgtThick )
|
||||
} // while ( avgThick < 0.99 )
|
||||
|
||||
if (nbSteps == 0 )
|
||||
return error("failed at the very first inflation step", data._index);
|
||||
|
||||
if ( 1.01 * avgThick < tgtThick )
|
||||
if ( avgThick < 0.99 )
|
||||
if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( data._index ))
|
||||
{
|
||||
SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
|
||||
@ -2994,14 +3247,13 @@ bool _ViscousBuilder::inflate(_SolidData& data)
|
||||
( new SMESH_ComputeError (COMPERR_WARNING,
|
||||
SMESH_Comment("Thickness ") << tgtThick <<
|
||||
" of viscous layers not reached,"
|
||||
" average reached thickness is " << avgThick ));
|
||||
" average reached thickness is " << avgThick*100 << "%."));
|
||||
}
|
||||
|
||||
|
||||
// Restore position of src nodes moved by infaltion on _noShrinkShapes
|
||||
dumpFunction(SMESH_Comment("restoNoShrink_So")<<data._index); // debug
|
||||
int iBeg, iEnd = 0;
|
||||
for ( int iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
|
||||
for ( iEnd = iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
|
||||
{
|
||||
iBeg = iEnd;
|
||||
iEnd = data._endEdgeOnShape[ iS ];
|
||||
@ -3041,6 +3293,16 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
||||
iBeg = iEnd;
|
||||
iEnd = data._endEdgeOnShape[ iS ];
|
||||
|
||||
// bool toSmooth = false;
|
||||
// for ( int i = iBeg; i < iEnd; ++i )
|
||||
// toSmooth = data._edges[ iBeg ]->NbSteps() >= nbSteps+1;
|
||||
// if ( !toSmooth )
|
||||
// {
|
||||
// if ( iS+1 == data._nbShapesToSmooth )
|
||||
// data._nbShapesToSmooth--;
|
||||
// continue; // target length reached some steps before
|
||||
// }
|
||||
|
||||
if ( !data._edges[ iBeg ]->_sWOL.IsNull() &&
|
||||
data._edges[ iBeg ]->_sWOL.ShapeType() == TopAbs_FACE )
|
||||
{
|
||||
@ -3089,10 +3351,10 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
|
||||
badNb = 0;
|
||||
moved = false;
|
||||
if ( step % 2 )
|
||||
for ( int i = iBeg; i < iEnd; ++i )
|
||||
for ( int i = iBeg; i < iEnd; ++i ) // iterate forward
|
||||
moved |= data._edges[i]->Smooth(badNb);
|
||||
else
|
||||
for ( int i = iEnd-1; i >= iBeg; --i )
|
||||
for ( int i = iEnd-1; i >= iBeg; --i ) // iterate backward
|
||||
moved |= data._edges[i]->Smooth(badNb);
|
||||
improved = ( badNb < oldBadNb );
|
||||
|
||||
@ -3330,14 +3592,14 @@ void _SolidData::SortOnEdge( const TopoDS_Edge& E,
|
||||
//================================================================================
|
||||
|
||||
bool _SolidData::GetShapeEdges(const TGeomID shapeID,
|
||||
size_t & edgesEnd,
|
||||
size_t & iEdgesEnd,
|
||||
int* iBeg,
|
||||
int* iEnd ) const
|
||||
{
|
||||
int beg = 0, end = 0;
|
||||
for ( edgesEnd = 0; edgesEnd < _endEdgeOnShape.size(); ++edgesEnd )
|
||||
for ( iEdgesEnd = 0; iEdgesEnd < _endEdgeOnShape.size(); ++iEdgesEnd )
|
||||
{
|
||||
end = _endEdgeOnShape[ edgesEnd ];
|
||||
end = _endEdgeOnShape[ iEdgesEnd ];
|
||||
TGeomID sID = _edges[ beg ]->_nodes[0]->getshapeId();
|
||||
if ( sID == shapeID )
|
||||
{
|
||||
@ -4699,7 +4961,7 @@ void _LayerEdge::SetNewLength( double len, SMESH_MesherHelper& helper )
|
||||
{
|
||||
if ( _len - len > -1e-6 )
|
||||
{
|
||||
_pos.push_back( _pos.back() );
|
||||
//_pos.push_back( _pos.back() );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4809,6 +5071,8 @@ bool _ViscousBuilder::refine(_SolidData& data)
|
||||
|
||||
// Create intermediate nodes on each _LayerEdge
|
||||
|
||||
int iS = 0, iEnd = data._endEdgeOnShape[ iS ];
|
||||
|
||||
for ( size_t i = 0; i < data._edges.size(); ++i )
|
||||
{
|
||||
_LayerEdge& edge = *data._edges[i];
|
||||
@ -4816,6 +5080,11 @@ bool _ViscousBuilder::refine(_SolidData& data)
|
||||
if ( edge._nodes.size() < 2 )
|
||||
continue; // on _noShrinkShapes
|
||||
|
||||
// get parameters of layers for the edge
|
||||
if ( i == iEnd )
|
||||
iEnd = data._endEdgeOnShape[ ++iS ];
|
||||
const AverageHyp& hyp = data._hypOnShape[ iS ];
|
||||
|
||||
// get accumulated length of segments
|
||||
vector< double > segLen( edge._pos.size() );
|
||||
segLen[0] = 0.0;
|
||||
@ -4826,7 +5095,7 @@ bool _ViscousBuilder::refine(_SolidData& data)
|
||||
const SMDS_MeshNode* tgtNode = edge._nodes.back();
|
||||
if ( edge._nodes.size() == 2 )
|
||||
{
|
||||
edge._nodes.resize( data._hyp->GetNumberLayers() + 1, 0 );
|
||||
edge._nodes.resize( hyp.GetNumberLayers() + 1, 0 );
|
||||
edge._nodes[1] = 0;
|
||||
edge._nodes.back() = tgtNode;
|
||||
}
|
||||
@ -4875,8 +5144,8 @@ bool _ViscousBuilder::refine(_SolidData& data)
|
||||
// calculate height of the first layer
|
||||
double h0;
|
||||
const double T = segLen.back(); //data._hyp.GetTotalThickness();
|
||||
const double f = data._hyp->GetStretchFactor();
|
||||
const int N = data._hyp->GetNumberLayers();
|
||||
const double f = hyp.GetStretchFactor();
|
||||
const int N = hyp.GetNumberLayers();
|
||||
const double fPowN = pow( f, N );
|
||||
if ( fPowN - 1 <= numeric_limits<double>::min() )
|
||||
h0 = T / N;
|
||||
@ -4995,8 +5264,10 @@ bool _ViscousBuilder::refine(_SolidData& data)
|
||||
TopExp_Explorer exp( data._solid, TopAbs_FACE );
|
||||
for ( ; exp.More(); exp.Next() )
|
||||
{
|
||||
if ( data._ignoreFaceIds.count( getMeshDS()->ShapeToIndex( exp.Current() )))
|
||||
const TGeomID faceID = getMeshDS()->ShapeToIndex( exp.Current() );
|
||||
if ( data._ignoreFaceIds.count( faceID ))
|
||||
continue;
|
||||
const bool isReversedFace = data._reversedFaceIds.count( faceID );
|
||||
SMESHDS_SubMesh* fSubM = getMeshDS()->MeshElements( exp.Current() );
|
||||
SMDS_ElemIteratorPtr fIt = fSubM->GetElements();
|
||||
while ( fIt->more() )
|
||||
@ -5011,14 +5282,15 @@ bool _ViscousBuilder::refine(_SolidData& data)
|
||||
for ( int iN = 0; iN < nbNodes; ++iN )
|
||||
{
|
||||
const SMDS_MeshNode* n = nIt->next();
|
||||
nnVec[ iN ] = & data._n2eMap[ n ]->_nodes;
|
||||
if ( nnVec[ iN ]->size() < 2 )
|
||||
const int i = isReversedFace ? nbNodes-1-iN : iN;
|
||||
nnVec[ i ] = & data._n2eMap[ n ]->_nodes;
|
||||
if ( nnVec[ i ]->size() < 2 )
|
||||
degenEdgeInd.insert( iN );
|
||||
else
|
||||
nbZ = nnVec[ iN ]->size();
|
||||
nbZ = nnVec[ i ]->size();
|
||||
|
||||
if ( helper.HasDegeneratedEdges() )
|
||||
nnSet.insert( nnVec[ iN ]);
|
||||
nnSet.insert( nnVec[ i ]);
|
||||
}
|
||||
if ( nbZ == 0 )
|
||||
continue;
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "SMESH_Hypothesis.hxx"
|
||||
#include "SMESH_ProxyMesh.hxx"
|
||||
#include "SMESH_ComputeError.hxx"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -39,7 +40,7 @@ class STDMESHERS_EXPORT StdMeshers_ViscousLayers : public SMESH_Hypothesis
|
||||
public:
|
||||
StdMeshers_ViscousLayers(int hypId, int studyId, SMESH_Gen* gen);
|
||||
|
||||
// Set boundary shapes, faces in 3D, edges in 2D, either to exclude from
|
||||
// Set boundary shapes (faces in 3D, edges in 2D) either to exclude from
|
||||
// treatment or to make the Viscous Layers on
|
||||
void SetBndShapes(const std::vector<int>& shapeIds, bool toIgnore);
|
||||
std::vector<int> GetBndShapes() const { return _shapeIds; }
|
||||
@ -63,6 +64,15 @@ public:
|
||||
const TopoDS_Shape& theShape,
|
||||
const bool toMakeN2NMap=false) const;
|
||||
|
||||
// Checks compatibility of assigned StdMeshers_ViscousLayers hypotheses
|
||||
static SMESH_ComputeErrorPtr
|
||||
CheckHypothesis(SMESH_Mesh& aMesh,
|
||||
const TopoDS_Shape& aShape,
|
||||
SMESH_Hypothesis::Hypothesis_Status& aStatus);
|
||||
|
||||
// Checks if viscous layers should be constructed on a shape
|
||||
bool IsShapeWithLayers(int shapeIndex) const;
|
||||
|
||||
virtual std::ostream & SaveTo(std::ostream & save);
|
||||
virtual std::istream & LoadFrom(std::istream & load);
|
||||
|
||||
|
@ -256,6 +256,7 @@ namespace VISCOUS_2D
|
||||
_PolyLine* _rightLine;
|
||||
int _firstPntInd; // index in vector<UVPtStruct> of _wire
|
||||
int _lastPntInd;
|
||||
int _index; // index in _ViscousBuilder2D::_polyLineVec
|
||||
|
||||
vector< _LayerEdge > _lEdges; /* _lEdges[0] is usually is not treated
|
||||
as it is equal to the last one of the _leftLine */
|
||||
@ -325,6 +326,7 @@ namespace VISCOUS_2D
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
typedef map< const SMDS_MeshNode*, _LayerEdge*, TIDCompare > TNode2Edge;
|
||||
typedef StdMeshers_ViscousLayers2D THypVL;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
/*!
|
||||
@ -335,14 +337,17 @@ namespace VISCOUS_2D
|
||||
public:
|
||||
_ViscousBuilder2D(SMESH_Mesh& theMesh,
|
||||
const TopoDS_Face& theFace,
|
||||
const StdMeshers_ViscousLayers2D* theHyp);
|
||||
vector< const THypVL* > & theHyp,
|
||||
vector< TopoDS_Shape > & theHypShapes);
|
||||
SMESH_ComputeErrorPtr GetError() const { return _error; }
|
||||
// does it's job
|
||||
SMESH_ProxyMesh::Ptr Compute(const TopoDS_Shape& theShapeHypAssignedTo);
|
||||
SMESH_ProxyMesh::Ptr Compute();
|
||||
|
||||
private:
|
||||
|
||||
bool findEdgesWithLayers(const TopoDS_Shape& theShapeHypAssignedTo);
|
||||
friend class ::StdMeshers_ViscousLayers2D;
|
||||
|
||||
bool findEdgesWithLayers();
|
||||
bool makePolyLines();
|
||||
bool inflate();
|
||||
bool fixCollisions();
|
||||
@ -362,9 +367,13 @@ namespace VISCOUS_2D
|
||||
GeomAPI_ProjectPointOnSurf* faceProj);
|
||||
void adjustCommonEdge( _PolyLine& LL, _PolyLine& LR );
|
||||
void calcLayersHeight(const double totalThick,
|
||||
vector<double>& heights);
|
||||
vector<double>& heights,
|
||||
const THypVL* hyp);
|
||||
bool removeMeshFaces(const TopoDS_Shape& face);
|
||||
|
||||
const THypVL* getLineHypothesis(int iPL);
|
||||
double getLineThickness (int iPL);
|
||||
|
||||
bool error( const string& text );
|
||||
SMESHDS_Mesh* getMeshDS() { return _mesh->GetMeshDS(); }
|
||||
_ProxyMeshOfFace* getProxyMesh();
|
||||
@ -377,7 +386,8 @@ namespace VISCOUS_2D
|
||||
// input data
|
||||
SMESH_Mesh* _mesh;
|
||||
TopoDS_Face _face;
|
||||
const StdMeshers_ViscousLayers2D* _hyp;
|
||||
vector< const THypVL* > _hyps;
|
||||
vector< TopoDS_Shape > _hypShapes;
|
||||
|
||||
// result data
|
||||
SMESH_ProxyMesh::Ptr _proxyMesh;
|
||||
@ -388,11 +398,12 @@ namespace VISCOUS_2D
|
||||
SMESH_MesherHelper _helper;
|
||||
TSideVector _faceSideVec; // wires (StdMeshers_FaceSide) of _face
|
||||
vector<_PolyLine> _polyLineVec; // fronts to advance
|
||||
vector< const THypVL* > _hypOfEdge; // a hyp per an EDGE of _faceSideVec
|
||||
bool _is2DIsotropic; // is same U and V resoulution of _face
|
||||
vector<TopoDS_Face> _clearedFaces; // FACEs whose mesh was removed by shrink()
|
||||
|
||||
double _fPowN; // to compute thickness of layers
|
||||
double _thickness; // required or possible layers thickness
|
||||
//double _fPowN; // to compute thickness of layers
|
||||
double _maxThickness; // max possible layers thickness
|
||||
|
||||
// sub-shapes of _face
|
||||
set<TGeomID> _ignoreShapeIds; // ids of EDGEs w/o layers
|
||||
@ -409,15 +420,32 @@ namespace VISCOUS_2D
|
||||
/*!
|
||||
* \brief Returns StdMeshers_ViscousLayers2D for the FACE
|
||||
*/
|
||||
const StdMeshers_ViscousLayers2D* findHyp(SMESH_Mesh& theMesh,
|
||||
bool findHyps(SMESH_Mesh& theMesh,
|
||||
const TopoDS_Face& theFace,
|
||||
TopoDS_Shape* assignedTo=0)
|
||||
vector< const StdMeshers_ViscousLayers2D* > & theHyps,
|
||||
vector< TopoDS_Shape > & theAssignedTo)
|
||||
{
|
||||
theHyps.clear();
|
||||
theAssignedTo.clear();
|
||||
SMESH_HypoFilter hypFilter
|
||||
( SMESH_HypoFilter::HasName( StdMeshers_ViscousLayers2D::GetHypType() ));
|
||||
const SMESH_Hypothesis * hyp =
|
||||
theMesh.GetHypothesis( theFace, hypFilter, /*ancestors=*/true, assignedTo );
|
||||
return dynamic_cast< const StdMeshers_ViscousLayers2D* > ( hyp );
|
||||
list< const SMESHDS_Hypothesis * > hypList;
|
||||
list< TopoDS_Shape > hypShapes;
|
||||
int nbHyps = theMesh.GetHypotheses
|
||||
( theFace, hypFilter, hypList, /*ancestors=*/true, &hypShapes );
|
||||
if ( nbHyps )
|
||||
{
|
||||
theHyps.reserve( nbHyps );
|
||||
theAssignedTo.reserve( nbHyps );
|
||||
list< const SMESHDS_Hypothesis * >::iterator hyp = hypList.begin();
|
||||
list< TopoDS_Shape >::iterator shape = hypShapes.begin();
|
||||
for ( ; hyp != hypList.end(); ++hyp, ++shape )
|
||||
{
|
||||
theHyps.push_back( static_cast< const StdMeshers_ViscousLayers2D* > ( *hyp ));
|
||||
theAssignedTo.push_back( *shape );
|
||||
}
|
||||
}
|
||||
return nbHyps;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@ -436,7 +464,7 @@ namespace VISCOUS_2D
|
||||
const SMESHDS_Mesh* theMesh,
|
||||
set< int > & theEdgeIds)
|
||||
{
|
||||
int nbToEdgesIgnore = 0;
|
||||
int nbEdgesToIgnore = 0;
|
||||
vector<TGeomID> ids = theHyp->GetBndShapes();
|
||||
if ( theHyp->IsToIgnoreShapes() ) // EDGEs to ignore are given
|
||||
{
|
||||
@ -448,20 +476,20 @@ namespace VISCOUS_2D
|
||||
SMESH_MesherHelper::IsSubShape( E, theFace ))
|
||||
{
|
||||
theEdgeIds.insert( ids[i] );
|
||||
++nbToEdgesIgnore;
|
||||
++nbEdgesToIgnore;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // EDGEs to make the Viscous Layers on are given
|
||||
{
|
||||
TopExp_Explorer E( theFace, TopAbs_EDGE );
|
||||
for ( ; E.More(); E.Next(), ++nbToEdgesIgnore )
|
||||
for ( ; E.More(); E.Next(), ++nbEdgesToIgnore )
|
||||
theEdgeIds.insert( theMesh->ShapeToIndex( E.Current() ));
|
||||
|
||||
for ( size_t i = 0; i < ids.size(); ++i )
|
||||
nbToEdgesIgnore -= theEdgeIds.erase( ids[i] );
|
||||
nbEdgesToIgnore -= theEdgeIds.erase( ids[i] );
|
||||
}
|
||||
return nbToEdgesIgnore;
|
||||
return nbEdgesToIgnore;
|
||||
}
|
||||
|
||||
} // namespace VISCOUS_2D
|
||||
@ -489,12 +517,12 @@ StdMeshers_ViscousLayers2D::Compute(SMESH_Mesh& theMesh,
|
||||
{
|
||||
SMESH_ProxyMesh::Ptr pm;
|
||||
|
||||
TopoDS_Shape hypAssignedTo;
|
||||
const StdMeshers_ViscousLayers2D* vlHyp = VISCOUS_2D::findHyp( theMesh, theFace, &hypAssignedTo );
|
||||
if ( vlHyp )
|
||||
vector< const StdMeshers_ViscousLayers2D* > hyps;
|
||||
vector< TopoDS_Shape > hypShapes;
|
||||
if ( VISCOUS_2D::findHyps( theMesh, theFace, hyps, hypShapes ))
|
||||
{
|
||||
VISCOUS_2D::_ViscousBuilder2D builder( theMesh, theFace, vlHyp );
|
||||
pm = builder.Compute( hypAssignedTo );
|
||||
VISCOUS_2D::_ViscousBuilder2D builder( theMesh, theFace, hyps, hypShapes );
|
||||
pm = builder.Compute();
|
||||
SMESH_ComputeErrorPtr error = builder.GetError();
|
||||
if ( error && !error->IsOK() )
|
||||
theMesh.GetSubMesh( theFace )->GetComputeError() = error;
|
||||
@ -510,6 +538,38 @@ StdMeshers_ViscousLayers2D::Compute(SMESH_Mesh& theMesh,
|
||||
return pm;
|
||||
}
|
||||
// --------------------------------------------------------------------------------
|
||||
SMESH_ComputeErrorPtr
|
||||
StdMeshers_ViscousLayers2D::CheckHypothesis(SMESH_Mesh& theMesh,
|
||||
const TopoDS_Shape& theShape,
|
||||
SMESH_Hypothesis::Hypothesis_Status& theStatus)
|
||||
{
|
||||
SMESH_ComputeErrorPtr error = SMESH_ComputeError::New(COMPERR_OK);
|
||||
theStatus = SMESH_Hypothesis::HYP_OK;
|
||||
|
||||
TopExp_Explorer exp( theShape, TopAbs_FACE );
|
||||
for ( ; exp.More() && theStatus == SMESH_Hypothesis::HYP_OK; exp.Next() )
|
||||
{
|
||||
const TopoDS_Face& face = TopoDS::Face( exp.Current() );
|
||||
vector< const StdMeshers_ViscousLayers2D* > hyps;
|
||||
vector< TopoDS_Shape > hypShapes;
|
||||
if ( VISCOUS_2D::findHyps( theMesh, face, hyps, hypShapes ))
|
||||
{
|
||||
VISCOUS_2D::_ViscousBuilder2D builder( theMesh, face, hyps, hypShapes );
|
||||
builder._faceSideVec =
|
||||
StdMeshers_FaceSide::GetFaceWires( face, theMesh, true, error,
|
||||
SMESH_ProxyMesh::Ptr(),
|
||||
/*theCheckVertexNodes=*/false);
|
||||
if ( error->IsOK() && !builder.findEdgesWithLayers())
|
||||
{
|
||||
error = builder.GetError();
|
||||
if ( error && !error->IsOK() )
|
||||
theStatus = SMESH_Hypothesis::HYP_INCOMPAT_HYPS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
// --------------------------------------------------------------------------------
|
||||
void StdMeshers_ViscousLayers2D::RestoreListeners() const
|
||||
{
|
||||
StudyContextStruct* sc = _gen->GetStudyContext( _studyId );
|
||||
@ -549,17 +609,20 @@ using namespace VISCOUS_2D;
|
||||
|
||||
_ViscousBuilder2D::_ViscousBuilder2D(SMESH_Mesh& theMesh,
|
||||
const TopoDS_Face& theFace,
|
||||
const StdMeshers_ViscousLayers2D* theHyp):
|
||||
_mesh( &theMesh ), _face( theFace ), _hyp( theHyp ), _helper( theMesh )
|
||||
vector< const THypVL* > & theHyps,
|
||||
vector< TopoDS_Shape > & theAssignedTo):
|
||||
_mesh( &theMesh ), _face( theFace ), _helper( theMesh )
|
||||
{
|
||||
_hyps.swap( theHyps );
|
||||
_hypShapes.swap( theAssignedTo );
|
||||
|
||||
_helper.SetSubShape( _face );
|
||||
_helper.SetElementsOnShape( true );
|
||||
|
||||
_face.Orientation( TopAbs_FORWARD ); // 2D logic works only in this case
|
||||
_surface = BRep_Tool::Surface( _face );
|
||||
|
||||
if ( _hyp )
|
||||
_fPowN = pow( _hyp->GetStretchFactor(), _hyp->GetNumberLayers() );
|
||||
_error = SMESH_ComputeError::New(COMPERR_OK);
|
||||
|
||||
_nbLE = 0;
|
||||
}
|
||||
@ -593,14 +656,14 @@ bool _ViscousBuilder2D::error(const string& text )
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute(const TopoDS_Shape& theShapeHypAssignedTo)
|
||||
SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute()
|
||||
{
|
||||
_error = SMESH_ComputeError::New(COMPERR_OK);
|
||||
_faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error);
|
||||
|
||||
if ( !_error->IsOK() )
|
||||
return _proxyMesh;
|
||||
|
||||
if ( !findEdgesWithLayers(theShapeHypAssignedTo) ) // analysis of a shape
|
||||
if ( !findEdgesWithLayers() ) // analysis of a shape
|
||||
return _proxyMesh;
|
||||
|
||||
if ( ! makePolyLines() ) // creation of fronts
|
||||
@ -629,21 +692,79 @@ SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute(const TopoDS_Shape& theShapeHypA
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool _ViscousBuilder2D::findEdgesWithLayers(const TopoDS_Shape& theShapeHypAssignedTo)
|
||||
bool _ViscousBuilder2D::findEdgesWithLayers()
|
||||
{
|
||||
// collect all EDGEs to ignore defined by hyp
|
||||
int nbMyEdgesIgnored = getEdgesToIgnore( _hyp, _face, getMeshDS(), _ignoreShapeIds );
|
||||
// collect all EDGEs to ignore defined by _hyps
|
||||
typedef std::pair< set<TGeomID>, const THypVL* > TEdgesOfHyp;
|
||||
vector< TEdgesOfHyp > ignoreEdgesOfHyp( _hyps.size() );
|
||||
for ( size_t i = 0; i < _hyps.size(); ++i )
|
||||
{
|
||||
ignoreEdgesOfHyp[i].second = _hyps[i];
|
||||
getEdgesToIgnore( _hyps[i], _face, getMeshDS(), ignoreEdgesOfHyp[i].first );
|
||||
}
|
||||
|
||||
// get all shared EDGEs
|
||||
TopTools_MapOfShape sharedEdges;
|
||||
TopTools_IndexedMapOfShape hypFaces; // faces with VL hyps
|
||||
for ( size_t i = 0; i < _hypShapes.size(); ++i )
|
||||
TopExp::MapShapes( _hypShapes[i], TopAbs_FACE, hypFaces );
|
||||
TopTools_IndexedDataMapOfShapeListOfShape facesOfEdgeMap;
|
||||
TopExp::MapShapesAndAncestors( theShapeHypAssignedTo,
|
||||
TopAbs_EDGE, TopAbs_FACE, facesOfEdgeMap);
|
||||
for ( int iF = 1; iF <= hypFaces.Extent(); ++iF )
|
||||
TopExp::MapShapesAndAncestors( hypFaces(iF), TopAbs_EDGE, TopAbs_FACE, facesOfEdgeMap);
|
||||
for ( int iE = 1; iE <= facesOfEdgeMap.Extent(); ++iE )
|
||||
if ( facesOfEdgeMap( iE ).Extent() > 1 )
|
||||
sharedEdges.Add( facesOfEdgeMap.FindKey( iE ));
|
||||
|
||||
// check all EDGEs of the _face
|
||||
// fill _hypOfEdge
|
||||
if ( _hyps.size() > 1 )
|
||||
{
|
||||
// check if two hypotheses define different parameters for the same EDGE
|
||||
for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
|
||||
{
|
||||
StdMeshers_FaceSidePtr wire = _faceSideVec[ iWire ];
|
||||
for ( int iE = 0; iE < wire->NbEdges(); ++iE )
|
||||
{
|
||||
const THypVL* hyp = 0;
|
||||
const TGeomID edgeID = wire->EdgeID( iE );
|
||||
if ( !sharedEdges.Contains( wire->Edge( iE )))
|
||||
{
|
||||
for ( size_t i = 0; i < ignoreEdgesOfHyp.size(); ++i )
|
||||
if ( ! ignoreEdgesOfHyp[i].first.count( edgeID ))
|
||||
{
|
||||
if ( hyp )
|
||||
return error(SMESH_Comment("Several hypotheses define "
|
||||
"Viscous Layers on the edge #") << edgeID );
|
||||
hyp = ignoreEdgesOfHyp[i].second;
|
||||
}
|
||||
}
|
||||
_hypOfEdge.push_back( hyp );
|
||||
if ( !hyp )
|
||||
_ignoreShapeIds.insert( edgeID );
|
||||
}
|
||||
// check if two hypotheses define different number of viscous layers for
|
||||
// adjacent EDGEs
|
||||
const THypVL *hyp, *prevHyp = _hypOfEdge.back();
|
||||
size_t iH = _hypOfEdge.size() - wire->NbEdges();
|
||||
for ( ; iH < _hypOfEdge.size(); ++iH )
|
||||
{
|
||||
hyp = _hypOfEdge[ iH ];
|
||||
if ( hyp && prevHyp &&
|
||||
hyp->GetNumberLayers() != prevHyp->GetNumberLayers() )
|
||||
{
|
||||
return error("Two hypotheses define different number of "
|
||||
"viscous layers on adjacent edges");
|
||||
}
|
||||
prevHyp = hyp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( _hyps.size() == 1 )
|
||||
{
|
||||
_ignoreShapeIds.swap( ignoreEdgesOfHyp[0].first );
|
||||
}
|
||||
|
||||
// check all EDGEs of the _face to fill _ignoreShapeIds and _noShrinkVert
|
||||
|
||||
int totalNbEdges = 0;
|
||||
for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
|
||||
{
|
||||
@ -674,9 +795,9 @@ bool _ViscousBuilder2D::findEdgesWithLayers(const TopoDS_Shape& theShapeHypAssig
|
||||
for ( ; hyp != allHyps.end() && !viscHyp; ++hyp )
|
||||
viscHyp = dynamic_cast<const StdMeshers_ViscousLayers2D*>( *hyp );
|
||||
|
||||
set<TGeomID> neighbourIgnoreEdges;
|
||||
if (viscHyp)
|
||||
getEdgesToIgnore( viscHyp, neighbourFace, getMeshDS(), neighbourIgnoreEdges );
|
||||
// set<TGeomID> neighbourIgnoreEdges;
|
||||
// if (viscHyp)
|
||||
// getEdgesToIgnore( viscHyp, neighbourFace, getMeshDS(), neighbourIgnoreEdges );
|
||||
|
||||
for ( int iV = 0; iV < 2; ++iV )
|
||||
{
|
||||
@ -688,9 +809,18 @@ bool _ViscousBuilder2D::findEdgesWithLayers(const TopoDS_Shape& theShapeHypAssig
|
||||
PShapeIteratorPtr edgeIt = _helper.GetAncestors( vertex, *_mesh, TopAbs_EDGE );
|
||||
while ( const TopoDS_Shape* edge = edgeIt->next() )
|
||||
if ( !edge->IsSame( wire->Edge( iE )) &&
|
||||
_helper.IsSubShape( *edge, neighbourFace ) &&
|
||||
( neighbourIgnoreEdges.count( getMeshDS()->ShapeToIndex( *edge )) ||
|
||||
sharedEdges.Contains( *edge )))
|
||||
_helper.IsSubShape( *edge, neighbourFace ))
|
||||
{
|
||||
const TGeomID neighbourID = getMeshDS()->ShapeToIndex( *edge );
|
||||
bool hasVL = !sharedEdges.Contains( *edge );
|
||||
if ( hasVL )
|
||||
{
|
||||
hasVL = false;
|
||||
for ( hyp = allHyps.begin(); hyp != allHyps.end() && !hasVL; ++hyp )
|
||||
if ( viscHyp = dynamic_cast<const THypVL*>( *hyp ))
|
||||
hasVL = viscHyp->IsShapeWithLayers( neighbourID );
|
||||
}
|
||||
if ( !hasVL )
|
||||
{
|
||||
_noShrinkVert.insert( getMeshDS()->ShapeToIndex( vertex ));
|
||||
break;
|
||||
@ -701,19 +831,22 @@ bool _ViscousBuilder2D::findEdgesWithLayers(const TopoDS_Shape& theShapeHypAssig
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nbMyEdgesIgnored = _ignoreShapeIds.size();
|
||||
|
||||
// add VERTEXes w/o layers to _ignoreShapeIds (this is used by toShrinkForAdjacent())
|
||||
for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
|
||||
{
|
||||
StdMeshers_FaceSidePtr wire = _faceSideVec[ iWire ];
|
||||
for ( int iE = 0; iE < wire->NbEdges(); ++iE )
|
||||
{
|
||||
TGeomID edge1 = wire->EdgeID( iE );
|
||||
TGeomID edge2 = wire->EdgeID( iE+1 );
|
||||
if ( _ignoreShapeIds.count( edge1 ) && _ignoreShapeIds.count( edge2 ))
|
||||
_ignoreShapeIds.insert( getMeshDS()->ShapeToIndex( wire->LastVertex( iE )));
|
||||
}
|
||||
}
|
||||
// for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
|
||||
// {
|
||||
// StdMeshers_FaceSidePtr wire = _faceSideVec[ iWire ];
|
||||
// for ( int iE = 0; iE < wire->NbEdges(); ++iE )
|
||||
// {
|
||||
// TGeomID edge1 = wire->EdgeID( iE );
|
||||
// TGeomID edge2 = wire->EdgeID( iE+1 );
|
||||
// if ( _ignoreShapeIds.count( edge1 ) && _ignoreShapeIds.count( edge2 ))
|
||||
// _ignoreShapeIds.insert( getMeshDS()->ShapeToIndex( wire->LastVertex( iE )));
|
||||
// }
|
||||
// }
|
||||
|
||||
return ( nbMyEdgesIgnored < totalNbEdges );
|
||||
}
|
||||
@ -772,6 +905,7 @@ bool _ViscousBuilder2D::makePolyLines()
|
||||
for ( int iE = 0; iE < wire->NbEdges(); ++iE )
|
||||
{
|
||||
_PolyLine& L = _polyLineVec[ iPoLine++ ];
|
||||
L._index = iPoLine-1;
|
||||
L._wire = wire.get();
|
||||
L._edgeInd = iE;
|
||||
L._advancable = !_ignoreShapeIds.count( wire->EdgeID( iE ));
|
||||
@ -846,13 +980,16 @@ bool _ViscousBuilder2D::makePolyLines()
|
||||
// Evaluate max possible _thickness if required layers thickness seems too high
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
_thickness = _hyp->GetTotalThickness();
|
||||
_maxThickness = _hyps[0]->GetTotalThickness();
|
||||
for ( size_t iH = 1; iH < _hyps.size(); ++iH )
|
||||
_maxThickness = Max( _maxThickness, _hyps[iH]->GetTotalThickness() );
|
||||
|
||||
_SegmentTree::box_type faceBndBox2D;
|
||||
for ( iPoLine = 0; iPoLine < _polyLineVec.size(); ++iPoLine )
|
||||
faceBndBox2D.Add( *_polyLineVec[ iPoLine]._segTree->getBox() );
|
||||
double boxTol = 1e-3 * sqrt( faceBndBox2D.SquareExtent() );
|
||||
//
|
||||
if ( _thickness * maxLen2dTo3dRatio > sqrt( faceBndBox2D.SquareExtent() ) / 10 )
|
||||
const double boxTol = 1e-3 * sqrt( faceBndBox2D.SquareExtent() );
|
||||
|
||||
if ( _maxThickness * maxLen2dTo3dRatio > sqrt( faceBndBox2D.SquareExtent() ) / 10 )
|
||||
{
|
||||
vector< const _Segment* > foundSegs;
|
||||
double maxPossibleThick = 0;
|
||||
@ -885,7 +1022,7 @@ bool _ViscousBuilder2D::makePolyLines()
|
||||
}
|
||||
}
|
||||
if ( maxPossibleThick > 0. )
|
||||
_thickness = Min( _hyp->GetTotalThickness(), maxPossibleThick );
|
||||
_maxThickness = Min( _maxThickness, maxPossibleThick );
|
||||
}
|
||||
|
||||
// Adjust _LayerEdge's at _PolyLine's extremities
|
||||
@ -930,13 +1067,14 @@ bool _ViscousBuilder2D::makePolyLines()
|
||||
for ( iPoLine = 0; iPoLine < _polyLineVec.size(); ++iPoLine )
|
||||
{
|
||||
lineBoxes[ iPoLine ] = *_polyLineVec[ iPoLine ]._segTree->getBox();
|
||||
lineBoxes[ iPoLine ].Enlarge( maxLen2dTo3dRatio * _thickness *
|
||||
lineBoxes[ iPoLine ].Enlarge( maxLen2dTo3dRatio * getLineThickness( iPoLine ) *
|
||||
( _polyLineVec[ iPoLine ]._advancable ? 2. : 1.2 ));
|
||||
}
|
||||
// _reachableLines
|
||||
for ( iPoLine = 0; iPoLine < _polyLineVec.size(); ++iPoLine )
|
||||
{
|
||||
_PolyLine& L1 = _polyLineVec[ iPoLine ];
|
||||
const double thick1 = getLineThickness( iPoLine );
|
||||
for ( size_t iL2 = 0; iL2 < _polyLineVec.size(); ++iL2 )
|
||||
{
|
||||
_PolyLine& L2 = _polyLineVec[ iL2 ];
|
||||
@ -950,7 +1088,7 @@ bool _ViscousBuilder2D::makePolyLines()
|
||||
{
|
||||
_LayerEdge& LE = L1._lEdges[iLE];
|
||||
if ( !lineBoxes[ iL2 ].IsOut ( LE._uvOut,
|
||||
LE._uvOut + LE._normal2D *_thickness * LE._len2dTo3dRatio ))
|
||||
LE._uvOut + LE._normal2D * thick1 * LE._len2dTo3dRatio ))
|
||||
{
|
||||
L1._reachableLines.push_back( & L2 );
|
||||
break;
|
||||
@ -1024,7 +1162,7 @@ void _ViscousBuilder2D::adjustCommonEdge( _PolyLine& LL, _PolyLine& LR )
|
||||
// during inflate().
|
||||
//
|
||||
// find max length of the VERTEX-based _LayerEdge whose direction is normAvg
|
||||
double maxLen2D = _thickness * EL._len2dTo3dRatio;
|
||||
double maxLen2D = _maxThickness * EL._len2dTo3dRatio;
|
||||
const gp_XY& pCommOut = ER._uvOut;
|
||||
gp_XY pCommIn = pCommOut + normAvg * maxLen2D;
|
||||
_Segment segCommon( pCommOut, pCommIn );
|
||||
@ -1067,7 +1205,7 @@ void _ViscousBuilder2D::adjustCommonEdge( _PolyLine& LL, _PolyLine& LR )
|
||||
_SegmentIntersection lastIntersection;
|
||||
for ( ; iLE < L._lEdges.size(); ++iLE, eIt += dIt )
|
||||
{
|
||||
gp_XY uvIn = eIt->_uvOut + eIt->_normal2D * _thickness * eIt->_len2dTo3dRatio;
|
||||
gp_XY uvIn = eIt->_uvOut + eIt->_normal2D * _maxThickness * eIt->_len2dTo3dRatio;
|
||||
_Segment segOfEdge( eIt->_uvOut, uvIn );
|
||||
if ( !intersection.Compute( segCommon, segOfEdge ))
|
||||
break;
|
||||
@ -1148,7 +1286,7 @@ void _ViscousBuilder2D::setLayerEdgeData( _LayerEdge& lEdge,
|
||||
gp_Vec faceNorm = du ^ dv;
|
||||
gp_Vec normal = faceNorm ^ tangent;
|
||||
normal.Normalize();
|
||||
p = pOut.XYZ() + normal.XYZ() * /*1e-2 * */_hyp->GetTotalThickness() / _hyp->GetNumberLayers();
|
||||
p = pOut.XYZ() + normal.XYZ() * /*1e-2 * */_hyps[0]->GetTotalThickness() / _hyps[0]->GetNumberLayers();
|
||||
faceProj->Perform( p );
|
||||
if ( !faceProj->IsDone() || faceProj->NbPoints() < 1 )
|
||||
return setLayerEdgeData( lEdge, u, pcurve, curve, p, reverse, NULL );
|
||||
@ -1205,7 +1343,7 @@ bool _ViscousBuilder2D::inflate()
|
||||
{
|
||||
// Limit size of inflation step by geometry size found by
|
||||
// itersecting _LayerEdge's with _Segment's
|
||||
double minSize = _thickness, maxSize = 0;
|
||||
double minSize = _maxThickness, maxSize = 0;
|
||||
vector< const _Segment* > foundSegs;
|
||||
_SegmentIntersection intersection;
|
||||
for ( size_t iL1 = 0; iL1 < _polyLineVec.size(); ++iL1 )
|
||||
@ -1233,29 +1371,30 @@ bool _ViscousBuilder2D::inflate()
|
||||
}
|
||||
}
|
||||
if ( minSize > maxSize ) // no collisions possible
|
||||
maxSize = _thickness;
|
||||
maxSize = _maxThickness;
|
||||
#ifdef __myDEBUG
|
||||
cout << "-- minSize = " << minSize << ", maxSize = " << maxSize << endl;
|
||||
#endif
|
||||
|
||||
double curThick = 0, stepSize = minSize;
|
||||
int nbSteps = 0;
|
||||
if ( maxSize > _thickness )
|
||||
maxSize = _thickness;
|
||||
if ( maxSize > _maxThickness )
|
||||
maxSize = _maxThickness;
|
||||
while ( curThick < maxSize )
|
||||
{
|
||||
curThick += stepSize * 1.25;
|
||||
if ( curThick > _thickness )
|
||||
curThick = _thickness;
|
||||
if ( curThick > _maxThickness )
|
||||
curThick = _maxThickness;
|
||||
|
||||
// Elongate _LayerEdge's
|
||||
for ( size_t iL = 0; iL < _polyLineVec.size(); ++iL )
|
||||
{
|
||||
_PolyLine& L = _polyLineVec[ iL ];
|
||||
if ( !L._advancable ) continue;
|
||||
const double lineThick = Min( curThick, getLineThickness( iL ));
|
||||
bool lenChange = false;
|
||||
for ( size_t iLE = L.FirstLEdge(); iLE < L._lEdges.size(); ++iLE )
|
||||
lenChange |= L._lEdges[iLE].SetNewLength( curThick );
|
||||
lenChange |= L._lEdges[iLE].SetNewLength( lineThick );
|
||||
// for ( int k=0; k<L._segments.size(); ++k)
|
||||
// cout << "( " << L._segments[k].p1().X() << ", " <<L._segments[k].p1().Y() << " ) "
|
||||
// << "( " << L._segments[k].p2().X() << ", " <<L._segments[k].p2().Y() << " ) "
|
||||
@ -1270,7 +1409,7 @@ bool _ViscousBuilder2D::inflate()
|
||||
{
|
||||
break; // no more inflating possible
|
||||
}
|
||||
stepSize = Max( stepSize , _thickness / 10. );
|
||||
stepSize = Max( stepSize , _maxThickness / 10. );
|
||||
nbSteps++;
|
||||
}
|
||||
|
||||
@ -1533,26 +1672,28 @@ bool _ViscousBuilder2D::shrink()
|
||||
int iPFrom = L._firstPntInd, iPTo = L._lastPntInd;
|
||||
if ( isShrinkableL )
|
||||
{
|
||||
const THypVL* hyp = getLineHypothesis( L._leftLine->_index );
|
||||
vector<gp_XY>& uvVec = L._lEdges.front()._uvRefined;
|
||||
for ( int i = 0; i < _hyp->GetNumberLayers(); ++i ) {
|
||||
for ( int i = 0; i < hyp->GetNumberLayers(); ++i ) {
|
||||
const UVPtStruct& uvPt = points[ iPFrom + i + 1 ];
|
||||
L._leftNodes.push_back( uvPt.node );
|
||||
uvVec.push_back ( pcurve->Value( uvPt.param ).XY() );
|
||||
}
|
||||
iPFrom += hyp->GetNumberLayers();
|
||||
}
|
||||
if ( isShrinkableR )
|
||||
{
|
||||
const THypVL* hyp = getLineHypothesis( L._rightLine->_index );
|
||||
vector<gp_XY>& uvVec = L._lEdges.back()._uvRefined;
|
||||
for ( int i = 0; i < _hyp->GetNumberLayers(); ++i ) {
|
||||
for ( int i = 0; i < hyp->GetNumberLayers(); ++i ) {
|
||||
const UVPtStruct& uvPt = points[ iPTo - i - 1 ];
|
||||
L._rightNodes.push_back( uvPt.node );
|
||||
uvVec.push_back ( pcurve->Value( uvPt.param ).XY() );
|
||||
}
|
||||
iPTo -= hyp->GetNumberLayers();
|
||||
}
|
||||
// make proxy sub-mesh data of present nodes
|
||||
//
|
||||
if ( isShrinkableL ) iPFrom += _hyp->GetNumberLayers();
|
||||
if ( isShrinkableR ) iPTo -= _hyp->GetNumberLayers();
|
||||
UVPtStructVec nodeDataVec( & points[ iPFrom ], & points[ iPTo + 1 ]);
|
||||
|
||||
double normSize = nodeDataVec.back().normParam - nodeDataVec.front().normParam;
|
||||
@ -1723,14 +1864,14 @@ bool _ViscousBuilder2D::shrink()
|
||||
( isR ? L._leftLine->_lEdges.back() : L._rightLine->_lEdges.front() );
|
||||
length2D = neighborLE._length2D;
|
||||
if ( length2D == 0 )
|
||||
length2D = _thickness * nearLE._len2dTo3dRatio;
|
||||
length2D = _maxThickness * nearLE._len2dTo3dRatio;
|
||||
}
|
||||
}
|
||||
|
||||
// move u to the internal boundary of layers
|
||||
// u --> u
|
||||
// x-x-x-x-----x-----x----
|
||||
double maxLen3D = Min( _thickness, edgeLen / ( 1 + nbAdvancable ));
|
||||
double maxLen3D = Min( _maxThickness, edgeLen / ( 1 + nbAdvancable ));
|
||||
double maxLen2D = maxLen3D * nearLE._len2dTo3dRatio;
|
||||
if ( !length2D ) length2D = length1D / len1dTo2dRatio;
|
||||
if ( Abs( length2D ) > maxLen2D )
|
||||
@ -1746,7 +1887,8 @@ bool _ViscousBuilder2D::shrink()
|
||||
|
||||
// compute params of layers on L
|
||||
vector<double> heights;
|
||||
calcLayersHeight( u - u0, heights );
|
||||
const THypVL* hyp = getLineHypothesis( L2->_index );
|
||||
calcLayersHeight( u - u0, heights, hyp );
|
||||
//
|
||||
vector< double > params( heights.size() );
|
||||
for ( size_t i = 0; i < params.size(); ++i )
|
||||
@ -1756,13 +1898,13 @@ bool _ViscousBuilder2D::shrink()
|
||||
// x-x-x-x---
|
||||
vector< const SMDS_MeshNode* >& layersNode = isR ? L._rightNodes : L._leftNodes;
|
||||
vector<gp_XY>& nodeUV = ( isR ? L._lEdges.back() : L._lEdges[0] )._uvRefined;
|
||||
nodeUV.resize ( _hyp->GetNumberLayers() );
|
||||
layersNode.resize( _hyp->GetNumberLayers() );
|
||||
nodeUV.resize ( hyp->GetNumberLayers() );
|
||||
layersNode.resize( hyp->GetNumberLayers() );
|
||||
const SMDS_MeshNode* vertexNode = nodeDataVec[ iPEnd ].node;
|
||||
const SMDS_MeshNode * prevNode = vertexNode;
|
||||
for ( size_t i = 0; i < params.size(); ++i )
|
||||
{
|
||||
gp_Pnt p = curve.Value( params[i] );
|
||||
const gp_Pnt p = curve.Value( params[i] );
|
||||
layersNode[ i ] = helper.AddNode( p.X(), p.Y(), p.Z(), /*id=*/0, params[i] );
|
||||
nodeUV [ i ] = pcurve->Value( params[i] ).XY();
|
||||
helper.AddEdge( prevNode, layersNode[ i ] );
|
||||
@ -1773,7 +1915,7 @@ bool _ViscousBuilder2D::shrink()
|
||||
if ( !L2->_advancable )
|
||||
{
|
||||
isRShrinkedForAdjacent = isR;
|
||||
nodeDataForAdjacent.resize( _hyp->GetNumberLayers() );
|
||||
nodeDataForAdjacent.resize( hyp->GetNumberLayers() );
|
||||
|
||||
size_t iFrw = 0, iRev = nodeDataForAdjacent.size()-1, *i = isR ? &iRev : &iFrw;
|
||||
nodeDataForAdjacent[ *i ] = points[ isR ? L._lastPntInd : L._firstPntInd ];
|
||||
@ -1890,11 +2032,11 @@ bool _ViscousBuilder2D::shrink()
|
||||
{
|
||||
// refine the not shared _LayerEdge
|
||||
vector<double> layersHeight;
|
||||
calcLayersHeight( LE2._length2D, layersHeight );
|
||||
calcLayersHeight( LE2._length2D, layersHeight, getLineHypothesis( L2._index ));
|
||||
|
||||
vector<gp_XY>& nodeUV2 = LE2._uvRefined;
|
||||
nodeUV2.resize ( _hyp->GetNumberLayers() );
|
||||
layerNodes2.resize( _hyp->GetNumberLayers() );
|
||||
nodeUV2.resize ( layersHeight.size() );
|
||||
layerNodes2.resize( layersHeight.size() );
|
||||
for ( size_t i = 0; i < layersHeight.size(); ++i )
|
||||
{
|
||||
gp_XY uv = LE2._uvOut + LE2._normal2D * layersHeight[i];
|
||||
@ -1952,12 +2094,13 @@ bool _ViscousBuilder2D::toShrinkForAdjacent( const TopoDS_Face& adjFace,
|
||||
if ( _noShrinkVert.count( getMeshDS()->ShapeToIndex( V )) || adjFace.IsNull() )
|
||||
return false;
|
||||
|
||||
TopoDS_Shape hypAssignedTo;
|
||||
if ( const StdMeshers_ViscousLayers2D* vlHyp = findHyp( *_mesh, adjFace, &hypAssignedTo ))
|
||||
vector< const StdMeshers_ViscousLayers2D* > hyps;
|
||||
vector< TopoDS_Shape > hypShapes;
|
||||
if ( VISCOUS_2D::findHyps( *_mesh, adjFace, hyps, hypShapes ))
|
||||
{
|
||||
VISCOUS_2D::_ViscousBuilder2D builder( *_mesh, adjFace, vlHyp );
|
||||
VISCOUS_2D::_ViscousBuilder2D builder( *_mesh, adjFace, hyps, hypShapes );
|
||||
builder._faceSideVec = StdMeshers_FaceSide::GetFaceWires( adjFace, *_mesh, true, _error );
|
||||
builder.findEdgesWithLayers( hypAssignedTo );
|
||||
builder.findEdgesWithLayers();
|
||||
|
||||
PShapeIteratorPtr edgeIt = _helper.GetAncestors( V, *_mesh, TopAbs_EDGE );
|
||||
while ( const TopoDS_Shape* edgeAtV = edgeIt->next() )
|
||||
@ -2180,7 +2323,8 @@ bool _ViscousBuilder2D::refine()
|
||||
}
|
||||
|
||||
// normalized height of layers
|
||||
calcLayersHeight( 1., layersHeight );
|
||||
const THypVL* hyp = getLineHypothesis( iL );
|
||||
calcLayersHeight( 1., layersHeight, hyp);
|
||||
|
||||
// Create layers of faces
|
||||
|
||||
@ -2192,11 +2336,11 @@ bool _ViscousBuilder2D::refine()
|
||||
for ( int i = L._firstPntInd; i <= L._lastPntInd; ++i )
|
||||
outerNodes[ i-L._firstPntInd ] = points[i].node;
|
||||
|
||||
L._leftNodes .reserve( _hyp->GetNumberLayers() );
|
||||
L._rightNodes.reserve( _hyp->GetNumberLayers() );
|
||||
L._leftNodes .reserve( hyp->GetNumberLayers() );
|
||||
L._rightNodes.reserve( hyp->GetNumberLayers() );
|
||||
int cur = 0, prev = -1; // to take into account orientation of _face
|
||||
if ( isReverse ) std::swap( cur, prev );
|
||||
for ( int iF = 0; iF < _hyp->GetNumberLayers(); ++iF ) // loop on layers of faces
|
||||
for ( int iF = 0; iF < hyp->GetNumberLayers(); ++iF ) // loop on layers of faces
|
||||
{
|
||||
// create innerNodes of a current layer
|
||||
for ( size_t i = iN0; i < iNE; ++i )
|
||||
@ -2358,6 +2502,30 @@ bool _ViscousBuilder2D::removeMeshFaces(const TopoDS_Shape& face)
|
||||
return thereWereElems;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Returns a hypothesis for a _PolyLine
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
const StdMeshers_ViscousLayers2D* _ViscousBuilder2D::getLineHypothesis(int iPL)
|
||||
{
|
||||
return iPL < (int)_hypOfEdge.size() ? _hypOfEdge[ iPL ] : _hyps[0];
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Returns a layers thickness for a _PolyLine
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
double _ViscousBuilder2D::getLineThickness(int iPL)
|
||||
{
|
||||
if ( const StdMeshers_ViscousLayers2D* h = getLineHypothesis( iPL ))
|
||||
return Min( _maxThickness, h->GetTotalThickness() );
|
||||
return _maxThickness;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Creates a _ProxyMeshOfFace and store it in a sub-mesh of FACE
|
||||
@ -2384,21 +2552,23 @@ _ProxyMeshOfFace* _ViscousBuilder2D::getProxyMesh()
|
||||
//================================================================================
|
||||
|
||||
void _ViscousBuilder2D::calcLayersHeight(const double totalThick,
|
||||
vector<double>& heights)
|
||||
vector<double>& heights,
|
||||
const THypVL* hyp)
|
||||
{
|
||||
heights.resize( _hyp->GetNumberLayers() );
|
||||
const double fPowN = pow( hyp->GetStretchFactor(), hyp->GetNumberLayers() );
|
||||
heights.resize( hyp->GetNumberLayers() );
|
||||
double h0;
|
||||
if ( _fPowN - 1 <= numeric_limits<double>::min() )
|
||||
h0 = totalThick / _hyp->GetNumberLayers();
|
||||
if ( fPowN - 1 <= numeric_limits<double>::min() )
|
||||
h0 = totalThick / hyp->GetNumberLayers();
|
||||
else
|
||||
h0 = totalThick * ( _hyp->GetStretchFactor() - 1 )/( _fPowN - 1 );
|
||||
h0 = totalThick * ( hyp->GetStretchFactor() - 1 )/( fPowN - 1 );
|
||||
|
||||
double hSum = 0, hi = h0;
|
||||
for ( int i = 0; i < _hyp->GetNumberLayers(); ++i )
|
||||
for ( int i = 0; i < hyp->GetNumberLayers(); ++i )
|
||||
{
|
||||
hSum += hi;
|
||||
heights[ i ] = hSum;
|
||||
hi *= _hyp->GetStretchFactor();
|
||||
hi *= hyp->GetStretchFactor();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,10 @@ class STDMESHERS_EXPORT StdMeshers_ViscousLayers2D : public StdMeshers_ViscousLa
|
||||
{
|
||||
public:
|
||||
StdMeshers_ViscousLayers2D(int hypId, int studyId, SMESH_Gen* gen);
|
||||
|
||||
// Computes temporary 2D mesh to be used by 2D algorithm.
|
||||
// Return SMESH_ProxyMesh for the given FACE, or NULL in case of error
|
||||
/*!
|
||||
* \brief Computes temporary 2D mesh to be used by 2D algorithm.
|
||||
* Return SMESH_ProxyMesh for the given FACE, or NULL in case of error
|
||||
*/
|
||||
static SMESH_ProxyMesh::Ptr Compute(SMESH_Mesh& theMesh,
|
||||
const TopoDS_Face& theShape);
|
||||
/*!
|
||||
@ -46,6 +47,12 @@ public:
|
||||
*/
|
||||
void RestoreListeners() const;
|
||||
|
||||
/*!
|
||||
* \brief Checks compatibility of assigned StdMeshers_ViscousLayers2D hypotheses
|
||||
*/
|
||||
static SMESH_ComputeErrorPtr CheckHypothesis(SMESH_Mesh& aMesh,
|
||||
const TopoDS_Shape& aShape,
|
||||
Hypothesis_Status& aStatus);
|
||||
/*!
|
||||
* \brief Initialize my parameter values by the mesh built on the geometry
|
||||
* \param theMesh - the built mesh
|
||||
|