mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-27 19:00:33 +05:00
Merge branch 'master' into V7_5_BR
This commit is contained in:
commit
b21a1e5b25
@ -17,8 +17,10 @@
|
|||||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# examples that cant be used for testing because they use external mesher plug-ins
|
||||||
SET(BAD_TESTS
|
SET(BAD_TESTS
|
||||||
3dmesh.py
|
3dmesh.py
|
||||||
|
a3DmeshOnModified2Dmesh.py
|
||||||
creating_meshes_ex01.py
|
creating_meshes_ex01.py
|
||||||
creating_meshes_ex03.py
|
creating_meshes_ex03.py
|
||||||
creating_meshes_ex05.py
|
creating_meshes_ex05.py
|
||||||
@ -39,14 +41,14 @@ SET(BAD_TESTS
|
|||||||
quality_controls_ex20.py
|
quality_controls_ex20.py
|
||||||
quality_controls_ex21.py
|
quality_controls_ex21.py
|
||||||
quality_controls_ex22.py
|
quality_controls_ex22.py
|
||||||
viewing_meshes_ex01.py
|
viewing_meshes_ex01.py
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(GOOD_TESTS
|
SET(GOOD_TESTS
|
||||||
cartesian_algo.py
|
cartesian_algo.py
|
||||||
creating_meshes_ex02.py
|
creating_meshes_ex02.py
|
||||||
creating_meshes_ex04.py
|
creating_meshes_ex04.py
|
||||||
creating_meshes_ex06.py
|
creating_meshes_ex06.py
|
||||||
creating_meshes_ex07.py
|
creating_meshes_ex07.py
|
||||||
creating_meshes_ex08.py
|
creating_meshes_ex08.py
|
||||||
defining_hypotheses_ex01.py
|
defining_hypotheses_ex01.py
|
||||||
|
62
doc/salome/examples/a3DmeshOnModified2Dmesh.py
Normal file
62
doc/salome/examples/a3DmeshOnModified2Dmesh.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import salome
|
||||||
|
salome.salome_init()
|
||||||
|
|
||||||
|
from salome.geom import geomBuilder
|
||||||
|
geompy = geomBuilder.New(salome.myStudy)
|
||||||
|
|
||||||
|
# This script demonstrates generation of 3D mesh basing on a modified 2D mesh
|
||||||
|
#
|
||||||
|
# Purpose is to get a tetrahedral mesh in a sphere cut by a cube.
|
||||||
|
# The requirement is to have a surface mesh on the cube comprised of
|
||||||
|
# triangles of exactly the same size arranged in a grid pattern.
|
||||||
|
#
|
||||||
|
# To fulfill this requirement we mesh the box using Quadrangle (Mapping)
|
||||||
|
# meshing algorithm, split quadrangles into triangles and then generate
|
||||||
|
# tetrahedrons.
|
||||||
|
|
||||||
|
|
||||||
|
# Make the geometry
|
||||||
|
|
||||||
|
Box_1 = geompy.MakeBox(-100,-100,-100, 100, 100, 100)
|
||||||
|
Sphere_1 = geompy.MakeSphereR( 300 )
|
||||||
|
Cut_1 = geompy.MakeCut(Sphere_1, Box_1, theName="Cut_1")
|
||||||
|
# get a spherical face
|
||||||
|
Sph_Face = geompy.ExtractShapes( Sphere_1, geompy.ShapeType["FACE"] )[0]
|
||||||
|
|
||||||
|
# get the shape Sph_Face turned into during MakeCut()
|
||||||
|
Sph_Face = geompy.GetInPlace(Cut_1, Sph_Face, isNewImplementation=True, theName="Sphere_1")
|
||||||
|
|
||||||
|
|
||||||
|
# 1) Define a mesh with 1D and 2D meshers
|
||||||
|
|
||||||
|
import SMESH
|
||||||
|
from salome.smesh import smeshBuilder
|
||||||
|
smesh = smeshBuilder.New(salome.myStudy)
|
||||||
|
|
||||||
|
Mesh_1 = smesh.Mesh(Cut_1)
|
||||||
|
|
||||||
|
# "global" meshers (assigned to Cut_1) that will be used for the box
|
||||||
|
Regular_1D = Mesh_1.Segment()
|
||||||
|
Local_Length_1 = Regular_1D.LocalLength(20)
|
||||||
|
Quadrangle_2D = Mesh_1.Quadrangle()
|
||||||
|
|
||||||
|
# a "local" mesher (assigned to a sub-mesh on Sphere_1) to mesh the sphere
|
||||||
|
algo_2D = Mesh_1.Triangle( smeshBuilder.NETGEN_1D2D, Sph_Face )
|
||||||
|
algo_2D.SetMaxSize( 70. )
|
||||||
|
algo_2D.SetFineness( smeshBuilder.Moderate )
|
||||||
|
algo_2D.SetMinSize( 7. )
|
||||||
|
|
||||||
|
# 2) Compute 2D mesh
|
||||||
|
isDone = Mesh_1.Compute()
|
||||||
|
|
||||||
|
# 3) Split quadrangles into triangles
|
||||||
|
isDone = Mesh_1.SplitQuadObject( Mesh_1, Diag13=True )
|
||||||
|
|
||||||
|
# 4) Define a 3D mesher
|
||||||
|
Mesh_1.Tetrahedron()
|
||||||
|
|
||||||
|
# 5) Compute 3D mesh
|
||||||
|
Mesh_1.Compute()
|
||||||
|
|
||||||
|
if salome.sg.hasDesktop():
|
||||||
|
salome.sg.updateObjBrowser(1)
|
@ -1,9 +1,14 @@
|
|||||||
# Use 3D extrusion meshing algorithm
|
# Use 3D extrusion meshing algorithm
|
||||||
|
|
||||||
import salome, smesh, SMESH, geompy
|
import salome
|
||||||
|
|
||||||
salome.salome_init()
|
salome.salome_init()
|
||||||
smesh.SetCurrentStudy( salome.myStudy )
|
|
||||||
|
from salome.geom import geomBuilder
|
||||||
|
geompy = geomBuilder.New(salome.myStudy)
|
||||||
|
|
||||||
|
import SMESH
|
||||||
|
from salome.smesh import smeshBuilder
|
||||||
|
smesh = smeshBuilder.New(salome.myStudy)
|
||||||
|
|
||||||
OX = geompy.MakeVectorDXDYDZ(1,0,0)
|
OX = geompy.MakeVectorDXDYDZ(1,0,0)
|
||||||
OY = geompy.MakeVectorDXDYDZ(0,1,0)
|
OY = geompy.MakeVectorDXDYDZ(0,1,0)
|
||||||
|
@ -7,10 +7,12 @@ a set of entities with a simple topology.
|
|||||||
|
|
||||||
It is possible to \subpage constructing_meshes_page "construct meshes"
|
It is possible to \subpage constructing_meshes_page "construct meshes"
|
||||||
on the basis of geometrical shapes produced in the GEOM module.
|
on the basis of geometrical shapes produced in the GEOM module.
|
||||||
It is also possible to
|
Construction of \subpage constructing_submeshes_page "sub-meshes"
|
||||||
\subpage constructing_submeshes_page "construct mesh on a part of the geometrical object",
|
allows to mesh parts of the geometrical object, for example a face,
|
||||||
for example, a face, with different meshing parameters or using
|
with different meshing parameters or using another meshing algorithm
|
||||||
another meshing algorithm.
|
than other parts.
|
||||||
|
|
||||||
|
3D mesh can be generated basing on a 2D closed mesh.
|
||||||
|
|
||||||
Several created meshes can be \subpage building_compounds_page "combined into another mesh".
|
Several created meshes can be \subpage building_compounds_page "combined into another mesh".
|
||||||
|
|
||||||
@ -62,44 +64,4 @@ described in the following way:
|
|||||||
coordinates of the corresponding vertex.</li>
|
coordinates of the corresponding vertex.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<br><h2>Connections</h2>
|
|
||||||
|
|
||||||
Each mesh entity bounds 0 or more mesh entities of higher
|
|
||||||
dimension. In the same way each mesh entity is bounded by 0 or more
|
|
||||||
mesh entities of lower dimension:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>A node bounds edges, faces and volumes</li>
|
|
||||||
<li>An edge bounds faces, and volumes</li>
|
|
||||||
<li>A face bounds volumes</li>
|
|
||||||
<li>A volume is bounded by faces, edges and nodes</li>
|
|
||||||
<li>A face is bounded by edges, and nodes</li>
|
|
||||||
<li>An edge is bounded by nodes</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
You can notice that there are two types of connections: \b inverse and
|
|
||||||
\b direct connections.
|
|
||||||
|
|
||||||
<br><h2>Inverse connections</h2>
|
|
||||||
|
|
||||||
This relationship has a particularity that the order of bounded
|
|
||||||
entities has not a direct meaning. Also the number of bounded entities
|
|
||||||
is not fixed.
|
|
||||||
|
|
||||||
\b Example: The edges surrounding a node. The 3rd edge has no more
|
|
||||||
sense that the 5th one.
|
|
||||||
|
|
||||||
<br><h2>Direct connections</h2>
|
|
||||||
|
|
||||||
This relationship has a particularity that the order of bounding
|
|
||||||
entities is meaningful. The number of bounding entities is fixed and
|
|
||||||
depends on the type of the entity (hexahedron, tetrahedron,?).
|
|
||||||
|
|
||||||
\b Example: An edge is composed of two nodes. A face is composed of 3
|
|
||||||
or 4 edges depending if we are dealing with triangles or quadrangles.
|
|
||||||
|
|
||||||
The connections are not only restricted to entities of one dimension
|
|
||||||
higher or lower. For example some algorithms may be interested to
|
|
||||||
retrieve all the faces surrounding a node.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -52,15 +52,15 @@ geometrical objects.
|
|||||||
|
|
||||||
There is also a number of more specific algorithms:
|
There is also a number of more specific algorithms:
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>\subpage prism_3d_algo_page "for meshing prismatic shapes"</li>
|
||||||
<li>\subpage projection_algos_page "for meshing by projection of another mesh"</li>
|
<li>\subpage projection_algos_page "for meshing by projection of another mesh"</li>
|
||||||
<li>\subpage import_algos_page "for meshing by importing elements from another mesh"</li>
|
<li>\subpage import_algos_page "for meshing by importing elements from another mesh"</li>
|
||||||
<li>\subpage radial_prism_algo_page "for meshing geometrical objects with cavities"</li>
|
<li>\subpage radial_prism_algo_page "for meshing geometrical objects with cavities"</li>
|
||||||
<li>\subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"</li>
|
|
||||||
<li>\subpage prism_3d_algo_page "for meshing prismatic shapes"</li>
|
|
||||||
<li>\subpage radial_quadrangle_1D2D_algo_page "for meshing special 2d faces (circles and part of circles)"</li>
|
<li>\subpage radial_quadrangle_1D2D_algo_page "for meshing special 2d faces (circles and part of circles)"</li>
|
||||||
<li>\subpage use_existing_page "Use Edges to be Created Manually" and
|
<li>\subpage use_existing_page "Use Edges to be Created Manually" and
|
||||||
\ref use_existing_page "Use Faces to be Created Manually" algorithms can be
|
\ref use_existing_page "Use Faces to be Created Manually" algorithms can be
|
||||||
used to create a 1D or a 2D mesh in a python script.</li>
|
used to create a 1D or a 2D mesh in a python script.</li>
|
||||||
|
<li>\subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
\ref constructing_meshes_page "Constructing meshes" page describes in
|
\ref constructing_meshes_page "Constructing meshes" page describes in
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
<li> \ref preview_anchor "Previewing the mesh" (optional)</li>
|
<li> \ref preview_anchor "Previewing the mesh" (optional)</li>
|
||||||
<li> \ref submesh_order_anchor "Changing sub-mesh priority" (optional)</li>
|
<li> \ref submesh_order_anchor "Changing sub-mesh priority" (optional)</li>
|
||||||
<li> \ref compute_anchor "Computing the mesh"</li>
|
<li> \ref compute_anchor "Computing the mesh"</li>
|
||||||
|
<li> \ref edit_anchor "Editing the mesh" (optional)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
\anchor create_mesh_anchor
|
\anchor create_mesh_anchor
|
||||||
@ -357,8 +358,29 @@ computation reporting. There are the following possibilities: always
|
|||||||
show the information box, show only if an error occurs or never.
|
show the information box, show only if an error occurs or never.
|
||||||
By default, the information box is always shown after mesh computation operation.
|
By default, the information box is always shown after mesh computation operation.
|
||||||
|
|
||||||
<br><br>
|
<p><p>
|
||||||
|
\anchor edit_anchor
|
||||||
|
<h2>Editing the mesh</h2>
|
||||||
|
|
||||||
|
It is possible to \ref modifying_meshes_page "edit the mesh" of
|
||||||
|
lower dimension before generation of mesh of higher dimension.
|
||||||
|
|
||||||
|
For example you can generate 2D mesh, modify it using e.g.
|
||||||
|
\ref pattern_mapping_page, and then generate 3D mesh basing on the
|
||||||
|
modified 2D mesh. The workflow is following:
|
||||||
|
- Define 1D and 2D meshing algorithms.
|
||||||
|
- Compute the mesh. 2D mesh is generated.
|
||||||
|
- Apply \ref pattern_mapping_page.
|
||||||
|
- Define 3D meshing algorithms without modifying 1D and 2D algorithms
|
||||||
|
and hypotheses.
|
||||||
|
- Compute the mesh. 3D mesh is generated.
|
||||||
|
|
||||||
|
\note Nodes and elements added \ref adding_nodes_and_elements_page
|
||||||
|
"manually" can't be used in this workflow because the manually created
|
||||||
|
entities are not attached to any geometry and thus (usually) can't be
|
||||||
|
found by a mesher paving some geometry.
|
||||||
|
|
||||||
|
<b>See Also</b> a sample TUI Script demonstrates the possibility of
|
||||||
|
\ref tui_editing_while_meshing "Intermediate edition while meshing"
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -51,6 +51,11 @@ or vice versa.</li>
|
|||||||
<li>\subpage cut_mesh_by_plane_page "Cut a tetrahedron mesh by a plane".</li>
|
<li>\subpage cut_mesh_by_plane_page "Cut a tetrahedron mesh by a plane".</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
It is possible to \ref edit_anchor "modify the mesh" of lower
|
||||||
|
dimension before generation of mesh of higher dimension.
|
||||||
|
|
||||||
|
<p><br></p>
|
||||||
|
|
||||||
\note It is possible to use the variables defined in the SALOME \b NoteBook
|
\note It is possible to use the variables defined in the SALOME \b NoteBook
|
||||||
to specify the numerical parameters used for modification of any object.
|
to specify the numerical parameters used for modification of any object.
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ The smp file contains 4 sections:
|
|||||||
|
|
||||||
-# The first line indicates the total number of pattern nodes (N).
|
-# The first line indicates the total number of pattern nodes (N).
|
||||||
-# The next N lines describe nodes coordinates. Each line contains 2
|
-# The next N lines describe nodes coordinates. Each line contains 2
|
||||||
node coordinates for a 2D pattern or 3 node cordinates for a 3D pattern.
|
node coordinates for a 2D pattern or 3 node coordinates for a 3D pattern.
|
||||||
Note, that node coordinates of a 3D pattern can be defined only by relative values in range [0;1].
|
Note, that node coordinates of a 3D pattern can be defined only by relative values in range [0;1].
|
||||||
-# The key-points line contains the indices of the nodes to be mapped on geometrical
|
-# The key-points line contains the indices of the nodes to be mapped on geometrical
|
||||||
vertices (for a 2D pattern only). Index n refers to the node described
|
vertices (for a 2D pattern only). Index n refers to the node described
|
||||||
@ -89,7 +89,7 @@ An example of a simple 3D pattern smp file:
|
|||||||
|
|
||||||
<br><h2>Application of pattern mapping</h2>
|
<br><h2>Application of pattern mapping</h2>
|
||||||
|
|
||||||
<em>To apply pattern mapping to a geometrical object:</em>
|
<em>To apply pattern mapping to a geometrical object or mesh elements:</em>
|
||||||
|
|
||||||
From the \b Modification menu choose the <b>Pattern Mapping</b> item or click
|
From the \b Modification menu choose the <b>Pattern Mapping</b> item or click
|
||||||
<em>"Pattern mapping"</em> button in the toolbar.
|
<em>"Pattern mapping"</em> button in the toolbar.
|
||||||
@ -113,16 +113,17 @@ created manually or generated automatically from an existing mesh or submesh.</l
|
|||||||
boundaries of the pattern must also be equal to the number of vertices
|
boundaries of the pattern must also be equal to the number of vertices
|
||||||
on internal boundaries of the face;</li>
|
on internal boundaries of the face;</li>
|
||||||
<li> \b Vertex to which the first key-point should be mapped;</li>
|
<li> \b Vertex to which the first key-point should be mapped;</li>
|
||||||
|
</ul>
|
||||||
Alternatively, it is possible to select <b>Refine selected mesh elements</b>
|
Alternatively, it is possible to select <b>Refine selected mesh elements</b>
|
||||||
checkbox and apply the pattern to
|
check-box and apply the pattern to <ul>
|
||||||
<li> <b>Mesh Face</b> instead of a geometric Face</li>
|
<li> <b>Mesh Face</b> instead of a geometric Face</li>
|
||||||
<li> and select \b Node instead of vertex.</li>
|
<li> and select \b Node instead of vertex.</li>
|
||||||
|
</ul>
|
||||||
Additionally it is possible to:
|
Additionally it is possible to: <ul>
|
||||||
<li> <b>Reverse the order of key-points</b> By default, the vertices of
|
<li> <b>Reverse the order of key-points</b>. By default, the vertices of
|
||||||
a face are ordered counterclockwise.<li>
|
a face are ordered counterclockwise.</li>
|
||||||
<li> Enable to <b> Create polygons near boundary</b> </li>
|
<li> Enable to <b> Create polygons near boundary</b> </li>
|
||||||
<li> and <b>Create polyhedrons near boundary</b><li>
|
<li> and <b>Create polyhedrons near boundary</b></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
\n For a <b>3D pattern</b>
|
\n For a <b>3D pattern</b>
|
||||||
@ -133,21 +134,27 @@ In this dialog you should specify:
|
|||||||
<ul>
|
<ul>
|
||||||
<li> \b Pattern, which can be loaded from .smp pattern file previously
|
<li> \b Pattern, which can be loaded from .smp pattern file previously
|
||||||
created manually or generated automatically from an existing mesh or submesh.</li>
|
created manually or generated automatically from an existing mesh or submesh.</li>
|
||||||
<li> A 3D block (Solid) object;</li>
|
<li> A 3D block (Solid) object.</li>
|
||||||
<li> Two vertices that specify the order of nodes in the resulting mesh.</li>
|
<li> Two vertices that specify the order of nodes in the resulting
|
||||||
|
mesh.</li>
|
||||||
|
</ul>
|
||||||
Alternatively, it is possible to select <b>Refine selected mesh elements</b>
|
Alternatively, it is possible to select <b>Refine selected mesh elements</b>
|
||||||
checkbox and apply the pattern to
|
checkbox and apply the pattern to
|
||||||
|
<ul>
|
||||||
<li> One or several <b>Mesh volumes</b> instead of a geometric 3D
|
<li> One or several <b>Mesh volumes</b> instead of a geometric 3D
|
||||||
object</li>
|
object</li>
|
||||||
<li> and select two /b Nodes instead of vertices.</li>
|
<li> and select two /b Nodes instead of vertices.</li>
|
||||||
|
</ul>
|
||||||
Additionally it is possible to:
|
Additionally it is possible to:
|
||||||
|
<ul>
|
||||||
<li> Enable to <b> Create polygons near boundary</b> </li>
|
<li> Enable to <b> Create polygons near boundary</b> </li>
|
||||||
<li> and <b>Create polyhedrons near boundary</b><li>
|
<li> and <b>Create polyhedrons near boundary</b></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
\n Automatic Generation
|
<br>
|
||||||
|
<h3> Automatic Generation </h3>
|
||||||
|
|
||||||
To generate a pattern automatically from an existing mesh or submesh,
|
To generate a pattern automatically from an existing mesh or sub-mesh,
|
||||||
click \b New button.
|
click \b New button.
|
||||||
|
|
||||||
The following dialog box will appear:
|
The following dialog box will appear:
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
<h2>Change priority of submeshes in Mesh</h2>
|
<h2>Change priority of submeshes in Mesh</h2>
|
||||||
\tui_script{creating_meshes_ex03.py}
|
\tui_script{creating_meshes_ex03.py}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
\anchor tui_editing_while_meshing
|
||||||
|
<h2>Intermediate edition while meshing</h2>
|
||||||
|
\tui_script{a3DmeshOnModified2Dmesh.py}
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
\anchor tui_editing_mesh
|
\anchor tui_editing_mesh
|
||||||
<h2>Editing a mesh</h2>
|
<h2>Editing a mesh</h2>
|
||||||
|
@ -4251,11 +4251,11 @@ void BelongToGeom::init()
|
|||||||
myIsSubshape = IsSubShape(aMap, myShape);
|
myIsSubshape = IsSubShape(aMap, myShape);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myIsSubshape)
|
//if (!myIsSubshape) // to be always ready to check an element not bound to geometry
|
||||||
{
|
{
|
||||||
myElementsOnShapePtr.reset(new ElementsOnShape());
|
myElementsOnShapePtr.reset(new ElementsOnShape());
|
||||||
myElementsOnShapePtr->SetTolerance(myTolerance);
|
myElementsOnShapePtr->SetTolerance(myTolerance);
|
||||||
myElementsOnShapePtr->SetAllNodes(true); // belong, while false means "lays on"
|
myElementsOnShapePtr->SetAllNodes(true); // "belong", while false means "lays on"
|
||||||
myElementsOnShapePtr->SetMesh(myMeshDS);
|
myElementsOnShapePtr->SetMesh(myMeshDS);
|
||||||
myElementsOnShapePtr->SetShape(myShape, myType);
|
myElementsOnShapePtr->SetShape(myShape, myType);
|
||||||
}
|
}
|
||||||
@ -4296,36 +4296,43 @@ bool BelongToGeom::IsSatisfy (long theId)
|
|||||||
{
|
{
|
||||||
if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
|
if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
|
||||||
{
|
{
|
||||||
|
if ( aNode->getshapeId() < 1 )
|
||||||
|
return myElementsOnShapePtr->IsSatisfy(theId);
|
||||||
|
|
||||||
const SMDS_PositionPtr& aPosition = aNode->GetPosition();
|
const SMDS_PositionPtr& aPosition = aNode->GetPosition();
|
||||||
SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
|
SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
|
||||||
switch( aTypeOfPosition )
|
switch( aTypeOfPosition )
|
||||||
{
|
{
|
||||||
case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
|
case SMDS_TOP_VERTEX : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX ));
|
||||||
case SMDS_TOP_EDGE : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
|
case SMDS_TOP_EDGE : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE ));
|
||||||
case SMDS_TOP_FACE : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
|
case SMDS_TOP_FACE : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_FACE ));
|
||||||
case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
|
case SMDS_TOP_3DSPACE: return ( IsContains( myMeshDS,myShape,aNode,TopAbs_SOLID ) ||
|
||||||
|
IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
|
if ( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ))
|
||||||
{
|
{
|
||||||
|
if ( anElem->getshapeId() < 1 )
|
||||||
|
return myElementsOnShapePtr->IsSatisfy(theId);
|
||||||
|
|
||||||
if( myType == SMDSAbs_All )
|
if( myType == SMDSAbs_All )
|
||||||
{
|
{
|
||||||
return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
|
return ( IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
|
||||||
IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
|
IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
|
||||||
IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
|
IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID )||
|
||||||
IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
|
IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL ));
|
||||||
}
|
}
|
||||||
else if( myType == anElem->GetType() )
|
else if( myType == anElem->GetType() )
|
||||||
{
|
{
|
||||||
switch( myType )
|
switch( myType )
|
||||||
{
|
{
|
||||||
case SMDSAbs_Edge : return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE );
|
case SMDSAbs_Edge : return ( IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ));
|
||||||
case SMDSAbs_Face : return IsContains( myMeshDS,myShape,anElem,TopAbs_FACE );
|
case SMDSAbs_Face : return ( IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ));
|
||||||
case SMDSAbs_Volume: return IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
|
case SMDSAbs_Volume: return ( IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID )||
|
||||||
IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
|
IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,20 +82,25 @@ namespace SMESH
|
|||||||
return GEOM::GEOM_Object::_nil();
|
return GEOM::GEOM_Object::_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
GEOM::GEOM_Object_ptr GetGeom (_PTR(SObject) theSO)
|
GEOM::GEOM_Object_var GetGeom (_PTR(SObject) theSO)
|
||||||
{
|
{
|
||||||
|
GEOM::GEOM_Object_var aMeshShape;
|
||||||
if (!theSO)
|
if (!theSO)
|
||||||
return GEOM::GEOM_Object::_nil();
|
return aMeshShape;
|
||||||
|
|
||||||
|
CORBA::Object_var obj = _CAST( SObject,theSO )->GetObject();
|
||||||
|
aMeshShape = GEOM::GEOM_Object::_narrow( obj );
|
||||||
|
if ( !aMeshShape->_is_nil() )
|
||||||
|
return aMeshShape;
|
||||||
|
|
||||||
_PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
|
_PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
|
||||||
if (!aStudy)
|
if (!aStudy)
|
||||||
return GEOM::GEOM_Object::_nil();
|
return aMeshShape;
|
||||||
|
|
||||||
_PTR(ChildIterator) anIter (aStudy->NewChildIterator(theSO));
|
_PTR(ChildIterator) anIter (aStudy->NewChildIterator(theSO));
|
||||||
for ( ; anIter->More(); anIter->Next()) {
|
for ( ; anIter->More(); anIter->Next()) {
|
||||||
_PTR(SObject) aSObject = anIter->Value();
|
_PTR(SObject) aSObject = anIter->Value();
|
||||||
_PTR(SObject) aRefSOClient;
|
_PTR(SObject) aRefSOClient;
|
||||||
GEOM::GEOM_Object_var aMeshShape;
|
|
||||||
|
|
||||||
if (aSObject->ReferencedObject(aRefSOClient)) {
|
if (aSObject->ReferencedObject(aRefSOClient)) {
|
||||||
SALOMEDS_SObject* aRefSO = _CAST(SObject,aRefSOClient);
|
SALOMEDS_SObject* aRefSO = _CAST(SObject,aRefSOClient);
|
||||||
@ -104,11 +109,10 @@ namespace SMESH
|
|||||||
SALOMEDS_SObject* aSO = _CAST(SObject,aSObject);
|
SALOMEDS_SObject* aSO = _CAST(SObject,aSObject);
|
||||||
aMeshShape = GEOM::GEOM_Object::_narrow(aSO->GetObject());
|
aMeshShape = GEOM::GEOM_Object::_narrow(aSO->GetObject());
|
||||||
}
|
}
|
||||||
|
if ( !aMeshShape->_is_nil() )
|
||||||
if (!aMeshShape->_is_nil())
|
return aMeshShape;
|
||||||
return aMeshShape._retn();
|
|
||||||
}
|
}
|
||||||
return GEOM::GEOM_Object::_nil();
|
return aMeshShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMESHGUI_EXPORT char* GetGeomName( _PTR(SObject) smeshSO )
|
SMESHGUI_EXPORT char* GetGeomName( _PTR(SObject) smeshSO )
|
||||||
|
@ -47,7 +47,7 @@ namespace SMESH
|
|||||||
|
|
||||||
SMESHGUI_EXPORT GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh( _PTR(SObject), bool* isMesh=0 );
|
SMESHGUI_EXPORT GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh( _PTR(SObject), bool* isMesh=0 );
|
||||||
|
|
||||||
SMESHGUI_EXPORT GEOM::GEOM_Object_ptr GetGeom( _PTR(SObject) );
|
SMESHGUI_EXPORT GEOM::GEOM_Object_var GetGeom( _PTR(SObject) );
|
||||||
|
|
||||||
SMESHGUI_EXPORT char* GetGeomName( _PTR(SObject) smeshSO );
|
SMESHGUI_EXPORT char* GetGeomName( _PTR(SObject) smeshSO );
|
||||||
|
|
||||||
|
@ -511,10 +511,14 @@ namespace SMESH
|
|||||||
|
|
||||||
return SMESH::SMESH_Hypothesis::_nil();
|
return SMESH::SMESH_Hypothesis::_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsApplicable(const QString& aHypType,
|
bool IsApplicable(const QString& aHypType,
|
||||||
GEOM::GEOM_Object_ptr theGeomObject,
|
GEOM::GEOM_Object_ptr theGeomObject,
|
||||||
const bool toCheckAll)
|
const bool toCheckAll)
|
||||||
{
|
{
|
||||||
|
if ( getenv("NO_LIMIT_ALGO_BY_SHAPE")) // allow a workaround for a case if
|
||||||
|
return true; // IsApplicable() returns false due to a bug
|
||||||
|
|
||||||
HypothesisData* aHypData = GetHypothesisData(aHypType);
|
HypothesisData* aHypData = GetHypothesisData(aHypType);
|
||||||
QString aServLib = aHypData->ServerLibName;
|
QString aServLib = aHypData->ServerLibName;
|
||||||
return SMESHGUI::GetSMESHGen()->IsApplicable( aHypType.toLatin1().data(),
|
return SMESHGUI::GetSMESHGen()->IsApplicable( aHypType.toLatin1().data(),
|
||||||
|
@ -247,8 +247,9 @@ void SMESHGUI_MeshOp::startOperation()
|
|||||||
myDlg->activateObject( myIsMesh ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Mesh );
|
myDlg->activateObject( myIsMesh ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Mesh );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
myDlg->activateObject( SMESHGUI_MeshDlg::Obj );
|
myDlg->activateObject( SMESHGUI_MeshDlg::Obj );
|
||||||
|
}
|
||||||
myDlg->setCurrentTab( SMESH::DIM_3D );
|
myDlg->setCurrentTab( SMESH::DIM_3D );
|
||||||
|
|
||||||
QStringList TypeMeshList;
|
QStringList TypeMeshList;
|
||||||
@ -2614,11 +2615,11 @@ void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theI
|
|||||||
|
|
||||||
bool toCheckIsApplicableToAll = !myIsMesh;
|
bool toCheckIsApplicableToAll = !myIsMesh;
|
||||||
GEOM::GEOM_Object_var aGeomVar;
|
GEOM::GEOM_Object_var aGeomVar;
|
||||||
QString anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
|
QString anEntry =
|
||||||
|
myDlg->selectedObject( myToCreate ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Obj );
|
||||||
if ( _PTR(SObject) so = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
|
if ( _PTR(SObject) so = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
|
||||||
{
|
{
|
||||||
CORBA::Object_var obj = _CAST( SObject,so )->GetObject();
|
aGeomVar = SMESH::GetGeom( so );
|
||||||
aGeomVar = GEOM::GEOM_Object::_narrow( obj );
|
|
||||||
if ( !aGeomVar->_is_nil() && toCheckIsApplicableToAll )
|
if ( !aGeomVar->_is_nil() && toCheckIsApplicableToAll )
|
||||||
toCheckIsApplicableToAll = ( aGeomVar->GetType() == GEOM_GROUP );
|
toCheckIsApplicableToAll = ( aGeomVar->GetType() == GEOM_GROUP );
|
||||||
}
|
}
|
||||||
|
@ -4280,16 +4280,17 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
|||||||
vMap.Add( (*a2v).second );
|
vMap.Add( (*a2v).second );
|
||||||
|
|
||||||
// check if there are possible variations in choosing corners
|
// check if there are possible variations in choosing corners
|
||||||
bool isThereVariants = false;
|
bool haveVariants = false;
|
||||||
if ( vertexByAngle.size() > nbCorners )
|
if ( vertexByAngle.size() > nbCorners )
|
||||||
{
|
{
|
||||||
double lostAngle = a2v->first;
|
double lostAngle = a2v->first;
|
||||||
double lastAngle = ( --a2v, a2v->first );
|
double lastAngle = ( --a2v, a2v->first );
|
||||||
isThereVariants = ( lostAngle * 1.1 >= lastAngle );
|
haveVariants = ( lostAngle * 1.1 >= lastAngle );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const double angleTol = 5.* M_PI/180;
|
||||||
myCheckOri = ( vertexByAngle.size() > nbCorners ||
|
myCheckOri = ( vertexByAngle.size() > nbCorners ||
|
||||||
vertexByAngle.begin()->first < 5.* M_PI/180 );
|
vertexByAngle.begin()->first < angleTol );
|
||||||
|
|
||||||
// make theWire begin from a corner vertex or triaVertex
|
// make theWire begin from a corner vertex or triaVertex
|
||||||
if ( nbCorners == 3 )
|
if ( nbCorners == 3 )
|
||||||
@ -4306,9 +4307,10 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
|||||||
vector< double > angles;
|
vector< double > angles;
|
||||||
vector< TopoDS_Edge > edgeVec;
|
vector< TopoDS_Edge > edgeVec;
|
||||||
vector< int > cornerInd, nbSeg;
|
vector< int > cornerInd, nbSeg;
|
||||||
angles.reserve( vertexByAngle.size() );
|
int nbSegTot = 0;
|
||||||
|
angles .reserve( vertexByAngle.size() );
|
||||||
edgeVec.reserve( vertexByAngle.size() );
|
edgeVec.reserve( vertexByAngle.size() );
|
||||||
nbSeg.reserve( vertexByAngle.size() );
|
nbSeg .reserve( vertexByAngle.size() );
|
||||||
cornerInd.reserve( nbCorners );
|
cornerInd.reserve( nbCorners );
|
||||||
for ( edge = theWire.begin(); edge != theWire.end(); ++edge )
|
for ( edge = theWire.begin(); edge != theWire.end(); ++edge )
|
||||||
{
|
{
|
||||||
@ -4321,105 +4323,219 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
|||||||
theVertices.push_back( v );
|
theVertices.push_back( v );
|
||||||
cornerInd.push_back( angles.size() );
|
cornerInd.push_back( angles.size() );
|
||||||
}
|
}
|
||||||
angles.push_back( angleByVertex.IsBound( v ) ? angleByVertex( v ) : -M_PI );
|
angles .push_back( angleByVertex.IsBound( v ) ? angleByVertex( v ) : -M_PI );
|
||||||
edgeVec.push_back( *edge );
|
edgeVec.push_back( *edge );
|
||||||
if ( theConsiderMesh && isThereVariants )
|
if ( theConsiderMesh && haveVariants )
|
||||||
{
|
{
|
||||||
if ( SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( *edge ))
|
if ( SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( *edge ))
|
||||||
nbSeg.push_back( sm->NbNodes() + 1 );
|
nbSeg.push_back( sm->NbNodes() + 1 );
|
||||||
else
|
else
|
||||||
nbSeg.push_back( 0 );
|
nbSeg.push_back( 0 );
|
||||||
|
nbSegTot += nbSeg.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// refine the result vector - make sides elual by length if
|
// refine the result vector - make sides equal by length if
|
||||||
// there are several equal angles
|
// there are several equal angles
|
||||||
if ( isThereVariants )
|
if ( haveVariants )
|
||||||
{
|
{
|
||||||
if ( nbCorners == 3 )
|
if ( nbCorners == 3 )
|
||||||
angles[0] = 2 * M_PI; // not to move the base triangle VERTEX
|
angles[0] = 2 * M_PI; // not to move the base triangle VERTEX
|
||||||
|
|
||||||
set< int > refinedCorners;
|
// here we refer to VERTEX'es and EDGEs by indices in angles and edgeVec vectors
|
||||||
|
typedef int TGeoIndex;
|
||||||
|
|
||||||
|
// for each vertex find a vertex till which there are nbSegHalf segments
|
||||||
|
const int nbSegHalf = ( nbSegTot % 2 || nbCorners == 3 ) ? 0 : nbSegTot / 2;
|
||||||
|
vector< TGeoIndex > halfDivider( angles.size(), -1 );
|
||||||
|
int nbHalfDividers = 0;
|
||||||
|
if ( nbSegHalf )
|
||||||
|
{
|
||||||
|
// get min angle of corners
|
||||||
|
double minAngle = 10.;
|
||||||
|
for ( size_t iC = 0; iC < cornerInd.size(); ++iC )
|
||||||
|
minAngle = Min( minAngle, angles[ cornerInd[ iC ]]);
|
||||||
|
|
||||||
|
// find halfDivider's
|
||||||
|
for ( TGeoIndex iV1 = 0; iV1 < TGeoIndex( angles.size() ); ++iV1 )
|
||||||
|
{
|
||||||
|
int nbSegs = 0;
|
||||||
|
TGeoIndex iV2 = iV1;
|
||||||
|
do {
|
||||||
|
nbSegs += nbSeg[ iV2 ];
|
||||||
|
iV2 = helper.WrapIndex( iV2 + 1, nbSeg.size() );
|
||||||
|
} while ( nbSegs < nbSegHalf );
|
||||||
|
|
||||||
|
if ( nbSegs == nbSegHalf &&
|
||||||
|
angles[ iV1 ] + angleTol >= minAngle &&
|
||||||
|
angles[ iV2 ] + angleTol >= minAngle )
|
||||||
|
{
|
||||||
|
halfDivider[ iV1 ] = iV2;
|
||||||
|
++nbHalfDividers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set< TGeoIndex > refinedCorners, treatedCorners;
|
||||||
for ( size_t iC = 0; iC < cornerInd.size(); ++iC )
|
for ( size_t iC = 0; iC < cornerInd.size(); ++iC )
|
||||||
{
|
{
|
||||||
int iV = cornerInd[iC];
|
TGeoIndex iV = cornerInd[iC];
|
||||||
if ( !refinedCorners.insert( iV ).second )
|
if ( !treatedCorners.insert( iV ).second )
|
||||||
continue;
|
continue;
|
||||||
list< int > equalVertices;
|
list< TGeoIndex > equVerts; // inds of vertices that can become corners
|
||||||
equalVertices.push_back( iV );
|
equVerts.push_back( iV );
|
||||||
int nbC[2] = { 0, 0 };
|
int nbC[2] = { 0, 0 };
|
||||||
// find equal angles backward and forward from the iV-th corner vertex
|
// find equal angles backward and forward from the iV-th corner vertex
|
||||||
for ( int isFwd = 0; isFwd < 2; ++isFwd )
|
for ( int isFwd = 0; isFwd < 2; ++isFwd )
|
||||||
{
|
{
|
||||||
int dV = isFwd ? +1 : -1;
|
int dV = isFwd ? +1 : -1;
|
||||||
int iCNext = helper.WrapIndex( iC + dV, cornerInd.size() );
|
int iCNext = helper.WrapIndex( iC + dV, cornerInd.size() );
|
||||||
int iVNext = helper.WrapIndex( iV + dV, angles.size() );
|
TGeoIndex iVNext = helper.WrapIndex( iV + dV, angles.size() );
|
||||||
while ( iVNext != iV )
|
while ( iVNext != iV )
|
||||||
{
|
{
|
||||||
bool equal = Abs( angles[iV] - angles[iVNext] ) < 0.1 * angles[iV];
|
bool equal = Abs( angles[iV] - angles[iVNext] ) < angleTol;
|
||||||
if ( equal )
|
if ( equal )
|
||||||
equalVertices.insert( isFwd ? equalVertices.end() : equalVertices.begin(), iVNext );
|
equVerts.insert( isFwd ? equVerts.end() : equVerts.begin(), iVNext );
|
||||||
if ( iVNext == cornerInd[ iCNext ])
|
if ( iVNext == cornerInd[ iCNext ])
|
||||||
{
|
{
|
||||||
if ( !equal )
|
if ( !equal )
|
||||||
|
{
|
||||||
|
if ( angles[iV] < angles[iVNext] )
|
||||||
|
refinedCorners.insert( iVNext );
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
nbC[ isFwd ]++;
|
nbC[ isFwd ]++;
|
||||||
refinedCorners.insert( cornerInd[ iCNext ] );
|
treatedCorners.insert( cornerInd[ iCNext ] );
|
||||||
iCNext = helper.WrapIndex( iCNext + dV, cornerInd.size() );
|
iCNext = helper.WrapIndex( iCNext + dV, cornerInd.size() );
|
||||||
}
|
}
|
||||||
iVNext = helper.WrapIndex( iVNext + dV, angles.size() );
|
iVNext = helper.WrapIndex( iVNext + dV, angles.size() );
|
||||||
}
|
}
|
||||||
|
if ( iVNext == iV )
|
||||||
|
break; // all angles equal
|
||||||
}
|
}
|
||||||
// move corners to make sides equal by length
|
|
||||||
int nbEqualV = equalVertices.size();
|
const bool allCornersSame = ( nbC[0] == 3 );
|
||||||
int nbExcessV = nbEqualV - ( 1 + nbC[0] + nbC[1] );
|
if ( allCornersSame && nbHalfDividers > 0 )
|
||||||
if ( nbExcessV > 0 )
|
|
||||||
{
|
{
|
||||||
// calculate normalized length of each side enclosed between neighbor equalVertices
|
// select two halfDivider's as corners
|
||||||
vector< double > curLengths;
|
TGeoIndex hd1, hd2 = -1;
|
||||||
double totalLen = 0;
|
int iC2;
|
||||||
vector< int > evVec( equalVertices.begin(), equalVertices.end() );
|
for ( iC2 = 0; iC2 < cornerInd.size() && hd2 < 0; ++iC2 )
|
||||||
int iEV = 0;
|
|
||||||
int iE = cornerInd[ helper.WrapIndex( iC - nbC[0] - 1, cornerInd.size() )];
|
|
||||||
int iEEnd = cornerInd[ helper.WrapIndex( iC + nbC[1] + 1, cornerInd.size() )];
|
|
||||||
while ( curLengths.size() < nbEqualV + 1 )
|
|
||||||
{
|
{
|
||||||
curLengths.push_back( totalLen );
|
hd1 = cornerInd[ iC2 ];
|
||||||
|
hd2 = halfDivider[ hd1 ];
|
||||||
|
if ( std::find( equVerts.begin(), equVerts.end(), hd2 ) == equVerts.end() )
|
||||||
|
hd2 = -1; // hd2-th vertex can't become a corner
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( hd2 >= 0 )
|
||||||
|
{
|
||||||
|
angles[ hd1 ] = 2 * M_PI; // make hd1-th vertex no more "equal"
|
||||||
|
angles[ hd2 ] = 2 * M_PI;
|
||||||
|
refinedCorners.insert( hd1 );
|
||||||
|
refinedCorners.insert( hd2 );
|
||||||
|
treatedCorners = refinedCorners;
|
||||||
|
// update cornerInd
|
||||||
|
equVerts.push_front( equVerts.back() );
|
||||||
|
equVerts.push_back( equVerts.front() );
|
||||||
|
list< TGeoIndex >::iterator hdPos =
|
||||||
|
std::find( equVerts.begin(), equVerts.end(), hd2 );
|
||||||
|
if ( hdPos == equVerts.end() ) break;
|
||||||
|
cornerInd[ helper.WrapIndex( iC2 + 0, cornerInd.size()) ] = hd1;
|
||||||
|
cornerInd[ helper.WrapIndex( iC2 + 1, cornerInd.size()) ] = *( --hdPos );
|
||||||
|
cornerInd[ helper.WrapIndex( iC2 + 2, cornerInd.size()) ] = hd2;
|
||||||
|
cornerInd[ helper.WrapIndex( iC2 + 3, cornerInd.size()) ] = *( ++hdPos, ++hdPos );
|
||||||
|
|
||||||
|
theVertices[ 0 ] = helper.IthVertex( 0, edgeVec[ cornerInd[0] ]);
|
||||||
|
theVertices[ 1 ] = helper.IthVertex( 0, edgeVec[ cornerInd[1] ]);
|
||||||
|
theVertices[ 2 ] = helper.IthVertex( 0, edgeVec[ cornerInd[2] ]);
|
||||||
|
theVertices[ 3 ] = helper.IthVertex( 0, edgeVec[ cornerInd[3] ]);
|
||||||
|
iC = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move corners to make sides equal by length
|
||||||
|
int nbEqualV = equVerts.size();
|
||||||
|
int nbExcessV = nbEqualV - ( 1 + nbC[0] + nbC[1] );
|
||||||
|
if ( nbExcessV > 0 ) // there is nbExcessV vertices that can become corners
|
||||||
|
{
|
||||||
|
// calculate normalized length of each "side" enclosed between neighbor equVerts
|
||||||
|
vector< double > accuLength;
|
||||||
|
double totalLen = 0;
|
||||||
|
vector< TGeoIndex > evVec( equVerts.begin(), equVerts.end() );
|
||||||
|
int iEV = 0;
|
||||||
|
TGeoIndex iE = cornerInd[ helper.WrapIndex( iC - nbC[0] - 1, cornerInd.size() )];
|
||||||
|
TGeoIndex iEEnd = cornerInd[ helper.WrapIndex( iC + nbC[1] + 1, cornerInd.size() )];
|
||||||
|
while ( accuLength.size() < nbEqualV + int( !allCornersSame ) )
|
||||||
|
{
|
||||||
|
// accumulate length of edges before iEV-th equal vertex
|
||||||
|
accuLength.push_back( totalLen );
|
||||||
do {
|
do {
|
||||||
curLengths.back() += SMESH_Algo::EdgeLength( edgeVec[ iE ]);
|
accuLength.back() += SMESH_Algo::EdgeLength( edgeVec[ iE ]);
|
||||||
iE = helper.WrapIndex( iE + 1, edgeVec.size());
|
iE = helper.WrapIndex( iE + 1, edgeVec.size());
|
||||||
if ( iEV < evVec.size() && iE == evVec[ iEV++ ] )
|
if ( iEV < evVec.size() && iE == evVec[ iEV ] ) {
|
||||||
break;
|
iEV++;
|
||||||
|
break; // equal vertex reached
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while( iE != iEEnd );
|
while( iE != iEEnd );
|
||||||
totalLen = curLengths.back();
|
totalLen = accuLength.back();
|
||||||
}
|
}
|
||||||
curLengths.resize( equalVertices.size() );
|
accuLength.resize( equVerts.size() );
|
||||||
for ( size_t iS = 0; iS < curLengths.size(); ++iS )
|
for ( size_t iS = 0; iS < accuLength.size(); ++iS )
|
||||||
curLengths[ iS ] /= totalLen;
|
accuLength[ iS ] /= totalLen;
|
||||||
|
|
||||||
// find equalVertices most close to the ideal sub-division of all sides
|
// find equVerts most close to the ideal sub-division of all sides
|
||||||
int iBestEV = 0;
|
int iBestEV = 0;
|
||||||
int iCorner = helper.WrapIndex( iC - nbC[0], cornerInd.size() );
|
int iCorner = helper.WrapIndex( iC - nbC[0], cornerInd.size() );
|
||||||
int nbSides = 2 + nbC[0] + nbC[1];
|
int nbSides = Min( nbCorners, 2 + nbC[0] + nbC[1] );
|
||||||
for ( int iS = 1; iS < nbSides; ++iS, ++iBestEV )
|
for ( int iS = 1; iS < nbSides; ++iS, ++iBestEV )
|
||||||
{
|
{
|
||||||
double idealLen = iS / double( nbSides );
|
double idealLen = iS / double( nbSides );
|
||||||
double d, bestDist = 1.;
|
double d, bestDist = 2.;
|
||||||
for ( iEV = iBestEV; iEV < curLengths.size(); ++iEV )
|
for ( iEV = iBestEV; iEV < accuLength.size(); ++iEV )
|
||||||
if (( d = Abs( idealLen - curLengths[ iEV ])) < bestDist )
|
{
|
||||||
|
d = Abs( idealLen - accuLength[ iEV ]);
|
||||||
|
|
||||||
|
// take into account presence of a coresponding halfDivider
|
||||||
|
const double cornerWgt = 0.5 / nbSides;
|
||||||
|
const double vertexWgt = 0.25 / nbSides;
|
||||||
|
TGeoIndex hd = halfDivider[ evVec[ iEV ]];
|
||||||
|
if ( hd < 0 )
|
||||||
|
d += vertexWgt;
|
||||||
|
else if( refinedCorners.count( hd ))
|
||||||
|
d -= cornerWgt;
|
||||||
|
else
|
||||||
|
d -= vertexWgt;
|
||||||
|
|
||||||
|
// choose vertex with the best d
|
||||||
|
if ( d < bestDist )
|
||||||
{
|
{
|
||||||
bestDist = d;
|
bestDist = d;
|
||||||
iBestEV = iEV;
|
iBestEV = iEV;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ( iBestEV > iS-1 + nbExcessV )
|
if ( iBestEV > iS-1 + nbExcessV )
|
||||||
iBestEV = iS-1 + nbExcessV;
|
iBestEV = iS-1 + nbExcessV;
|
||||||
theVertices[ iCorner ] = helper.IthVertex( 0, edgeVec[ evVec[ iBestEV ]]);
|
theVertices[ iCorner ] = helper.IthVertex( 0, edgeVec[ evVec[ iBestEV ]]);
|
||||||
|
refinedCorners.insert( evVec[ iBestEV ]);
|
||||||
iCorner = helper.WrapIndex( iCorner + 1, cornerInd.size() );
|
iCorner = helper.WrapIndex( iCorner + 1, cornerInd.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // if ( nbExcessV > 0 )
|
||||||
|
else
|
||||||
|
{
|
||||||
|
refinedCorners.insert( cornerInd[ iC ]);
|
||||||
}
|
}
|
||||||
}
|
} // loop on cornerInd
|
||||||
}
|
|
||||||
|
// make theWire begin from the cornerInd[0]-th EDGE
|
||||||
|
while ( !theWire.front().IsSame( edgeVec[ cornerInd[0] ]))
|
||||||
|
theWire.splice( theWire.begin(), theWire, --theWire.end() );
|
||||||
|
|
||||||
|
} // if ( haveVariants )
|
||||||
|
|
||||||
return nbCorners;
|
return nbCorners;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user