bos #29628 Remove MEFISTO 2D algorithm

This commit is contained in:
vsr 2022-04-15 18:49:22 +03:00
parent b9f284f09b
commit c08606439a
55 changed files with 105 additions and 11537 deletions

View File

@ -89,13 +89,6 @@ ELSE(SMESH_USE_MESHGEMS_HYPOSET)
SET(SMESH_USE_MESHGEMS_HYPOSET_VAR "false")
ENDIF(SMESH_USE_MESHGEMS_HYPOSET)
#On Linux use Fortran to compile MEFISTO2D
IF(NOT WIN32)
ENABLE_LANGUAGE(Fortran)
SET(SALOME_SMESH_ENABLE_MEFISTO ON)
ADD_DEFINITIONS(-DENABLE_MEFISTO)
ENDIF(NOT WIN32)
MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_SMESH_USE_CGNS SALOME_SMESH_USE_TBB SALOME_SMESH_DYNLOAD_LOCAL SMESH_USE_MESHGEMS_HYPOSET)
# Prerequisites
@ -231,19 +224,6 @@ ENDIF(SALOME_SMESH_USE_TBB)
FIND_PACKAGE(SalomeMEDFile REQUIRED)
#On Windows use f2c to generate C MEFISTO2D code
IF(WIN32)
SET(SALOME_SMESH_ENABLE_MEFISTO OFF)
FIND_PACKAGE(Salomef2c QUIET)
IF(${F2C_FOUND})
ADD_DEFINITIONS(-DENABLE_MEFISTO)
SET(SALOME_SMESH_ENABLE_MEFISTO ON)
MESSAGE(STATUS "Build MEFISTO2D mesher using Fortran to C generator")
ELSE(${F2C_FOUND})
MESSAGE(FATAL "Fortran to C generator is not found: MEFISTO2D mesher cannot be compiled! Please define F2C_ROOT_DIR !")
ENDIF(${F2C_FOUND})
ENDIF(WIN32)
SET (SALOME_SMESH_DISABLE_MG_ADAPT OFF)
SET (SALOME_SMESH_DISABLE_HOMARD_ADAPT OFF)
@ -261,12 +241,6 @@ IF(SALOME_SMESH_DISABLE_HOMARD_ADAPT)
ENDIF()
IF(SALOME_SMESH_ENABLE_MEFISTO)
SET(MEFISTO2D_NAME "MEFISTO_2D")
ELSE(SALOME_SMESH_ENABLE_MEFISTO)
SET(MEFISTO2D_NAME "NOT_FOUND")
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
# Detection summary:
SALOME_PACKAGE_REPORT_AND_CHECK()
@ -359,11 +333,6 @@ SET(_${PROJECT_NAME}_exposed_targets
SPADDERPluginTesterEngine SalomeIDLSMESH SalomeIDLSPADDER
)
IF(SALOME_SMESH_ENABLE_MEFISTO)
LIST(APPEND _${PROJECT_NAME}_exposed_targets
MEFISTO2D)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
IF(SALOME_BUILD_GUI)
LIST(APPEND _${PROJECT_NAME}_exposed_targets
SMESHObject SMESHFiltersSelection SMESH PluginUtils StdMeshersGUI

View File

@ -58,15 +58,11 @@ SET(SALOME_SMESH_BUILD_TESTS @SALOME_BUILD_TESTS@)
SET(SALOME_SMESH_BUILD_GUI @SALOME_BUILD_GUI@)
SET(SALOME_SMESH_USE_CGNS @SALOME_SMESH_USE_CGNS@)
SET(SALOME_SMESH_USE_TBB @SALOME_SMESH_USE_TBB@)
SET(SALOME_SMESH_ENABLE_MEFISTO @SALOME_SMESH_ENABLE_MEFISTO@)
SET(SALOME_SMESH_DISABLE_MG_ADAPT @SALOME_SMESH_DISABLE_MG_ADAPT@)
SET(SALOME_SMESH_DISABLE_HOMARD_ADAPT @SALOME_SMESH_DISABLE_HOMARD_ADAPT@)
IF(SALOME_SMESH_DISABLE_MG_ADAPT)
LIST(APPEND SMESH_DEFINITIONS "-DDISABLE_MG_ADAPT")
ENDIF()
IF(NOT WIN32)
LIST(APPEND SMESH_DEFINITIONS "-DENABLE_MEFISTO")
ENDIF(NOT WIN32)
# Level 1 prerequisites:
SET_AND_CHECK(GEOM_ROOT_DIR_EXP "@PACKAGE_GEOM_ROOT_DIR@")
@ -145,9 +141,6 @@ SET(SMESH_MeshDriverMED MeshDriverMED)
SET(SMESH_MeshDriverSTL MeshDriverSTL)
SET(SMESH_MeshDriverUNV MeshDriverUNV)
SET(SMESH_MEDWrapper MEDWrapper)
IF(SALOME_SMESH_ENABLE_MEFISTO)
SET(SMESH_MEFISTO2D MEFISTO2D)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
SET(SMESH_SMESHObject SMESHObject)
SET(SMESH_PluginUtils PluginUtils)
SET(SMESH_SMDS SMDS)

View File

@ -97,18 +97,18 @@ class TestMesh(unittest.TestCase):
self.assertEqual(regular.GetName(), 'Regular_1D')
self.processGuiEvents()
# **** create mefisto 2d
print('...... Mefisto 2D')
mefisto = smesh.CreateHypothesis( 'MEFISTO_2D', lib )
listHyp = mefisto.GetCompatibleHypothesis()
self.assertEqual(mefisto.GetName(), 'MEFISTO_2D')
# **** create netgen 2d
print('...... Netgen 2D')
netgen = smesh.CreateHypothesis( 'NETGEN_2D', lib )
listHyp = netgen.GetCompatibleHypothesis()
self.assertEqual(netgen.GetName(), 'NETGEN_2D')
self.processGuiEvents()
# ---- create mesh on box
print('... Create mesh on box')
mesh = smesh.CreateMesh(box)
self.assertEqual(mesh.AddHypothesis(box, regular)[0], SMESH.HYP_OK)
self.assertEqual(mesh.AddHypothesis(box, mefisto)[0], SMESH.HYP_OK)
self.assertEqual(mesh.AddHypothesis(box, netgen)[0], SMESH.HYP_OK)
self.assertEqual(mesh.AddHypothesis(box, nb_segments)[0], SMESH.HYP_OK)
self.assertEqual(mesh.AddHypothesis(box, max_area)[0], SMESH.HYP_OK)
self.processGuiEvents()

View File

@ -9,50 +9,40 @@ from salome.smesh import smeshBuilder
geom_builder = geomBuilder.New()
smesh_builder = smeshBuilder.New()
Box_1 = geom_builder.MakeBoxDXDYDZ(200, 200, 200)
[Face_1,Face_2,Face_3,Face_4,Face_5,Face_6] = geom_builder.SubShapeAllSorted(Box_1, geom_builder.ShapeType["FACE"])
box = geom_builder.MakeBoxDXDYDZ(200, 200, 200)
[Face_1, Face_2, Face_3, Face_4, Face_5, Face_6] = geom_builder.SubShapeAllSorted(box, geom_builder.ShapeType["FACE"])
# create Mesh object on Box shape
Mesh_1 = smesh_builder.Mesh(Box_1)
mesh = smesh_builder.Mesh(box)
# assign mesh algorithms and hypotheses
Regular_1D = Mesh_1.Segment()
Nb_Segments_1 = Regular_1D.NumberOfSegments(20)
MEFISTO_2D = Mesh_1.Triangle()
Max_Element_Area_1 = MEFISTO_2D.MaxElementArea(1200)
Tetrahedron = Mesh_1.Tetrahedron()
Max_Element_Volume_1 = Tetrahedron.MaxElementVolume(40000)
mesh.Segment().NumberOfSegments(20)
mesh.Triangle().MaxElementArea(1200)
mesh.Tetrahedron().MaxElementVolume(40000)
# create sub-mesh and assign algorithms on Face_1
Regular_1D_1 = Mesh_1.Segment(geom=Face_1)
Nb_Segments_2 = Regular_1D_1.NumberOfSegments(4)
MEFISTO_2D_1 = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO,geom=Face_1)
SubMesh_1 = MEFISTO_2D_1.GetSubMesh()
mesh.Segment(geom=Face_1).NumberOfSegments(4)
mesh.Triangle(geom=Face_1)
# create sub-mesh and assign algorithms on Face_2
Regular_1D_2 = Mesh_1.Segment(geom=Face_2)
Nb_Segments_3 = Regular_1D_2.NumberOfSegments(8)
MEFISTO_2D_2 = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO,geom=Face_2)
SubMesh_2 = MEFISTO_2D_2.GetSubMesh()
mesh.Segment(geom=Face_2).NumberOfSegments(8)
mesh.Triangle(geom=Face_2)
# create sub-mesh and assign algorithms on Face_3
Regular_1D_3 = Mesh_1.Segment(geom=Face_3)
Nb_Segments_4 = Regular_1D_3.NumberOfSegments(12)
MEFISTO_2D_3 = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO,geom=Face_3)
SubMesh_3 = MEFISTO_2D_3.GetSubMesh()
mesh.Segment(geom=Face_3).NumberOfSegments(12)
mesh.Triangle(geom=Face_3)
# check existing sub-mesh priority order
[ [ SubMesh_1, SubMesh_3, SubMesh_2 ] ] = Mesh_1.GetMeshOrder()
isDone = Mesh_1.Compute()
print("Nb elements at initial order of sub-meshes:", Mesh_1.NbElements())
# get existing sub-mesh priority order: F1 -> F2 -> F3
[[SubMesh_F1, SubMesh_F3, SubMesh_F2]] = mesh.GetMeshOrder()
isDone = mesh.Compute()
print("Nb elements at initial order of sub-meshes:", mesh.NbElements())
# set new sub-mesh order
isDone = Mesh_1.SetMeshOrder( [ [ SubMesh_1, SubMesh_2, SubMesh_3 ] ])
# compute mesh
isDone = Mesh_1.Compute()
print("Nb elements at new order of sub-meshes:", Mesh_1.NbElements())
# set new sub-mesh order: F2 -> F1 -> F3
isDone = mesh.SetMeshOrder([[SubMesh_F2, SubMesh_F1, SubMesh_F3]])
isDone = mesh.Compute()
print("Nb elements at new order of sub-meshes:", mesh.NbElements())
# compute with other sub-mesh order
isDone = Mesh_1.SetMeshOrder( [ [ SubMesh_2, SubMesh_1, SubMesh_3 ] ])
isDone = Mesh_1.Compute()
print("Nb elements at another order of sub-meshes:", Mesh_1.NbElements())
# compute with other sub-mesh order: F3 -> F2 -> F1
isDone = mesh.SetMeshOrder([[SubMesh_F3, SubMesh_F2, SubMesh_F1]])
isDone = mesh.Compute()
print("Nb elements at another order of sub-meshes:", mesh.NbElements())

View File

@ -34,10 +34,10 @@ hexa.Compute()
# 2. Create a tetrahedral mesh on the box
tetra = smesh_builder.Mesh(box, "Box : tetrahedrical mesh")
# create a Regular 1D algorithm for edges
# create a 1D algorithm for edges
algo1D = tetra.Segment()
# create a Mefisto 2D algorithm for faces
# create a 2D algorithm for faces
algo2D = tetra.Triangle()
# create a 3D algorithm for solids

View File

@ -25,7 +25,7 @@ geom_builder.addToStudy( box, 'box' )
geom_builder.addToStudyInFather( box, Face_1, 'Face_1' )
geom_builder.addToStudyInFather( box, Face_2, 'Face_2' )
# Make the source mesh triangulated by MEFISTO
# Make the source mesh triangulated by default algorithm
src_mesh = smesh_builder.Mesh(Face_1, "Source mesh")
src_mesh.Segment().NumberOfSegments(15)
src_mesh.Triangle()

View File

@ -41,12 +41,10 @@ vec2 = geom_builder.MakeVector(Vertex_5, Vertex_6)
# meshing (we have linear tetrahedrons here, but other elements are OK)
Mesh_1 = smesh_builder.Mesh(Partition_1)
Regular_1D = Mesh_1.Segment()
Nb_Segments_1 = Regular_1D.NumberOfSegments(15)
MEFISTO_2D = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO)
Length_From_Edges_2D = MEFISTO_2D.LengthFromEdges()
ALGO3D = Mesh_1.Tetrahedron()
isDone = Mesh_1.Compute()
Mesh_1.Segment().NumberOfSegments(15)
Mesh_1.Triangle().LengthFromEdges()
Mesh_1.Tetrahedron()
Mesh_1.Compute()
# relevant groups of volumes and faces

View File

@ -14,17 +14,16 @@ smesh_builder = smeshBuilder.New()
Sphere = geom_builder.MakeSphereR( 100 )
geom_builder.addToStudy( Sphere, "Sphere" )
# create simple trihedral mesh
# create simple tetrahedral mesh
Mesh = smesh_builder.Mesh(Sphere)
Regular_1D = Mesh.Segment()
Nb_Segments = Regular_1D.NumberOfSegments(5)
MEFISTO_2D = Mesh.Triangle()
Tetrahedron = Mesh.Tetrahedron()
Mesh.Segment().NumberOfSegments(5)
Mesh.Triangle()
Mesh.Tetrahedron()
# compute mesh
isDone = Mesh.Compute()
Mesh.Compute()
# convert to quadratic
# theForce3d = 1; this results in the medium node lying at the

View File

@ -16,10 +16,8 @@ idbox = geom_builder.addToStudy(box, "box")
# create a mesh
mesh = smesh_builder.Mesh(box, "Mesh_free_nodes")
algo = mesh.Segment()
algo.NumberOfSegments(10)
algo = mesh.Triangle(smeshBuilder.MEFISTO)
algo.MaxElementArea(150.)
mesh.Segment().NumberOfSegments(10)
mesh.Triangle().MaxElementArea(150.)
mesh.Compute()
# Remove some elements to obtain free nodes

View File

@ -39,11 +39,10 @@ geom_builder.addToStudy( Plane_2, "Plane_2" )
###### SMESH part ######
Mesh_1 = smesh_builder.Mesh(Partition_1)
Regular_1D = Mesh_1.Segment()
Max_Size_1 = Regular_1D.MaxSize(34.641)
MEFISTO_2D = Mesh_1.Triangle()
Tetrahedronn = Mesh_1.Tetrahedron()
isDone = Mesh_1.Compute()
Mesh_1.Segment().MaxSize(34.641)
Mesh_1.Triangle()
Mesh_1.Tetrahedron()
Mesh_1.Compute()
# create a group of free faces
aFilter = smesh_builder.GetFilter(SMESH.FACE, SMESH.FT_FreeFaces )

View File

@ -63,7 +63,7 @@ Viscous Layers and Viscous Layers 2D
**Viscous Layers** and **Viscous Layers 2D** additional
hypotheses can be used by several 3D algorithms, for example
Hexahedron(i,j,k), or 2D algorithms, for example Triangle
(MEFISTO), correspondingly. These hypotheses allow creation of layers
(NETGEN_2D), correspondingly. These hypotheses allow creation of layers
of highly stretched elements, prisms in 3D and quadrilaterals in 2D,
near mesh boundary, which is beneficial for high quality viscous
computations.

View File

@ -19,7 +19,6 @@ An algorithm represents either an implementation of a certain meshing technique
* For meshing of 2D entities (**faces**):
* **Triangle: Mefisto** meshing algorithm - splits faces into triangular elements.
* :ref:`Quadrangle: Mapping <quad_ijk_algo_page>` meshing algorithm - splits faces into quadrangular elements.
.. image:: ../images/image123.gif

View File

@ -229,24 +229,24 @@ Choose **Change sub-mesh priority** from the **Mesh** menu or a pop-up menu. The
There is an example of sub-mesh order modifications taking a Mesh created on a Box shape. The main Mesh object:
* *1D* **Wire discretisation** with **Number of Segments** = 20
* *2D* **Triangle: Mefisto** with Hypothesis **Max Element Area**
* *2D* **Triangle** with Hypothesis **Max Element Area**
The first sub-mesh **Submesh_1** created on **Face_1** is:
* *1D* **Wire discretisation** with **Number of Segments** = 4
* *2D* **Triangle: Mefisto** with Hypothesis **MaxElementArea** = 1200
* *2D* **Triangle** with Hypothesis **MaxElementArea** = 1200
The second sub-mesh **Submesh_2** created on **Face_2** is:
* *1D* **Wire discretisation** with **Number of Segments** = 8
* *2D* **Triangle: Mefisto** with Hypothesis **MaxElementArea** = 1200
* *2D* **Triangle** with Hypothesis **MaxElementArea** = 1200
And the last sub-mesh **Submesh_3** created on **Face_3** is:
* *1D* **Wire discretisation** with **Number of Segments** = 12
* *2D* **Triangle: Mefisto** with Hypothesis **MaxElementArea** = 1200
* *2D* **Triangle** with Hypothesis **MaxElementArea** = 1200
The sub-meshes become concurrent if they share sub-shapes that can be meshed with different algorithms (or different hypotheses). In the example, we have three sub-meshes with concurrent algorithms, because they have different hypotheses.

View File

@ -102,8 +102,6 @@ Defining hypotheses
.. autosummary::
StdMeshersBuilder_Triangle_MEFISTO.MaxElementArea
StdMeshersBuilder_Triangle_MEFISTO.LengthFromEdges
StdMeshersBuilder_Quadrangle.QuadrangleParameters
StdMeshersBuilder_Quadrangle.QuadranglePreference
StdMeshersBuilder_Quadrangle.TrianglePreference

View File

@ -42,13 +42,13 @@ User Guide.
For instance::
MEFISTO_2D_1 = Mesh_1.Triangle(algo=smesh.MEFISTO,geom=Face_1)
Quadrangle_2D_1 = Mesh_1.Quadrangle(algo=smesh.QUADRANGLE,geom=Face_1)
is replaced by::
MEFISTO_2D_1 = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO,geom=Face_1)
Quadrangle_2D_1 = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE,geom=Face_1)
StdMeshers algorithms concerned are *REGULAR, PYTHON, COMPOSITE, MEFISTO, Hexa, QUADRANGLE, RADIAL_QUAD*.
StdMeshers algorithms concerned are *REGULAR, PYTHON, COMPOSITE, Hexa, QUADRANGLE, RADIAL_QUAD*.
SMESH Plugins provide such algorithms as: *NETGEN, NETGEN_FULL, FULL_NETGEN, NETGEN_1D2D3D, NETGEN_1D2D, NETGEN_2D, NETGEN_3D*.

View File

@ -42,18 +42,18 @@ A usual workflow to generate a mesh on geometry is following:
#. Create and assign :ref:`algorithms <basic_meshing_algos_page>` by calling corresponding methods of the mesh. If a sub-shape is provided as an argument, a :ref:`sub-mesh <constructing_submeshes_page>` is implicitly created on this sub-shape:
.. code-block:: python
regular1D = mesh.Segment()
mefisto = mesh.Triangle( smeshBuilder.MEFISTO )
# use other triangle algorithm on a face -- a sub-mesh appears in the mesh
netgen = mesh.Triangle( smeshBuilder.NETGEN_1D2D, face )
regular1D = mesh.Segment()
quadrangle = mesh.Quadrangle()
# use other 2D algorithm on a face -- a sub-mesh appears in the mesh
triangle = mesh.Triangle( face )
#. Create and assign :ref:`hypotheses <about_hypo_page>` by calling corresponding methods of algorithms:
.. code-block:: python
segLen10 = regular1D.LocalLength( 10. )
maxArea = mefisto.LocalLength( 100. )
netgen.SetMaxSize( 20. )
netgen.SetFineness( smeshBuilder.VeryCoarse )
regular1D.LocalLength( 10. )
quadrangle.Reduced()
triangle.SetMaxSize( 20. )
triangle.SetFineness( smeshBuilder.VeryCoarse )
#. :ref:`Compute the mesh <compute_anchor>` (generate mesh nodes and elements):
.. code-block:: python

View File

@ -19,7 +19,7 @@ and hypotheses.
* :ref:`Fixed Points 1D <tui_fixed_points>` hypothesis
* Triangle: Mefisto 2D algorithm
* Triangle: NETGEN 2D algorithm
* :ref:`tui_max_element_area` hypothesis
* :ref:`tui_length_from_edges` hypothesis

View File

@ -933,7 +933,7 @@ module StdMeshers
* interface of "Viscous Layers 2D" hypothesis.
* This hypothesis specifies parameters of layers of quadrilaterals to build
* near mesh boundary. This hypothesis can be used by several 2D algorithms:
* Mefisto, Quadrangle (mapping), NETGEN, BLSURF
* Quadrangle (mapping), NETGEN, BLSURF
*/
interface StdMeshers_ViscousLayers2D : SMESH::SMESH_Hypothesis
{
@ -1129,13 +1129,6 @@ module StdMeshers
{
};
/*!
* StdMeshers_MEFISTO_2D: interface of "Triangle (Mefisto)" algorithm
*/
interface StdMeshers_MEFISTO_2D : SMESH::SMESH_2D_Algo
{
};
/*!
* StdMeshers_Quadrangle_2D: interface of "Quadrangle (Mapping)" algorithm
*/

View File

@ -37,7 +37,7 @@ SET(SMESH_RESOURCES_FILES
mesh_add.png
mesh_add_sub.png
mesh_algo_hexa.png
mesh_algo_mefisto.png
mesh_algo_tri.png
mesh_algo_quad.png
mesh_algo_regular.png
mesh_algo_tetra.png
@ -187,7 +187,7 @@ SET(SMESH_RESOURCES_FILES
mesh_tree_algo_0D.png
mesh_tree_algo_existing_2D.png
mesh_tree_algo_hexa.png
mesh_tree_algo_mefisto.png
mesh_tree_algo_tri.png
mesh_tree_algo_polygon.png
mesh_tree_algo_prism.png
mesh_tree_algo_projection_2d.png

View File

@ -308,24 +308,6 @@
</python-wrap>
</algorithm>
<algorithm type ="@MEFISTO2D_NAME@"
label-id ="Triangle: Mefisto"
icon-id ="mesh_algo_mefisto.png"
group-id ="1"
priority ="40"
hypos ="LengthFromEdges,MaxElementArea"
opt-hypos ="ViscousLayers2D"
input ="EDGE"
output ="TRIA"
dim ="2">
<python-wrap>
<algo>MEFISTO_2D=Triangle(algo=smeshBuilder.MEFISTO)</algo>
<hypo>LengthFromEdges=LengthFromEdges()</hypo>
<hypo>MaxElementArea=MaxElementArea(SetMaxElementArea())</hypo>
<hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2),SetGroupName())</hypo>
</python-wrap>
</algorithm>
<algorithm type ="Quadrangle_2D"
label-id ="Quadrangle: Mapping"
icon-id ="mesh_algo_quad.png"

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 450 B

View File

@ -43,10 +43,6 @@ SET(SUBDIRS_COMMON
SalomeSessionless
)
IF(SALOME_SMESH_ENABLE_MEFISTO)
SET(SUBDIRS_MEFISTO2 MEFISTO2)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
##
# CGNS
##
@ -71,7 +67,6 @@ ENDIF(SALOME_BUILD_GUI)
SET(SUBDIRS
${SUBDIRS_COMMON}
${SUBDIRS_MEFISTO2}
${SUBDIRS_CGNS}
${SUBDIRS_GUI}
)

View File

@ -1,100 +0,0 @@
# Copyright (C) 2012-2021 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
# --- options ---
# additional include directories
INCLUDE_DIRECTORIES(
${KERNEL_INCLUDE_DIRS}
${OpenCASCADE_INCLUDE_DIR}
${HDF5_INCLUDE_DIRS}
${PLATFORM_INCLUDES}
)
# additional preprocessor / compiler flags
ADD_DEFINITIONS(
${OpenCASCADE_DEFINITIONS}
)
# libraries to link to
SET(_link_LIBRARIES
${OpenCASCADE_FoundationClasses_LIBRARIES}
${KERNEL_SALOMELocalTrace}
)
# --- headers ---
# header files / no moc processing
SET(MEFISTO2D_HEADERS
aptrte.h
Rn.h
)
# --- sources ---
IF(${F2C_FOUND})
ADD_DEFINITIONS()
SET(F2C_INPUT ${CMAKE_CURRENT_SOURCE_DIR}/trte.f)
SET(F2C_OUTPUT trte.c)
# additional include directories
INCLUDE_DIRECTORIES(${f2c_INCLUDE_DIRS})
# additional preprocessor / compiler flags
ADD_DEFINITIONS(-DF2C_BUILD)
# libraries to link to
SET(_link_LIBRARIES ${_link_LIBRARIES} ${f2c_LIBRARIES})
# generate C sources from Fortran
ADD_CUSTOM_COMMAND(
OUTPUT ${F2C_OUTPUT}
COMMAND ${f2c_GENERATOR} ${F2C_INPUT}
MAIN_DEPENDENCY ${F2C_INPUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
# sources / static
SET(MEFISTO2D_SOURCES
aptrte.cxx
${F2C_OUTPUT}
)
ELSE(${F2C_FOUND})
# sources / static
SET(MEFISTO2D_SOURCES
aptrte.cxx
trte.f
)
ENDIF(${F2C_FOUND})
# --- rules ---
ADD_LIBRARY(MEFISTO2D ${MEFISTO2D_SOURCES})
TARGET_LINK_LIBRARIES(MEFISTO2D ${_link_LIBRARIES} )
#Ignore MSVCRT.lib on WINDOWS in case using f2c code generator
IF(WIN32)
IF(CMAKE_BUILD_TYPE STREQUAL Debug)
IF(${F2C_FOUND})
SET_TARGET_PROPERTIES(MEFISTO2D PROPERTIES LINK_FLAGS "/NODEFAULTLIB:MSVCRT")
ENDIF(${F2C_FOUND})
ENDIF()
ENDIF(WIN32)
INSTALL(TARGETS MEFISTO2D EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
INSTALL(FILES ${MEFISTO2D_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS})

View File

@ -1,236 +0,0 @@
// MEFISTO : library to compute 2D triangulation from segmented boundaries
//
// Copyright (C) 2006-2021 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : Rn.h
// Module : SMESH
// Authors: Frederic HECHT & Alain PERRONNET
// Date : 13 novembre 2006
#ifndef Rn__h
#define Rn__h
#include <gp_Pnt.hxx> //Dans OpenCascade
#include <gp_Vec.hxx> //Dans OpenCascade
#include <gp_Dir.hxx> //Dans OpenCascade
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// BUT: Definir les espaces affines R R2 R3 R4 soit Rn pour n=1,2,3,4
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// AUTEUR : Frederic HECHT ANALYSE NUMERIQUE UPMC PARIS OCTOBRE 2000
// MODIFS : Alain PERRONNET ANALYSE NUMERIQUE UPMC PARIS NOVEMBRE 2000
//...............................................................................
#include <iostream>
#include <cmath>
template<class T> inline T Abs (const T &a){return a <0 ? -a : a;}
template<class T> inline void Echange (T& a,T& b) {T c=a;a=b;b=c;}
template<class T> inline T Min (const T &a,const T &b) {return a < b ? a : b;}
template<class T> inline T Max (const T &a,const T & b) {return a > b ? a : b;}
template<class T> inline T Max (const T &a,const T & b,const T & c){return Max(Max(a,b),c);}
template<class T> inline T Min (const T &a,const T & b,const T & c){return Min(Min(a,b),c);}
template<class T> inline T Max (const T &a,const T & b,const T & c,const T & d)
{return Max(Max(a,b),Max(c,d));}
template<class T> inline T Min (const T &a,const T & b,const T & c,const T & d)
{return Min(Min(a,b),Min(c,d));}
//le type Nom des entites geometriques P L S V O
//===========
typedef char Nom[1+24];
//le type N des nombres entiers positifs
//=========
#ifndef PCLINUX64
typedef unsigned long int N;
#else
typedef unsigned int N;
#endif
//le type Z des nombres entiers relatifs
//=========
#ifndef PCLINUX64
typedef long int Z;
#else
typedef int Z;
#endif
//le type R des nombres "reels"
//=========
typedef double R;
//le type XPoint des coordonnees d'un pixel dans une fenetre
//==============
//typedef struct { short int x,y } XPoint; //en fait ce type est defini dans X11-Window
// #include <X11/Xlib.h>
//la classe R2
//============
class R2
{
friend std::ostream& operator << (std::ostream& f, const R2 & P)
{ f << P.x << ' ' << P.y ; return f; }
friend std::istream& operator >> (std::istream& f, R2 & P)
{ f >> P.x >> P.y ; return f; }
friend std::ostream& operator << (std::ostream& f, const R2 * P)
{ f << P->x << ' ' << P->y ; return f; }
friend std::istream& operator >> (std::istream& f, R2 * P)
{ f >> P->x >> P->y ; return f; }
public:
R x,y; //les donnees
R2 () :x(0),y(0) {} //les constructeurs
R2 (R a,R b) :x(a),y(b) {}
R2 (R2 A,R2 B) :x(B.x-A.x),y(B.y-A.y) {} //vecteur defini par 2 points
R2 operator+(R2 P) const {return R2(x+P.x,y+P.y);} // Q+P possible
R2 operator+=(R2 P) {x += P.x;y += P.y; return *this;}// Q+=P;
R2 operator-(R2 P) const {return R2(x-P.x,y-P.y);} // Q-P
R2 operator-=(R2 P) {x -= P.x;y -= P.y; return *this;} // Q-=P;
R2 operator-()const {return R2(-x,-y);} // -Q
R2 operator+()const {return *this;} // +Q
R operator,(R2 P)const {return x*P.x+y*P.y;} // produit scalaire (Q,P)
R operator^(R2 P)const {return x*P.y-y*P.x;} // produit vectoriel Q^P
R2 operator*(R c)const {return R2(x*c,y*c);} // produit a droite P*c
R2 operator*=(R c) {x *= c; y *= c; return *this;}
R2 operator/(R c)const {return R2(x/c,y/c);} // division par un reel
R2 operator/=(R c) {x /= c; y /= c; return *this;}
R & operator[](int i) {return (&x)[i];} // la coordonnee i
R2 orthogonal() {return R2(-y,x);} //le vecteur orthogonal dans R2
friend R2 operator*(R c,R2 P) {return P*c;} // produit a gauche c*P
};
//la classe R3
//============
class R3
{
friend std::ostream& operator << (std::ostream& f, const R3 & P)
{ f << P.x << ' ' << P.y << ' ' << P.z ; return f; }
friend std::istream& operator >> (std::istream& f, R3 & P)
{ f >> P.x >> P.y >> P.z ; return f; }
friend std::ostream& operator << (std::ostream& f, const R3 * P)
{ f << P->x << ' ' << P->y << ' ' << P->z ; return f; }
friend std::istream& operator >> (std::istream& f, R3 * P)
{ f >> P->x >> P->y >> P->z ; return f; }
public:
R x,y,z; //les 3 coordonnees
R3 () :x(0),y(0),z(0) {} //les constructeurs
R3 (R a,R b,R c):x(a),y(b),z(c) {} //Point ou Vecteur (a,b,c)
R3 (R3 A,R3 B):x(B.x-A.x),y(B.y-A.y),z(B.z-A.z) {} //Vecteur AB
R3 (gp_Pnt P) : x(P.X()), y(P.Y()), z(P.Z()) {} //Point d'OpenCascade
R3 (gp_Vec V) : x(V.X()), y(V.Y()), z(V.Z()) {} //Vecteur d'OpenCascade
R3 (gp_Dir P) : x(P.X()), y(P.Y()), z(P.Z()) {} //Direction d'OpenCascade
R3 operator+(R3 P)const {return R3(x+P.x,y+P.y,z+P.z);}
R3 operator+=(R3 P) {x += P.x; y += P.y; z += P.z; return *this;}
R3 operator-(R3 P)const {return R3(x-P.x,y-P.y,z-P.z);}
R3 operator-=(R3 P) {x -= P.x; y -= P.y; z -= P.z; return *this;}
R3 operator-()const {return R3(-x,-y,-z);}
R3 operator+()const {return *this;}
R operator,(R3 P)const {return x*P.x+y*P.y+z*P.z;} // produit scalaire
R3 operator^(R3 P)const {return R3(y*P.z-z*P.y ,P.x*z-x*P.z, x*P.y-y*P.x);} // produit vectoriel
R3 operator*(R c)const {return R3(x*c,y*c,z*c);}
R3 operator*=(R c) {x *= c; y *= c; z *= c; return *this;}
R3 operator/(R c)const {return R3(x/c,y/c,z/c);}
R3 operator/=(R c) {x /= c; y /= c; z /= c; return *this;}
R & operator[](int i) {return (&x)[i];}
friend R3 operator*(R c,R3 P) {return P*c;}
R3 operator=(gp_Pnt P) {return R3(P.X(),P.Y(),P.Z());}
R3 operator=(gp_Dir P) {return R3(P.X(),P.Y(),P.Z());}
friend gp_Pnt gp_pnt(R3 xyz) { return gp_Pnt(xyz.x,xyz.y,xyz.z); }
//friend gp_Pnt operator=() { return gp_Pnt(x,y,z); }
friend gp_Dir gp_dir(R3 xyz) { return gp_Dir(xyz.x,xyz.y,xyz.z); }
bool DansPave( R3 & xyzMin, R3 & xyzMax )
{ return xyzMin.x<=x && x<=xyzMax.x &&
xyzMin.y<=y && y<=xyzMax.y &&
xyzMin.z<=z && z<=xyzMax.z; }
};
//la classe R4
//============
class R4: public R3
{
friend std::ostream& operator <<(std::ostream& f, const R4 & P )
{ f << P.x << ' ' << P.y << ' ' << P.z << ' ' << P.omega; return f; }
friend std::istream& operator >>(std::istream& f, R4 & P)
{ f >> P.x >> P.y >> P.z >> P.omega ; return f; }
friend std::ostream& operator <<(std::ostream& f, const R4 * P )
{ f << P->x << ' ' << P->y << ' ' << P->z << ' ' << P->omega; return f; }
friend std::istream& operator >>(std::istream& f, R4 * P)
{ f >> P->x >> P->y >> P->z >> P->omega ; return f; }
public:
R omega; //la donnee du poids supplementaire
R4 () :omega(1.0) {} //les constructeurs
R4 (R a,R b,R c,R d):R3(a,b,c),omega(d) {}
R4 (R4 A,R4 B) :R3(B.x-A.x,B.y-A.y,B.z-A.z),omega(B.omega-A.omega) {}
R4 operator+(R4 P)const {return R4(x+P.x,y+P.y,z+P.z,omega+P.omega);}
R4 operator+=(R4 P) {x += P.x;y += P.y;z += P.z;omega += P.omega;return *this;}
R4 operator-(R4 P)const {return R4(x-P.x,y-P.y,z-P.z,omega-P.omega);}
R4 operator-=(R4 P) {x -= P.x;y -= P.y;z -= P.z;omega -= P.omega;return *this;}
R4 operator-()const {return R4(-x,-y,-z,-omega);}
R4 operator+()const {return *this;}
R operator,(R4 P)const {return x*P.x+y*P.y+z*P.z+omega*P.omega;} // produit scalaire
R4 operator*(R c)const {return R4(x*c,y*c,z*c,omega*c);}
R4 operator*=(R c) {x *= c; y *= c; z *= c; omega *= c; return *this;}
R4 operator/(R c)const {return R4(x/c,y/c,z/c,omega/c);}
R4 operator/=(R c) {x /= c; y /= c; z /= c; omega /= c; return *this;}
R & operator[](int i) {return (&x)[i];}
friend R4 operator*(R c,R4 P) {return P*c;}
};
//quelques fonctions supplementaires sur ces classes
//==================================================
inline R Aire2d(const R2 A,const R2 B,const R2 C){return (B-A)^(C-A);}
inline R Angle2d(R2 P){ return atan2(P.y,P.x);}
inline R Norme2_2(const R2 & A){ return (A,A);}
inline R Norme2(const R2 & A){ return sqrt((A,A));}
inline R NormeInfinie(const R2 & A){return Max(Abs(A.x),Abs(A.y));}
inline R Norme2_2(const R3 & A){ return (A,A);}
inline R Norme2(const R3 & A){ return sqrt((A,A));}
inline R NormeInfinie(const R3 & A){return Max(Abs(A.x),Abs(A.y),Abs(A.z));}
inline R Norme2_2(const R4 & A){ return (A,A);}
inline R Norme2(const R4 & A){ return sqrt((A,A));}
inline R NormeInfinie(const R4 & A){return Max(Abs(A.x),Abs(A.y),Abs(A.z),Abs(A.omega));}
inline R2 XY(R3 P) {return R2(P.x, P.y);} //restriction a R2 d'un R3 par perte de z
inline R3 Min(R3 P, R3 Q)
{return R3(P.x<Q.x ? P.x : Q.x, P.y<Q.y ? P.y : Q.y, P.z<Q.z ? P.z : Q.z);} //Pt de xyz Min
inline R3 Max(R3 P, R3 Q)
{return R3(P.x>Q.x ? P.x : Q.x, P.y>Q.y ? P.y : Q.y, P.z>Q.z ? P.z : Q.z);} //Pt de xyz Max
#endif

View File

@ -1,869 +0,0 @@
// MEFISTO2: a library to compute 2D triangulation from segmented boundaries
//
// Copyright (C) 2006-2021 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : aptrte.cxx le C++ de l'appel du trianguleur plan
// Module : SMESH
// Author : Alain PERRONNET
// Date : 13 novembre 2006
#include "Rn.h"
#include "aptrte.h"
#include "utilities.h"
using namespace std;
extern "C"
{
R aretemaxface_;
MEFISTO2D_EXPORT
R
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
areteideale()//( R3 xyz, R3 direction )
{
return aretemaxface_;
}
}
//calcul de la longueur ideale de l'arete au sommet xyz (z ici inactif)
//dans la direction donnee
//a ajuster pour chaque surface plane et selon l'entier notysu (voir plus bas)
static double cpunew, cpuold=0;
void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
tempscpu_( double & tempsec )
//Retourne le temps CPU utilise en secondes
{
tempsec = ( (double) clock() ) / CLOCKS_PER_SEC;
//MESSAGE( "temps cpu=" << tempsec );
}
void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
deltacpu_( R & dtcpu )
//Retourne le temps CPU utilise en secondes depuis le precedent appel
{
tempscpu_( cpunew );
dtcpu = R( cpunew - cpuold );
cpuold = cpunew;
//MESSAGE( "delta temps cpu=" << dtcpu );
return;
}
void aptrte( Z nutysu, R aretmx,
Z nblf, Z * nudslf, R2 * uvslf,
Z nbpti, R2 * uvpti,
Z & nbst, R2 * & uvst,
Z & nbt, Z * & nust,
Z & ierr )
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// but : appel de la triangulation par un arbre-4 recouvrant
// ----- de triangles equilateraux
// le contour du domaine plan est defini par des lignes fermees
// la premiere ligne etant l'enveloppe de toutes les autres
// la fonction areteideale(s,d) donne la taille d'arete
// au point s dans la direction (actuellement inactive) d
// des lors toute arete issue d'un sommet s devrait avoir une longueur
// comprise entre 0.65 areteideale_(s,d) et 1.3 areteideale_(s,d)
//
//Attention:
// Les tableaux uvslf et uvpti sont supposes ne pas avoir de sommets identiques!
// De meme, un sommet d'une ligne fermee ne peut appartenir a une autre ligne fermee
//
// entrees:
// --------
// nutysu : numero de traitement de areteideale_(s,d) selon le type de surface
// 0 pas d'emploi de la fonction areteideale_() et aretmx est active
// 1 il existe une fonction areteideale_(s,d)
// dont seules les 2 premieres composantes de uv sont actives
// ... autres options a definir ...
// aretmx : longueur maximale des aretes de la future triangulation
// nblf : nombre de lignes fermees de la surface
// nudslf : numero du dernier sommet de chacune des nblf lignes fermees
// nudslf(0)=0 pour permettre la difference sans test
// Attention le dernier sommet de chaque ligne est raccorde au premier
// tous les sommets et les points internes ont des coordonnees
// UV differentes <=> Pas de point double!
// uvslf : uv des nudslf(nblf) sommets des lignes fermees
// nbpti : nombre de points internes futurs sommets de la triangulation
// uvpti : uv des points internes futurs sommets de la triangulation
//
// sorties:
// --------
// nbst : nombre de sommets de la triangulation finale
// uvst : coordonnees uv des nbst sommets de la triangulation
// nbt : nombre de triangles de la triangulation finale
// nust : 4 numeros dans uvst des sommets des nbt triangles
// s1, s2, s3, 0: no dans uvst des 3 sommets et 0 car quadrangle!
// ierr : 0 si pas d'erreur
// > 0 sinon
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// auteur : Alain Perronnet Laboratoire J.-L. LIONS Paris UPMC mars 2006
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{
Z nbsttria=4; //Attention: 4 sommets stockes par triangle
//no st1, st2, st3, 0 (non quadrangle)
R d, tcpu=0;
// R3 direction=R3(0,0,0); //direction pour areteideale() inactive ici!
Z nbarfr=nudslf[nblf]; //nombre total d'aretes des lignes fermees
Z mxtrou = Max( 1024, nblf ); //nombre maximal de trous dans la surface
R3 *mnpxyd=NULL;
Z *mnsoar=NULL, mosoar=7, mxsoar, n1soar; //le hachage des aretes
Z *mnartr=NULL, moartr=3, mxartr, n1artr; //le no des 3 aretes des triangles
Z *mntree=NULL, motree=9, mxtree; //L'arbre 4 de TE et nombre d'entiers par TE
Z *mnqueu=NULL, mxqueu;
Z *mn1arcf=NULL;
Z *mnarcf=NULL, mxarcf;
Z *mnarcf1=NULL;
Z *mnarcf2=NULL;
Z *mnarcf3=NULL;
Z *mntrsu=NULL;
Z *mnslig=NULL;
Z *mnarst=NULL;
Z *mnlftr=NULL;
R3 comxmi[2]; //coordonnees UV Min et Maximales
R aremin, aremax; //longueur minimale et maximale des aretes
R airemx; //aire maximale souhaitee d'un triangle
R quamoy, quamin;
Z noar0, noar, na;
Z i, l, n, ns, ns0, ns1, ns2, nosotr[3], nt;
Z mxsomm, nbsomm, nbarpi, nbarli, ndtri0, mn;
Z moins1=-1;
Z nuds = 0;
// initialisation du temps cpu
deltacpu_( d );
ierr = 0;
// quelques reservations de tableaux pour faire les calculs
// ========================================================
// declaration du tableau des coordonnees des sommets de la frontiere
// puis des sommets internes ajoutes
// majoration empirique du nombre de sommets de la triangulation
i = 4*nbarfr/10;
mxsomm = Max( 20000, 64*nbpti+i*i );
// MESSAGE( "APTRTE: Debut de la triangulation plane avec " );
// MESSAGE( "nutysu=" << nutysu << " aretmx=" << aretmx
// << " mxsomm=" << mxsomm );
// MESSAGE( nbarfr << " sommets sur la frontiere et " << nbpti << " points internes");
NEWDEPART:
//mnpxyd( 3, mxsomm ) les coordonnees UV des sommets et la taille d'arete aux sommets
if( mnpxyd!=NULL ) delete [] mnpxyd;
mnpxyd = new R3[mxsomm];
if( mnpxyd==NULL ) goto ERREUR;
// le tableau mnsoar des aretes des triangles
// 1: sommet 1 dans pxyd,
// 2: sommet 2 dans pxyd,
// 3: numero de 1 a nblf de la ligne qui supporte l'arete
// 4: numero dans mnartr du triangle 1 partageant cette arete,
// 5: numero dans mnartr du triangle 2 partageant cette arete,
// 6: chainage des aretes frontalieres ou internes ou
// des aretes simples des etoiles de triangles,
// 7: chainage du hachage des aretes
// nombre d'aretes = 3 ( nombre de sommets - 1 + nombre de trous )
// pour le hachage des aretes mxsoar doit etre > 3*mxsomm!
// h(ns1,ns2) = min( ns1, ns2 )
if( mnsoar!=NULL ) delete [] mnsoar;
mxsoar = 3 * ( mxsomm + mxtrou );
mnsoar = new Z[mosoar*mxsoar];
if( mnsoar==NULL ) goto ERREUR;
//initialiser le tableau mnsoar pour le hachage des aretes
insoar( mxsomm, mosoar, mxsoar, n1soar, mnsoar );
// mnarst( mxsomm ) numero mnsoar d'une arete pour chacun des sommets
if( mnarst!=NULL ) delete [] mnarst;
mnarst = new Z[1+mxsomm];
if( mnarst==NULL ) goto ERREUR;
n = 1+mxsomm;
azeroi( n, mnarst );
// mnslig( mxsomm ) no de sommet dans sa ligne pour chaque sommet frontalier
// ou no du point si interne forc'e par l'utilisateur
// ou 0 si interne cree par le module
if( mnslig!=NULL ) delete [] mnslig;
mnslig = new Z[mxsomm];
if( mnslig==NULL ) goto ERREUR;
azeroi( mxsomm, mnslig );
// initialisation des aretes frontalieres de la triangulation future
// renumerotation des sommets des aretes des lignes pour la triangulation
// mise a l'echelle des coordonnees des sommets pour obtenir une
// meilleure precision lors des calculs + quelques verifications
// boucle sur les lignes fermees qui forment la frontiere
// ======================================================================
noar = 0;
aremin = 1e100;
aremax = 0;
for (n=1; n<=nblf; n++)
{
//l'initialisation de la premiere arete de la ligne n dans la triangulation
//-------------------------------------------------------------------------
//le sommet ns0 est le numero de l'origine de la ligne
ns0 = nudslf[n-1];
mnpxyd[ns0].x = uvslf[ns0].x;
mnpxyd[ns0].y = uvslf[ns0].y;
mnpxyd[ns0].z = areteideale();//( mnpxyd[ns0], direction );
// MESSAGE("Sommet " << ns0 << ": " << mnpxyd[ns0].x
// << " " << mnpxyd[ns0].y << " longueur arete=" << mnpxyd[ns0].z);
//carre de la longueur de l'arete 1 de la ligne fermee n
d = pow( uvslf[ns0+1].x - uvslf[ns0].x, 2 )
+ pow( uvslf[ns0+1].y - uvslf[ns0].y, 2 ) ;
aremin = Min( aremin, d );
aremax = Max( aremax, d );
//le numero des 2 sommets (ns1,ns2) de la premiere arete de la ligne
//initialisation de la 1-ere arete ns1-ns1+1 de cette ligne fermee n
//le numero des 2 sommets ns1 ns2 de la 1-ere arete
//Attention: les numeros ns debutent a 1 (ils ont >0)
// les tableaux c++ demarrent a zero!
// les tableaux fortran demarrent ou l'on veut!
ns0++;
ns1 = ns0;
ns2 = ns1+1;
//le numero n de la ligne du sommet et son numero ns1 dans la ligne
mnslig[ns0-1] = 1000000 * n + ns1-nudslf[n-1];
fasoar( ns1, ns2, moins1, moins1, n,
mosoar, mxsoar, n1soar, mnsoar, mnarst,
noar0, ierr );
//pas de test sur ierr car pas de saturation possible a ce niveau
//le pointeur dans le hachage sur la premiere arete de la ligne fermee n
//mndalf[n] = noar0;
//la nouvelle arete est la suivante de l'arete definie juste avant
if( noar > 0 )
mnsoar[mosoar * noar - mosoar + 5] = noar0;
//l'initialisation des aretes suivantes de la ligne dans la triangulation
//-----------------------------------------------------------------------
nbarli = nudslf[n] - nudslf[n-1]; //nombre d'aretes=sommets de la ligne n
for (i=2; i<=nbarli; i++)
{
ns1 = ns2; //le numero de l'arete et le numero du premier sommet de l'arete
if( i < nbarli )
//nbs+1 est le 2-eme sommet de l'arete i de la ligne fermee n
ns2 = ns1+1;
else
//le 2-eme sommet de la derniere arete est le premier sommet de la ligne
ns2 = ns0;
//l'arete precedente est dotee de sa suivante:celle cree ensuite
//les 2 coordonnees du sommet ns2 de la ligne
ns = ns1 - 1;
//debut ajout 5/10/2006 ................................................
nuds = Max( nuds, ns ); //le numero du dernier sommet traite
//fin ajout 5/10/2006 ................................................
mnpxyd[ns].x = uvslf[ns].x;
mnpxyd[ns].y = uvslf[ns].y;
mnpxyd[ns].z = areteideale();//( mnpxyd[ns], direction );
// MESSAGE("Sommet " << ns << ": " << mnpxyd[ns].x
// << " " << mnpxyd[ns].y << " longueur arete=" << mnpxyd[ns].z);
//carre de la longueur de l'arete
d = pow( uvslf[ns2-1].x - uvslf[ns1-1].x, 2)
+ pow( uvslf[ns2-1].y - uvslf[ns1-1].y, 2);
aremin = Min( aremin, d );
aremax = Max( aremax, d );
//debut ajout du 5/10/2006 .............................................
//la longueur de l'arete ns1-ns2
d = sqrt( d );
//longueur arete = Min ( aretmx, aretes incidentes )
mnpxyd[ns ].z = Min( mnpxyd[ns ].z, d );
mnpxyd[ns2-1].z = Min( mnpxyd[ns2-1].z, d );
//fin ajout du 5/10/2006 ...............................................
//le numero n de la ligne du sommet et son numero ns1 dans la ligne
mnslig[ns] = 1000000 * n + ns1-nudslf[n-1];
//ajout de l'arete dans la liste
fasoar( ns1, ns2, moins1, moins1, n,
mosoar, mxsoar, n1soar, mnsoar,
mnarst, noar, ierr );
//pas de test sur ierr car pas de saturation possible a ce niveau
//chainage des aretes frontalieres en position 6 du tableau mnsoar
//la nouvelle arete est la suivante de l'arete definie juste avant
mnsoar[ mosoar * noar0 - mosoar + 5 ] = noar;
noar0 = noar;
}
//attention: la derniere arete de la ligne fermee enveloppe
// devient en fait la premiere arete de cette ligne
// dans le chainage des aretes de la frontiere!
}
if( ierr != 0 ) goto ERREUR;
aremin = sqrt( aremin ); //longueur minimale d'une arete des lignes fermees
aremax = sqrt( aremax ); //longueur maximale d'une arete
//debut ajout 9/11/2006 ................................................
// devenu un commentaire aretmx = Min( aretmx, aremax ); //pour homogeneiser
// protection contre une arete max desiree trop grande ou trop petite
if( aretmx > aremax*2.05 ) aretmx = aremax;
// protection contre une arete max desiree trop petite
if( (aremax-aremin) > (aremin+aremax)*0.05 && aretmx < aremin*0.5 )
aretmx =(aremin+aremax*2)/3.0;
if( aretmx < aremin && aremin > 0 )
aretmx = aremin;
//sauvegarde pour la fonction areteideale_
aretemaxface_ = aretmx;
//aire maximale souhaitee des triangles
airemx = aretmx * aretmx * sqrt(3.0) / 2.0; //Aire triangle equilateral
for(i=0; i<=nuds; i++ )
mnpxyd[i].z = Min( mnpxyd[i].z, aretmx );
//MESSAGE("Numero du dernier sommet frontalier=" << nuds+1);
//fin ajout 9/11/2006 .................................................
// MESSAGE("Sur le bord: arete min=" << aremin << " arete max=" << aremax );
// MESSAGE("Triangulation: arete mx=" << aretmx
// << " triangle aire mx=" << airemx );
//chainage des aretes frontalieres : la derniere arete frontaliere
mnsoar[ mosoar * noar - mosoar + 5 ] = 0;
//tous les sommets et aretes frontaliers sont numerotes de 1 a nbarfr
//reservation du tableau des numeros des 3 aretes de chaque triangle
//mnartr( moartr, mxartr )
//En nombre: Triangles = Aretes Internes + Aretes Frontalieres - Sommets + 1-Trous
// 3Triangles = 2 Aretes internes + Aretes frontalieres
// d'ou 3T/2 < AI + AF => T < 3T/2 - Sommets + 1-Trous
//nombre de triangles < 2 ( nombre de sommets - 1 + nombre de trous )
if( mnartr!=NULL ) delete [] mnartr;
mxartr = 2 * ( mxsomm + mxtrou );
mnartr = new Z[moartr*mxartr];
if( mnartr==NULL ) goto ERREUR;
//Ajout des points internes
ns1 = nudslf[ nblf ];
for (i=0; i<nbpti; i++)
{
//les 2 coordonnees du point i de sommet nbs
mnpxyd[ns1].x = uvpti[i].x;
mnpxyd[ns1].y = uvpti[i].y;
mnpxyd[ns1].z = areteideale();//( mnpxyd[ns1], direction );
//le numero i du point interne
mnslig[ns1] = i+1;
ns1++;
}
//nombre de sommets de la frontiere et internes
nbarpi = ns1;
// creation de l'arbre-4 des te (tableau letree)
// ajout dans les te des sommets des lignes et des points internes imposes
// =======================================================================
// premiere estimation de mxtree
mxtree = 2 * mxsomm;
NEWTREE: //en cas de saturation de l'un des tableaux, on boucle
//MESSAGE( "Debut triangulation avec mxsomm=" << mxsomm );
if( mntree != NULL ) delete [] mntree;
nbsomm = nbarpi;
mntree = new Z[motree*(1+mxtree)];
if( mntree==NULL ) goto ERREUR;
//initialisation du tableau letree et ajout dans letree des sommets 1 a nbsomm
comxmi[0].x = comxmi[1].x = uvslf[0].x;
comxmi[0].y = comxmi[1].y = uvslf[0].y;
teajte( mxsomm, nbsomm, mnpxyd, comxmi, aretmx, mxtree, mntree, ierr );
comxmi[0].z=0;
comxmi[1].z=0;
if( ierr == 51 )
{
//saturation de letree => sa taille est augmentee et relance
mxtree = mxtree * 2;
ierr = 0;
//MESSAGE( "Nouvelle valeur de mxtree=" << mxtree );
goto NEWTREE;
}
deltacpu_( d );
tcpu += d;
//MESSAGE( "Temps de l'ajout arbre-4 des Triangles Equilateraux=" << d << " secondes" );
if( ierr != 0 ) goto ERREUR;
//ici le tableau mnpxyd contient les sommets des te et les points frontaliers et internes
// homogeneisation de l'arbre des te a un saut de taille au plus
// prise en compte des tailles d'aretes souhaitees autour des sommets initiaux
// ===========================================================================
// reservation de la queue pour parcourir les te de l'arbre
if( mnqueu != NULL ) delete [] mnqueu;
mxqueu = mxtree;
mnqueu = new Z[mxqueu];
if( mnqueu==NULL) goto ERREUR;
tehote( nutysu, nbarpi, mxsomm, nbsomm, mnpxyd,
comxmi, aretmx,
mntree, mxqueu, mnqueu,
ierr );
deltacpu_( d );
tcpu += d;
//MESSAGE("Temps de l'adaptation et l'homogeneisation de l'arbre-4 des TE="
// << d << " secondes");
if( ierr != 0 )
{
//destruction du tableau auxiliaire et de l'arbre
if( ierr == 51 )
{
//letree sature
mxtree = mxtree * 2;
//MESSAGE( "Redemarrage avec la valeur de mxtree=" << mxtree );
ierr = 0;
goto NEWTREE;
}
else
goto ERREUR;
}
// trianguler les triangles equilateraux feuilles a partir de leurs 3 sommets
// et des points de la frontiere, des points internes imposes interieurs
// ==========================================================================
tetrte( comxmi, aretmx, nbarpi, mxsomm, mnpxyd,
mxqueu, mnqueu, mntree, mosoar, mxsoar, n1soar, mnsoar,
moartr, mxartr, n1artr, mnartr, mnarst,
ierr );
// destruction de la queue et de l'arbre devenus inutiles
delete [] mnqueu; mnqueu=NULL;
delete [] mntree; mntree=NULL;
//Temps calcul
deltacpu_( d );
tcpu += d;
//MESSAGE( "Temps de la triangulation des TE=" << d << " secondes" );
// ierr =0 si pas d'erreur
// =1 si le tableau mnsoar est sature
// =2 si le tableau mnartr est sature
// =3 si aucun des triangles ne contient l'un des points internes
// =5 si saturation de la queue de parcours de l'arbre des te
if( ierr != 0 ) goto ERREUR;
//qualites de la triangulation actuelle
qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
nbt, quamoy, quamin );
// boucle sur les aretes internes (non sur une ligne de la frontiere)
// avec echange des 2 diagonales afin de rendre la triangulation delaunay
// ======================================================================
// formation du chainage 6 des aretes internes a echanger eventuellement
aisoar( mosoar, mxsoar, mnsoar, na );
tedela( mnpxyd, mnarst,
mosoar, mxsoar, n1soar, mnsoar, na,
moartr, mxartr, n1artr, mnartr, n );
//MESSAGE( "Nombre d'echanges des diagonales de 2 triangles=" << n );
deltacpu_( d );
tcpu += d;
// MESSAGE("Temps de la triangulation Delaunay par echange des diagonales="
// << d << " secondes");
//qualites de la triangulation actuelle
qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
nbt, quamoy, quamin );
// detection des aretes frontalieres initiales perdues
// triangulation frontale pour les restaurer
// ===================================================
mxarcf = mxsomm/5;
if( mn1arcf != NULL ) delete [] mn1arcf;
if( mnarcf != NULL ) delete [] mnarcf;
if( mnarcf1 != NULL ) delete [] mnarcf1;
if( mnarcf2 != NULL ) delete [] mnarcf2;
mn1arcf = new Z[1+mxarcf];
if( mn1arcf == NULL ) goto ERREUR;
mnarcf = new Z[3*mxarcf];
if( mnarcf == NULL ) goto ERREUR;
mnarcf1 = new Z[mxarcf];
if( mnarcf1 == NULL ) goto ERREUR;
mnarcf2 = new Z[mxarcf];
if( mnarcf2 == NULL ) goto ERREUR;
terefr( nbarpi, mnpxyd,
mosoar, mxsoar, n1soar, mnsoar,
moartr, mxartr, n1artr, mnartr, mnarst,
mxarcf, mn1arcf, mnarcf, mnarcf1, mnarcf2,
n, ierr );
//MESSAGE( "Restauration de " << n << " aretes perdues de la frontiere ierr=" << ierr );
deltacpu_( d );
tcpu += d;
//MESSAGE("Temps de la recuperation des aretes perdues de la frontiere="
// << d << " secondes");
if( ierr != 0 ) goto ERREUR;
//qualites de la triangulation actuelle
qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
nbt, quamoy, quamin );
// fin de la triangulation avec respect des aretes initiales frontalieres
// suppression des triangles externes a la surface
// ===============================================
// recherche du dernier triangle utilise
mn = mxartr * moartr;
for ( ndtri0=mxartr; ndtri0<=1; ndtri0-- )
{
mn -= moartr;
if( mnartr[mn] != 0 ) break;
}
if( mntrsu != NULL ) delete [] mntrsu;
mntrsu = new Z[ndtri0];
if( mntrsu == NULL ) goto ERREUR;
if( mnlftr != NULL ) delete [] mnlftr;
mnlftr = new Z[nblf];
if( mnlftr == NULL ) goto ERREUR;
for (n=0; n<nblf; n++) //numero de la ligne fermee de 1 a nblf
mnlftr[n] = n+1;
tesuex( nblf, mnlftr,
ndtri0, nbsomm, mnpxyd, mnslig,
mosoar, mxsoar, mnsoar,
moartr, mxartr, n1artr, mnartr, mnarst,
nbt, mntrsu, ierr );
delete [] mnlftr; mnlftr=NULL;
delete [] mntrsu; mntrsu=NULL;
deltacpu_( d );
tcpu += d;
//MESSAGE( "Temps de la suppression des triangles externes=" << d << "ierr=" << ierr );
if( ierr != 0 ) goto ERREUR;
//qualites de la triangulation actuelle
qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
nbt, quamoy, quamin );
// amelioration de la qualite de la triangulation par
// barycentrage des sommets internes a la triangulation
// suppression des aretes trop longues ou trop courtes
// modification de la topologie des groupes de triangles
// mise en delaunay de la triangulation
// =====================================================
mnarcf3 = new Z[mxarcf];
if( mnarcf3 == NULL )
{
MESSAGE ( "aptrte: MC saturee mnarcf3=" << mnarcf3 );
goto ERREUR;
}
teamqt( nutysu, aretmx, airemx,
mnarst, mosoar, mxsoar, n1soar, mnsoar,
moartr, mxartr, n1artr, mnartr,
mxarcf, mnarcf2, mnarcf3,
mn1arcf, mnarcf, mnarcf1,
nbarpi, nbsomm, mxsomm, mnpxyd, mnslig,
ierr );
if( mnarcf3 != NULL ) {delete [] mnarcf3; mnarcf3=NULL;}
if( mn1arcf != NULL ) {delete [] mn1arcf; mn1arcf=NULL;}
if( mnarcf != NULL ) {delete [] mnarcf; mnarcf =NULL;}
if( mnarcf1 != NULL ) {delete [] mnarcf1; mnarcf1=NULL;}
if( mnarcf2 != NULL ) {delete [] mnarcf2; mnarcf2=NULL;}
deltacpu_( d );
tcpu += d;
//MESSAGE( "Temps de l'amelioration de la qualite de la triangulation=" << d );
if( ierr == -13 ) ierr=0; //6/10/2006 arret de l'amelioration apres boucle infinie dans caetoi
if( ierr != 0 ) goto ERREUR;
//qualites de la triangulation finale
qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
nbt, quamoy, quamin );
// renumerotation des sommets internes: mnarst(i)=numero final du sommet
// ===================================
for (i=0; i<=nbsomm; i++)
mnarst[i] = 0;
for (nt=1; nt<=mxartr; nt++)
{
if( mnartr[nt*moartr-moartr] != 0 )
{
//le numero des 3 sommets du triangle nt
nusotr( nt, mosoar, mnsoar, moartr, mnartr, nosotr );
//les 3 sommets du triangle sont actifs
mnarst[ nosotr[0] ] = 1;
mnarst[ nosotr[1] ] = 1;
mnarst[ nosotr[2] ] = 1;
}
}
nbst = 0;
for (i=1; i<=nbsomm; i++)
{
if( mnarst[i] >0 )
mnarst[i] = ++nbst;
}
// generation du tableau uvst de la surface triangulee
// ---------------------------------------------------
if( uvst != NULL ) delete [] uvst;
uvst = new R2[nbst];
if( uvst == NULL ) goto ERREUR;
nbst=-1;
for (i=0; i<nbsomm; i++ )
{
if( mnarst[i+1]>0 )
{
nbst++;
uvst[nbst].x = mnpxyd[i].x;
uvst[nbst].y = mnpxyd[i].y;
//si le sommet est un point ou appartient a une ligne
//ses coordonnees initiales sont restaurees
n = mnslig[i];
if( n > 0 )
{
if( n >= 1000000 )
{
//sommet d'une ligne
//retour aux coordonnees initiales dans uvslf
l = n / 1000000;
n = n - 1000000 * l + nudslf[l-1] - 1;
uvst[nbst].x = uvslf[n].x;
uvst[nbst].y = uvslf[n].y;
}
else
{
//point utilisateur n interne impose
//retour aux coordonnees initiales dans uvpti
uvst[nbst].x = uvpti[n-1].x;
uvst[nbst].y = uvpti[n-1].y;
}
}
}
}
nbst++;
// generation du tableau 'nsef' de la surface triangulee
// -----------------------------------------------------
// boucle sur les triangles occupes (internes et externes)
if( nust != NULL ) delete [] nust;
nust = new Z[nbsttria*nbt];
if( nust == NULL ) goto ERREUR;
nbt = 0;
for (i=1; i<=mxartr; i++)
{
//le triangle i de mnartr
if( mnartr[i*moartr-moartr] != 0 )
{
//le triangle i est interne => nosotr numero de ses 3 sommets
nusotr( i, mosoar, mnsoar, moartr, mnartr, nosotr );
nust[nbt++] = mnarst[ nosotr[0] ];
nust[nbt++] = mnarst[ nosotr[1] ];
nust[nbt++] = mnarst[ nosotr[2] ];
nust[nbt++] = 0;
}
}
nbt /= nbsttria; //le nombre final de triangles de la surface
// MESSAGE( "APTRTE: Fin de la triangulation plane avec "<<nbst<<" sommets et "
// << nbt << " triangles" );
deltacpu_( d );
tcpu += d;
// MESSAGE( "APTRTE: Temps total de la triangulation plane=" << tcpu << " secondes" );
// destruction des tableaux auxiliaires
// ------------------------------------
NETTOYAGE:
if( mnarst != NULL ) delete [] mnarst;
if( mnartr != NULL ) delete [] mnartr;
if( mnslig != NULL ) delete [] mnslig;
if( mnsoar != NULL ) delete [] mnsoar;
if( mnpxyd != NULL ) delete [] mnpxyd;
if( mntree != NULL ) delete [] mntree;
if( mnqueu != NULL ) delete [] mnqueu;
if( mntrsu != NULL ) delete [] mntrsu;
if( mnlftr != NULL ) delete [] mnlftr;
if( mn1arcf != NULL ) delete [] mn1arcf;
if( mnarcf != NULL ) delete [] mnarcf;
if( mnarcf1 != NULL ) delete [] mnarcf1;
if( mnarcf2 != NULL ) delete [] mnarcf2;
if( mnarcf3 != NULL ) delete [] mnarcf3;
return;
ERREUR:
if( ierr == 51 || ierr == 52 )
{
//saturation des sommets => redepart avec 2 fois plus de sommets
mxsomm = 2 * mxsomm;
ierr = 0;
goto NEWDEPART;
}
else
{
MESSAGE( "APTRTE: Triangulation NON REALISEE avec erreur=" << ierr );
if( ierr == 0 ) ierr=1;
goto NETTOYAGE;
}
}
void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
qualitetrte( R3 *mnpxyd,
Z & mosoar, Z & /*mxsoar*/, Z *mnsoar,
Z & moartr, Z & mxartr, Z *mnartr,
Z & nbtria, R & quamoy, R & quamin )
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// but : calculer la qualite moyenne et minimale de la triangulation
// ----- actuelle definie par les tableaux mnsoar et mnartr
// entrees:
// --------
// mnpxyd : tableau des coordonnees 2d des points
// par point : x y distance_souhaitee
// mosoar : nombre maximal d'entiers par arete et
// indice dans mnsoar de l'arete suivante dans le hachage
// mxsoar : nombre maximal d'aretes stockables dans le tableau mnsoar
// attention: mxsoar>3*mxsomm obligatoire!
// mnsoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
// chainage des aretes frontalieres, chainage du hachage des aretes
// hachage des aretes = mnsoar(1)+mnsoar(2)*2
// avec mxsoar>=3*mxsomm
// une arete i de mnsoar est vide <=> mnsoar(1,i)=0 et
// mnsoar(2,arete vide)=l'arete vide qui precede
// mnsoar(3,arete vide)=l'arete vide qui suit
// moartr : nombre maximal d'entiers par arete du tableau mnartr
// mxartr : nombre maximal de triangles declarables
// mnartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
// arete1 = 0 si triangle vide => arete2 = triangle vide suivant
// sorties:
// --------
// nbtria : nombre de triangles internes au domaine
// quamoy : qualite moyenne des triangles actuels
// quamin : qualite minimale des triangles actuels
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{
R d, aire, qualite;
Z nosotr[3], mn, nbtrianeg, nt, ntqmin;
aire = 0;
quamoy = 0;
quamin = 2.0;
nbtria = 0;
nbtrianeg = 0;
ntqmin = 0;
mn = -moartr;
for ( nt=1; nt<=mxartr; nt++ )
{
mn += moartr;
if( mnartr[mn]!=0 )
{
//un triangle occupe de plus
nbtria++;
//le numero des 3 sommets du triangle nt
nusotr( nt, mosoar, mnsoar, moartr, mnartr, nosotr );
//la qualite du triangle ns1 ns2 ns3
qutr2d( mnpxyd[nosotr[0]-1], mnpxyd[nosotr[1]-1], mnpxyd[nosotr[2]-1],
qualite );
//la qualite moyenne
quamoy += qualite;
//la qualite minimale
if( qualite < quamin )
{
quamin = qualite;
ntqmin = nt;
}
//aire signee du triangle nt
d = surtd2( mnpxyd[nosotr[0]-1], mnpxyd[nosotr[1]-1], mnpxyd[nosotr[2]-1] );
if( d<0 )
{
//un triangle d'aire negative de plus
nbtrianeg++;
MESSAGE("ATTENTION: le triangle " << nt << " de sommets:"
<< nosotr[0] << " " << nosotr[1] << " " << nosotr[2]
<< " a une aire " << d <<"<=0");
}
//aire des triangles actuels
aire += Abs(d);
}
}
//les affichages
quamoy /= nbtria;
// MESSAGE("Qualite moyenne=" << quamoy
// << " Qualite minimale=" << quamin
// << " des " << nbtria << " triangles de surface plane totale="
// << aire);
if( quamin<0.3 )
{
//le numero des 3 sommets du triangle ntqmin de qualite minimale
nusotr(ntqmin, mosoar, mnsoar, moartr, mnartr, nosotr );
// MESSAGE("Triangle de qualite minimale "<<quamin<<" de sommets:"
// <<nosotr[0]<<" "<<nosotr[1]<<" "<<nosotr[2]<<" ");
// for (int i=0;i<3;i++)
// MESSAGE("Sommet "<<nosotr[i]<<": x="<< mnpxyd[nosotr[i]-1].x
// <<" y="<< mnpxyd[nosotr[i]-1].y);
}
if( nbtrianeg>0 )
MESSAGE( "ATTENTION: "<< nbtrianeg << " TRIANGLES d'AIRE NEGATIVE" );
return;
}

View File

@ -1,451 +0,0 @@
// SMESH MEFISTO2 : algorithm for meshing
//
// Copyright (C) 2006-2021 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : aptrte.h
// Author : Alain PERRONNET
// Module : SMESH
// Date : 13 novembre 2006
#ifndef aptrte__h
#define aptrte__h
#include <climits> // limites min max int long real ...
#ifndef WIN32
#include <unistd.h> // gethostname, ...
#endif
#include <stdio.h>
#ifndef WIN32
#include <iostream> // pour cout cin ...
#include <iomanip> // pour le format des io setw, stx, setfill, ...
#endif
#include <string.h> // pour les fonctions sur les chaines de caracteres
#include <ctype.h>
#include <stdlib.h>
#include <math.h> // pour les fonctions mathematiques
#include <time.h>
#include <sys/types.h>
#ifndef WIN32
#include <sys/time.h>
#endif
#ifdef WIN32
#if defined MEFISTO2D_EXPORTS
#define MEFISTO2D_EXPORT __declspec( dllexport )
#else
#define MEFISTO2D_EXPORT __declspec( dllimport )
#endif
#else
#define MEFISTO2D_EXPORT
#endif
MEFISTO2D_EXPORT
void aptrte( Z nutysu, R aretmx,
Z nblf, Z *nudslf, R2 *uvslf,
Z nbpti, R2 *uvpti,
Z & nbst, R2 * & uvst, Z & nbt, Z * & nust,
Z & ierr );
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// but : appel de la triangulation par un arbre-4 recouvrant
// ----- de triangles equilateraux
// le contour du domaine plan est defini par des lignes fermees
// la premiere ligne etant l'enveloppe de toutes les autres
// la fonction areteideale_(s,d) donne la taille d'arete
// au point s dans la direction d (direction inactive pour l'instant)
// des lors toute arete issue d'un sommet s devrait avoir une longueur
// comprise entre 0.65 areteideale_(s,d) et 1.3 areteideale_(s,d)
//
//Attention:
// Les tableaux uvslf et uvpti sont supposes ne pas avoir de sommets identiques!
// De meme, un sommet d'une ligne fermee ne peut appartenir a une autre ligne fermee
//
// entrees:
// --------
// nutysu : numero de traitement de areteideale_() selon le type de surface
// 0 pas d'emploi de la fonction areteideale_() et aretmx est active
// 1 il existe une fonction areteideale_(s,d)
// dont seules les 2 premieres composantes de uv sont actives
// ... autres options a definir ...
// aretmx : longueur maximale des aretes de la future triangulation
// nblf : nombre de lignes fermees de la surface
// nudslf : numero du dernier sommet de chacune des nblf lignes fermees
// nudslf(0)=0 pour permettre la difference sans test
// Attention le dernier sommet de chaque ligne est raccorde au premier
// tous les sommets et les points internes ont des coordonnees
// UV differentes <=> Pas de point double!
// uvslf : uv des nudslf(nblf) sommets des lignes fermees
// nbpti : nombre de points internes futurs sommets de la triangulation
// uvpti : uv des points internes futurs sommets de la triangulation
//
// sorties:
// --------
// nbst : nombre de sommets de la triangulation finale
// uvst : coordonnees uv des nbst sommets de la triangulation
// nbt : nombre de triangles de la triangulation finale
// nust : 3 numeros dans uvst des sommets des nbt triangles
// ierr : 0 si pas d'erreur
// > 0 sinon
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// auteur : Alain Perronnet Analyse Numerique Paris UPMC decembre 2001
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#if WIN32 & DFORTRAN
#define tempscpu TEMPSCPU
#define deltacpu DELTACPU
#define insoar INSOAR
#define azeroi AZEROI
#define fasoar FASOAR
#define teajte TEAJTE
#define tehote TEHOTE
#define tetrte TETRTE
#define aisoar AISOAR
#define tedela TEDELA
#define terefr TEREFR
#define tesuex TESUEX
#define teamqt TEAMQT
#define nusotr NUSOTR
#define qutr2d QUTR2D
#define surtd2 SURTD2
#define qualitetrte QUALITETRTE
#define areteideale ARETEIDEALE
#else
#define tempscpu tempscpu_
#define deltacpu deltacpu_
#define insoar insoar_
#define azeroi azeroi_
#define fasoar fasoar_
#define teajte teajte_
#define tehote tehote_
#define tetrte tetrte_
#define aisoar aisoar_
#define tedela tedela_
#define terefr terefr_
#define tesuex tesuex_
#define teamqt teamqt_
#define nusotr nusotr_
#define qutr2d qutr2d_
#define surtd2 surtd2_
#define qualitetrte qualitetrte_
#define areteideale areteideale_
#endif
extern "C" { void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
qualitetrte( R3 *mnpxyd,
Z & mosoar, Z & mxsoar, Z *mnsoar,
Z & moartr, Z & mxartr, Z *mnartr,
Z & nbtria, R & quamoy, R & quamin ); }
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// but : calculer la qualite moyenne et minimale de la triangulation
// ----- actuelle definie par les tableaux nosoar et noartr
// entrees:
// --------
// mnpxyd : tableau des coordonnees 2d des points
// par point : x y distance_souhaitee
// mosoar : nombre maximal d'entiers par arete et
// indice dans nosoar de l'arete suivante dans le hachage
// mxsoar : nombre maximal d'aretes stockables dans le tableau nosoar
// attention: mxsoar>3*mxsomm obligatoire!
// nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
// chainage des aretes frontalieres, chainage du hachage des aretes
// hachage des aretes = nosoar(1)+nosoar(2)*2
// avec mxsoar>=3*mxsomm
// une arete i de nosoar est vide <=> nosoar(1,i)=0 et
// nosoar(2,arete vide)=l'arete vide qui precede
// nosoar(3,arete vide)=l'arete vide qui suit
// moartr : nombre maximal d'entiers par arete du tableau noartr
// mxartr : nombre maximal de triangles declarables
// noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
// arete1 = 0 si triangle vide => arete2 = triangle vide suivant
// sorties:
// --------
// nbtria : nombre de triangles internes au domaine
// quamoy : qualite moyenne des triangles actuels
// quamin : qualite minimale des triangles actuels
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
extern "C" { void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
tempscpu( double & tempsec );
}
//Retourne le temps CPU utilise en secondes
extern "C" { void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
deltacpu( R & dtcpu );
}
//Retourne le temps CPU utilise en secondes depuis le precedent appel
//initialiser le tableau mnsoar pour le hachage des aretes
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
insoar( Z & mxsomm, Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar );
}
//mettre a zero les nb entiers de tab
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
azeroi( Z & nb, Z * tab );
}
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
fasoar( Z & ns1, Z & ns2, Z & nt1, Z & nt2, Z & nolign,
Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar, Z * mnarst,
Z & noar, Z & ierr );
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// but : former l'arete de sommet ns1-ns2 dans le hachage du tableau
// ----- nosoar des aretes de la triangulation
// entrees:
// --------
// ns1 ns2: numero pxyd des 2 sommets de l'arete
// nt1 : numero du triangle auquel appartient l'arete
// nt1=-1 si numero inconnu
// nt2 : numero de l'eventuel second triangle de l'arete si connu
// nt2=-1 si numero inconnu
// nolign : numero de la ligne fermee de l'arete
// =0 si l'arete n'est une arete de ligne
// ce numero est ajoute seulement si l'arete est creee
// mosoar : nombre maximal d'entiers par arete du tableau nosoar
// mxsoar : nombre maximal d'aretes stockables dans le tableau nosoar
// modifies:
// ---------
// n1soar : numero de la premiere arete vide dans le tableau nosoar
// une arete i de nosoar est vide <=> nosoar(1,i)=0
// chainage des aretes vides amont et aval
// l'arete vide qui precede=nosoar(4,i)
// l'arete vide qui suit =nosoar(5,i)
// nosoar : numero des 2 sommets, no ligne, 2 triangles de l'arete,
// chainage momentan'e d'aretes, chainage du hachage des aretes
// hachage des aretes = min( nosoar(1), nosoar(2) )
// noarst : noarst(np) numero d'une arete du sommet np
// ierr : si < 0 en entree pas d'affichage en cas d'erreur du type
// "arete appartenant a plus de 2 triangles et a creer!"
// si >=0 en entree affichage de ce type d'erreur
// sorties:
// --------
// noar : >0 numero de l'arete retrouvee ou ajoutee
// ierr : =0 si pas d'erreur
// =1 si le tableau nosoar est sature
// =2 si arete a creer et appartenant a 2 triangles distincts
// des triangles nt1 et nt2
// =3 si arete appartenant a 2 triangles distincts
// differents des triangles nt1 et nt2
// =4 si arete appartenant a 2 triangles distincts
// dont le second n'est pas le triangle nt2
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//initialisation du tableau letree et ajout dans letree des sommets 1 a nbsomm
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
teajte( Z & mxsomm, Z & nbsomm, R3 * mnpxyd, R3 * comxmi,
R & aretmx, Z & mxtree, Z * letree,
Z & ierr );
}
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
tehote( Z & nutysu, Z & nbarpi, Z & mxsomm, Z & nbsomm, R3 * mnpxyd,
R3 * comxmi, R & aretmx,
Z * letree, Z & mxqueu, Z * mnqueu,
Z & ierr );
}
// homogeneisation de l'arbre des te a un saut de taille au plus
// prise en compte des tailles d'aretes souhaitees autour des sommets initiaux
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
tetrte( R3 * comxmi, R & aretmx, Z & nbarpi, Z & mxsomm, R3 * mnpxyd,
Z & mxqueu, Z * mnqueu, Z * mntree,
Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar,
Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z * mnarst,
Z & ierr );
}
// trianguler les triangles equilateraux feuilles a partir de leurs 3 sommets
// et des points de la frontiere, des points internes imposes interieurs
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
aisoar( Z & mosoar, Z & mxsoar, Z * mnsoar, Z & na );
}
// formation du chainage 6 des aretes internes a echanger eventuellement
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
tedela( R3 * mnpxyd, Z * mnarst,
Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar, Z & na,
Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z & n );
}
// boucle sur les aretes internes (non sur une ligne de la frontiere)
// avec echange des 2 diagonales afin de rendre la triangulation delaunay
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
terefr( Z & nbarpi, R3 * mnpxyd,
Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar,
Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z * mnarst,
Z & mxarcf, Z * mnarc1, Z * mnarc2,
Z * mnarc3, Z * mnarc4,
Z & n, Z & ierr );
}
// detection des aretes frontalieres initiales perdues
// triangulation frontale pour les restaurer
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
tesuex( Z & nblf, Z * nulftr,
Z & ndtri0, Z & nbsomm, R3 * mnpxyd, Z * mnslig,
Z & mosoar, Z & mxsoar, Z * mnsoar,
Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z * mnarst,
Z & nbtria, Z * mntrsu, Z & ierr );
}
// suppression des triangles externes a la surface
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
teamqt( Z & nutysu, R & aretmx, R & airemx,
Z * mnarst, Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar,
Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr,
Z & mxarcf, Z * mntrcf, Z * mnstbo,
Z * n1arcf, Z * mnarcf, Z * mnarc1,
Z & nbarpi, Z & nbsomm, Z & mxsomm,
R3 * mnpxyd, Z * mnslig,
Z & ierr );
}
// amelioration de la qualite de la triangulation par
// barycentrage des sommets internes a la triangulation
// suppression des aretes trop longues ou trop courtes
// modification de la topologie des groupes de triangles
// mise en delaunay de la triangulation
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
nusotr( Z & nt, Z & mosoar, Z * mnsoar, Z & moartr, Z * mnartr,Z * nosotr );
}
//retrouver les numero des 3 sommets du triangle nt
extern "C" {void
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
qutr2d( R3 & p1, R3 & p2, R3 & p3, R & qualite );
}
//calculer la qualite d'un triangle de R2 de sommets p1, p2, p3
extern "C" { R
#ifdef WIN32
#ifdef F2C_BUILD
#else
__stdcall
#endif
#endif
surtd2( R3 & p1, R3 & p2, R3 & p3 );
}
//calcul de la surface d'un triangle defini par 3 points de r**2
#endif

View File

@ -1,30 +0,0 @@
c MEFISTO : library to compute 2D triangulation from segmented boundaries
c
c Copyright (C) 2006-2021 CEA/DEN, EDF R&D, OPEN CASCADE
c
c This library is free software; you can redistribute it and/or
c modify it under the terms of the GNU Lesser General Public
c License as published by the Free Software Foundation; either
c version 2.1 of the License, or (at your option) any later version.
c
c This library is distributed in the hope that it will be useful,
c but WITHOUT ANY WARRANTY; without even the implied warranty of
c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c Lesser General Public License for more details.
c
c You should have received a copy of the GNU Lesser General Public
c License along with this library; if not, write to the Free Software
c Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
c
c See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
c
c File : areteideale.f
c Module : SMESH
c Author : Alain PERRONNET
c Date : 13 novembre 2006
double precision function areteideale( xyz, direction )
double precision xyz(3), direction(3)
areteideale = 10
return
end

File diff suppressed because it is too large Load Diff

View File

@ -413,7 +413,7 @@
</message>
<message>
<source>ICON_PATTERN_2d</source>
<translation>mesh_algo_mefisto.png</translation>
<translation>mesh_algo_tri.png</translation>
</message>
<message>
<source>ICON_PATTERN_3d</source>

View File

@ -42,13 +42,8 @@ Algorithm type: Python 1D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBu
COMPOSITE = "CompositeSegment_1D"
"""
Algorithm type: Composite segment 1D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_CompositeSegment`
"""
MEFISTO = "MEFISTO_2D"
"""
Algorithm type: Triangle MEFISTO 2D algorithm, see :class:`~StdMeshersBuilder.StdMeshersBuilder_Triangle_MEFISTO`
"""
Hexa = "Hexa_3D"
"""
@ -623,72 +618,6 @@ class StdMeshersBuilder_Segment_Python(Mesh_Algorithm):
pass # end of StdMeshersBuilder_Segment_Python class
class StdMeshersBuilder_Triangle_MEFISTO(Mesh_Algorithm):
"""
Triangle MEFISTO 2D algorithm.
It is created by calling smeshBuilder.Mesh.Triangle(smeshBuilder.MEFISTO,geom=0)
"""
meshMethod = "Triangle"
"""
name of the dynamic method in smeshBuilder.Mesh class
"""
algoType = MEFISTO
"""
type of algorithm used with helper function in smeshBuilder.Mesh class
"""
isDefault = True
"""
flag pointing whether this algorithm should be used by default in dynamic method
of smeshBuilder.Mesh class
"""
docHelper = "Create triangle 2D algorithm for faces"
"""
doc string of the method
"""
def __init__(self, mesh, geom=0):
"""
Private constructor.
Parameters:
mesh: parent mesh object algorithm is assigned to
geom: geometry (shape/sub-shape) algorithm is assigned to;
if it is :code:`0` (default), the algorithm is assigned to the main shape
"""
Mesh_Algorithm.__init__(self)
self.Create(mesh, geom, self.algoType)
pass
def MaxElementArea(self, area, UseExisting=0):
"""
Defines "MaxElementArea" hypothesis basing on the definition of the maximum area of each triangle
Parameters:
area: for the maximum area of each triangle
UseExisting: if ==true - searches for an existing hypothesis created with the
same parameters, else (default) - Create a new one
"""
from salome.smesh.smeshBuilder import IsEqual
comparator = lambda hyp, args: IsEqual(hyp.GetMaxElementArea(), args[0])
hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting,
CompareMethod=comparator)
hyp.SetMaxElementArea(area)
return hyp
def LengthFromEdges(self):
"""
Defines "LengthFromEdges" hypothesis to build triangles
based on the length of the edges taken from the wire
"""
hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp)
return hyp
pass # end of StdMeshersBuilder_Triangle_MEFISTO class
class StdMeshersBuilder_Quadrangle(Mesh_Algorithm):
"""
Defines a quadrangle 2D algorithm.

View File

@ -2125,7 +2125,7 @@ class Mesh(metaclass = MeshMeta):
def AutomaticTetrahedralization(self, fineness=0):
"""
Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
Parameters:
fineness: [0.0,1.0] defines mesh fineness

View File

@ -372,7 +372,7 @@ class Mesh_Algorithm:
"""
Defines "ViscousLayers2D" hypothesis to give parameters of layers of quadrilateral
elements to build near mesh boundary. This hypothesis can be used by several 2D algorithms:
NETGEN 2D, NETGEN 1D-2D, Quadrangle (mapping), MEFISTO, MG-CADSurf
NETGEN 2D, NETGEN 1D-2D, Quadrangle (mapping), MG-CADSurf
Parameters:
thickness: total thickness of layers of quadrilaterals

View File

@ -38,12 +38,6 @@ INCLUDE_DIRECTORIES(
${TBB_INCLUDES}
)
IF(SALOME_SMESH_ENABLE_MEFISTO)
INCLUDE_DIRECTORIES(
${PROJECT_SOURCE_DIR}/src/MEFISTO2
)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
# additional preprocessor / compiler flags
ADD_DEFINITIONS(
${OpenCASCADE_DEFINITIONS}
@ -68,10 +62,6 @@ SET(_link_LIBRARIES
${Boost_LIBRARIES}
)
IF(SALOME_SMESH_ENABLE_MEFISTO)
SET(_link_LIBRARIES ${_link_LIBRARIES} MEFISTO2D)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
# --- headers ---
# header files / no moc processing
@ -136,9 +126,6 @@ SET(StdMeshers_HEADERS
StdMeshers_BlockRenumber.hxx
)
IF(SALOME_SMESH_ENABLE_MEFISTO)
SET(StdMeshers_HEADERS ${StdMeshers_HEADERS} StdMeshers_MEFISTO_2D.hxx)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
# --- sources ---
# sources / static
@ -203,10 +190,6 @@ SET(StdMeshers_SOURCES
StdMeshers_BlockRenumber.cxx
)
IF(SALOME_SMESH_ENABLE_MEFISTO)
SET(StdMeshers_SOURCES ${StdMeshers_SOURCES} StdMeshers_MEFISTO_2D.cxx)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
# --- rules ---
ADD_LIBRARY(StdMeshers ${StdMeshers_SOURCES})

View File

@ -43,7 +43,7 @@ StdMeshers_LengthFromEdges::StdMeshers_LengthFromEdges(int hypId, SMESH_Gen* gen
{
_mode =1;
_name = "LengthFromEdges";
_param_algo_dim = 2; // is used by SMESH_MEFISTO_2D
_param_algo_dim = 2;
}
//=============================================================================

View File

@ -1,860 +0,0 @@
// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// SMESH SMESH : implementation of SMESH idl descriptions
// File : StdMeshers_MEFISTO_2D.cxx
// Moved here from SMESH_MEFISTO_2D.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
//
#include "StdMeshers_MEFISTO_2D.hxx"
#include "SMDS_EdgePosition.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Comment.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_subMesh.hxx"
#include "StdMeshers_FaceSide.hxx"
#include "StdMeshers_LengthFromEdges.hxx"
#include "StdMeshers_MaxElementArea.hxx"
#include "StdMeshers_ViscousLayers2D.hxx"
#include "utilities.h"
#include "Rn.h"
#include "aptrte.h"
#include <BRepGProp.hxx>
#include <BRepTools.hxx>
#include <BRep_Tool.hxx>
#include <GProp_GProps.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <Precision.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Wire.hxx>
#include <gp_Pnt2d.hxx>
using namespace std;
#ifdef _DEBUG_
//#define DUMP_POINTS // to print coordinates of MEFISTO input
#endif
//=============================================================================
/*!
*
*/
//=============================================================================
StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, SMESH_Gen * gen):
SMESH_2D_Algo(hypId, gen)
{
_name = "MEFISTO_2D";
_shapeType = (1 << TopAbs_FACE);
_compatibleHypothesis.push_back("MaxElementArea");
_compatibleHypothesis.push_back("LengthFromEdges");
_compatibleHypothesis.push_back("ViscousLayers2D");
_edgeLength = 0;
_maxElementArea = 0;
_hypMaxElementArea = NULL;
_hypLengthFromEdges = NULL;
_helper = 0;
}
//=============================================================================
/*!
*
*/
//=============================================================================
StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
{
}
//=============================================================================
/*!
*
*/
//=============================================================================
bool StdMeshers_MEFISTO_2D::CheckHypothesis
(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
SMESH_Hypothesis::Hypothesis_Status& aStatus)
{
_hypMaxElementArea = NULL;
_hypLengthFromEdges = NULL;
_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;
const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
int nbHyp = hyps.size();
if (!nbHyp)
{
aStatus = SMESH_Hypothesis::HYP_OK; //SMESH_Hypothesis::HYP_MISSING;
return true; // (PAL13464) can work with no hypothesis, LengthFromEdges is default one
}
itl = hyps.begin();
theHyp = (*itl); // use only the first hypothesis
string hypName = theHyp->GetName();
bool isOk = false;
if (hypName == "MaxElementArea")
{
_hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
ASSERT(_hypMaxElementArea);
_maxElementArea = _hypMaxElementArea->GetMaxArea();
isOk = true;
aStatus = SMESH_Hypothesis::HYP_OK;
}
else if (hypName == "LengthFromEdges")
{
_hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
ASSERT(_hypLengthFromEdges);
isOk = true;
aStatus = SMESH_Hypothesis::HYP_OK;
}
else
aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
if (isOk)
{
isOk = false;
if (_maxElementArea > 0)
{
//_edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant
_edgeLength = sqrt(2. * _maxElementArea/sqrt(3.0));
isOk = true;
}
else
isOk = (_hypLengthFromEdges != NULL); // **** check mode
if (!isOk)
aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
}
return isOk;
}
//=============================================================================
/*!
*
*/
//=============================================================================
bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
{
TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
// helper builds quadratic mesh if necessary
SMESH_MesherHelper helper(aMesh);
_helper = &helper;
_quadraticMesh = _helper->IsQuadraticSubMesh(aShape);
const bool skipMediumNodes = _quadraticMesh;
// build viscous layers if required
SMESH_ProxyMesh::Ptr proxyMesh = StdMeshers_ViscousLayers2D::Compute( aMesh, F );
if ( !proxyMesh )
return false;
// get all edges of a face
TError problem;
TWireVector wires =
StdMeshers_FaceSide::GetFaceWires( F, aMesh, skipMediumNodes, problem, _helper, proxyMesh );
int nbWires = wires.size();
if ( problem && !problem->IsOK() ) return error( problem );
if ( nbWires == 0 ) return error( "Problem in StdMeshers_FaceSide::GetFaceWires()");
if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments
return error(COMPERR_BAD_INPUT_MESH,
SMESH_Comment("Too few segments: ")<<wires[0]->NbSegments());
// compute average edge length
if (!_hypMaxElementArea)
{
_edgeLength = 0;
int nbSegments = 0;
for ( int iW = 0; iW < nbWires; ++iW )
{
StdMeshers_FaceSidePtr wire = wires[ iW ];
_edgeLength += wire->Length();
nbSegments += wire->NbSegments();
}
if ( nbSegments )
_edgeLength /= nbSegments;
}
if (/*_hypLengthFromEdges &&*/ _edgeLength < DBL_MIN )
_edgeLength = 100;
Z nblf; //nombre de lignes fermees (enveloppe en tete)
Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
R2 *uvslf = NULL;
Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
R2 *uvpti = NULL;
Z nbst;
R2 *uvst = NULL;
Z nbt;
Z *nust = NULL;
Z ierr = 0;
Z nutysu = 1; // 1: il existe un fonction areteideale_()
// Z nutysu=0; // 0: on utilise aretmx
R aretmx = _edgeLength; // longueur max aretes future triangulation
if ( _hypMaxElementArea )
aretmx *= 1.5;
nblf = nbWires;
nudslf = new Z[1 + nblf];
nudslf[0] = 0;
int iw = 1;
int nbpnt = 0;
// count nb of input points
for ( int iW = 0; iW < nbWires; ++iW )
{
nbpnt += wires[iW]->NbPoints() - 1;
nudslf[iw++] = nbpnt;
}
uvslf = new R2[nudslf[nblf]];
double scalex, scaley;
ComputeScaleOnFace(aMesh, F, scalex, scaley);
// correspondence mefisto index --> Nodes
vector< const SMDS_MeshNode*> mefistoToDS(nbpnt, (const SMDS_MeshNode*)0);
bool isOk = false;
// fill input points UV
if ( LoadPoints(wires, uvslf, mefistoToDS, scalex, scaley) )
{
// Compute
aptrte(nutysu, aretmx,
nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
if (ierr == 0)
{
StoreResult(nbst, uvst, nbt, nust, mefistoToDS, scalex, scaley);
isOk = true;
}
else
{
error(ierr,"Error in Triangulation (aptrte())");
}
}
if (nudslf != NULL) delete[]nudslf;
if (uvslf != NULL) delete[]uvslf;
if (uvst != NULL) delete[]uvst;
if (nust != NULL) delete[]nust;
return isOk;
}
//=============================================================================
/*!
*
*/
//=============================================================================
bool StdMeshers_MEFISTO_2D::Evaluate(SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
MapShapeNbElems& aResMap)
{
TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
double aLen = 0.0;
int NbSeg = 0;
bool IsQuadratic = false;
bool IsFirst = true;
TopExp_Explorer exp(F,TopAbs_EDGE);
for(; exp.More(); exp.Next()) {
TopoDS_Edge E = TopoDS::Edge(exp.Current());
MapShapeNbElemsItr anIt = aResMap.find( aMesh.GetSubMesh(E) );
if( anIt == aResMap.end() ) continue;
std::vector<smIdType> aVec = (*anIt).second;
int nbe = Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
NbSeg += nbe;
if(IsFirst) {
IsQuadratic = ( aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge] );
IsFirst = false;
}
double a,b;
TopLoc_Location L;
Handle(Geom_Curve) C = BRep_Tool::Curve(E,L,a,b);
gp_Pnt P1;
C->D0(a,P1);
double dp = (b-a)/nbe;
for(int i=1; i<=nbe; i++) {
gp_Pnt P2;
C->D0(a+i*dp,P2);
aLen += P1.Distance(P2);
P1 = P2;
}
}
if(NbSeg<1) {
std::vector<smIdType> aResVec(SMDSEntity_Last);
for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
aResMap.insert(std::make_pair(sm,aResVec));
SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,
"Submesh can not be evaluated",this));
return false;
}
aLen = aLen/NbSeg; // middle length
_edgeLength = Precision::Infinite();
double tmpLength = Min( _edgeLength, aLen );
GProp_GProps G;
BRepGProp::SurfaceProperties(aShape,G);
double anArea = G.Mass();
int nbFaces = Precision::IsInfinite( tmpLength ) ? 0 :
(int)( anArea/(tmpLength*tmpLength*sqrt(3.)/4) );
int nbNodes = (int) ( nbFaces*3 - (NbSeg-1)*2 ) / 6;
std::vector<smIdType> aVec(SMDSEntity_Last);
for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
if(IsQuadratic) {
aVec[SMDSEntity_Quad_Triangle] = nbFaces;
aVec[SMDSEntity_Node] = (int)( nbNodes + nbFaces*3 - (NbSeg-1) );
}
else {
aVec[SMDSEntity_Node] = nbNodes;
aVec[SMDSEntity_Triangle] = nbFaces;
}
SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
aResMap.insert(std::make_pair(sm,aVec));
return true;
}
//=======================================================================
//function : fixOverlappedLinkUV
//purpose : prevent failure due to overlapped adjacent links
//=======================================================================
static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 )
{
gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y );
gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y );
double tol2 = DBL_MIN * DBL_MIN;
double sqMod1 = v1.SquareModulus();
if ( sqMod1 <= tol2 ) return false;
double sqMod2 = v2.SquareModulus();
if ( sqMod2 <= tol2 ) return false;
double dot = v1*v2;
// check sinus >= 1.e-3
const double minSin = 1.e-3;
if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) {
MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y);
v1.SetCoord( -v1.Y(), v1.X() );
double delta = sqrt( sqMod1 ) * minSin;
if ( v1.X() < 0 )
uv0.x -= delta;
else
uv0.x += delta;
if ( v1.Y() < 0 )
uv0.y -= delta;
else
uv0.y += delta;
// #ifdef _DEBUG_
// MESSAGE(" -> " << uv0.x << " " << uv0.y << " ");
// MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " <<
// "v2( " << v2.X() << " " << v2.Y() << " ) ");
// MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2)));
// v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y );
// v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y );
// gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y );
// sqMod1 = v1.SquareModulus();
// sqMod2 = v2.SquareModulus();
// dot = v1*v2;
// double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2));
// MESSAGE("NEW SIN: " << sin);
// #endif
return true;
}
return false;
}
//=======================================================================
//function : fixCommonVertexUV
//purpose :
//=======================================================================
static bool fixCommonVertexUV (R2 & theUV,
const TopoDS_Vertex& theV,
const TopoDS_Face& theF,
const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
SMESH_Mesh & theMesh,
const double theScaleX,
const double theScaleY,
const bool theCreateQuadratic)
{
if( !theVWMap.Contains( theV )) return false;
// check if there is another wire sharing theV
const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
TopTools_ListIteratorOfListOfShape aWIt;
TopTools_MapOfShape aWires;
for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
aWires.Add( aWIt.Value() );
if ( aWires.Extent() < 2 ) return false;
TopoDS_Shape anOuterWire = BRepTools::OuterWire(theF);
TopoDS_Shape anInnerWire;
for ( aWIt.Initialize( WList ); aWIt.More() && anInnerWire.IsNull(); aWIt.Next() )
if ( !anOuterWire.IsSame( aWIt.Value() ))
anInnerWire = aWIt.Value();
TopTools_ListOfShape EList;
list< double > UList;
// find edges of theW sharing theV
// and find 2d normal to them at theV
gp_Vec2d N(0.,0.);
TopoDS_Iterator itE( anInnerWire );
for ( ; itE.More(); itE.Next() )
{
const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
TopoDS_Iterator itV( E );
for ( ; itV.More(); itV.Next() )
{
const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
if ( !V.IsSame( theV ))
continue;
EList.Append( E );
Standard_Real u = BRep_Tool::Parameter( V, E );
UList.push_back( u );
double f, l;
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
gp_Vec2d d1;
gp_Pnt2d p;
C2d->D1( u, p, d1 );
gp_Vec2d n( d1.Y() * theScaleX, -d1.X() * theScaleY);
if ( E.Orientation() == TopAbs_REVERSED )
n.Reverse();
N += n.Normalized();
}
}
// define step size by which to move theUV
gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
gp_Pnt2d thisUV( theUV.x, theUV.y );
double maxDist = -DBL_MAX;
TopTools_ListIteratorOfListOfShape aEIt (EList);
list< double >::iterator aUIt = UList.begin();
for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
{
const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
double f, l;
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
double umin = DBL_MAX, umax = -DBL_MAX;
SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
if ( !nIt->more() ) // no nodes on edge, only on vertices
{
umin = l;
umax = f;
}
else {
while ( nIt->more() ) {
const SMDS_MeshNode* node = nIt->next();
// check if node is medium
if ( theCreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
continue;
SMDS_EdgePositionPtr epos = node->GetPosition();
double u = epos->GetUParameter();
if ( u < umin )
umin = u;
if ( u > umax )
umax = u;
}
}
bool isFirstCommon = ( *aUIt == f );
gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
double dist = thisUV.SquareDistance( uv );
if ( dist > maxDist ) {
maxDist = dist;
nextUV = uv;
}
}
R2 uv0, uv1, uv2;
uv0.x = thisUV.X(); uv0.y = thisUV.Y();
uv1.x = nextUV.X(); uv1.y = nextUV.Y();
uv2.x = thisUV.X(); uv2.y = thisUV.Y();
uv1.x *= theScaleX; uv1.y *= theScaleY;
if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
{
double step = thisUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
// move theUV along the normal by the step
N *= step;
MESSAGE("--fixCommonVertexUV move(" << theUV.x << " " << theUV.x
<< ") by (" << N.X() << " " << N.Y() << ")"
<< endl << "--- MAX DIST " << maxDist);
theUV.x += N.X();
theUV.y += N.Y();
return true;
}
return false;
}
//=============================================================================
/*!
*
*/
//=============================================================================
bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires,
R2 * uvslf,
vector<const SMDS_MeshNode*>& mefistoToDS,
double scalex,
double scaley)
{
// to avoid passing same uv points for a vertex common to 2 wires
TopoDS_Face F;
TopTools_IndexedDataMapOfShapeListOfShape VWMap;
if ( wires.size() > 1 )
{
F = TopoDS::Face( _helper->GetSubShape() );
TopExp::MapShapesAndAncestors( F, TopAbs_VERTEX, TopAbs_WIRE, VWMap );
int nbVertices = 0;
for ( size_t iW = 0; iW < wires.size(); ++iW )
nbVertices += wires[ iW ]->NbEdges();
if ( nbVertices == VWMap.Extent() )
VWMap.Clear(); // wires have no common vertices
}
int m = 0;
for ( size_t iW = 0; iW < wires.size(); ++iW )
{
const vector<UVPtStruct>& uvPtVec = wires[ iW ]->GetUVPtStruct();
if ((int) uvPtVec.size() != wires[ iW ]->NbPoints() ) {
return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Unexpected nb of points on wire ")
<< iW << ": " << uvPtVec.size()<<" != "<<wires[ iW ]->NbPoints()
<< ", probably because of invalid node parameters on geom edges");
}
if ( m + uvPtVec.size()-1 > mefistoToDS.size() ) {
MESSAGE("Wrong mefistoToDS.size: "<<mefistoToDS.size()<<" < "<<m + uvPtVec.size()-1);
return error("Internal error");
}
list< int > mOnVertex;
vector<UVPtStruct>::const_iterator uvPt = uvPtVec.begin();
for ( ++uvPt; uvPt != uvPtVec.end(); ++uvPt )
{
// bind mefisto ID to node
mefistoToDS[m] = uvPt->node;
// set UV
uvslf[m].x = uvPt->u * scalex;
uvslf[m].y = uvPt->v * scaley;
switch ( uvPt->node->GetPosition()->GetTypeOfPosition())
{
case SMDS_TOP_VERTEX:
mOnVertex.push_back( m );
break;
case SMDS_TOP_EDGE:
// In order to detect degenerated faces easily, we replace
// nodes on a degenerated edge by node on the vertex of that edge
if ( _helper->IsDegenShape( uvPt->node->getshapeId() ))
{
int edgeID = uvPt->node->getshapeId();
SMESH_subMesh* edgeSM = _helper->GetMesh()->GetSubMeshContaining( edgeID );
SMESH_subMeshIteratorPtr smIt = edgeSM->getDependsOnIterator( /*includeSelf=*/0,
/*complexShapeFirst=*/0);
if ( smIt->more() )
{
SMESH_subMesh* vertexSM = smIt->next();
SMDS_NodeIteratorPtr nIt = vertexSM->GetSubMeshDS()->GetNodes();
if ( nIt->more() )
mefistoToDS[m] = nIt->next();
}
}
break;
default:;
}
m++;
}
int mFirst = 0, mLast = 0;
if (!mOnVertex.empty()) {
mFirst = mOnVertex.front();
mLast = m - 1;
}
list< int >::iterator mIt = mOnVertex.begin();
for ( ; mIt != mOnVertex.end(); ++mIt)
{
int m = *mIt;
if ( iW && !VWMap.IsEmpty()) { // except outer wire
// avoid passing same uv point for a vertex common to 2 wires
int vID = mefistoToDS[m]->getshapeId();
TopoDS_Vertex V = TopoDS::Vertex( _helper->GetMeshDS()->IndexToShape( vID ));
if ( fixCommonVertexUV( uvslf[m], V, F, VWMap, *_helper->GetMesh(),
scalex, scaley, _quadraticMesh )) {
myNodesOnCommonV.push_back( mefistoToDS[m] );
continue;
}
}
// prevent failure on overlapped adjacent links,
// check only links ending in vertex nodes
int mB = m - 1, mA = m + 1; // indices Before and After
if ( mB < mFirst ) mB = mLast;
if ( mA > mLast ) mA = mFirst;
fixOverlappedLinkUV (uvslf[ mB ], uvslf[ m ], uvslf[ mA ]);
}
}
#ifdef DUMP_POINTS
cout << "MEFISTO INPUT************" << endl;
for ( int i =0; i < m; ++i )
cout << i << ": \t" << uvslf[i].x << ", " << uvslf[i].y
<< " Node " << mefistoToDS[i]->GetID()<< endl;
#endif
return true;
}
//=============================================================================
/*!
*
*/
//=============================================================================
void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & /*aMesh*/,
const TopoDS_Face & aFace,
double & scalex,
double & scaley)
{
TopoDS_Wire W = BRepTools::OuterWire(aFace);
double xmin = 1.e300; // min & max of face 2D parametric coord.
double xmax = -1.e300;
double ymin = 1.e300;
double ymax = -1.e300;
const int nbp = 23;
scalex = 1;
scaley = 1;
TopExp_Explorer wexp(W, TopAbs_EDGE);
for ( ; wexp.More(); wexp.Next())
{
const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
double f, l;
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, aFace, f, l);
if ( C2d.IsNull() ) continue;
double du = (l - f) / double (nbp);
for (int i = 0; i <= nbp; i++)
{
double param = f + double (i) * du;
gp_Pnt2d p = C2d->Value(param);
if (p.X() < xmin)
xmin = p.X();
if (p.X() > xmax)
xmax = p.X();
if (p.Y() < ymin)
ymin = p.Y();
if (p.Y() > ymax)
ymax = p.Y();
}
}
double xmoy = (xmax + xmin) / 2.;
double ymoy = (ymax + ymin) / 2.;
double xsize = xmax - xmin;
double ysize = ymax - ymin;
TopLoc_Location L;
Handle(Geom_Surface) S = BRep_Tool::Surface(aFace,L); // 3D surface
double length_x = 0;
double length_y = 0;
gp_Pnt PX0 = S->Value(xmin, ymoy);
gp_Pnt PY0 = S->Value(xmoy, ymin);
double dx = xsize / double (nbp);
double dy = ysize / double (nbp);
for (int i = 1; i <= nbp; i++)
{
double x = xmin + double (i) * dx;
gp_Pnt PX = S->Value(x, ymoy);
double y = ymin + double (i) * dy;
gp_Pnt PY = S->Value(xmoy, y);
length_x += PX.Distance(PX0);
length_y += PY.Distance(PY0);
PX0 = PX;
PY0 = PY;
}
scalex = length_x / xsize;
scaley = length_y / ysize;
double xyratio = xsize*scalex/(ysize*scaley);
const double maxratio = 1.e2;
if (xyratio > maxratio) {
scaley *= xyratio / maxratio;
}
else if (xyratio < 1./maxratio) {
scalex *= 1 / xyratio / maxratio;
}
}
// namespace
// {
// bool isDegenTria( const SMDS_MeshNode * nn[3] )
// {
// SMESH_TNodeXYZ p1( nn[0] );
// SMESH_TNodeXYZ p2( nn[1] );
// SMESH_TNodeXYZ p3( nn[2] );
// gp_XYZ vec1 = p2 - p1;
// gp_XYZ vec2 = p3 - p1;
// gp_XYZ cross = vec1 ^ vec2;
// const double eps = 1e-100;
// return ( fabs( cross.X() ) < eps &&
// fabs( cross.Y() ) < eps &&
// fabs( cross.Z() ) < eps );
// }
// }
//=============================================================================
/*!
*
*/
//=============================================================================
void StdMeshers_MEFISTO_2D::StoreResult(Z nbst, R2 * uvst, Z nbt, Z * nust,
vector< const SMDS_MeshNode*>&mefistoToDS,
double scalex, double scaley)
{
_helper->SetElementsOnShape( true );
TopoDS_Face F = TopoDS::Face( _helper->GetSubShape() );
Handle(Geom_Surface) S = BRep_Tool::Surface( F );
//const size_t nbInputNodes = mefistoToDS.size();
Z n = mefistoToDS.size(); // nb input points
mefistoToDS.resize( nbst );
for ( ; n < nbst; n++)
{
if (!mefistoToDS[n])
{
double u = uvst[n][0] / scalex;
double v = uvst[n][1] / scaley;
gp_Pnt P = S->Value(u, v);
mefistoToDS[n] = _helper->AddNode( P.X(), P.Y(), P.Z(), 0, u, v );
}
}
Z m = 0;
// triangle points must be in trigonometric order if face is Forward
// else they must be put clockwise
int i1 = 1, i2 = 2;
if ( F.Orientation() != TopAbs_FORWARD )
std::swap( i1, i2 );
const SMDS_MeshNode * nn[3];
for (n = 1; n <= nbt; n++)
{
// const bool allNodesAreOld = ( nust[m + 0] <= nbInputNodes &&
// nust[m + 1] <= nbInputNodes &&
// nust[m + 2] <= nbInputNodes );
nn[ 0 ] = mefistoToDS[ nust[m++] - 1 ];
nn[ 1 ] = mefistoToDS[ nust[m++] - 1 ];
nn[ 2 ] = mefistoToDS[ nust[m++] - 1 ];
m++;
// avoid creating degenetrated faces
bool isDegen = ( _helper->HasDegeneratedEdges() &&
( nn[0] == nn[1] || nn[1] == nn[2] || nn[2] == nn[0] ));
// It was an attempt to fix a problem of a zero area face whose all nodes
// are on one staight EDGE. But omitting this face makes a hole in the mesh :(
// if ( !isDegen && allNodesAreOld )
// isDegen = isDegenTria( nn );
if ( !isDegen )
_helper->AddFace( nn[0], nn[i1], nn[i2] );
}
// remove bad elements built on vertices shared by wires
list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
for ( ; itN != myNodesOnCommonV.end(); itN++ )
{
const SMDS_MeshNode* node = *itN;
SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
while ( invElemIt->more() )
{
const SMDS_MeshElement* elem = invElemIt->next();
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
int nbSame = 0;
while ( itN->more() )
if ( itN->next() == node)
nbSame++;
if (nbSame > 1) {
MESSAGE( "RM bad element " << elem->GetID());
_helper->GetMeshDS()->RemoveElement( elem );
}
}
}
}

View File

@ -1,91 +0,0 @@
// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// SMESH SMESH : implementation of SMESH idl descriptions
// File : StdMeshers_MEFISTO_2D.hxx
// Moved here from SMESH_MEFISTO_2D.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
//
#ifndef _StdMeshers_MEFISTO_2D_HXX_
#define _StdMeshers_MEFISTO_2D_HXX_
#include "SMESH_StdMeshers.hxx"
#include "SMESH_Algo.hxx"
class TopoDS_Face;
class StdMeshers_MaxElementArea;
class StdMeshers_LengthFromEdges;
class SMDS_MeshNode;
class SMESH_MesherHelper;
class StdMeshers_FaceSide;
#include <vector>
#include <list>
#include "Rn.h"
class STDMESHERS_EXPORT StdMeshers_MEFISTO_2D: public SMESH_2D_Algo
{
public:
StdMeshers_MEFISTO_2D(int hypId, SMESH_Gen* gen);
virtual ~StdMeshers_MEFISTO_2D();
virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
SMESH_Hypothesis::Hypothesis_Status& aStatus);
virtual bool Compute(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape);
virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
MapShapeNbElems& aResMap);
typedef boost::shared_ptr< StdMeshers_FaceSide> StdMeshers_FaceSidePtr;
typedef std::vector< StdMeshers_FaceSidePtr > TWireVector;
bool LoadPoints(TWireVector & wires,
R2* uvslf,
std::vector< const SMDS_MeshNode*>& mefistoToDS,
double scalex, double scaley);
void ComputeScaleOnFace(SMESH_Mesh& aMesh,
const TopoDS_Face& aFace,
double& scalex,
double& scaley);
void StoreResult (Z nbst, R2* uvst, Z nbt, Z* nust,
std::vector< const SMDS_MeshNode*>& mefistoToDS,
double scalex, double scaley);
protected:
double _edgeLength;
double _maxElementArea;
const StdMeshers_MaxElementArea* _hypMaxElementArea;
const StdMeshers_LengthFromEdges* _hypLengthFromEdges;
std::list<const SMDS_MeshNode*> myNodesOnCommonV;
SMESH_MesherHelper* _helper; // tool for working with quadratic elements
};
#endif

View File

@ -123,10 +123,6 @@
<source>ICON_SMESH_TREE_ALGO_Hexa_3D</source>
<translation>mesh_tree_algo_hexa.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_ALGO_MEFISTO_2D</source>
<translation>mesh_tree_algo_mefisto.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_ALGO_PolygonPerFace_2D</source>
<translation>mesh_tree_algo_polygon.png</translation>
@ -289,7 +285,7 @@
</message>
<message>
<source>ICON_SMESH_TREE_HYPO_TrianglePreference</source>
<translation>mesh_tree_algo_mefisto.png</translation>
<translation>mesh_tree_algo_tri.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_HYPO_QuadraticMesh</source>

View File

@ -39,12 +39,6 @@ INCLUDE_DIRECTORIES(
${PROJECT_BINARY_DIR}/idl
)
IF(SALOME_SMESH_ENABLE_MEFISTO)
INCLUDE_DIRECTORIES(
${PROJECT_SOURCE_DIR}/src/MEFISTO2
)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
# additional preprocessor / compiler flags
ADD_DEFINITIONS(
${OpenCASCADE_DEFINITIONS}
@ -122,9 +116,6 @@ SET(StdMeshersEngine_HEADERS
StdMeshers_PolyhedronPerSolid_3D_i.hxx
StdMeshers_BlockRenumber_i.hxx
)
IF(SALOME_SMESH_ENABLE_MEFISTO)
SET(StdMeshersEngine_HEADERS ${StdMeshersEngine_HEADERS} StdMeshers_MEFISTO_2D_i.hxx)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
# --- sources ---
# sources / static
@ -180,10 +171,6 @@ SET(StdMeshersEngine_SOURCES
StdMeshers_BlockRenumber_i.cxx
)
IF(SALOME_SMESH_ENABLE_MEFISTO)
SET(StdMeshersEngine_SOURCES ${StdMeshersEngine_SOURCES} StdMeshers_MEFISTO_2D_i.cxx)
ENDIF(SALOME_SMESH_ENABLE_MEFISTO)
# --- rules ---
ADD_LIBRARY(StdMeshersEngine ${StdMeshersEngine_SOURCES})

View File

@ -1,81 +0,0 @@
// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
// File : StdMeshers_MEFISTO_2D_i.cxx
// Moved here from SMESH_MEFISTO_2D_i.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
// $Header$
//
#include "StdMeshers_MEFISTO_2D_i.hxx"
#include "SMESH_Gen.hxx"
#include "Utils_CorbaException.hxx"
#include "utilities.h"
using namespace std;
//=============================================================================
/*!
* StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i
*
* Constructor
*/
//=============================================================================
StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA,
::SMESH_Gen* theGenImpl )
: SALOME::GenericObj_i( thePOA ),
SMESH_Hypothesis_i( thePOA ),
SMESH_Algo_i( thePOA ),
SMESH_2D_Algo_i( thePOA )
{
myBaseImpl = new ::StdMeshers_MEFISTO_2D( theGenImpl->GetANewId(),
theGenImpl );
}
//=============================================================================
/*!
* StdMeshers_MEFISTO_2D_i::~StdMeshers_MEFISTO_2D_i
*
* Destructor
*/
//=============================================================================
StdMeshers_MEFISTO_2D_i::~StdMeshers_MEFISTO_2D_i()
{
}
//=============================================================================
/*!
* StdMeshers_MEFISTO_2D_i::GetImpl
*
* Get implementation
*/
//=============================================================================
::StdMeshers_MEFISTO_2D* StdMeshers_MEFISTO_2D_i::GetImpl()
{
return ( ::StdMeshers_MEFISTO_2D* )myBaseImpl;
}

View File

@ -1,62 +0,0 @@
// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
// File : StdMeshers_MEFISTO_2D_i.hxx
// Moved here from SMESH_MEFISTO_2D_i.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
// $Header$
//
#ifndef _StdMeshers_MEFISTO_2D_I_HXX_
#define _StdMeshers_MEFISTO_2D_I_HXX_
#include "SMESH_StdMeshers_I.hxx"
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
#include "SMESH_2D_Algo_i.hxx"
#include "StdMeshers_MEFISTO_2D.hxx"
class SMESH_Gen;
// ======================================================
// Triangle (MEFISTO) 2d algorithm
// ======================================================
class STDMESHERS_I_EXPORT StdMeshers_MEFISTO_2D_i:
public virtual POA_StdMeshers::StdMeshers_MEFISTO_2D,
public virtual SMESH_2D_Algo_i
{
public:
// Constructor
StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA,
::SMESH_Gen* theGenImpl );
// Destructor
virtual ~StdMeshers_MEFISTO_2D_i();
// Get implementation
::StdMeshers_MEFISTO_2D* GetImpl();
};
#endif

View File

@ -77,9 +77,6 @@
#include "StdMeshers_UseExisting_1D2D_i.hxx"
#include "StdMeshers_ViscousLayers2D_i.hxx"
#include "StdMeshers_ViscousLayers_i.hxx"
#ifdef ENABLE_MEFISTO
#include "StdMeshers_MEFISTO_2D_i.hxx"
#endif
namespace SMESH {
class ApplicableToAny
@ -214,10 +211,6 @@ STDMESHERS_I_EXPORT
// Algorithms
else if (strcmp(aHypName, "Regular_1D") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_Regular_1D_i>;
#ifdef ENABLE_MEFISTO
else if (strcmp(aHypName, "MEFISTO_2D") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_MEFISTO_2D_i>;
#endif
else if (strcmp(aHypName, "Quadrangle_2D") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_Quadrangle_2D_i, StdMeshers_Quadrangle_2D_i>;
else if (strcmp(aHypName, "QuadFromMedialAxis_1D2D") == 0)

View File

@ -87,12 +87,12 @@ smesh.SetName(hypNbSeg, "Nb. Segments")
#--------------------------Max. Element Area
maxElementArea = 200
algoMef = mesh.Triangle()
listHyp = algoMef.GetCompatibleHypothesis()
print(algoMef.GetName())
algoMef.SetName("Triangle (Mefisto)")
algoTri = mesh.Triangle()
listHyp = algoTri.GetCompatibleHypothesis()
print(algoTri.GetName())
algoTri.SetName("Triangle")
hypArea200 = algoMef.MaxElementArea(maxElementArea)
hypArea200 = algoTri.MaxElementArea(maxElementArea)
print(hypArea200.GetName())
print(hypArea200.GetMaxElementArea())
smesh.SetName(hypArea200, "Max. Element Area")

View File

@ -69,9 +69,9 @@ smesh.SetName(hypNbSeg1, "NumberOfSegments_" + str(numberOfSegments1))
maxElementArea = 30
algoMef = mesh1.Triangle()
algoMef.SetName("MEFISTO_2D")
hypArea = algoMef.MaxElementArea(maxElementArea)
algoTri = mesh1.Triangle()
algoTri.SetName("Triangle")
hypArea = algoTri.MaxElementArea(maxElementArea)
smesh.SetName(hypArea, "MaxElementArea_" + str(maxElementArea))

View File

@ -129,8 +129,8 @@ smesh.SetName(hAvLength, "AverageLength_"+str(theAverageLength))
print("-------------------------- MaxElementArea")
theMaxElementArea = 20
algoMef = mesh.Triangle(smeshBuilder.MEFISTO)
hArea = algoMef.MaxElementArea( theMaxElementArea )
algoTri = mesh.Triangle()
hArea = algoTri.MaxElementArea( theMaxElementArea )
print(hArea.GetName())
print(hArea.GetId())
print(hArea.GetMaxElementArea())

View File

@ -149,8 +149,8 @@ print("-------------------------- MaxElementArea")
maxElementArea = 0.1
mefisto2D = mesh.Triangle()
hypArea = mefisto2D.MaxElementArea(maxElementArea)
triangle = mesh.Triangle()
hypArea = triangle.MaxElementArea(maxElementArea)
print(hypArea.GetName())
print(hypArea.GetId())
print(hypArea.GetMaxElementArea())

View File

@ -103,8 +103,8 @@ print("-------------------------- MaxElementArea")
maxElementArea = 500
mefisto2D = mesh.Triangle()
hypArea = mefisto2D.MaxElementArea(maxElementArea)
triangle = mesh.Triangle()
hypArea = triangle.MaxElementArea(maxElementArea)
print(hypArea.GetName())
print(hypArea.GetId())
print(hypArea.GetMaxElementArea())

View File

@ -113,8 +113,8 @@ print("-------------------------- MaxElementArea")
maxElementArea = 500
mefisto2D = mesh.Triangle()
hypArea = mefisto2D.MaxElementArea(maxElementArea)
triangle = mesh.Triangle()
hypArea = triangle.MaxElementArea(maxElementArea)
print(hypArea.GetName())
print(hypArea.GetId())
print(hypArea.GetMaxElementArea())

View File

@ -72,8 +72,8 @@ print("-------------------------- MaxElementArea")
maxElementArea = 500
mefisto2D = mesh.Triangle()
hypArea = mefisto2D.MaxElementArea(maxElementArea)
triangle = mesh.Triangle()
hypArea = triangle.MaxElementArea(maxElementArea)
print(hypArea.GetName())
print(hypArea.GetId())
print(hypArea.GetMaxElementArea())

View File

@ -71,23 +71,11 @@ print(hypNbSeg.GetId())
print(hypNbSeg.GetNumberOfSegments())
smesh.SetName(hypNbSeg, "NumberOfSegments_" + str(numberOfSegments))
## print "-------------------------- MaxElementArea"
## maxElementArea = 80
## mefisto2D = mesh.Triangle()
## mefisto2D.SetName("MEFISTO_2D")
## hypArea = mefisto2D.MaxElementArea(maxElementArea)
## print hypArea.GetName()
## print hypArea.GetId()
## print hypArea.GetMaxElementArea()
## smesh.SetName(hypArea, "MaxElementArea_" + str(maxElementArea))
print("-------------------------- LengthFromEdges")
mefisto2D = mesh.Triangle()
mefisto2D.SetName("MEFISTO_2D")
hypLengthFromEdges = mefisto2D.LengthFromEdges()
triangle = mesh.Triangle()
triangle.SetName("Triangle")
hypLengthFromEdges = triangle.LengthFromEdges()
print(hypLengthFromEdges.GetName())
print(hypLengthFromEdges.GetId())
smesh.SetName(hypLengthFromEdges, "LengthFromEdges")

View File

@ -85,8 +85,8 @@ smesh.SetName(hypLength, "LocalLength_" + str(lengthOfSegments))
print("-------------------------- LengthFromEdges")
mefisto2D = mesh.Triangle()
hypLengthFromEdge = mefisto2D.LengthFromEdges()
triangle = mesh.Triangle()
hypLengthFromEdge = triangle.LengthFromEdges()
print(hypLengthFromEdge.GetName())
print(hypLengthFromEdge.GetId())
smesh.SetName(hypLengthFromEdge,"LengthFromEdge")

View File

@ -128,7 +128,7 @@ smesh.SetName(hypNbSeg, "NumberOfSegments_" + str(numberOfSegment))
maxElementArea = 20
algo2 = mesh.Triangle(smeshBuilder.MEFISTO)
algo2 = mesh.Triangle()
hypArea = algo2.MaxElementArea(maxElementArea)
print(hypArea.GetName())
print(hypArea.GetId())

View File

@ -69,34 +69,25 @@ mesh = smesh.Mesh(box, "Meshbox")
print("-------------------------- add hypothesis to box")
algo_1 = mesh.Segment(box)
hyp = algo_1.LocalLength(100)
hyp = mesh.Segment(box).LocalLength(100)
print(hyp.GetName())
print(hyp.GetId())
print(hyp.GetLength())
algo_2 = mesh.Triangle(smeshBuilder.MEFISTO, box)
hyp = algo_2.MaxElementArea(5000)
hyp = mesh.Triangle().MaxElementArea(5000)
print(hyp.GetName())
print(hyp.GetId())
print(hyp.GetMaxElementArea())
smesh.SetName(algo_2.GetSubMesh(), "SubMeshBox")
print("-------------------------- add hypothesis to edge")
edge = salome.IDToObject(ide)
algo_3 = mesh.Segment(edge)
hyp = algo_3.LocalLength(100)
hyp = mesh.Segment(edge).LocalLength(100)
print(hyp.GetName())
print(hyp.GetId())
print(hyp.GetLength())
smesh.SetName(algo_3.GetSubMesh(), "SubMeshEdge")
print("-------------------------- compute face")
face = salome.IDToObject(idf)

View File

@ -55,18 +55,17 @@ algo1 = mesh.Segment()
algo1.NumberOfSegments(10)
# Set 2D algorithm/hypotheses to mesh
algo2 = mesh.Triangle(smeshBuilder.MEFISTO)
algo2 = mesh.Triangle()
algo2.MaxElementArea(10)
# Create submesh on face
algo3 = mesh.Segment(face)
algo3.NumberOfSegments(10)
algo4 = mesh.Triangle(smeshBuilder.MEFISTO, face)
algo4 = mesh.Triangle(face)
algo4.MaxElementArea(100)
submesh = algo4.GetSubMesh()
smesh.SetName(submesh, "SubMeshFace")
mesh.Compute()
faces = submesh.GetElementsByType(SMESH.FACE)

View File

@ -59,15 +59,10 @@ smesh = smeshBuilder.New()
# multiples meshes built in parallel, complex and numerous mesh edition (performance)
Mesh_1 = smesh.Mesh(Box_1_1)
Mesh_1.Segment().LocalLength(5)
Mesh_1.Triangle()
Regular_1D = Mesh_1.Segment()
Local_Length_1 = Regular_1D.LocalLength(5)
MEFISTO_2D = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO)
ok = Mesh_1.Compute()
if not ok:
if not Mesh_1.Compute():
raise Exception("Error when computing Mesh_1")
edge_ox_1 = Mesh_1.GroupOnGeom(edge_ox,'edge_ox',SMESH.EDGE)