STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
SET(${PROJECT_NAME_UC}_MAJOR_VERSION 8)
-SET(${PROJECT_NAME_UC}_MINOR_VERSION 3)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 4)
SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
SET(${PROJECT_NAME_UC}_VERSION
${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
OPTION(SALOME_BUILD_GUI "Enable GUI" ON)
OPTION(SALOME_SMESH_USE_CGNS "Enable import/export to CGNS format" OFF)
OPTION(SALOME_SMESH_USE_TBB "Enable parallel computation" OFF)
+OPTION(SALOME_SMESH_DYNLOAD_LOCAL "Load plug-ins' symbols locally (Linux only)" ON)
+
+IF(SALOME_SMESH_DYNLOAD_LOCAL)
+ ADD_DEFINITIONS(-DDYNLOAD_LOCAL)
+ENDIF(SALOME_SMESH_DYNLOAD_LOCAL)
#On Linux use Fortran to compile MEFISTO2D
IF(NOT WIN32)
ADD_DEFINITIONS(-DENABLE_MEFISTO)
ENDIF(NOT WIN32)
-MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_SMESH_USE_CGNS SALOME_SMESH_USE_TBB)
+MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_SMESH_USE_CGNS SALOME_SMESH_USE_TBB SALOME_SMESH_DYNLOAD_LOCAL)
# Prerequisites
# =============
# Find "big" prerequisites first - they reference themselves many others
-# -> this can help finding the smaller prerequisites and detect conficts.
+# -> this can help finding the smaller prerequisites and detect conflicts.
# In our case KERNEL has already loaded many prereq:
##
2004-01-05 16:14 Jerome Robert <jerome.robert@eads.net>
- * adm_local/unix/config_files/check_Netgen.m4: Fix a mispelled
+ * adm_local/unix/config_files/check_Netgen.m4: Fix a misspelled
environment variable for idl python
2004-01-05 14:28 tag V1_3_1
2004-01-05 09:05 Jerome Robert <jerome.robert@eads.net>
* src/: SMDS/SMDS_Mesh.cxx, SMESHDS/SMESHDS_Document.cxx: [Bug
- SMESH4830] bug in instal with gcc 2.95. Bug fixed. Note: SGI say
+ SMESH4830] bug in install with gcc 2.95. Bug fixed. Note: SGI say
that <algorithm> is requiered to use set_intersection (see
http://www.sgi.com/tech/stl/set_intersection.html).
2003-12-15 13:15 Nadir Bouhamou <nadir.bouhamou@cea.fr>
* src/SMESHDS/SMESHDS_Script.cxx: correct a small bug found by the
- EDF developpement team (PN and AT) : AddVolume in the case of a
+ EDF development team (PN and AT) : AddVolume in the case of a
Tetrahedron.
2003-12-11 09:51 Jerome Robert <jerome.robert@eads.net>
* idl/Makefile.in, adm_local/unix/make_commence.in,
adm_local/unix/make_omniorb.in, build_configure,
- configure.in.base: NRI : Update IDL Dependancies.
+ configure.in.base: NRI : Update IDL Dependencies.
2003-05-28 07:20 Nicolas Rejneri <nicolas.rejneri@opencascade.com>
Pre-requisites
--------------
-SALOME platform relies on a set of third-party softwares; some of them are needed
+SALOME platform relies on a set of third-party software; some of them are needed
at build time only, while other ones are needed in runtime also.
For more information about the pre-requisites please visit SALOME platform web
# - Config file for the @PROJECT_NAME@ package
# It defines the following variables.
-# Specific to the pacakge @PROJECT_NAME@ itself:
+# Specific to the package @PROJECT_NAME@ itself:
# @PROJECT_NAME_UC@_ROOT_DIR_EXP - the root path of the installation providing this CMake file
#
-# Copyright (C) 2012-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2017 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
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
-# examples that can't be used for testing because they use external mesher plug-ins
-SET(BAD_TESTS
- 3dmesh.py
- a3DmeshOnModified2Dmesh.py
- creating_meshes_ex01.py
- creating_meshes_ex03.py
- creating_meshes_ex05.py
- defining_hypotheses_ex06.py
- defining_hypotheses_ex09.py
- defining_hypotheses_ex17.py
- filters_ex02.py
- filters_ex08.py
- filters_ex23.py
- filters_ex24.py
- filters_ex25.py
- filters_ex32.py
- filters_ex35.py
- generate_flat_elements.py
- modifying_meshes_ex26.py
- notebook_smesh.py
- quality_controls_ex06.py
- quality_controls_ex20.py
- quality_controls_ex21.py
- quality_controls_ex22.py
- viewing_meshes_ex01.py
- )
-
-SET(GOOD_TESTS
- cartesian_algo.py
- creating_meshes_ex02.py
- creating_meshes_ex04.py
- creating_meshes_ex06.py
- creating_meshes_ex07.py
- creating_meshes_ex08.py
- defining_hypotheses_ex01.py
- defining_hypotheses_ex02.py
- defining_hypotheses_ex03.py
- defining_hypotheses_ex04.py
- defining_hypotheses_ex05.py
- defining_hypotheses_ex07.py
- defining_hypotheses_ex08.py
- defining_hypotheses_ex10.py
- defining_hypotheses_ex11.py
- defining_hypotheses_ex12.py
- defining_hypotheses_ex13.py
- defining_hypotheses_ex14.py
- defining_hypotheses_ex15.py
- defining_hypotheses_ex16.py
- defining_hypotheses_adaptive1d.py
- filters_ex01.py
- filters_ex03.py
- filters_ex04.py
- filters_ex05.py
- filters_ex06.py
- filters_ex07.py
- filters_ex09.py
- filters_ex10.py
- filters_ex11.py
- filters_ex12.py
- filters_ex13.py
- filters_ex14.py
- filters_ex15.py
- filters_ex16.py
- filters_ex17.py
- filters_ex18.py
- filters_ex19.py
- filters_ex20.py
- filters_ex21.py
- filters_ex22.py
- filters_ex26.py
- filters_ex27.py
- filters_ex28.py
- filters_ex29.py
- filters_ex30.py
- filters_ex31.py
- filters_ex33.py
- filters_ex34.py
- filters_ex36.py
- filters_ex37.py
- filters_ex38.py
- filters_ex39.py
- filters_node_nb_conn.py
- filters_belong2group.py
- grouping_elements_ex01.py
- grouping_elements_ex02.py
- grouping_elements_ex03.py
- grouping_elements_ex04.py
- grouping_elements_ex05.py
- grouping_elements_ex06.py
- grouping_elements_ex07.py
- grouping_elements_ex08.py
- measurements_ex01.py
- measurements_ex02.py
- modifying_meshes_ex01.py
- modifying_meshes_ex02.py
- modifying_meshes_ex03.py
- modifying_meshes_ex04.py
- modifying_meshes_ex05.py
- modifying_meshes_ex06.py
- modifying_meshes_ex07.py
- modifying_meshes_ex08.py
- modifying_meshes_ex09.py
- modifying_meshes_ex10.py
- modifying_meshes_ex11.py
- modifying_meshes_ex12.py
- modifying_meshes_ex13.py
- modifying_meshes_ex14.py
- modifying_meshes_ex15.py
- modifying_meshes_ex16.py
- modifying_meshes_ex17.py
- modifying_meshes_ex18.py
- modifying_meshes_ex19.py
- modifying_meshes_ex20.py
- modifying_meshes_ex21.py
- modifying_meshes_ex22.py
- modifying_meshes_ex23.py
- modifying_meshes_ex24.py
- modifying_meshes_ex25.py
- prism_3d_algo.py
- quality_controls_ex01.py
- quality_controls_ex02.py
- quality_controls_ex03.py
- quality_controls_ex04.py
- quality_controls_ex05.py
- quality_controls_ex07.py
- quality_controls_ex08.py
- quality_controls_ex09.py
- quality_controls_ex10.py
- quality_controls_ex11.py
- quality_controls_ex12.py
- quality_controls_ex13.py
- quality_controls_ex14.py
- quality_controls_ex15.py
- quality_controls_ex16.py
- quality_controls_ex17.py
- quality_controls_ex18.py
- quality_controls_ex19.py
- transforming_meshes_ex01.py
- transforming_meshes_ex02.py
- transforming_meshes_ex03.py
- transforming_meshes_ex04.py
- transforming_meshes_ex05.py
- transforming_meshes_ex06.py
- transforming_meshes_ex07.py
- transforming_meshes_ex08.py
- transforming_meshes_ex09.py
- transforming_meshes_ex10.py
- transforming_meshes_ex11.py
- transforming_meshes_ex12.py
- transforming_meshes_ex13.py
- use_existing_faces.py
- viewing_meshes_ex02.py
- split_biquad.py
-)
-
-SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} testme.py)
+INCLUDE(tests.set)
SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env)
INSTALL(FILES CTestTestfileInstall.cmake
DESTINATION ${TEST_INSTALL_DIRECTORY}
RENAME CTestTestfile.cmake)
+INSTALL(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY})
-# Copyright (C) 2015-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2015-2017 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
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+INCLUDE(tests.set)
+
SET(SALOME_TEST_DRIVER "$ENV{ABSOLUTE_APPLI_PATH}/bin/salome/appliskel/salome_test_driver.py")
SET(COMPONENT_NAME SMESH)
SET(TIMEOUT 300)
-SET(GOOD_TESTS
- cartesian_algo
- creating_meshes_ex02
- creating_meshes_ex04
- creating_meshes_ex06
- creating_meshes_ex07
- creating_meshes_ex08
- defining_hypotheses_ex01
- defining_hypotheses_ex02
- defining_hypotheses_ex03
- defining_hypotheses_ex04
- defining_hypotheses_ex05
- defining_hypotheses_ex07
- defining_hypotheses_ex08
- defining_hypotheses_ex10
- defining_hypotheses_ex11
- defining_hypotheses_ex12
- defining_hypotheses_ex13
- defining_hypotheses_ex14
- defining_hypotheses_ex15
- defining_hypotheses_ex16
- defining_hypotheses_adaptive1d
- filters_ex01
- filters_ex03
- filters_ex04
- filters_ex05
- filters_ex06
- filters_ex07
- filters_ex09
- filters_ex10
- filters_ex11
- filters_ex12
- filters_ex13
- filters_ex14
- filters_ex15
- filters_ex16
- filters_ex17
- filters_ex18
- filters_ex19
- filters_ex20
- filters_ex21
- filters_ex22
- filters_ex26
- filters_ex27
- filters_ex28
- filters_ex29
- filters_ex30
- filters_ex31
- filters_ex33
- filters_ex34
- filters_ex36
- grouping_elements_ex01
- grouping_elements_ex02
- grouping_elements_ex03
- grouping_elements_ex04
- grouping_elements_ex05
- grouping_elements_ex06
- grouping_elements_ex07
- grouping_elements_ex08
- measurements_ex01
- measurements_ex02
- modifying_meshes_ex01
- modifying_meshes_ex02
- modifying_meshes_ex03
- modifying_meshes_ex04
- modifying_meshes_ex05
- modifying_meshes_ex06
- modifying_meshes_ex07
- modifying_meshes_ex08
- modifying_meshes_ex09
- modifying_meshes_ex10
- modifying_meshes_ex11
- modifying_meshes_ex12
- modifying_meshes_ex13
- modifying_meshes_ex14
- modifying_meshes_ex15
- modifying_meshes_ex16
- modifying_meshes_ex17
- modifying_meshes_ex18
- modifying_meshes_ex19
- modifying_meshes_ex20
- modifying_meshes_ex21
- modifying_meshes_ex22
- modifying_meshes_ex23
- modifying_meshes_ex24
- modifying_meshes_ex25
- prism_3d_algo
- quality_controls_ex01
- quality_controls_ex02
- quality_controls_ex03
- quality_controls_ex04
- quality_controls_ex05
- quality_controls_ex07
- quality_controls_ex08
- quality_controls_ex09
- quality_controls_ex10
- quality_controls_ex11
- quality_controls_ex12
- quality_controls_ex13
- quality_controls_ex14
- quality_controls_ex15
- quality_controls_ex16
- quality_controls_ex17
- quality_controls_ex18
- quality_controls_ex19
- transforming_meshes_ex01
- transforming_meshes_ex02
- transforming_meshes_ex03
- transforming_meshes_ex04
- transforming_meshes_ex05
- transforming_meshes_ex06
- transforming_meshes_ex07
- transforming_meshes_ex08
- transforming_meshes_ex09
- transforming_meshes_ex10
- transforming_meshes_ex11
- transforming_meshes_ex12
- transforming_meshes_ex13
- use_existing_faces
- viewing_meshes_ex02
-)
-
FOREACH(tfile ${GOOD_TESTS})
- SET(TEST_NAME SMESH_${tfile})
- ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} ${tfile}.py)
+ GET_FILENAME_COMPONENT(BASE_NAME ${tfile} NAME_WE)
+ SET(TEST_NAME SMESH_${BASE_NAME})
+ ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} ${tfile})
SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
ENDFOREACH()
--- /dev/null
+# -*- coding: utf-8 -*-
+
+import sys
+import salome
+
+salome.salome_init()
+theStudy = salome.myStudy
+
+import SMESH, SALOMEDS
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New(theStudy)
+unPentaBiQuad = smesh.Mesh()
+nodeID = unPentaBiQuad.AddNode( 0, 0, 0 )
+nodeID = unPentaBiQuad.AddNode( 10, 0, 0 )
+nodeID = unPentaBiQuad.AddNode( 0, 10, 0 )
+nodeID = unPentaBiQuad.AddNode( 0, 0, 10 )
+nodeID = unPentaBiQuad.AddNode( 10, 0, 10 )
+nodeID = unPentaBiQuad.AddNode( 0, 10, 10 )
+nodeID = unPentaBiQuad.AddNode( 5, 0, 0 )
+nodeID = unPentaBiQuad.AddNode( 7, 7, 0 )
+nodeID = unPentaBiQuad.AddNode( 0, 5, 0 )
+nodeID = unPentaBiQuad.AddNode( 5, 0, 10 )
+nodeID = unPentaBiQuad.AddNode( 7, 7, 10 )
+nodeID = unPentaBiQuad.AddNode( 0, 5, 10 )
+nodeID = unPentaBiQuad.AddNode( 0, 0, 5 )
+nodeID = unPentaBiQuad.AddNode( 10, 0, 5 )
+nodeID = unPentaBiQuad.AddNode( 0, 10, 5 )
+nodeID = unPentaBiQuad.AddNode( 5, -1, 5 )
+nodeID = unPentaBiQuad.AddNode( 8, 8, 5 )
+nodeID = unPentaBiQuad.AddNode( -1, 5, 5 )
+volID = unPentaBiQuad.AddVolume( [ 4, 5, 6, 1, 2, 3, 10, 11, 12, 7, 8, 9, 13, 14, 15, 16, 17, 18 ] )
+
+infos = unPentaBiQuad.GetMeshInfo()
+print "Number of biquadratic pentahedrons:", infos[SMESH.Entity_BiQuad_Penta]
+if (infos[SMESH.Entity_BiQuad_Penta] != 1):
+ raise RuntimeError("Bad number of biquadratic pentahedrons: should be 1")
+
+## Set names of Mesh objects
+smesh.SetName(unPentaBiQuad.GetMesh(), 'unPentaBiQuad')
+
+if salome.sg.hasDesktop():
+ salome.sg.updateObjBrowser(True)
--- /dev/null
+# -*- coding: utf-8 -*-
+
+import sys
+import salome
+
+salome.salome_init()
+theStudy = salome.myStudy
+
+import GEOM
+from salome.geom import geomBuilder
+import math
+import SALOMEDS
+
+geompy = geomBuilder.New(theStudy)
+
+O = geompy.MakeVertex(0, 0, 0)
+OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+Divided_Disk_1 = geompy.MakeDividedDisk(100, 1, GEOM.SQUARE)
+geompy.addToStudy( O, 'O' )
+geompy.addToStudy( OX, 'OX' )
+geompy.addToStudy( OY, 'OY' )
+geompy.addToStudy( OZ, 'OZ' )
+geompy.addToStudy( Divided_Disk_1, 'Divided Disk_1' )
+
+import SMESH, SALOMEDS
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New(theStudy)
+aFilterManager = smesh.CreateFilterManager()
+Mesh_1 = smesh.Mesh(Divided_Disk_1)
+Regular_1D = Mesh_1.Segment()
+Number_of_Segments_1 = Regular_1D.NumberOfSegments(6)
+Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE)
+isDone = Mesh_1.Compute()
+aMaxElementLength2D0x5d7fdf0 = aFilterManager.CreateMaxElementLength2D()
+isDone = Mesh_1.QuadToTriObject( Mesh_1, )
+Mesh_1.ExtrusionSweepObjects( [ Mesh_1 ], [ Mesh_1 ], [ Mesh_1 ], [ 0, 0, 50 ], 3, 1 )
+Mesh_1.ConvertToQuadratic(0, Mesh_1,True)
+
+infos = Mesh_1.GetMeshInfo()
+print "Number of biquadratic pentahedrons:", infos[SMESH.Entity_BiQuad_Penta]
+if (infos[SMESH.Entity_BiQuad_Penta] != 1080):
+ raise RuntimeError("Bad number of biquadratic pentahedrons: should be 1080")
+
+## Set names of Mesh objects
+smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
+smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D')
+smesh.SetName(Number_of_Segments_1, 'Number of Segments_1')
+smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1')
+
+
+if salome.sg.hasDesktop():
+ salome.sg.updateObjBrowser(True)
# Extrusion
-import salome
+import salome, math
salome.salome_init()
-import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy)
-import SMESH, SALOMEDS
+import SMESH
from salome.smesh import smeshBuilder
smesh = smeshBuilder.New(salome.myStudy)
-import SMESH_mechanic
+# create an empty mesh
+mesh = smesh.Mesh()
-#smesh = SMESH_mechanic.smesh
-mesh = SMESH_mechanic.mesh
+# add a node
+mesh.AddNode( 0.,0.,0. )
-# select the top face
-faces = geompy.SubShapeAllSorted(SMESH_mechanic.shape_mesh, geompy.ShapeType["FACE"])
-face = faces[7]
-geompy.addToStudyInFather(SMESH_mechanic.shape_mesh, face, "face circular top")
+# extrude a node into a line of 10 segments along the X axis
+ids = mesh.GetNodesId()
+stepVector = [1.,0.,0.]
+nbSteps = 10
+mesh.ExtrusionSweep( ids, stepVector, nbSteps, IsNodes=True )
-# create a vector for extrusion
-point = SMESH.PointStruct(0., 0., 5.)
-vector = SMESH.DirStruct(point)
+# create some groups
+lastNode = mesh.GetNodesId()[-1]
+lastNodeGroup = mesh.MakeGroupByIds( "node %s"% lastNode, SMESH.NODE, [lastNode])
+lineGroup = mesh.MakeGroupByIds( "line", SMESH.EDGE, mesh.GetElementsId() )
-# create a group to be extruded
-GroupTri = mesh.GroupOnGeom(face, "Group of faces (extrusion)", SMESH.FACE)
+# rotate the segments around the first node to get a mesh of a disk quarter
+axisZ = [0.,0.,0., 0.,0.,1.]
+groups = mesh.RotationSweepObject( lineGroup, axisZ, math.pi/2., 10, 1e-3, MakeGroups=True, TotalAngle=True )
-# perform extrusion of the group
-mesh.ExtrusionSweepObject(GroupTri, vector, 5)
+# extrude all faces into volumes
+obj = mesh
+stepVector = [0.,0.,-1.]
+nbSteps = 5
+groups = mesh.ExtrusionSweepObject2D( obj, stepVector, nbSteps, MakeGroups=True )
+
+# remove all segments created by the last command
+for g in groups:
+ if g.GetType() == SMESH.EDGE:
+ mesh.RemoveGroupWithContents( g )
+
+# extrude all segments into faces along Z
+obj = mesh
+stepVector = [0.,0.,1.]
+mesh.ExtrusionSweepObject1D( obj, stepVector, nbSteps )
+
+# extrude a group
+lineExtruded = None
+for g in mesh.GetGroups( SMESH.FACE ):
+ if g.GetName() == "line_extruded":
+ lineExtruded = g
+ break
+obj = lineExtruded
+stepVector = [0,-5.,0.]
+nbSteps = 1
+mesh.ExtrusionSweepObject( obj, stepVector, nbSteps )
+
+# extrude all nodes and triangle faces of the disk quarter, applying a scale factor
+diskGroup = None
+for g in mesh.GetGroups( SMESH.FACE ):
+ if g.GetName() == "line_rotated":
+ diskGroup = g
+ break
+crit = [ smesh.GetCriterion( SMESH.FACE, SMESH.FT_ElemGeomType,'=',SMESH.Geom_TRIANGLE ),
+ smesh.GetCriterion( SMESH.FACE, SMESH.FT_BelongToMeshGroup,'=', diskGroup )]
+trianglesFilter = smesh.GetFilterFromCriteria( crit )
+
+nodes = [ diskGroup ]
+edges = []
+faces = [ trianglesFilter ]
+stepVector = [0,0,1]
+nbSteps = 10
+mesh.ExtrusionSweepObjects( nodes, edges, faces, stepVector, nbSteps, scaleFactors=[0.5], linearVariation=True )
+
+# extrude a cylindrical group of faces by normal
+cylGroup = None
+for g in mesh.GetGroups( SMESH.FACE ):
+ if g.GetName().startswith("node "):
+ cylGroup = g
+ break
+
+elements = cylGroup
+stepSize = 5.
+nbSteps = 2
+mesh.ExtrusionByNormal( elements, stepSize, nbSteps )
salome.sg.updateObjBrowser(True)
--- /dev/null
+# Copyright (C) 2015-2017 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
+#
+
+# examples that can't be used for testing because they use external mesher plug-ins
+SET(BAD_TESTS
+ 3dmesh.py
+ a3DmeshOnModified2Dmesh.py
+ creating_meshes_ex01.py
+ creating_meshes_ex03.py
+ creating_meshes_ex05.py
+ defining_hypotheses_ex06.py
+ defining_hypotheses_ex09.py
+ defining_hypotheses_ex17.py
+ filters_ex02.py
+ filters_ex08.py
+ filters_ex23.py
+ filters_ex24.py
+ filters_ex25.py
+ filters_ex32.py
+ filters_ex35.py
+ generate_flat_elements.py
+ modifying_meshes_ex26.py
+ notebook_smesh.py
+ quality_controls_ex06.py
+ quality_controls_ex20.py
+ quality_controls_ex21.py
+ quality_controls_ex22.py
+ viewing_meshes_ex01.py
+ )
+
+SET(GOOD_TESTS
+ cartesian_algo.py
+ create_penta_biquad.py
+ creating_meshes_ex02.py
+ creating_meshes_ex04.py
+ creating_meshes_ex06.py
+ creating_meshes_ex07.py
+ creating_meshes_ex08.py
+ defining_hypotheses_ex01.py
+ defining_hypotheses_ex02.py
+ defining_hypotheses_ex03.py
+ defining_hypotheses_ex04.py
+ defining_hypotheses_ex05.py
+ defining_hypotheses_ex07.py
+ defining_hypotheses_ex08.py
+ defining_hypotheses_ex10.py
+ defining_hypotheses_ex11.py
+ defining_hypotheses_ex12.py
+ defining_hypotheses_ex13.py
+ defining_hypotheses_ex14.py
+ defining_hypotheses_ex15.py
+ defining_hypotheses_ex16.py
+ defining_hypotheses_adaptive1d.py
+ extrusion_penta_biquad.py
+ filters_ex01.py
+ filters_ex03.py
+ filters_ex04.py
+ filters_ex05.py
+ filters_ex06.py
+ filters_ex07.py
+ filters_ex09.py
+ filters_ex10.py
+ filters_ex11.py
+ filters_ex12.py
+ filters_ex13.py
+ filters_ex14.py
+ filters_ex15.py
+ filters_ex16.py
+ filters_ex17.py
+ filters_ex18.py
+ filters_ex19.py
+ filters_ex20.py
+ filters_ex21.py
+ filters_ex22.py
+ filters_ex26.py
+ filters_ex27.py
+ filters_ex28.py
+ filters_ex29.py
+ filters_ex30.py
+ filters_ex31.py
+ filters_ex33.py
+ filters_ex34.py
+ filters_ex36.py
+ filters_ex37.py
+ filters_ex38.py
+ filters_ex39.py
+ filters_node_nb_conn.py
+ filters_belong2group.py
+ grouping_elements_ex01.py
+ grouping_elements_ex02.py
+ grouping_elements_ex03.py
+ grouping_elements_ex04.py
+ grouping_elements_ex05.py
+ grouping_elements_ex06.py
+ grouping_elements_ex07.py
+ grouping_elements_ex08.py
+ measurements_ex01.py
+ measurements_ex02.py
+ modifying_meshes_ex01.py
+ modifying_meshes_ex02.py
+ modifying_meshes_ex03.py
+ modifying_meshes_ex04.py
+ modifying_meshes_ex05.py
+ modifying_meshes_ex06.py
+ modifying_meshes_ex07.py
+ modifying_meshes_ex08.py
+ modifying_meshes_ex09.py
+ modifying_meshes_ex10.py
+ modifying_meshes_ex11.py
+ modifying_meshes_ex12.py
+ modifying_meshes_ex13.py
+ modifying_meshes_ex14.py
+ modifying_meshes_ex15.py
+ modifying_meshes_ex16.py
+ modifying_meshes_ex17.py
+ modifying_meshes_ex18.py
+ modifying_meshes_ex19.py
+ modifying_meshes_ex20.py
+ modifying_meshes_ex21.py
+ modifying_meshes_ex22.py
+ modifying_meshes_ex23.py
+ modifying_meshes_ex24.py
+ modifying_meshes_ex25.py
+ prism_3d_algo.py
+ quality_controls_ex01.py
+ quality_controls_ex02.py
+ quality_controls_ex03.py
+ quality_controls_ex04.py
+ quality_controls_ex05.py
+ quality_controls_ex07.py
+ quality_controls_ex08.py
+ quality_controls_ex09.py
+ quality_controls_ex10.py
+ quality_controls_ex11.py
+ quality_controls_ex12.py
+ quality_controls_ex13.py
+ quality_controls_ex14.py
+ quality_controls_ex15.py
+ quality_controls_ex16.py
+ quality_controls_ex17.py
+ quality_controls_ex18.py
+ quality_controls_ex19.py
+ transforming_meshes_ex01.py
+ transforming_meshes_ex02.py
+ transforming_meshes_ex03.py
+ transforming_meshes_ex04.py
+ transforming_meshes_ex05.py
+ transforming_meshes_ex06.py
+ transforming_meshes_ex07.py
+ transforming_meshes_ex08.py
+ transforming_meshes_ex09.py
+ transforming_meshes_ex10.py
+ transforming_meshes_ex11.py
+ transforming_meshes_ex12.py
+ transforming_meshes_ex13.py
+ use_existing_faces.py
+ viewing_meshes_ex02.py
+ split_biquad.py
+)
+
+SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} testme.py)
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/input $(GEOM_ROOT_DIR)/share/doc/salome/gui/GEOM/input
FILE_PATTERNS = *.doc
EXCLUDE =
+EXCLUDE_PATTERNS = tui_*.doc
IMAGE_PATH = $(GEOM_ROOT_DIR)/share/doc/salome/gui/GEOM @CMAKE_CURRENT_SOURCE_DIR@/images
EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/doc/salome/examples @CMAKE_SOURCE_DIR@/src/SMESH_SWIG
tmp2/smesh_algorithm.py \
tmp2/StdMeshersBuilder.py \
tmp2/smeshstudytools.py \
- tmp1/smeshBuilder.py
-FILE_PATTERNS =
+ tmp1/smeshBuilder.py \
+ @CMAKE_CURRENT_SOURCE_DIR@/input
+FILE_PATTERNS = tui_*.doc
IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/images
RECURSIVE = NO
-EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/src/SMESH_SWIG
+EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/src/SMESH_SWIG @CMAKE_SOURCE_DIR@/doc/salome/examples
#---------------------------------------------------------------------------
#HTML related options
#---------------------------------------------------------------------------
GENERATE_TAGFILE = smeshpy_doc.tag
SEARCHENGINE = YES
+
+#---------------------------------------------------------------------------
+#Custom commands
+#---------------------------------------------------------------------------
+ALIASES += tui_script{1}="\include \1 <a href=\"../../examples/SMESH/\1\">Download this script</a>"
Mesh generation on the geometry is performed in the bottom-up
flow: nodes on vertices are created first, then edges are divided into
-segments using nodes on vertices; the node of segments are then
+segments using nodes on vertices; the nodes of segments are then
used to mesh faces; then the nodes of faces are used to mesh
solids. This automatically assures the conformity of the mesh.
defined by two opposing faces having the same number of vertices and
edges. These two faces should be connected by quadrangle "side" faces.
+\image html prism_mesh.png "Clipping view of a mesh of a prism with non-planar base and top faces"
+
The prism is allowed to have sides composed of several faces. (A prism
side is a row of faces (or one face) connecting the corresponding edges of
the top and base faces). However, a prism
\page smeshpy_interface_page Python interface
-Python API for SALOME %Mesh module defines several classes that can
+Python API of SALOME %Mesh module defines several classes that can
be used for easy mesh creation and edition.
-Documentation for SALOME %Mesh module Python API is available in two forms:
+Documentation of SALOME %Mesh module Python API is available in two forms:
- <a href="smeshpy_doc/modules.html">Structured documentation</a>, where all methods and
classes are grouped by their functionality.
- <a href="smeshpy_doc/namespaces.html">Linear documentation</a> grouped only by classes, declared
SALOMEDS::Study GetCurrentStudy();
/*!
- * Create a hypothesis that can be shared by differents parts of the mesh.
+ * Create a hypothesis that can be shared by different parts of the mesh.
* An hypothesis is either:
* - a method used to generate or modify a part of the mesh (algorithm).
* - a parameter or a law used by an algorithm.
Entity_TriQuad_Hexa,
Entity_Penta,
Entity_Quad_Penta,
+ Entity_BiQuad_Penta,
Entity_Hexagonal_Prism,
Entity_Polyhedra,
Entity_Quad_Polyhedra,
/*!
* Enumeration for ExportToMED*()
+ * MED_V2_1 and MED_V2_2 are here for compatibility and mean respectively obsolete and MED_LATEST.
+ * MED_MINOR_0 to MED_MINOR_9 are use to specify the minor version used by MEDfichier
+ * to write MED files (major version cannot be changed).
+ * This allows backward compatibility from a newer version of SALOME to an older one:
+ * for instance, a MESH produced in SALOME 8.4 (med 3.3) can be written in med 3.2 format
+ * to be read in SALOME 8.3.
*/
enum MED_VERSION
{
MED_V2_1,
- MED_V2_2
+ MED_V2_2,
+ MED_LATEST,
+ MED_MINOR_0,
+ MED_MINOR_1,
+ MED_MINOR_2,
+ MED_MINOR_3,
+ MED_MINOR_4,
+ MED_MINOR_5,
+ MED_MINOR_6,
+ MED_MINOR_7,
+ MED_MINOR_8,
+ MED_MINOR_9
};
/*!
raises (SALOME::SALOME_Exception);
/*!
- * Export Mesh to MED_V2_1 MED format
- * Works, just the same as ExportToMEDX with MED_VERSION parameter equal to MED_V2_1
+ * Export Mesh to MED_LATEST MED format
+ * Works, just the same as ExportToMEDX with MED_VERSION parameter equal to MED_LATEST
* and overwrite parameter equal to true
* The method is kept in order to support old functionality
*/
in boolean isascii ) raises (SALOME::SALOME_Exception);
void ExportCGNS( in SMESH_IDSource meshPart,
in string file,
- in boolean overwrite ) raises (SALOME::SALOME_Exception);
+ in boolean overwrite,
+ in boolean groupElemsByType) raises (SALOME::SALOME_Exception);
void ExportGMF( in SMESH_IDSource meshPart,
in string file,
in boolean withRequiredGroups) raises (SALOME::SALOME_Exception);
*/
long FindElementByNodes(in long_array nodes);
+ /*!
+ * Return elements including all given nodes.
+ */
+ long_array GetElementsByNodes(in long_array nodes, in ElementType elem_type);
+
/*!
* Returns true if given element is polygon
*/
aVal = Max(aVal,Max(L7,L8));
break;
}
- case SMDSEntity_Quad_Penta: { // quadratic pentas
+ case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta: { // quadratic pentas
double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
}
break;
case SMDSEntity_Pyramid:
- if (len == 5){ // piramids
+ if (len == 5){ // pyramid
double L1 = getDistance(P( 1 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 4 ));
}
break;
case SMDSEntity_Penta:
- if (len == 6) { // pentaidres
+ if (len == 6) { // pentahedron
double L1 = getDistance(P( 1 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 1 ));
}
break;
case SMDSEntity_Quad_Tetra:
- if (len == 10){ // quadratic tetraidrs
+ if (len == 10){ // quadratic tetrahedron
double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 ));
}
break;
case SMDSEntity_Quad_Pyramid:
- if (len == 13){ // quadratic piramids
+ if (len == 13){ // quadratic pyramid
double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
}
break;
case SMDSEntity_Quad_Penta:
- if (len == 15){ // quadratic pentaidres
+ case SMDSEntity_BiQuad_Penta:
+ if (len >= 15){ // quadratic pentahedron
double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
break;
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
- if (len >= 20) { // quadratic hexaider
+ if (len >= 20) { // quadratic hexahedron
double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 ));
if ( shapeChanges )
{
+ // find most complex shapes
TopTools_IndexedMapOfShape shapesMap;
TopAbs_ShapeEnum shapeTypes[4] = { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX };
TopExp_Explorer sub;
bool ElementsOnShape::IsSatisfy( long elemId )
{
- const SMDS_Mesh* mesh = myMeshModifTracer.GetMesh();
- const SMDS_MeshElement* elem =
- ( myType == SMDSAbs_Node ? mesh->FindNode( elemId ) : mesh->FindElement( elemId ));
- if ( !elem || myClassifiers.empty() )
+ if ( myClassifiers.empty() )
+ return false;
+
+ const SMDS_Mesh* mesh = myMeshModifTracer.GetMesh();
+ if ( myType == SMDSAbs_Node )
+ return IsSatisfy( mesh->FindNode( elemId ));
+ return IsSatisfy( mesh->FindElement( elemId ));
+}
+
+bool ElementsOnShape::IsSatisfy (const SMDS_MeshElement* elem)
+{
+ if ( !elem )
return false;
bool isSatisfy = myAllNodesFlag, isNodeOut;
return isSatisfy;
}
+bool ElementsOnShape::IsSatisfy (const SMDS_MeshNode* node,
+ TopoDS_Shape* okShape)
+{
+ if ( !node )
+ return false;
+
+ if ( !myOctree && myClassifiers.size() > 5 )
+ {
+ myWorkClassifiers.resize( myClassifiers.size() );
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ myWorkClassifiers[ i ] = & myClassifiers[ i ];
+ myOctree = new OctreeClassifier( myWorkClassifiers );
+ }
+
+ bool isNodeOut = true;
+
+ if ( okShape || !getNodeIsOut( node, isNodeOut ))
+ {
+ SMESH_NodeXYZ aPnt = node;
+ if ( myOctree )
+ {
+ myWorkClassifiers.clear();
+ myOctree->GetClassifiersAtPoint( aPnt, myWorkClassifiers );
+
+ for ( size_t i = 0; i < myWorkClassifiers.size(); ++i )
+ myWorkClassifiers[i]->SetChecked( false );
+
+ for ( size_t i = 0; i < myWorkClassifiers.size(); ++i )
+ if ( !myWorkClassifiers[i]->IsChecked() &&
+ !myWorkClassifiers[i]->IsOut( aPnt ))
+ {
+ isNodeOut = false;
+ if ( okShape )
+ *okShape = myWorkClassifiers[i]->Shape();
+ break;
+ }
+ }
+ else
+ {
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ if ( !myClassifiers[i].IsOut( aPnt ))
+ {
+ isNodeOut = false;
+ if ( okShape )
+ *okShape = myWorkClassifiers[i]->Shape();
+ break;
+ }
+ }
+ setNodeIsOut( node, isNodeOut );
+ }
+
+ return !isNodeOut;
+}
+
void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape,
double theTol,
const Bnd_B3d* theBox )
if ( myProjFace.IsDone() && myProjFace.LowerDistance() <= myTol )
{
// check relatively to the face
- Quantity_Parameter u, v;
+ Standard_Real u, v;
myProjFace.LowerDistanceParameters(u, v);
gp_Pnt2d aProjPnt (u, v);
BRepClass_FaceClassifier aClsf ( TopoDS::Face( myShape ), aProjPnt, myTol );
bool GetAllNodes() const { return myAllNodesFlag; }
void SetShape (const TopoDS_Shape& theShape,
const SMDSAbs_ElementType theType);
+ bool IsSatisfy (const SMDS_MeshElement* elem);
+ bool IsSatisfy (const SMDS_MeshNode* node, TopoDS_Shape* okShape=0);
private:
#include "DriverCGNS_Write.hxx"
+#include "SMDS_IteratorOnIterators.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMDS_VolumeTool.hxx"
#include "SMESHDS_GroupBase.hxx"
interlaces[SMDSEntity_Quad_Penta] = ids;
cgTypes [SMDSEntity_Quad_Penta] = CGNS_ENUMV( PENTA_15 );
}
+ {
+ static int ids[] = { 0,2,1,3,5,4,8,7,6,9,11,10,14,13,12,15,16,17 }; // TODO: check CGNS ORDER
+ interlaces[SMDSEntity_BiQuad_Penta] = ids;
+ cgTypes [SMDSEntity_BiQuad_Penta] = CGNS_ENUMV( PENTA_18 );
+ }
{
static int ids[] = { 0,3,2,1,4,7,6,5 };
interlaces[SMDSEntity_Hexa] = ids;
// write into a section all successive elements of one geom type
int iSec;
vector< cgsize_t > elemData;
- SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator();
+ SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator();
+ vector< SMDS_ElemIteratorPtr > elemItVec;
+ if ( _elementsByType )
+ {
+ // create an iterator returning all elements by type
+ for ( int type = SMDSEntity_Node + 1; type < SMDSEntity_Last; ++type )
+ {
+ if ( type == SMDSEntity_Ball )
+ continue; // not supported
+ elemIt = myMesh->elementEntityIterator( SMDSAbs_EntityType( type ));
+ if ( elemIt->more() )
+ elemItVec.push_back( elemIt );
+ }
+ typedef SMDS_IteratorOnIterators< const SMDS_MeshElement*,
+ vector< SMDS_ElemIteratorPtr > > TVecIterator;
+ elemIt.reset( new TVecIterator( elemItVec ));
+ }
+
const SMDS_MeshElement* elem = elemIt->next();
while ( elem )
{
elem = elemIt->more() ? elemIt->next() : 0;
continue;
}
+ else // skip NOT SUPPORTED elements
+ {
+ while ( elemIt->more() )
+ {
+ elem = elemIt->next();
+ if ( elem->GetEntityType() != elemType )
+ break;
+ }
+ }
SMESH_Comment sectionName( cg_ElementTypeName( cgType ));
sectionName << " " << startID << " - " << cgID-1;
cgID-1, /*nbndry=*/0, &elemData[0], &iSec) != CG_OK )
return addMessage( cg_get_error(), /*fatal = */true );
}
+
// Write polyhedral volumes
// -------------------------
switch ( meshDim ) {
case 3:
switch ( group->GetType() ) {
- case SMDSAbs_Volume: location = CGNS_ENUMV( FaceCenter ); break; // !!!
- case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break; // OK
- case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break; // OK
+#if CGNS_VERSION > 3130
+ case SMDSAbs_Volume: location = CGNS_ENUMV( CellCenter ); break;
+#else
+ case SMDSAbs_Volume: location = CGNS_ENUMV( FaceCenter ); break;
+#endif
+ case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break;
+ case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break;
default:;
}
break;
case 2:
switch ( group->GetType() ) {
- case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break; // ???
- case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break; // OK
+#if CGNS_VERSION > 3130
+ case SMDSAbs_Face: location = CGNS_ENUMV( CellCenter ); break;
+#else
+ case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break;
+#endif
+ case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break;
default:;
}
break;
case 1:
- location = CGNS_ENUMV( EdgeCenter ); break; // ???
+#if CGNS_VERSION > 3130
+ location = CGNS_ENUMV( CellCenter ); break;
+#else
+ location = CGNS_ENUMV( EdgeCenter ); break;
+#endif
break;
}
}
// try to extract type of boundary condition from the group name
string name = group->GetStoreName();
CGNS_ENUMT( BCType_t ) bcType = getBCType( name );
- while ( !groupNames.insert( name ).second )
- name = (SMESH_Comment( "Group_") << groupNames.size());
-
+ if ( !groupNames.insert( name ).second ) // assure name uniqueness
+ {
+ int index = 1;
+ string newName;
+ do {
+ newName = SMESH_Comment( name ) << "_" << index++;
+ }
+ while ( !groupNames.insert( newName ).second );
+ name = newName;
+ }
// write IDs of elements
vector< cgsize_t > pnts;
pnts.reserve( group->Extent() );
const SMDS_MeshElement* elem = elemIt->next();
pnts.push_back( cgnsID( elem, elem2cgIDByEntity[ elem->GetEntityType() ]));
}
+ if ( pnts.size() == 0 )
+ continue; // can't store empty group
int iBC;
if ( cg_boco_write( _fn, iBase, iZone, name.c_str(), bcType,
CGNS_ENUMV( PointList ), pnts.size(), &pnts[0], &iBC) != CG_OK )
return addMessage( cg_get_error(), /*fatal = */true);
// write BC location
- if ( location != CGNS_ENUMV( Vertex ))
+ if ( location != CGNS_ENUMV( Vertex ) || meshDim == 1 )
{
if ( cg_boco_gridlocation_write( _fn, iBase, iZone, iBC, location) != CG_OK )
return addMessage( cg_get_error(), /*fatal = */false);
*/
//================================================================================
-DriverCGNS_Write::DriverCGNS_Write(): _fn(0)
+DriverCGNS_Write::DriverCGNS_Write(): _fn(0), _elementsByType( false )
{
}
virtual Status Perform();
+ // to export elements either in the order of their IDs or by geometric type
+ void SetElementsByType( bool isByType ) { _elementsByType = isByType; }
+
private:
int _fn; //!< file index
+
+ // if true all elements of same geometry are exported at ones,
+ // else elements are exported in order of their IDs
+ bool _elementsByType;
};
#endif
case ePYRA13: aNbNodes = 13; break;
case ePENTA6: aNbNodes = 6; break;
case ePENTA15: aNbNodes = 15; break;
+ case ePENTA18: aNbNodes = 18; break;
case eHEXA8: aNbNodes = 8; break;
case eHEXA20: aNbNodes = 20; break;
case eHEXA27: aNbNodes = 27; break;
isRenum = anIsElemNum;
}
break;
+ case ePENTA18:
+ aNbNodes = 18;
+ if(anIsElemNum)
+ anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+ aNodeIds[2], aNodeIds[3],
+ aNodeIds[4], aNodeIds[5],
+ aNodeIds[6], aNodeIds[7],
+ aNodeIds[8], aNodeIds[9],
+ aNodeIds[10], aNodeIds[11],
+ aNodeIds[12], aNodeIds[13],
+ aNodeIds[14], aNodeIds[15],
+ aNodeIds[16], aNodeIds[17],
+ aCellInfo->GetElemNum(iElem));
+ if (!anElement) {
+ anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
+ FindNode(myMesh,aNodeIds[1]),
+ FindNode(myMesh,aNodeIds[2]),
+ FindNode(myMesh,aNodeIds[3]),
+ FindNode(myMesh,aNodeIds[4]),
+ FindNode(myMesh,aNodeIds[5]),
+ FindNode(myMesh,aNodeIds[6]),
+ FindNode(myMesh,aNodeIds[7]),
+ FindNode(myMesh,aNodeIds[8]),
+ FindNode(myMesh,aNodeIds[9]),
+ FindNode(myMesh,aNodeIds[10]),
+ FindNode(myMesh,aNodeIds[11]),
+ FindNode(myMesh,aNodeIds[12]),
+ FindNode(myMesh,aNodeIds[13]),
+ FindNode(myMesh,aNodeIds[14]),
+ FindNode(myMesh,aNodeIds[15]),
+ FindNode(myMesh,aNodeIds[16]),
+ FindNode(myMesh,aNodeIds[17]));
+ isRenum = anIsElemNum;
+ }
+ break;
case eHEXA8:
aNbNodes = 8;
if(anIsElemNum)
theVec[ SMDSEntity_TriQuad_Hexa ] = MED::eHEXA27 ;
theVec[ SMDSEntity_Penta ] = MED::ePENTA6 ;
theVec[ SMDSEntity_Quad_Penta ] = MED::ePENTA15 ;
+ theVec[ SMDSEntity_BiQuad_Penta ] = MED::ePENTA18 ;
theVec[ SMDSEntity_Hexagonal_Prism ] = MED::eOCTA12 ;
theVec[ SMDSEntity_Polyhedra ] = MED::ePOLYEDRE;
//theVec[ SMDSEntity_Quad_Polyhedra ] = MED::ePOLYEDRE; // !!
{
Driver_SMESHDS_Mesh::SetFile(theFileName);
myMedVersion = theId;
+ //MESSAGE("myMedVersion:"<<myMedVersion);
}
void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName)
Driver_SMESHDS_Mesh::SetFile(theFileName);
}
+/*!
+ * MED version is either the latest available, or with an inferior minor,
+ * to ensure backward compatibility on writing med files.
+ */
string DriverMED_W_SMESHDS_Mesh::GetVersionString(const MED::EVersion theVersion, int theNbDigits)
{
TInt majeur, mineur, release;
majeur = mineur = release = 0;
-// if ( theVersion == eV2_1 )
-// MED::GetVersionRelease<eV2_1>(majeur, mineur, release);
-// else
- MED::GetVersionRelease<eV2_2>(majeur, mineur, release);
+ MED::GetVersionRelease<eV2_2>(majeur, mineur, release);
+ TInt imposedMineur = mineur;
+ switch( theVersion ) {
+ case MED::eV2_1 :
+ case MED::eV2_2 :
+ case MED::eLATEST : break;
+ case MED::eMINOR_0 : imposedMineur = 0; break;
+ case MED::eMINOR_1 : imposedMineur = 1; break;
+ case MED::eMINOR_2 : imposedMineur = 2; break;
+ case MED::eMINOR_3 : imposedMineur = 3; break;
+ case MED::eMINOR_4 : imposedMineur = 4; break;
+ case MED::eMINOR_5 : imposedMineur = 5; break;
+ case MED::eMINOR_6 : imposedMineur = 6; break;
+ case MED::eMINOR_7 : imposedMineur = 7; break;
+ case MED::eMINOR_8 : imposedMineur = 8; break;
+ case MED::eMINOR_9 : imposedMineur = 9; break;
+ case MED::eVUnknown : imposedMineur = mineur; break;
+ }
+ if (imposedMineur > mineur)
+ imposedMineur = mineur;
ostringstream name;
if ( theNbDigits > 0 )
name << majeur;
if ( theNbDigits > 1 )
- name << "." << mineur;
+ name << "." << imposedMineur;
if ( theNbDigits > 2 )
name << "." << release;
return name.str();
break;
}
}
-
+ //MESSAGE("myMedVersion:"<<myMedVersion);
MED::PWrapper myMed = CrWrapper(myFile,myMedVersion);
PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName);
//MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
SMDSAbs_Volume));
aTElemTypeDatas.push_back( TElemTypeData(anEntity,
ePENTA15,
- nbElemInfo.NbPrisms( ORDER_QUADRATIC ),
+ nbElemInfo.NbQuadPrisms(),
+ SMDSAbs_Volume));
+ aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+ ePENTA18,
+ nbElemInfo.NbBiQuadPrisms(),
SMDSAbs_Volume));
aTElemTypeDatas.push_back( TElemTypeData(anEntity,
eHEXA8,
{
// Treat standard types
// ---------------------
-
// allocate data arrays
PCellInfo aCellInfo = myMed->CrCellInfo( aMeshInfo,
aElemTypeData->_entity,
// build map of family numbers for this type
if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])
{
- //cout << " fillElemFamilyMap()" << endl;
fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType );
isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true;
}
// store data in a file
myMed->SetCellInfo(aCellInfo);
}
-
} // loop on geom types
-
-
}
catch(const std::exception& exc) {
INFOS("The following exception was caught:\n\t"<<exc.what());
#endif
namespace MED{
-
- enum EVersion {eVUnknown = -1, eV2_1, eV2_2};
+ // enum EVersion sould be synchronized with enum MED_VERSION in SMESH_Mesh.idl (.hh)
+ // i.e. same positive values!
+ enum EVersion {eVUnknown = -1, eV2_1, eV2_2, eLATEST,
+ eMINOR_0, eMINOR_1, eMINOR_2, eMINOR_3, eMINOR_4, eMINOR_5, eMINOR_6, eMINOR_7, eMINOR_8, eMINOR_9};
typedef enum {eFAUX, eVRAI} EBooleen ;
typedef double TFloat;
typedef enum {ePOINT1=1, eSEG2=102, eSEG3=103, eTRIA3=203,
eQUAD4=204, eTRIA6=206, eTRIA7=207, eQUAD8=208, eQUAD9=209,eTETRA4=304,
ePYRA5=305, ePENTA6=306, eHEXA8=308, eOCTA12=312, eTETRA10=310,
- ePYRA13=313, ePENTA15=315, eHEXA20=320, eHEXA27=327,
+ ePYRA13=313, ePENTA15=315, ePENTA18=318, eHEXA20=320, eHEXA27=327,
ePOLYGONE=400, ePOLYGON2=420, ePOLYEDRE=500, eNONE=0,
eBALL=1101 /*no such a type in med.h, it's just a trick*/,
eAllGeoType=-1 } EGeometrieElement;
#ifdef WIN32
#pragma warning(disable:4250)
#endif
-
+#include <utilities.h>
namespace MED
{
//---------------------------------------------------------------
aGeomMAILLESet.insert(eTETRA10);
aGeomMAILLESet.insert(ePYRA13);
aGeomMAILLESet.insert(ePENTA15);
+ aGeomMAILLESet.insert(ePENTA18);
aGeomMAILLESet.insert(eHEXA20);
aGeomMAILLESet.insert(eHEXA27);
aGeomMAILLESet.insert(ePOLYEDRE);
#include "MED_Factory.hxx"
#include "MED_Utilities.hxx"
#include "MED_V2_2_Wrapper.hxx"
-
#include <stdio.h>
#include <errno.h>
#include <sstream>
if(aMajor == 2 && aMinor == 1)
aVersion = eV2_1;
else
+ // TODO: check major is not superior to library and switch on minor
aVersion = eV2_2;
}
else {
}
PWrapper CrWrapper(const std::string& theFileName,
- bool theDoPreCheckInSeparateProcess)
+ bool theDoPreCheckInSeparateProcess,
+ int theMinor)
{
PWrapper aWrapper;
+ if (theMinor <0)
+ theMinor = MED_MINOR_NUM;
EVersion aVersion = GetVersionId(theFileName,theDoPreCheckInSeparateProcess);
switch(aVersion){
- case eV2_2:
- aWrapper.reset(new MED::V2_2::TVWrapper(theFileName));
- break;
case eV2_1:
EXCEPTION(std::runtime_error,"Cannot open file '"<<theFileName<<"'. Med version 2.1 is not supported any more.");
- //aWrapper.reset(new MED::V2_1::TVWrapper(theFileName));
break;
default:
- EXCEPTION(std::runtime_error,"MED::CrWrapper - theFileName = '"<<theFileName<<"'");
+ aWrapper.reset(new MED::V2_2::TVWrapper(theFileName, theMinor));
}
return aWrapper;
}
PWrapper CrWrapper(const std::string& theFileName, EVersion theId)
{
EVersion aVersion = GetVersionId(theFileName);
+ if (aVersion == eVUnknown) // no existing file
+ aVersion = theId;
if(aVersion != theId)
- remove(theFileName.c_str());
-
- PWrapper aWrapper;
- switch(theId){
- case eV2_2:
- aWrapper.reset(new MED::V2_2::TVWrapper(theFileName));
- break;
- case eV2_1:
- EXCEPTION(std::runtime_error,"Cannot open file '"<<theFileName<<"'. Med version 2.1 is not supported any more.");
- //aWrapper.reset(new MED::V2_1::TVWrapper(theFileName));
- break;
- default:
- aWrapper.reset(new MED::V2_2::TVWrapper(theFileName));
+ //remove(theFileName.c_str());
+ EXCEPTION(std::runtime_error,"Cannot open file for writing '"<<theFileName<<"'. existing file with another Med version.");
+
+ aVersion = theId;
+ int theMinor = -1; // not supported
+ switch (aVersion)
+ {
+ case eV2_1: break; // not supported
+ case eVUnknown:
+ case eV2_2:
+ case eLATEST: theMinor = MED_MINOR_NUM; break;
+ default: theMinor = aVersion - eMINOR_0;
}
+
+ if (theMinor < 0)
+ EXCEPTION(std::runtime_error,"Cannot open file '"<<theFileName<<"'. Med version 2.1 is not supported any more.");
+
+ PWrapper aWrapper;
+ aWrapper.reset(new MED::V2_2::TVWrapper(theFileName, theMinor));
return aWrapper;
}
MEDWRAPPER_FACTORY_EXPORT
PWrapper
CrWrapper(const std::string& theFileName,
- bool theDoPreCheckInSeparateProcess = false);
+ bool theDoPreCheckInSeparateProcess = false,
+ int theMinor=-1);
MEDWRAPPER_FACTORY_EXPORT
PWrapper
#include <med.h>
#include <med_err.h>
+#include <med_proto.h>
#ifdef _DEBUG_
static int MYDEBUG = 0;
TFile(const TFile&);
public:
- TFile(const std::string& theFileName):
+ TFile(const std::string& theFileName, TInt theMinor=-1):
myCount(0),
myFid(0),
- myFileName(theFileName)
- {}
+ myFileName(theFileName),
+ myMinor(theMinor)
+ {
+ if ((myMinor < 0) || (myMinor > MED_MINOR_NUM)) myMinor = MED_MINOR_NUM;
+ }
~TFile()
{
{
if(myCount++ == 0){
const char* aFileName = myFileName.c_str();
- myFid = MEDfileOpen(aFileName,med_access_mode(theMode));
+ myFid = MEDfileVersionOpen(aFileName,med_access_mode(theMode), MED_MAJOR_NUM, myMinor, MED_RELEASE_NUM);
}
if(theErr)
*theErr = TErr(myFid);
else if(myFid < 0)
- EXCEPTION(std::runtime_error,"TFile - MEDfileOpen('"<<myFileName<<"',"<<theMode<<")");
+ EXCEPTION(std::runtime_error,"TFile - MEDfileVersionOpen('"<<myFileName<<"',"<<theMode<<"',"<< MED_MAJOR_NUM<<"',"<< myMinor<<"',"<< MED_RELEASE_NUM<<")");
}
const TIdt& Id() const
TInt myCount;
TIdt myFid;
std::string myFileName;
+ TInt myMinor;
};
class TFileWrapper
{
PFile myFile;
+ TInt myMinor;
public:
- TFileWrapper(const PFile& theFile, EModeAcces theMode, TErr* theErr = NULL):
- myFile(theFile)
+ TFileWrapper(const PFile& theFile, EModeAcces theMode, TErr* theErr = NULL, TInt theMinor=-1):
+ myFile(theFile),
+ myMinor(theMinor)
{
+ if (myMinor < 0) myMinor = MED_MINOR_NUM;
myFile->Open(theMode,theErr);
}
//---------------------------------------------------------------
- TVWrapper::TVWrapper(const std::string& theFileName):
- myFile(new TFile(theFileName))
+ TVWrapper::TVWrapper(const std::string& theFileName, TInt theMinor):
+ myMinor(theMinor),
+ myFile(new TFile(theFileName, theMinor))
{
TErr aRet;
myFile->Open( eLECTURE_ECRITURE, &aRet );
- // if(aRet < 0)
- // myFile->Close();
- // myFile->Open( eLECTURE_AJOUT, &aRet );
- // }
if(aRet < 0) {
myFile->Close();
myFile->Open( eLECTURE, &aRet );
TVWrapper
::GetNbMeshes(TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
MED::TMeshInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EModeAcces theMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
::GetNbFamilies(const MED::TMeshInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
const MED::TMeshInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
const MED::TMeshInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
MED::TFamilyInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EModeAcces theMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EGeometrieElement theGeom,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EGeometrieElement theGeom,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EGeometrieElement theGeom,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EGeometrieElement theGeom,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EGeometrieElement theGeom,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EGeometrieElement theGeom,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
ETable theTable,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
::GetNodeInfo(MED::TNodeInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EModeAcces theMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
::GetPolygoneInfo(MED::TPolygoneInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EModeAcces theMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EConnectivite theConnMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return 0;
::GetPolyedreInfo(TPolyedreInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EModeAcces theMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EConnectivite theConnMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
EXCEPTION(std::runtime_error,"GetPolyedreConnSize - (...)");
{
TEntityInfo anInfo;
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return anInfo;
EConnectivite theConnMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
//----------------------------------------------------------------------------
void TVWrapper::GetCellInfo(MED::TCellInfo& theInfo, TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EModeAcces theMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
//! Read geom type of MED_BALL structural element
EGeometrieElement TVWrapper::GetBallGeom(const TMeshInfo& theMeshInfo)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE);
+ TErr anError;
+ TFileWrapper aFileWrapper(myFile, eLECTURE, &anError, myMinor);
// read med_geometry_type of "MED_BALL" element
char geotypename[ MED_NAME_SIZE + 1] = MED_BALL_NAME;
//! Read number of balls in the Mesh
TInt TVWrapper::GetNbBalls(const TMeshInfo& theMeshInfo)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE);
+ TErr anError;
+ TFileWrapper aFileWrapper(myFile, eLECTURE, &anError, myMinor);
EGeometrieElement ballType = GetBallGeom( theMeshInfo );
if ( ballType < 0 )
//! Read a MEDWrapped representation of MED_BALL from the MED file
void TVWrapper::GetBallInfo(TBallInfo& theInfo, TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
// check geometry of MED_BALL
if ( theInfo.myGeom == eBALL )
//! Write a MEDWrapped representation of MED_BALL to the MED file
void TVWrapper::SetBallInfo(const TBallInfo& theInfo, EModeAcces theMode, TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
TErr ret;
char ballsupportname[MED_NAME_SIZE+1]="BALL_SUPPORT_MESH";
TVWrapper
::GetNbFields(TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
::GetNbComp(TInt theFieldId,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
MED::TFieldInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EModeAcces theMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
TVWrapper
::GetNbGauss(TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
::GetGaussPreInfo(TInt theId,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return TGaussInfo::TInfo( TGaussInfo::TKey(ePOINT1,""),0 );
TGaussInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
TVWrapper
::GetNbProfiles(TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return -1;
::GetProfilePreInfo(TInt theId,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return TProfileInfo::TInfo();
TProfileInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EModeAcces theMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
TErr* theErr)
{
theEntity = EEntiteMaillage(-1);
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr){
if(theEntityInfo.empty())
MED::TTimeStampInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
const TGeom2Size& aGeom2Size = theInfo.myGeom2Size;
const TKey2Gauss& theKey2Gauss,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EModeAcces theMode,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
{
if(theInfo.myMeshInfo->myType != eSTRUCTURE)
return;
- TFileWrapper aFileWrapper(myFile,theMode,theErr);
+ TFileWrapper aFileWrapper(myFile,theMode,theErr, myMinor);
if(theErr && *theErr < 0)
return;
::GetGrilleInfo(TGrilleInfo& theInfo,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
EGrilleType& theGridType,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
EXCEPTION(std::runtime_error," GetGrilleType - aFileWrapper (...)");
TIntVector& theStruct,
TErr* theErr)
{
- TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
+ TFileWrapper aFileWrapper(myFile,eLECTURE,theErr, myMinor);
if(theErr && *theErr < 0)
return;
TVWrapper& operator=(const TVWrapper&);
public:
- TVWrapper(const std::string& theFileName);
+ TVWrapper(const std::string& theFileName, TInt theMinor=-1);
//----------------------------------------------------------------------------
virtual
protected:
PFile myFile;
+ TInt myMinor;
};
}
}
aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+ aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+ aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+ aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE);
aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
aHltFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+ aHltFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUADRATIC_WEDGE);
aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
aHltFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
aHltFilter->RegisterCellsWithType(VTK_POLYHEDRON);
#include <VTKViewer_Transform.h>
#include <VTKViewer_TransformFilter.h>
#include <VTKViewer_ExtractUnstructuredGrid.h>
+#include <VTKViewer_Actor.h>
// VTK Includes
#include <vtkObjectFactory.h>
myMapper = VTKViewer_PolyDataMapper::New();
myPlaneCollection = vtkPlaneCollection::New();
- vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
- myPolygonOffsetUnits);
+ VTKViewer_Actor::GetDefaultPolygonOffsetParameters(myPolygonOffsetFactor,
+ myPolygonOffsetUnits);
myMapper->UseLookupTableScalarRangeOn();
myMapper->SetColorModeToMapScalars();
#include <vtkCellArray.h>
#include <vtkCellData.h>
+#include <vtkLookupTable.h>
#include <vtkObjectFactory.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper2D.h>
+#include <vtkProperty2D.h>
#include <vtkScalarsToColors.h>
#include <vtkTextMapper.h>
#include <vtkTextProperty.h>
#include <vtkViewport.h>
#include <vtkWindow.h>
-#include <vtkLookupTable.h>
-#include <vtkProperty2D.h>
#define SHRINK_COEF 0.08;
// Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label
// format, no title, and vertical orientation. The initial scalar bar
// size is (0.05 x 0.8) of the viewport size.
-SMESH_ScalarBarActor::SMESH_ScalarBarActor() {
+SMESH_ScalarBarActor::SMESH_ScalarBarActor()
+{
this->LookupTable = NULL;
this->Position2Coordinate->SetValue(0.17, 0.8);
-
+
this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
this->PositionCoordinate->SetValue(0.82,0.1);
-
+
this->MaximumNumberOfColors = 64;
this->NumberOfLabels = 5;
this->NumberOfLabelsBuilt = 0;
this->TitleTextProperty = vtkTextProperty::New();
this->TitleTextProperty->ShallowCopy(this->LabelTextProperty);
- this->LabelFormat = new char[8];
+ this->LabelFormat = new char[8];
sprintf(this->LabelFormat,"%s","%-#6.3g");
this->TitleMapper = vtkTextMapper::New();
this->TitleActor->SetMapper(this->TitleMapper);
this->TitleActor->GetPositionCoordinate()->
SetReferenceCoordinate(this->PositionCoordinate);
-
+
this->TextMappers = NULL;
this->TextActors = NULL;
myDistribution = vtkPolyData::New();
myDistributionMapper = vtkPolyDataMapper2D::New();
myDistributionMapper->SetInputData(this->myDistribution);
-
+
myDistributionActor = vtkActor2D::New();
myDistributionActor->SetMapper(this->myDistributionMapper);
myDistributionActor->GetPositionCoordinate()->
{
this->TitleActor->ReleaseGraphicsResources(win);
if (this->TextMappers != NULL )
- {
+ {
for (int i=0; i < this->NumberOfLabelsBuilt; i++)
- {
+ {
this->TextActors[i]->ReleaseGraphicsResources(win);
- }
}
+ }
this->ScalarBarActor->ReleaseGraphicsResources(win);
// rnv begin
// Customization of the vtkScalarBarActor to show distribution histogram.
/*--------------------------------------------------------------------------*/
-SMESH_ScalarBarActor::~SMESH_ScalarBarActor() {
- if (this->LabelFormat)
- {
+SMESH_ScalarBarActor::~SMESH_ScalarBarActor()
+{
+ if (this->LabelFormat)
+ {
delete [] this->LabelFormat;
this->LabelFormat = NULL;
- }
+ }
this->TitleMapper->Delete();
this->TitleActor->Delete();
if (this->TextMappers != NULL )
- {
+ {
for (int i=0; i < this->NumberOfLabelsBuilt; i++)
- {
+ {
this->TextMappers[i]->Delete();
this->TextActors[i]->Delete();
- }
+ }
delete [] this->TextMappers;
delete [] this->TextActors;
- }
+ }
this->ScalarBar->Delete();
this->ScalarBarMapper->Delete();
this->ScalarBarActor->Delete();
if (this->Title)
- {
+ {
delete [] this->Title;
this->Title = NULL;
- }
-
+ }
+
this->SetLookupTable(NULL);
this->SetLabelTextProperty(NULL);
this->SetTitleTextProperty(NULL);
-
+
// rnv begin
// Customization of the vtkScalarBarActor to show distribution histogram:
myDistribution->Delete();
{
int renderedSomething = 0;
int i;
-
+
// Everything is built, just have to render
if (this->Title != NULL)
- {
+ {
renderedSomething += this->TitleActor->RenderOverlay(viewport);
- }
- if (!myTitleOnlyVisibility) {
+ }
+ if ( !myTitleOnlyVisibility ) {
this->ScalarBarActor->RenderOverlay(viewport);
this->myDistributionActor->RenderOverlay(viewport);
- if( this->TextActors == NULL)
- {
- vtkWarningMacro(<<"Need a mapper to render a scalar bar");
- return renderedSomething;
- }
-
- for (i=0; i<this->NumberOfLabels; i++)
- {
+ if ( this->TextActors == NULL )
+ {
+ vtkWarningMacro(<<"Need a mapper to render a scalar bar");
+ return renderedSomething;
+ }
+
+ for ( i=0; i<this->NumberOfLabels; i++ )
+ {
renderedSomething += this->TextActors[i]->RenderOverlay(viewport);
- }
- }
+ }
+ }
renderedSomething = (renderedSomething > 0)?(1):(0);
return renderedSomething;
int renderedSomething = 0;
int i;
int size[2];
-
+
if (!this->LookupTable)
- {
+ {
vtkWarningMacro(<<"Need a mapper to render a scalar bar");
return 0;
- }
+ }
if (!this->TitleTextProperty)
- {
+ {
vtkErrorMacro(<<"Need title text property to render a scalar bar");
return 0;
- }
+ }
if (!this->LabelTextProperty)
- {
+ {
vtkErrorMacro(<<"Need label text property to render a scalar bar");
return 0;
- }
+ }
// Check to see whether we have to rebuild everything
int positionsHaveChanged = 0;
- if (viewport->GetMTime() > this->BuildTime ||
- (viewport->GetVTKWindow() &&
+ if (viewport->GetMTime() > this->BuildTime ||
+ (viewport->GetVTKWindow() &&
viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
- {
+ {
// if the viewport has changed we may - or may not need
// to rebuild, it depends on if the projected coords chage
int *barOrigin;
barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
- size[0] =
+ size[0] =
this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
barOrigin[0];
- size[1] =
+ size[1] =
this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
barOrigin[1];
- if (this->LastSize[0] != size[0] ||
+ if (this->LastSize[0] != size[0] ||
this->LastSize[1] != size[1] ||
- this->LastOrigin[0] != barOrigin[0] ||
+ this->LastOrigin[0] != barOrigin[0] ||
this->LastOrigin[1] != barOrigin[1])
- {
+ {
positionsHaveChanged = 1;
- }
}
-
+ }
+
// Check to see whether we have to rebuild everything
- if (positionsHaveChanged ||
- this->GetMTime() > this->BuildTime ||
- this->LookupTable->GetMTime() > this->BuildTime ||
- this->LabelTextProperty->GetMTime() > this->BuildTime ||
- this->TitleTextProperty->GetMTime() > this->BuildTime)
- {
+ if ( positionsHaveChanged ||
+ this->GetMTime() > this->BuildTime ||
+ this->LookupTable->GetMTime() > this->BuildTime ||
+ this->LabelTextProperty->GetMTime() > this->BuildTime ||
+ this->TitleTextProperty->GetMTime() > this->BuildTime)
+ {
vtkDebugMacro(<<"Rebuilding subobjects");
// Delete previously constructed objects
//
- if (this->TextMappers != NULL )
+ if ( this->TextMappers != NULL )
+ {
+ for ( i = 0; i < this->NumberOfLabelsBuilt; i++ )
{
- for (i=0; i < this->NumberOfLabelsBuilt; i++)
- {
this->TextMappers[i]->Delete();
this->TextActors[i]->Delete();
- }
+ }
delete [] this->TextMappers;
delete [] this->TextActors;
- }
+ }
// Build scalar bar object; determine its type
//
- // is this a vtkLookupTable or a subclass of vtkLookupTable
+ // is this a vtkLookupTable or a subclass of vtkLookupTable
// with its scale set to log
// NOTE: it's possible we could to without the 'lut' variable
// later in the code, but if the vtkLookupTableSafeDownCast operation
vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
int isLogTable = 0;
if ( LUT )
- {
+ {
if ( LUT->GetScale() == VTK_SCALE_LOG10 )
- {
- isLogTable = 1;
- }
+ {
+ isLogTable = 1;
}
-
+ }
+
// we hard code how many steps to display
vtkScalarsToColors *lut = this->LookupTable;
int numColors = this->MaximumNumberOfColors;
if(!distrVisibility)
vtkDebugMacro(<<" Distribution invisible, because numColors == this->myNbValues.size()");
- if ( distrVisibility && GetDistributionVisibility() ) {
+ if ( distrVisibility && GetDistributionVisibility() )
+ {
for ( i = 0 ; i < (int)myNbValues.size(); i++ ) {
if ( myNbValues[i] ) {
numPositiveVal++;
this->myDistribution->SetPolys(distrPolys);
distrPts->Delete();
distrPolys->Delete();
- if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE ) {
+ if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE )
+ {
distColors = vtkUnsignedCharArray::New();
distColors->SetNumberOfComponents(3);
distColors->SetNumberOfTuples(numPositiveVal);
this->myDistribution->GetCellData()->SetScalars(distColors);
distColors->Delete();
- } else if( myDistributionColoringType == SMESH_MONOCOLOR_TYPE ){
+ }
+ else if( myDistributionColoringType == SMESH_MONOCOLOR_TYPE )
+ {
this->myDistribution->GetCellData()->SetScalars(NULL);
}
- } else {
+ }
+ else
+ {
myDistribution->Reset();
}
// rnv end
// get the viewport size in display coordinates
int *barOrigin, barWidth, barHeight, distrHeight;
barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
- size[0] =
+ size[0] =
this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
barOrigin[0];
- size[1] =
+ size[1] =
this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
barOrigin[1];
this->LastOrigin[0] = barOrigin[0];
this->LastOrigin[1] = barOrigin[1];
this->LastSize[0] = size[0];
this->LastSize[1] = size[1];
-
+
// Update all the composing objects
this->TitleActor->SetProperty(this->GetProperty());
this->TitleMapper->SetInput(this->Title);
if (this->TitleTextProperty->GetMTime() > this->BuildTime)
- {
+ {
// Shallow copy here so that the size of the title prop is not affected
// by the automatic adjustment of its text mapper's size (i.e. its
// mapper's text property is identical except for the font size
// the title and label text prop to be the same.
this->TitleMapper->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
this->TitleMapper->GetTextProperty()->SetJustificationToCentered();
- }
-
+ }
+
// find the best size for the title font
int titleSize[2];
this->SizeTitle(titleSize, size, viewport);
-
+
// find the best size for the ticks
int labelSize[2];
this->AllocateAndSizeLabels(labelSize, size, viewport,range);
this->NumberOfLabelsBuilt = this->NumberOfLabels;
-
+
// generate points
double x[3]; x[2] = 0.0;
double delta, itemH, shrink;
barHeight = (int)(0.86*size[1]);
delta=(double)barHeight/numColors;
-
+
for ( i=0; i<numPts/2; i++ ) {
x[0] = distrHeight+delimeter/2.0;
x[1] = i*delta;
pts->SetPoint(2*i+1,x);
}
- if(GetDistributionVisibility() && distrVisibility) {
- // Distribution points
+ if ( GetDistributionVisibility() && distrVisibility ) {
+ // Distribution points
shrink = delta*SHRINK_COEF;
vtkIdType distPtsId=0;
vtkIdType distPtsIds[4];
- for(i=0; i<numColors; i++) {
- if(myNbValues[i]) {
+ for ( i = 0; i < numColors; i++ ) {
+ if ( myNbValues[i] ) {
itemH = distrHeight*((double)myNbValues[i]/maxValue);
-
- if(distrHeight == itemH)
+
+ if(distrHeight == itemH)
itemH = itemH - delimeter/2;
x[1] = i*delta+shrink;
// first point of polygon (quadrangle)
- x[0] = 0;
+ x[0] = 0;
distPtsIds[0] = distPtsId;
distrPts->SetPoint(distPtsId++,x);
x[1] = i*delta+delta-shrink;
// third point of polygon (quadrangle)
- x[0] = 0;
+ x[0] = 0;
distPtsIds[3] = distPtsId;
distrPts->SetPoint(distPtsId++,x);
distrPolys->InsertNextCell(4,distPtsIds);
}
}
- }
+ }
}
// rnv end
else {
barWidth = size[0];
-
+
// rnv begin
// Customization of the vtkScalarBarActor to show distribution histogram.
double coef1, delimeter=0.0;
- if(GetDistributionVisibility() && distrVisibility) {
+ if ( GetDistributionVisibility() && distrVisibility ) {
coef1=0.62;
distrHeight = (int)((coef1/2)*size[1]);
- //delimeter between distribution diagram and scalar bar
+ //delimeter between distribution diagram and scalar bar
delimeter=0.02*size[1];
}
else {
barHeight = (int)(coef1*size[1]);
distrHeight = 0;
}
-
+
barHeight = (int)(coef1*size[1]);
-
+
delta=(double)barWidth/numColors;
- for (i=0; i<numPts/2; i++) {
+ for ( i = 0; i < numPts/2; i++ ) {
x[0] = i*delta;
x[1] = barHeight;
- pts->SetPoint(2*i,x);
+ pts->SetPoint(2*i,x);
x[1] = distrHeight + delimeter;
pts->SetPoint(2*i+1,x);
}
-
- if(GetDistributionVisibility() && distrVisibility) {
- // Distribution points
+
+ if ( GetDistributionVisibility() && distrVisibility ) {
+ // Distribution points
shrink = delta*SHRINK_COEF;
vtkIdType distPtsId=0;
vtkIdType distPtsIds[4];
- for(i=0; i<numColors; i++) {
+ for ( i = 0; i < numColors; i++ ) {
if(myNbValues[i]) {
itemH = distrHeight*((double)myNbValues[i]/maxValue);
-
+
// first point of polygon (quadrangle)
- x[0] = i*delta+shrink;
+ x[0] = i*delta+shrink;
x[1] = 0;
distPtsIds[0] = distPtsId;
distrPts->SetPoint(distPtsId++,x);
-
+
// second point of polygon (quadrangle)
- x[0] = i*delta+shrink;
+ x[0] = i*delta+shrink;
x[1] = itemH;
distPtsIds[3] = distPtsId;
distrPts->SetPoint(distPtsId++,x);
-
+
// third point of polygon (quadrangle)
- x[0] = i*delta+delta-shrink;
+ x[0] = i*delta+delta-shrink;
x[1] = 0;
distPtsIds[1] = distPtsId;
distrPts->SetPoint(distPtsId++,x);
-
+
// fourth point of polygon (quadrangle)
- x[0] = i*delta+delta-shrink;
+ x[0] = i*delta+delta-shrink;
x[1] = itemH;
distPtsIds[2] = distPtsId;
distrPts->SetPoint(distPtsId++,x);
-
+
// Add polygon into poly data
distrPolys->InsertNextCell(4,distPtsIds);
}
- }
+ }
}
// rnv end
}
-
+
//polygons & cell colors
unsigned char *rgba, *rgb;
vtkIdType ptIds[4], dcCount=0;
- for (i=0; i<numColors; i++)
- {
+ for ( i = 0; i < numColors; i++ )
+ {
ptIds[0] = 2*i;
ptIds[1] = ptIds[0] + 1;
ptIds[2] = ptIds[1] + 2;
polys->InsertNextCell(4,ptIds);
if ( isLogTable )
- {
- double rgbval = log10(range[0]) +
+ {
+ double rgbval = log10(range[0]) +
i*(log10(range[1])-log10(range[0]))/(numColors -1);
rgba = lut->MapValue(pow(10.0,rgbval));
- }
+ }
else
- {
+ {
rgba = lut->MapValue(range[0] + (range[1] - range[0])*
((double)i /(numColors-1.0)));
- }
+ }
rgb = colors->GetPointer(3*i); //write into array directly
rgb[0] = rgba[0];
rgb[1] = rgba[1];
rgb[2] = rgba[2];
-
+
// rnv begin
// Customization of the vtkScalarBarActor to show distribution histogram.
if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE &&
// Now position everything properly
//
double val;
- if (this->Orientation == VTK_ORIENT_VERTICAL)
- {
+ if ( this->Orientation == VTK_ORIENT_VERTICAL )
+ {
int sizeTextData[2];
-
+
// center the title
this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]);
-
- for (i=0; i < this->NumberOfLabels; i++)
+
+ for ( i = 0; i < this->NumberOfLabels; i++ )
+ {
+ if ( this->NumberOfLabels > 1 )
{
- if (this->NumberOfLabels > 1)
- {
val = (double)i/(this->NumberOfLabels-1) *barHeight;
- }
- else
- {
+ }
+ else
+ {
val = 0.5*barHeight;
- }
+ }
this->TextMappers[i]->GetSize(viewport,sizeTextData);
this->TextMappers[i]->GetTextProperty()->SetJustificationToLeft();
this->TextActors[i]->SetPosition(barWidth+3,
val - sizeTextData[1]/2);
- }
}
+ }
else
- {
- this->TitleActor->SetPosition(size[0]/2,
+ {
+ this->TitleActor->SetPosition(size[0]/2,
barHeight + labelSize[1] + 0.1*size[1]);
- for (i=0; i < this->NumberOfLabels; i++)
- {
+ for ( i = 0; i < this->NumberOfLabels; i++ )
+ {
this->TextMappers[i]->GetTextProperty()->SetJustificationToCentered();
if (this->NumberOfLabels > 1)
- {
+ {
val = (double)i/(this->NumberOfLabels-1) * barWidth;
- }
+ }
else
- {
+ {
val = 0.5*barWidth;
- }
- this->TextActors[i]->SetPosition(val, barHeight + 0.05*size[1]);
}
+ this->TextActors[i]->SetPosition(val, barHeight + 0.05*size[1]);
}
+ }
this->BuildTime.Modified();
- }
+ }
// Everything is built, just have to render
- if (this->Title != NULL)
- {
+ if ( this->Title != NULL )
+ {
renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
- }
+ }
this->ScalarBarActor->RenderOpaqueGeometry(viewport);
this->myDistributionActor->RenderOpaqueGeometry(viewport);
- for (i=0; i<this->NumberOfLabels; i++)
- {
+ for ( i = 0; i < this->NumberOfLabels; i++ )
+ {
renderedSomething += this->TextActors[i]->RenderOpaqueGeometry(viewport);
- }
+ }
renderedSomething = (renderedSomething > 0)?(1):(0);
this->Superclass::PrintSelf(os,indent);
if ( this->LookupTable )
- {
+ {
os << indent << "Lookup Table:\n";
this->LookupTable->PrintSelf(os,indent.GetNextIndent());
- }
+ }
else
- {
+ {
os << indent << "Lookup Table: (none)\n";
- }
+ }
if (this->TitleTextProperty)
- {
+ {
os << indent << "Title Text Property:\n";
this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
- }
+ }
else
- {
+ {
os << indent << "Title Text Property: (none)\n";
- }
+ }
if (this->LabelTextProperty)
- {
+ {
os << indent << "Label Text Property:\n";
this->LabelTextProperty->PrintSelf(os,indent.GetNextIndent());
- }
+ }
else
- {
+ {
os << indent << "Label Text Property: (none)\n";
- }
+ }
os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
- os << indent << "Maximum Number Of Colors: "
+ os << indent << "Maximum Number Of Colors: "
<< this->MaximumNumberOfColors << "\n";
os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n";
os << indent << "Orientation: ";
if ( this->Orientation == VTK_ORIENT_HORIZONTAL )
- {
+ {
os << "Horizontal\n";
- }
+ }
else
- {
+ {
os << "Vertical\n";
- }
+ }
os << indent << "Label Format: " << this->LabelFormat << "\n";
}
{
SMESH_ScalarBarActor *a = SMESH_ScalarBarActor::SafeDownCast(prop);
if ( a != NULL )
- {
+ {
this->SetPosition2(a->GetPosition2());
this->SetLookupTable(a->GetLookupTable());
this->SetMaximumNumberOfColors(a->GetMaximumNumberOfColors());
this->SetTitleTextProperty(a->GetTitleTextProperty());
this->SetLabelFormat(a->GetLabelFormat());
this->SetTitle(a->GetTitle());
- this->GetPositionCoordinate()->SetCoordinateSystem(
- a->GetPositionCoordinate()->GetCoordinateSystem());
- this->GetPositionCoordinate()->SetValue(
- a->GetPositionCoordinate()->GetValue());
- this->GetPosition2Coordinate()->SetCoordinateSystem(
- a->GetPosition2Coordinate()->GetCoordinateSystem());
- this->GetPosition2Coordinate()->SetValue(
- a->GetPosition2Coordinate()->GetValue());
- }
+ this->GetPositionCoordinate()->SetCoordinateSystem
+ (a->GetPositionCoordinate()->GetCoordinateSystem());
+ this->GetPositionCoordinate()->SetValue
+ (a->GetPositionCoordinate()->GetValue());
+ this->GetPosition2Coordinate()->SetCoordinateSystem
+ (a->GetPosition2Coordinate()->GetCoordinateSystem());
+ this->GetPosition2Coordinate()->SetValue
+ (a->GetPosition2Coordinate()->GetValue());
+ }
// Now do superclass
this->vtkActor2D::ShallowCopy(prop);
}
//----------------------------------------------------------------------------
-void SMESH_ScalarBarActor::AllocateAndSizeLabels(int *labelSize,
- int *size,
- vtkViewport *viewport,
- double *range)
+void SMESH_ScalarBarActor::AllocateAndSizeLabels(int *labelSize,
+ int *size,
+ vtkViewport *viewport,
+ double *range)
{
labelSize[0] = labelSize[1] = 0;
double val;
int i;
-
+
// TODO: this should be optimized, maybe by keeping a list of
// allocated mappers, in order to avoid creation/destruction of
// their underlying text properties (i.e. each time a mapper is
// created, text properties are created and shallow-assigned a font size
// which value might be "far" from the target font size).
- // is this a vtkLookupTable or a subclass of vtkLookupTable
+ // is this a vtkLookupTable or a subclass of vtkLookupTable
// with its scale set to log
vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
int isLogTable = 0;
if ( LUT )
- {
+ {
if ( LUT->GetScale() == VTK_SCALE_LOG10 )
- {
- isLogTable = 1;
- }
+ {
+ isLogTable = 1;
}
+ }
- for (i=0; i < this->NumberOfLabels; i++)
- {
+ for ( i = 0; i < this->NumberOfLabels; i++ )
+ {
this->TextMappers[i] = vtkTextMapper::New();
if ( isLogTable )
- {
+ {
double lval;
- if (this->NumberOfLabels > 1)
- {
+ if ( this->NumberOfLabels > 1 )
+ {
lval = log10(range[0]) + (double)i/(this->NumberOfLabels-1) *
(log10(range[1])-log10(range[0]));
- }
+ }
else
- {
+ {
lval = log10(range[0]) + 0.5*(log10(range[1])-log10(range[0]));
- }
- val = pow(10.0,lval);
}
+ val = pow(10.0,lval);
+ }
else
+ {
+ if ( this->NumberOfLabels > 1 )
{
- if (this->NumberOfLabels > 1)
- {
- val = range[0] +
+ val = range[0] +
(double)i/(this->NumberOfLabels-1) * (range[1]-range[0]);
- }
+ }
else
- {
+ {
val = range[0] + 0.5*(range[1]-range[0]);
- }
}
+ }
sprintf(string, this->LabelFormat, val);
this->TextMappers[i]->SetInput(string);
// which will be modified later). This allows text actors to
// share the same text property, and in that case specifically allows
// the title and label text prop to be the same.
- this->TextMappers[i]->GetTextProperty()->ShallowCopy(
- this->LabelTextProperty);
+ this->TextMappers[i]->GetTextProperty()->ShallowCopy(this->LabelTextProperty);
this->TextActors[i] = vtkActor2D::New();
this->TextActors[i]->SetMapper(this->TextMappers[i]);
this->TextActors[i]->SetProperty(this->GetProperty());
this->TextActors[i]->GetPositionCoordinate()->
SetReferenceCoordinate(this->PositionCoordinate);
- }
+ }
- if (this->NumberOfLabels)
- {
+ if ( this->NumberOfLabels )
+ {
int targetWidth, targetHeight;
// rnv begin
// Customization of the vtkScalarBarActor to show distribution histogram.
bool distrVisibility = ( this->MaximumNumberOfColors == (int) this->myNbValues.size() );
double coef;
- if( GetDistributionVisibility() && distrVisibility )
- if(this->Orientation == VTK_ORIENT_VERTICAL)
+ if ( GetDistributionVisibility() && distrVisibility )
+ if ( this->Orientation == VTK_ORIENT_VERTICAL )
coef = 0.4;
- else
+ else
coef = 0.18;
- else
- if(this->Orientation == VTK_ORIENT_VERTICAL)
+ else
+ if (this->Orientation == VTK_ORIENT_VERTICAL )
coef = 0.6;
- else
+ else
coef=0.25;
if ( this->Orientation == VTK_ORIENT_VERTICAL )
- {
+ {
targetWidth = (int)(coef*size[0]);
targetHeight = (int)(0.86*size[1]/this->NumberOfLabels);
- }
+ }
else
- {
+ {
targetWidth = (int)(size[0]*0.8/this->NumberOfLabels);
targetHeight = (int)(coef*size[1]);
- }
- // rnv end
-
- vtkTextMapper::SetMultipleConstrainedFontSize(viewport,
- targetWidth,
- targetHeight,
- this->TextMappers,
- this->NumberOfLabels,
- labelSize);
}
+ // rnv end
+
+ vtkTextMapper::SetMultipleConstrainedFontSize( viewport,
+ targetWidth,
+ targetHeight,
+ this->TextMappers,
+ this->NumberOfLabels,
+ labelSize );
+ }
}
//----------------------------------------------------------------------------
-void SMESH_ScalarBarActor::SizeTitle(int *titleSize,
- int *size,
+void SMESH_ScalarBarActor::SizeTitle(int *titleSize,
+ int *size,
vtkViewport *viewport)
{
titleSize[0] = titleSize[1] = 0;
- if (this->Title == NULL || !strlen(this->Title))
+ if ( this->Title == NULL || !strlen(this->Title) )
{
return;
}
/*--------------------------------------------------------------------------*/
-void SMESH_ScalarBarActor::SetDistributionVisibility(int flag) {
- myDistributionActor->SetVisibility(flag);
+void SMESH_ScalarBarActor::SetDistributionVisibility( int flag )
+{
+ myDistributionActor->SetVisibility( flag );
Modified();
}
/*--------------------------------------------------------------------------*/
-int SMESH_ScalarBarActor::GetDistributionVisibility() {
+int SMESH_ScalarBarActor::GetDistributionVisibility()
+{
return myDistributionActor->GetVisibility();
}
-void SMESH_ScalarBarActor::SetDistribution(std::vector<int> theNbValues) {
+void SMESH_ScalarBarActor::SetDistribution( const std::vector<int>& theNbValues )
+{
myNbValues = theNbValues;
-}
+}
-void SMESH_ScalarBarActor::SetDistributionColor (double rgb[3]) {
+void SMESH_ScalarBarActor::SetDistributionColor( double rgb[3] )
+{
myDistributionActor->GetProperty()->SetColor(rgb);
Modified();
}
-void SMESH_ScalarBarActor::GetDistributionColor (double rgb[3]) {
+void SMESH_ScalarBarActor::GetDistributionColor( double rgb[3] )
+{
myDistributionActor->GetProperty()->GetColor(rgb);
}
-void SMESH_ScalarBarActor::SetTitleOnlyVisibility( bool theTitleOnlyVisibility) {
+void SMESH_ScalarBarActor::SetTitleOnlyVisibility( bool theTitleOnlyVisibility )
+{
myTitleOnlyVisibility = theTitleOnlyVisibility;
}
-bool SMESH_ScalarBarActor::GetTitleOnlyVisibility() {
+bool SMESH_ScalarBarActor::GetTitleOnlyVisibility()
+{
return myTitleOnlyVisibility;
}
virtual int GetDistributionVisibility();
// Description:
// Set distribution
- virtual void SetDistribution(std::vector<int> theNbValues);
+ virtual void SetDistribution(const std::vector<int>& theNbValues);
// Description:
// Set distribution coloring type (SMESH_MONOCOLOR_TYPE or SMESH_MULTICOLOR_TYPE)
#define _OBJECTPOOL_HXX_
#include <vector>
-//#include <stack>
#include <iostream>
+#include "SMDS_Iterator.hxx"
+
namespace
{
// assure deallocation of memory of a vector
}
}
+template<class X> class ObjectPoolIterator;
+
template<class X> class ObjectPool
{
private:
- std::vector<X*> _chunkList;
+ std::vector<X*> _chunkList;
std::vector<bool> _freeList;
- int _nextFree;
- int _maxAvail;
- int _chunkSize;
- int _maxOccupied;
- int _nbHoles;
- int _lastDelChunk;
+ int _nextFree; // either the 1st hole or last added
+ int _maxAvail; // nb allocated elements
+ int _chunkSize;
+ int _maxOccupied; // max used ID
+ int _nbHoles;
+ int _lastDelChunk;
+
+ friend class ObjectPoolIterator<X>;
int getNextFree()
{
}
public:
- ObjectPool(int nblk)
+ ObjectPool(int nblk = 1024)
{
- _chunkSize = nblk;
- _nextFree = 0;
- _maxAvail = 0;
- _maxOccupied = 0;
- _nbHoles = 0;
+ _chunkSize = nblk;
+ _nextFree = 0;
+ _maxAvail = 0;
+ _maxOccupied = -1;
+ _nbHoles = 0;
+ _lastDelChunk = 0;
_chunkList.clear();
_freeList.clear();
- _lastDelChunk = 0;
}
virtual ~ObjectPool()
_freeList.insert(_freeList.end(), _chunkSize, true);
_maxAvail += _chunkSize;
_freeList[_nextFree] = false;
- obj = newChunk; // &newChunk[0];
+ obj = newChunk;
}
else
{
int chunkId = _nextFree / _chunkSize;
int rank = _nextFree - chunkId * _chunkSize;
_freeList[_nextFree] = false;
- obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
+ obj = _chunkList[chunkId] + rank;
}
- if (_nextFree < _maxOccupied)
+ if (_nextFree <= _maxOccupied)
{
_nbHoles-=1;
}
{
_maxOccupied = _nextFree;
}
- //obj->init();
return obj;
}
if (toFree < _nextFree)
_nextFree = toFree;
if (toFree < _maxOccupied)
- _nbHoles += 1;
+ ++_nbHoles;
+ else
+ --_maxOccupied;
_lastDelChunk = i;
- //obj->clean();
- //checkDelete(i); compactage non fait
}
void clear()
clearVector( _freeList );
}
+ // nb allocated elements
+ size_t size() const
+ {
+ return _freeList.size();
+ }
+
+ // nb used elements
+ size_t nbElements() const
+ {
+ return _maxOccupied + 1 - _nbHoles;
+ }
+
+ // return an element w/o any check
+ const X* operator[]( size_t i ) const // i < size()
+ {
+ int chunkId = i / _chunkSize;
+ int rank = i - chunkId * _chunkSize;
+ return _chunkList[ chunkId ] + rank;
+ }
+
+ // return only being used element
+ const X* at( size_t i ) const // i < size()
+ {
+ if ( i >= size() || _freeList[ i ] )
+ return 0;
+
+ int chunkId = i / _chunkSize;
+ int rank = i - chunkId * _chunkSize;
+ return _chunkList[ chunkId ] + rank;
+ }
+
// void destroy(int toFree)
// {
// // no control 0<= toFree < _freeList.size()
};
+template<class X> class ObjectPoolIterator : public SMDS_Iterator<const X*>
+{
+ const ObjectPool<X>& _pool;
+ int _i, _nbFound;
+public:
+
+ ObjectPoolIterator( const ObjectPool<X>& pool ) : _pool( pool ), _i( 0 ), _nbFound( 0 )
+ {
+ if ( more() && _pool._freeList[ _i ] == true )
+ {
+ next();
+ --_nbFound;
+ }
+ }
+
+ virtual bool more()
+ {
+ return ( _i <= _pool._maxOccupied && _nbFound < (int)_pool.nbElements() );
+ }
+
+ virtual const X* next()
+ {
+ const X* x = 0;
+ if ( more() )
+ {
+ x = _pool[ _i ];
+
+ ++_nbFound;
+
+ for ( ++_i; _i <= _pool._maxOccupied; ++_i )
+ if ( _pool._freeList[ _i ] == false )
+ break;
+ }
+ return x;
+ }
+};
+
#endif
SMDSEntity_TriQuad_Hexa,
SMDSEntity_Penta,
SMDSEntity_Quad_Penta,
+ SMDSEntity_BiQuad_Penta,
SMDSEntity_Hexagonal_Prism,
SMDSEntity_Polyhedra,
SMDSEntity_Quad_Polyhedra,
_cellDimension[VTK_TRIQUADRATIC_HEXAHEDRON] = 3;
_cellDimension[VTK_WEDGE] = 3;
_cellDimension[VTK_QUADRATIC_WEDGE] = 3;
+ _cellDimension[VTK_BIQUADRATIC_QUADRATIC_WEDGE] = 3;
_cellDimension[VTK_PYRAMID] = 3;
_cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
_cellDimension[VTK_HEXAGONAL_PRISM] = 3;
case VTK_QUADRATIC_WEDGE:
myInfo.myNbQuadPrisms++;
break;
+ case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
+ myInfo.myNbBiQuadPrisms++;
+ break;
case VTK_QUADRATIC_HEXAHEDRON:
myInfo.myNbQuadHexas++;
break;
+ case VTK_TRIQUADRATIC_HEXAHEDRON:
+ myInfo.myNbTriQuadHexas++;
+ break;
//#ifdef VTK_HAVE_POLYHEDRON
case VTK_POLYHEDRON:
myInfo.myNbPolyhedrons++;
return (const SMDS_MeshNode *)myNodes[vtkId+1];
}
-///////////////////////////////////////////////////////////////////////////////
-///Create a triangle and add it to the current mesh. This method do not bind an
-///ID to the create triangle.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+///Create a triangle and add it to the current mesh. This method does not bind
+///an ID to the create triangle.
+//////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
const SMDS_MeshNode * node2,
const SMDS_MeshNode * node3,
}
}
-///////////////////////////////////////////////////////////////////////////////
-///Create a quadrangle and add it to the current mesh. This methode do not bind
-///a ID to the create triangle.
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+///Create a quadrangle and add it to the current mesh. This method does not bind
+///an ID to the create triangle.
+////////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
const SMDS_MeshNode * node2,
const SMDS_MeshNode * node3,
return NULL;
}
+//================================================================================
+/*!
+ * \brief Return elements including all given nodes
+ * \param [in] nodes - nodes to find elements around
+ * \param [out] foundElems - the found elements
+ * \param [in] type - type of elements to find
+ * \return int - a number of found elements
+ */
+//================================================================================
+
+int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
+ std::vector<const SMDS_MeshElement *>& foundElems,
+ const SMDSAbs_ElementType type)
+{
+ // chose a node with minimal number of inverse elements
+ const SMDS_MeshNode* n0 = nodes[0];
+ int minNbInverse = n0 ? n0->NbInverseElements( type ) : 1000;
+ for ( size_t i = 1; i < nodes.size(); ++i )
+ if ( nodes[i] && nodes[i]->NbInverseElements( type ) < minNbInverse )
+ {
+ n0 = nodes[i];
+ minNbInverse = n0->NbInverseElements( type );
+ }
+
+ foundElems.clear();
+ if ( n0 )
+ {
+ foundElems.reserve( minNbInverse );
+ SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type );
+ while ( eIt->more() )
+ {
+ const SMDS_MeshElement* e = eIt->next();
+ bool includeAll = true;
+ for ( size_t i = 0; i < nodes.size() && includeAll; ++i )
+ if ( nodes[i] != n0 && e->GetNodeIndex( nodes[i] ) < 0 )
+ includeAll = false;
+ if ( includeAll )
+ foundElems.push_back( e );
+ }
+ }
+ return foundElems.size();
+}
+
//=======================================================================
//function : DumpNodes
//purpose :
//=======================================================================
//function : AddVolume
-//purpose :
+//purpose : 2d order Pentahedron (prism) with 15 nodes
//=======================================================================
SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
const SMDS_MeshNode * n2,
//=======================================================================
//function : AddVolumeWithID
-//purpose :
+//purpose : 2d order Pentahedron (prism) with 15 nodes
//=======================================================================
SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
int n4, int n5, int n6,
//=======================================================================
//function : AddVolumeWithID
-//purpose : 2d order Pentahedron with 15 nodes
+//purpose : 2d order Pentahedron (prism) with 15 nodes
//=======================================================================
SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
const SMDS_MeshNode * n2,
return volvtk;
}
+//=======================================================================
+//function : AddVolume
+//purpose : 2d order Pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n12,
+ const SMDS_MeshNode * n23,
+ const SMDS_MeshNode * n31,
+ const SMDS_MeshNode * n45,
+ const SMDS_MeshNode * n56,
+ const SMDS_MeshNode * n64,
+ const SMDS_MeshNode * n14,
+ const SMDS_MeshNode * n25,
+ const SMDS_MeshNode * n36,
+ const SMDS_MeshNode * n1245,
+ const SMDS_MeshNode * n2356,
+ const SMDS_MeshNode * n1346)
+{
+ //MESSAGE("AddVolume penta18");
+ int ID = myElementIDFactory->GetFreeID();
+ SMDS_MeshVolume * v =
+ SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
+ n45, n56, n64, n14, n25, n36, n1245, n2356, n1346, ID);
+ if(v==NULL) myElementIDFactory->ReleaseID(ID);
+ return v;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose : 2d order Pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
+ int n4, int n5, int n6,
+ int n12,int n23,int n31,
+ int n45,int n56,int n64,
+ int n14,int n25,int n36,
+ int n1245, int n2356, int n1346, int ID)
+{
+ //MESSAGE("AddVolumeWithID penta18 " << ID);
+ return SMDS_Mesh::AddVolumeWithID
+ ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1245),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2356),
+ (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1346),
+ ID);
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose : 2d order Pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n12,
+ const SMDS_MeshNode * n23,
+ const SMDS_MeshNode * n31,
+ const SMDS_MeshNode * n45,
+ const SMDS_MeshNode * n56,
+ const SMDS_MeshNode * n64,
+ const SMDS_MeshNode * n14,
+ const SMDS_MeshNode * n25,
+ const SMDS_MeshNode * n36,
+ const SMDS_MeshNode * n1245,
+ const SMDS_MeshNode * n2356,
+ const SMDS_MeshNode * n1346,
+ int ID)
+{
+ //MESSAGE("AddVolumeWithID penta18 "<< ID);
+ if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
+ !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
+ return 0;
+ if(hasConstructionFaces()) {
+ // creation quadratic faces - not implemented
+ return 0;
+ }
+ // --- retrieve nodes ID
+ myNodeIds.resize(18);
+ myNodeIds[0] = n1->getVtkId();
+ myNodeIds[1] = n2->getVtkId();
+ myNodeIds[2] = n3->getVtkId();
+
+ myNodeIds[3] = n4->getVtkId();
+ myNodeIds[4] = n5->getVtkId();
+ myNodeIds[5] = n6->getVtkId();
+
+ myNodeIds[6] = n12->getVtkId();
+ myNodeIds[7] = n23->getVtkId();
+ myNodeIds[8] = n31->getVtkId();
+
+ myNodeIds[9] = n45->getVtkId();
+ myNodeIds[10] = n56->getVtkId();
+ myNodeIds[11] = n64->getVtkId();
+
+ myNodeIds[12] = n14->getVtkId();
+ myNodeIds[13] = n25->getVtkId();
+ myNodeIds[14] = n36->getVtkId();
+
+ myNodeIds[15] = n1245->getVtkId();
+ myNodeIds[16] = n2356->getVtkId();
+ myNodeIds[17] = n1346->getVtkId();
+
+ SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+ volvtk->init(myNodeIds, this);
+ if (!this->registerElement(ID,volvtk))
+ {
+ this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+ myVolumePool->destroy(volvtk);
+ return 0;
+ }
+ adjustmyCellsCapacity(ID);
+ myCells[ID] = volvtk;
+ myInfo.myNbBiQuadPrisms++;
+
+ // if (!registerElement(ID, volvtk)) {
+ // RemoveElement(volvtk, false);
+ // volvtk = NULL;
+ // }
+ return volvtk;
+}
+
//=======================================================================
//function : AddVolume
const SMDS_MeshNode * n25,
const SMDS_MeshNode * n36);
+ // 2d order Pentahedron with 18 nodes
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3,
+ int n4, int n5, int n6,
+ int n12,int n23,int n31,
+ int n45,int n56,int n64,
+ int n14,int n25,int n36,
+ int n1245, int n2356, int n1346,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n12,
+ const SMDS_MeshNode * n23,
+ const SMDS_MeshNode * n31,
+ const SMDS_MeshNode * n45,
+ const SMDS_MeshNode * n56,
+ const SMDS_MeshNode * n64,
+ const SMDS_MeshNode * n14,
+ const SMDS_MeshNode * n25,
+ const SMDS_MeshNode * n36,
+ const SMDS_MeshNode * n1245,
+ const SMDS_MeshNode * n2356,
+ const SMDS_MeshNode * n1346,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n12,
+ const SMDS_MeshNode * n23,
+ const SMDS_MeshNode * n31,
+ const SMDS_MeshNode * n45,
+ const SMDS_MeshNode * n56,
+ const SMDS_MeshNode * n64,
+ const SMDS_MeshNode * n14,
+ const SMDS_MeshNode * n25,
+ const SMDS_MeshNode * n36,
+ const SMDS_MeshNode * n1245,
+ const SMDS_MeshNode * n2356,
+ const SMDS_MeshNode * n1346);
+
+
// 2d oreder Hexahedrons with 20 nodes
virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
int n5, int n6, int n7, int n8,
static const SMDS_MeshElement* FindElement(const std::vector<const SMDS_MeshNode *>& nodes,
const SMDSAbs_ElementType type=SMDSAbs_All,
const bool noMedium=true);
+ static int GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
+ std::vector<const SMDS_MeshElement *>& foundElems,
+ const SMDSAbs_ElementType type=SMDSAbs_All);
/*!
* \brief Raise an exception if free memory (ram+swap) too low
vtkTypes[ SMDSEntity_TriQuad_Hexa ] = VTK_TRIQUADRATIC_HEXAHEDRON;
vtkTypes[ SMDSEntity_Penta ] = VTK_WEDGE;
vtkTypes[ SMDSEntity_Quad_Penta ] = VTK_QUADRATIC_WEDGE;
+ vtkTypes[ SMDSEntity_BiQuad_Penta ] = VTK_BIQUADRATIC_QUADRATIC_WEDGE;
vtkTypes[ SMDSEntity_Hexagonal_Prism ] = VTK_HEXAGONAL_PRISM;
vtkTypes[ SMDSEntity_Polyhedra ] = VTK_POLYHEDRON;
//vtkTypes[ SMDSEntity_Quad_Polyhedra ] = ;
toVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
}
{
- const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
+ const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; // TODO: check
toVtkInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
}
+ {
+ const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};// TODO: check
+ toVtkInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 );
+ }
{
const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
toVtkInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
reverseInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
}
{
+ const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13,15,16,17};
+ reverseInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 );
+ }
+ {
const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
}
case SMDSEntity_TriQuad_Hexa:
case SMDSEntity_Penta:
case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
case SMDSEntity_Hexagonal_Prism:
case SMDSEntity_Polyhedra:
case SMDSEntity_Quad_Polyhedra: return SMDSAbs_Volume;
bool SMDS_MeshGroup::Contains(const SMDS_MeshElement * theElem) const
{
- return myElements.find(theElem)!=myElements.end();
+ return myElements.find(theElem) != myElements.end();
}
//=======================================================================
#include "SMESH_SMDS.hxx"
#include "SMDS_MeshElement.hxx"
+#include<utilities.h>
class SMDS_EXPORT SMDS_MeshInfo
{
inline int NbPrisms (SMDSAbs_ElementOrder order = ORDER_ANY) const;
inline int NbHexPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const;
int NbTriQuadHexas() const { return myNbTriQuadHexas; }
+ int NbQuadPrisms() const { return myNbQuadPrisms; }
+ int NbBiQuadPrisms() const { return myNbBiQuadPrisms; }
int NbPolyhedrons() const { return myNbPolyhedrons; }
protected:
int myNbTetras , myNbQuadTetras ;
int myNbHexas , myNbQuadHexas, myNbTriQuadHexas;
int myNbPyramids, myNbQuadPyramids;
- int myNbPrisms , myNbQuadPrisms ;
+ int myNbPrisms , myNbQuadPrisms, myNbBiQuadPrisms;
int myNbHexPrism;
int myNbPolyhedrons;
myNbTetras (0), myNbQuadTetras (0),
myNbHexas (0), myNbQuadHexas (0), myNbTriQuadHexas(0),
myNbPyramids (0), myNbQuadPyramids(0),
- myNbPrisms (0), myNbQuadPrisms (0),
+ myNbPrisms (0), myNbQuadPrisms (0), myNbBiQuadPrisms(0),
myNbHexPrism (0),
myNbPolyhedrons(0)
{
// 15 *
// 16 *
// 17 *
- // 18 *
- // 19 *
+ // 18 *
+ // 19
// 20 *
- // 21 *
- // 22 *
- // 23 *
- // 24 *
- // 25
- // 26
+ // 21
+ // 22
+ // 23
+ // 24
+ // 25 *
+ // 26 *
// 27 *
+ // 28 *
+ // 29 *
+ // 30 *
+ // 31 *
//
// So to have a unique index for each type basing on nb of nodes, we use a shift:
myShift.resize(SMDSAbs_NbElementTypes, 0);
- myShift[ SMDSAbs_Face ] = +15;// 3->18, 4->19, etc.
+ myShift[ SMDSAbs_Face ] = +22;// 3->25, 4->26, etc.
myShift[ SMDSAbs_Edge ] = +14;// 2->16, 3->17
myShift[ SMDSAbs_0DElement ] = +2; // 1->3
myShift[ SMDSAbs_Ball ] = +1; // 1->2
- myNb.resize( index( SMDSAbs_Volume,27 ) + 1, NULL);
+ myNb.resize( index( SMDSAbs_Face,9 ) + 1, NULL);
myNb[ index( SMDSAbs_Node,1 )] = & myNbNodes;
myNb[ index( SMDSAbs_0DElement,1 )] = & myNb0DElements;
myNb[ index( SMDSAbs_Volume, 12)] = & myNbHexPrism;
myNb[ index( SMDSAbs_Volume, 13)] = & myNbQuadPyramids;
myNb[ index( SMDSAbs_Volume, 15)] = & myNbQuadPrisms;
+ myNb[ index( SMDSAbs_Volume, 18)] = & myNbBiQuadPrisms;
myNb[ index( SMDSAbs_Volume, 20)] = & myNbQuadHexas;
myNb[ index( SMDSAbs_Volume, 27)] = & myNbTriQuadHexas;
}
inline int // NbPrisms
SMDS_MeshInfo::NbPrisms (SMDSAbs_ElementOrder order) const
-{ return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms : order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms; }
+{ return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms+myNbBiQuadPrisms: order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms+myNbBiQuadPrisms; }
inline int // NbHexPrisms
SMDS_MeshInfo::NbHexPrisms (SMDSAbs_ElementOrder order) const
break;
case SMDSAbs_Volume:
nb = ( myNbTetras+ myNbPyramids+ myNbPrisms+ myNbHexas+ myNbHexPrism+
- myNbQuadTetras+ myNbQuadPyramids+ myNbQuadPrisms+ myNbQuadHexas+ myNbTriQuadHexas+
+ myNbQuadTetras+ myNbQuadPyramids+ myNbQuadPrisms+ myNbBiQuadPrisms + myNbQuadHexas+ myNbTriQuadHexas+
myNbPolyhedrons );
break;
case SMDSAbs_Face:
case SMDSEntity_TriQuad_Hexa: return myNbTriQuadHexas;
case SMDSEntity_Penta: return myNbPrisms;
case SMDSEntity_Quad_Penta: return myNbQuadPrisms;
+ case SMDSEntity_BiQuad_Penta: return myNbBiQuadPrisms;
case SMDSEntity_Hexagonal_Prism: return myNbHexPrism;
case SMDSEntity_Polyhedra: return myNbPolyhedrons;
case SMDSEntity_0D: return myNb0DElements;
myNbQuadHexas +
myNbTriQuadHexas);
case SMDSGeom_PENTA: return (myNbPrisms +
- myNbQuadPrisms);
+ myNbQuadPrisms +
+ myNbBiQuadPrisms);
case SMDSGeom_HEXAGONAL_PRISM: return myNbHexPrism;
case SMDSGeom_POLYHEDRA: return myNbPolyhedrons;
// Discrete:
case SMDSEntity_Quad_Edge: myNbQuadEdges = nb; break;
case SMDSEntity_Quad_Hexa: myNbQuadHexas = nb; break;
case SMDSEntity_Quad_Penta: myNbQuadPrisms = nb; break;
+ case SMDSEntity_BiQuad_Penta: myNbBiQuadPrisms = nb; break;
case SMDSEntity_Quad_Pyramid: myNbQuadPyramids = nb; break;
case SMDSEntity_Quad_Quadrangle: myNbQuadQuadrangles = nb; break;
case SMDSEntity_Quad_Tetra: myNbQuadTetras = nb; break;
case 10: aType = SMDSEntity_Quad_Tetra; break;
case 13: aType = SMDSEntity_Quad_Pyramid; break;
case 15: aType = SMDSEntity_Quad_Penta; break;
+ case 18: aType = SMDSEntity_BiQuad_Penta; break;
case 20:
default: aType = SMDSEntity_Quad_Hexa; break;
}
break;
}
case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta: //TODO: check
{
static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 };
ids = id;
vtkIdType aType = VTK_TETRA;
switch (nodeIds.size()) // cases are in order of usage frequency
{
- case 4: aType = VTK_TETRA; break;
- case 8: aType = VTK_HEXAHEDRON; break;
- case 5: aType = VTK_PYRAMID; break;
- case 6: aType = VTK_WEDGE; break;
- case 10: aType = VTK_QUADRATIC_TETRA; break;
- case 20: aType = VTK_QUADRATIC_HEXAHEDRON; break;
- case 13: aType = VTK_QUADRATIC_PYRAMID; break;
- case 15: aType = VTK_QUADRATIC_WEDGE; break;
- case 12: aType = VTK_HEXAGONAL_PRISM; break;
- case 27: aType = VTK_TRIQUADRATIC_HEXAHEDRON;break;
+ case 4: aType = VTK_TETRA; break;
+ case 8: aType = VTK_HEXAHEDRON; break;
+ case 5: aType = VTK_PYRAMID; break;
+ case 6: aType = VTK_WEDGE; break;
+ case 10: aType = VTK_QUADRATIC_TETRA; break;
+ case 20: aType = VTK_QUADRATIC_HEXAHEDRON; break;
+ case 13: aType = VTK_QUADRATIC_PYRAMID; break;
+ case 15: aType = VTK_QUADRATIC_WEDGE; break;
+ case 18: aType = VTK_BIQUADRATIC_QUADRATIC_WEDGE; break;
+ case 12: aType = VTK_HEXAGONAL_PRISM; break;
+ case 27: aType = VTK_TRIQUADRATIC_HEXAHEDRON; break;
default: aType = VTK_HEXAHEDRON;
}
myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]);
case VTK_WEDGE:
case VTK_QUADRATIC_PYRAMID:
case VTK_QUADRATIC_WEDGE:
+ case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
nbFaces = 5;
break;
case VTK_HEXAHEDRON:
break;
case VTK_WEDGE:
case VTK_QUADRATIC_WEDGE:
+ case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
nbEdges = 9;
break;
case VTK_HEXAHEDRON:
case VTK_QUADRATIC_TETRA:
case VTK_QUADRATIC_PYRAMID:
case VTK_QUADRATIC_WEDGE:
+ case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
case VTK_QUADRATIC_HEXAHEDRON:
case VTK_TRIQUADRATIC_HEXAHEDRON:
return true;
rankFirstMedium = 5; // medium nodes are of rank 5 to 12
break;
case VTK_QUADRATIC_WEDGE:
+ case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
rankFirstMedium = 6; // medium nodes are of rank 6 to 14
break;
case VTK_QUADRATIC_HEXAHEDRON:
vtkIdType aVtkType = grid->GetCellType(myVtkID);
switch (aVtkType)
{
- case VTK_QUADRATIC_TETRA: return 4;
- case VTK_QUADRATIC_PYRAMID: return 5;
- case VTK_QUADRATIC_WEDGE: return 6;
+ case VTK_QUADRATIC_TETRA: return 4;
+ case VTK_QUADRATIC_PYRAMID: return 5;
+ case VTK_QUADRATIC_WEDGE:
+ case VTK_BIQUADRATIC_QUADRATIC_WEDGE: return 6;
case VTK_QUADRATIC_HEXAHEDRON:
- case VTK_TRIQUADRATIC_HEXAHEDRON: return 8;
+ case VTK_TRIQUADRATIC_HEXAHEDRON: return 8;
default:;
}
return NbNodes();
case VTK_QUADRATIC_WEDGE:
aType = SMDSEntity_Quad_Penta;
break;
+ case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
+ aType = SMDSEntity_BiQuad_Penta;
+ break;
case VTK_QUADRATIC_HEXAHEDRON:
aType = SMDSEntity_Quad_Hexa;
break;
break;
case VTK_WEDGE:
case VTK_QUADRATIC_WEDGE:
+ case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
aType = SMDSGeom_PENTA;
break;
case VTK_HEXAHEDRON:
#include "SMESH_TypeDefs.hxx"
#include "SMESH_subMesh.hxx"
-#include <Basics_OCCTVersion.hxx>
-
#include <BRepAdaptor_Curve.hxx>
#include <BRepLProp.hxx>
#include <BRep_Tool.hxx>
case GeomAbs_Hyperbola:
case GeomAbs_Parabola:
return false;
- // case GeomAbs_BezierCurve:
- // case GeomAbs_BSplineCurve:
- // case GeomAbs_OtherCurve:
+ // case GeomAbs_BezierCurve:
+ // case GeomAbs_BSplineCurve:
+ // case GeomAbs_OtherCurve:
default:;
}
- const double f = curve.FirstParameter();
- const double l = curve.LastParameter();
- const gp_Pnt pf = curve.Value( f );
- const gp_Pnt pl = curve.Value( l );
- const gp_Vec v1( pf, pl );
- const double v1Len = v1.Magnitude();
- if ( v1Len < std::numeric_limits< double >::min() )
+
+ // evaluate how far from a straight line connecting the curve ends
+ // stand internal points of the curve
+ double f = curve.FirstParameter();
+ double l = curve.LastParameter();
+ gp_Pnt pf = curve.Value( f );
+ gp_Pnt pl = curve.Value( l );
+ gp_Vec lineVec( pf, pl );
+ double lineLen2 = lineVec.SquareMagnitude();
+ if ( lineLen2 < std::numeric_limits< double >::min() )
return false; // E seems closed
- const double tol = Min( 10 * curve.Tolerance(), v1Len * 1e-2 );
+
+ double edgeTol = 10 * curve.Tolerance();
+ double lenTol2 = lineLen2 * 1e-4;
+ double tol2 = Min( edgeTol * edgeTol, lenTol2 );
+
const double nbSamples = 7;
for ( int i = 0; i < nbSamples; ++i )
{
- const double r = ( i + 1 ) / nbSamples;
- const gp_Pnt pi = curve.Value( f * r + l * ( 1 - r ));
- const gp_Vec vi( pf, pi );
- const double h = 0.5 * v1.Crossed( vi ).Magnitude() / v1Len;
- if ( h > tol )
+ double r = ( i + 1 ) / nbSamples;
+ gp_Pnt pi = curve.Value( f * r + l * ( 1 - r ));
+ gp_Vec vi( pf, pi );
+ double h2 = lineVec.Crossed( vi ).SquareMagnitude() / lineLen2;
+ if ( h2 > tol2 )
return false;
}
return true;
return error( COMPERR_BAD_INPUT_MESH, "Mesh built on shape expected");
}
+//=======================================================================
+//function : IsApplicableToShape
+//purpose : Return true if the algorithm can mesh a given shape
+//=======================================================================
+
+bool SMESH_Algo::IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+{
+ return true;
+}
+
//=======================================================================
//function : CancelCompute
//purpose : Sets _computeCanceled to true. It's usage depends on
*/
virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper);
+ /*!
+ * \brief Return true if the algorithm can mesh a given shape
+ * \param [in] aShape - shape to check
+ * \param [in] toCheckAll - if true, this check returns OK if all shapes are OK,
+ * else, returns OK if at least one shape is OK
+ * \retval bool - \c true by default
+ */
+ virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const;
+
/*!
* \brief Sets _computeCanceled to true. It's usage depends on
* implementation of a particular mesher.
bool theAllElemsToGroup)
throw(SALOME_Exception)
{
+ //MESSAGE("MED_VERSION:"<< theVersion);
SMESH_TRY;
DriverMED_W_SMESHDS_Mesh myWriter;
myWriter.SetMeshId(_id);
// myWriter.SetGroups(_mapGroup);
+ // pass group names to SMESHDS
if ( !meshPart )
{
for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
void SMESH_Mesh::ExportCGNS(const char * file,
const SMESHDS_Mesh* meshDS,
- const char * meshName)
+ const char * meshName,
+ const bool groupElemsByType)
{
int res = Driver_Mesh::DRS_FAIL;
+
+ // pass group names to SMESHDS
+ for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
+ SMESH_Group* group = it->second;
+ SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+ if ( groupDS ) {
+ string groupName = group->GetName();
+ groupDS->SetStoreName( groupName.c_str() );
+ }
+ }
#ifdef WITH_CGNS
+
DriverCGNS_Write myWriter;
myWriter.SetFile( file );
myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
if ( meshName && meshName[0] )
myWriter.SetMeshName( meshName );
+ myWriter.SetElementsByType( groupElemsByType );
res = myWriter.Perform();
+ if ( res != Driver_Mesh::DRS_OK )
+ {
+ SMESH_ComputeErrorPtr err = myWriter.GetError();
+ if ( err && !err->IsOK() && !err->myComment.empty() )
+ throw SALOME_Exception(("Export failed: " + err->myComment ).c_str() );
+ }
+
#endif
if ( res != Driver_Mesh::DRS_OK )
throw SALOME_Exception("Export failed");
return _myMeshDS->GetMeshInfo().NbPrisms(order);
}
+int SMESH_Mesh::NbQuadPrisms() const throw (SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->GetMeshInfo().NbQuadPrisms();
+}
+
+int SMESH_Mesh::NbBiQuadPrisms() const throw (SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ return _myMeshDS->GetMeshInfo().NbBiQuadPrisms();
+}
+
+
//================================================================================
/*!
* \brief Return number of hexagonal prisms in the mesh
const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception);
void ExportCGNS(const char * file,
const SMESHDS_Mesh* mesh,
- const char * meshName = 0);
+ const char * meshName = 0,
+ const bool groupElemsByType = false);
void ExportGMF(const char * file,
const SMESHDS_Mesh* mesh,
bool withRequiredGroups = true );
int NbTriQuadraticHexas() const throw(SALOME_Exception);
int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
int NbPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
+ int NbQuadPrisms() const throw(SALOME_Exception);
+ int NbBiQuadPrisms() const throw(SALOME_Exception);
int NbHexagonalPrisms() const throw(SALOME_Exception);
int NbPolyhedrons() const throw(SALOME_Exception);
#include "SMESH_OctreeNode.hxx"
#include "SMESH_subMesh.hxx"
-#include <Basics_OCCTVersion.hxx>
-
#include "utilities.h"
#include "chrono.hxx"
break;
case SMDSEntity_Penta:
case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
connVariants = thePentaTo3; nbTet = 3; nbVariants = 6;
break;
default:
}
// Remove bad elements, then equal nodes (order important)
- Remove( rmElemIds, false );
- Remove( rmNodeIds, true );
+ Remove( rmElemIds, /*isNodes=*/false );
+ Remove( rmNodeIds, /*isNodes=*/true );
return;
}
toRemove = true;
nbResElems = 0;
- if ( elem->IsQuadratic() && newElemDefs[0].myType == SMDSAbs_Face && nbNodes > 6 )
+ if ( newElemDefs[0].myIsQuad && newElemDefs[0].myType == SMDSAbs_Face && nbNodes > 6 )
{
// if corner nodes stick, remove medium nodes between them from uniqueNodes
int nbCorners = nbNodes / 2;
for ( int iCur = 0; iCur < nbCorners; ++iCur )
{
- int iPrev = ( iCur + 1 ) % nbCorners;
- if ( curNodes[ iCur ] == curNodes[ iPrev ] ) // corners stick
+ int iNext = ( iCur + 1 ) % nbCorners;
+ if ( curNodes[ iCur ] == curNodes[ iNext ] ) // corners stick
{
int iMedium = iCur + nbCorners;
vector< const SMDS_MeshNode* >::iterator i =
// | |
// +---+---+
// 0 7 3
- if (( nbUniqueNodes == 7 && nbRepl == 2 && iRepl[1] != 8 ) &&
- (( iRepl[0] == 1 && iRepl[1] == 4 && curNodes[1] == curNodes[0] ) ||
- ( iRepl[0] == 2 && iRepl[1] == 5 && curNodes[2] == curNodes[1] ) ||
- ( iRepl[0] == 3 && iRepl[1] == 6 && curNodes[3] == curNodes[2] ) ||
- ( iRepl[0] == 3 && iRepl[1] == 7 && curNodes[3] == curNodes[0] )))
+ if ( nbUniqueNodes == 7 &&
+ iRepl[0] < 4 &&
+ ( nbRepl == 1 || iRepl[1] != 8 ))
{
toRemove = false;
}
SMESH_MesherHelper& theHelper,
const bool theForce3d)
{
+ //MESSAGE("convertElemToQuadratic");
int nbElem = 0;
if( !theSm ) return nbElem;
case SMDSEntity_Quad_Triangle:
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_Quad_Hexa:
+ case SMDSEntity_Quad_Penta:
alreadyOK = !theHelper.GetIsBiQuadratic(); break;
case SMDSEntity_BiQuad_Triangle:
case SMDSEntity_BiQuad_Quadrangle:
case SMDSEntity_TriQuad_Hexa:
+ case SMDSEntity_BiQuad_Penta:
alreadyOK = theHelper.GetIsBiQuadratic();
hasCentralNodes = true;
break;
default:
alreadyOK = true;
}
- // take into account already present modium nodes
+ // take into account already present medium nodes
switch ( aType ) {
case SMDSAbs_Volume:
theHelper.AddTLinks( static_cast< const SMDS_MeshVolume* >( elem )); break;
NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], id, theForce3d);
break;
case SMDSEntity_Penta:
+ case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d);
break;
case SMDSEntity_Hexa:
void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theToBiQuad)
{
+ //MESSAGE("ConvertToQuadratic "<< theForce3d << " " << theToBiQuad);
SMESHDS_Mesh* meshDS = GetMeshDS();
SMESH_MesherHelper aHelper(*myMesh);
{
case SMDSEntity_Quad_Hexa: alreadyOK = !theToBiQuad; break;
case SMDSEntity_TriQuad_Hexa: alreadyOK = theToBiQuad; break;
+ case SMDSEntity_Quad_Penta: alreadyOK = !theToBiQuad; break;
+ case SMDSEntity_BiQuad_Penta: alreadyOK = theToBiQuad; break;
default: alreadyOK = true;
}
if ( alreadyOK )
nodes[3], nodes[4], id, theForce3d);
break;
case SMDSEntity_Penta:
+ case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
nodes[3], nodes[4], nodes[5], id, theForce3d);
+ for ( size_t i = 15; i < nodes.size(); ++i ) // rm central nodes
+ if ( nodes[i]->NbInverseElements() == 0 )
+ GetMeshDS()->RemoveFreeNode( nodes[i], /*sm=*/0, /*fromGroups=*/true );
break;
case SMDSEntity_Hexagonal_Prism:
default:
MESSAGE( "SMESH_MesherHelper::CheckNodeUV() failed to project" );
return false;
}
- Quantity_Parameter U,V;
+ Standard_Real U,V;
projector.LowerDistanceParameters(U,V);
uv.SetCoord( U,V );
surfPnt = surface->Value( U, V );
MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
return false;
}
- Quantity_Parameter U = projector->LowerDistanceParameter();
+ Standard_Real U = projector->LowerDistanceParameter();
u = double( U );
curvPnt = curve->Value( u );
dist = nodePnt.Distance( curvPnt );
const SMDS_MeshNode* n14 = GetMediumNode( n1, n4, force3d, TopAbs_SOLID );
const SMDS_MeshNode* n25 = GetMediumNode( n2, n5, force3d, TopAbs_SOLID );
const SMDS_MeshNode* n36 = GetMediumNode( n3, n6, force3d, TopAbs_SOLID );
+ if ( myCreateBiQuadratic )
+ {
+ const SMDS_MeshNode* n1245 = GetCentralNode( n1,n2,n4,n5,n12,n25,n45,n14,force3d );
+ const SMDS_MeshNode* n1346 = GetCentralNode( n1,n3,n4,n6,n31,n36,n64,n14,force3d );
+ const SMDS_MeshNode* n2356 = GetCentralNode( n2,n3,n6,n5,n23,n36,n56,n25,force3d );
- if(id)
- elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6,
- n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
+ if(id)
+ elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6,
+ n12, n23, n31, n45, n56, n64, n14, n25, n36,
+ n1245, n2356, n1346, id);
+ else
+ elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
+ n12, n23, n31, n45, n56, n64, n14, n25, n36,
+ n1245, n2356, n1346);
+ }
else
- elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
- n12, n23, n31, n45, n56, n64, n14, n25, n36);
+ {
+ if(id)
+ elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6,
+ n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
+ else
+ elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
+ n12, n23, n31, n45, n56, n64, n14, n25, n36);
+ }
}
if ( mySetElemOnShape && myShapeID > 0 )
meshDS->SetMeshElementOnShape( elem, myShapeID );
}
// nb rows of nodes
- size_t prevNbRows = theParam2ColumnMap.begin()->second.size(); // current, at least 1 here
+ size_t prevNbRows = theParam2ColumnMap.begin()->second.size(); // current, at least 1 here
size_t expectNbRows = faceSubMesh->NbElements() / ( theParam2ColumnMap.size()-1 ); // to be added
// fill theParam2ColumnMap column by column by passing from nodes on
void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
bool volumeOnly)
{
+ //MESSAGE("FixQuadraticElements " << volumeOnly);
// setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion
if ( getenv("NO_FixQuadraticElements") )
return;
nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--;
#endif
for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) {
+ MESSAGE("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key()));
MSG("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key()));
SMESH_MesherHelper h(*myMesh);
h.SetSubShape( fIt.Key() );
// 4. Move nodes
// -------------
- TIDSortedElemSet biQuadQuas, biQuadTris, triQuadHexa;
+ TIDSortedElemSet biQuadQuas, biQuadTris, triQuadHexa, biQuadPenta;
const bool toFixCentralNodes = ( myMesh->NbBiQuadQuadrangles() +
myMesh->NbBiQuadTriangles() +
- myMesh->NbTriQuadraticHexas() );
+ myMesh->NbTriQuadraticHexas() +
+ myMesh->NbBiQuadPrisms());
double distXYZ[4];
faceHlp.ToFixNodeParameters( true );
case SMDSEntity_BiQuad_Quadrangle: biQuadQuas.insert( e ); break;
case SMDSEntity_BiQuad_Triangle: biQuadTris.insert( e ); break;
case SMDSEntity_TriQuad_Hexa: triQuadHexa.insert( e ); break;
+ case SMDSEntity_BiQuad_Penta: biQuadPenta.insert( e ); break;
default:;
}
}
nCenterCoords.X(), nCenterCoords.Y(), nCenterCoords.Z());
}
}
+ // treat tri-quadratic hexahedra
+ {
+ SMDS_VolumeTool volExp;
+ TIDSortedElemSet::iterator pentIt = biQuadPenta.begin();
+ for ( ; pentIt != biQuadPenta.end(); ++pentIt )
+ {
+ MESSAGE("---");
+ volExp.Set( *pentIt, /*ignoreCentralNodes=*/false );
+ }
+ }
#ifdef _DEBUG_
// avoid warning: defined but not used operator<<()
SMESH_Comment() << *links.begin() << *faces.begin();
#include <gp_XY.hxx>
#include <gp_XYZ.hxx>
-#include <Basics_OCCTVersion.hxx>
-
#include <Basics_Utils.hxx>
#include "utilities.h"
Extrema_GenExtPS projector;
GeomAdaptor_Surface aSurface( BRep_Tool::Surface( face ));
- if ( theProject || needProject )
- projector.Initialize( aSurface, 20,20, 1e-5,1e-5 );
+ projector.Initialize( aSurface, 20,20, 1e-5,1e-5 );
int iPoint = 0;
TNodePointIDMap nodePointIDMap;
myPoints.resize( nbNodes );
+ // care of INTERNAL VERTEXes
+ TopExp_Explorer vExp( face, TopAbs_VERTEX, TopAbs_EDGE );
+ for ( ; vExp.More(); vExp.Next() )
+ {
+ const SMDS_MeshNode* node =
+ SMESH_Algo::VertexNode( TopoDS::Vertex( vExp.Current()), aMeshDS );
+ if ( !node || node->NbInverseElements( SMDSAbs_Face ) == 0 )
+ continue;
+ myPoints.resize( ++nbNodes );
+ list< TPoint* > & fPoints = getShapePoints( face );
+ nodePointIDMap.insert( make_pair( node, iPoint ));
+ TPoint* p = &myPoints[ iPoint++ ];
+ fPoints.push_back( p );
+ gp_XY uv = helper.GetNodeUV( face, node );
+ p->myInitUV.SetCoord( uv.X(), uv.Y() );
+ p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
+ }
+
// Load U of points on edges
+ Bnd_Box2d edgesUVBox;
+
list<int>::iterator nbEinW = myNbKeyPntInBoundary.begin();
int iE = 0;
vector< TopoDS_Edge > eVec;
else
keyPoint->myInitUV = C2d->Value( isForward ? f : l ).XY();
keyPoint->myInitXYZ.SetCoord (keyPoint->myInitUV.X(), keyPoint->myInitUV.Y(), 0);
+ edgesUVBox.Add( gp_Pnt2d( keyPoint->myInitUV ));
}
}
if ( !vPoint->empty() )
p->myInitUV = C2d->Value( u ).XY();
}
p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
+ edgesUVBox.Add( gp_Pnt2d( p->myInitUV ));
unIt++; unRIt++;
iPoint++;
}
else
keyPoint->myInitUV = C2d->Value( isForward ? l : f ).XY();
keyPoint->myInitXYZ.SetCoord( keyPoint->myInitUV.X(), keyPoint->myInitUV.Y(), 0 );
+ edgesUVBox.Add( gp_Pnt2d( keyPoint->myInitUV ));
}
}
if ( !vPoint->empty() )
nodePointIDMap.insert( make_pair( node, iPoint ));
TPoint* p = &myPoints[ iPoint++ ];
fPoints.push_back( p );
- if ( theProject )
+ if ( theProject || edgesUVBox.IsOut( p->myInitUV ) )
p->myInitUV = project( node, projector );
else {
const SMDS_FacePosition* pos =
#include "SMESH_MesherHelper.hxx"
#include "SMESH_subMeshEventListener.hxx"
-#include <Basics_OCCTVersion.hxx>
-
#include "utilities.h"
#include "OpUtil.hxx"
#include "Basics_Utils.hxx"
myIntegers.push_back(n36);
myNumber++;
}
+//=======================================================================
+//function : AddVolume
+//purpose :
+//=======================================================================
+void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2,
+ int n3, int n4, int n5,int n6,
+ int n12, int n23, int n31,
+ int n45, int n56, int n64,
+ int n14, int n25, int n36,
+ int n1245, int n2356, int n1346)
+{
+ if ( myType != SMESHDS_AddBiQuadPentahedron) {
+ MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+ return;
+ }
+ myIntegers.push_back(NewVolID);
+ myIntegers.push_back(n1);
+ myIntegers.push_back(n2);
+ myIntegers.push_back(n3);
+ myIntegers.push_back(n4);
+ myIntegers.push_back(n5);
+ myIntegers.push_back(n6);
+ myIntegers.push_back(n12);
+ myIntegers.push_back(n23);
+ myIntegers.push_back(n31);
+ myIntegers.push_back(n45);
+ myIntegers.push_back(n56);
+ myIntegers.push_back(n64);
+ myIntegers.push_back(n14);
+ myIntegers.push_back(n25);
+ myIntegers.push_back(n36);
+ myIntegers.push_back(n1245);
+ myIntegers.push_back(n2356);
+ myIntegers.push_back(n1346);
+ myNumber++;
+}
+
//=======================================================================
//function : AddVolume
int n1234,int n1256,int n2367,int n3478,
int n1458,int n5678,int nCenter)
{
- if ( myType != SMESHDS_AddQuadHexahedron) {
+ if ( myType != SMESHDS_AddTriQuadHexa) {
MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
return;
}
int n12, int n23, int n31,
int n45, int n56, int n64,
int n14, int n25, int n36);
+ void AddVolume(int NewVolID, int n1, int n2, int n3,
+ int n4, int n5, int n6,
+ int n12, int n23, int n31,
+ int n45, int n56, int n64,
+ int n14, int n25, int n36,
+ int n1245, int n2356, int n1346);
void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
int n5, int n6, int n7, int n8,
int n12, int n23, int n34, int n41,
SMESHDS_Add0DElement,
SMESHDS_AddBiQuadTriangle,
SMESHDS_AddBiQuadQuadrangle,
+ SMESHDS_AddBiQuadPentahedron,
SMESHDS_AddTriQuadHexa,
SMESHDS_AddHexagonalPrism,
SMESHDS_AddBall
//=============================================================================
/*!
- *
+ * Don't use it!
*/
//=============================================================================
virtual SMDS_ElemIteratorPtr GetElements() const = 0;
virtual int GetID (const int theIndex);
- // use it for iterations 1..Extent()
+ // DON'T use it for iterations 1..Extent()
virtual int GetTic() const = 0;
//=======================================================================
//function : AddVolume
-//purpose :
+//purpose : 2nd order pentahedron (prism) with 15 nodes
//=======================================================================
SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
const SMDS_MeshNode * n2,
//=======================================================================
//function : AddVolumeWithID
-//purpose :
+//purpose : 2nd order pentahedron (prism) with 15 nodes
//=======================================================================
SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
int n4, int n5, int n6,
n45,n56,n64,n14,n25,n36);
return anElem;
}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose : 2d order Pentahedron (prism) with 15 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n12,
+ const SMDS_MeshNode * n23,
+ const SMDS_MeshNode * n31,
+ const SMDS_MeshNode * n45,
+ const SMDS_MeshNode * n56,
+ const SMDS_MeshNode * n64,
+ const SMDS_MeshNode * n14,
+ const SMDS_MeshNode * n25,
+ const SMDS_MeshNode * n36,
+ int ID)
+{
+ return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
+ n4->GetID(), n5->GetID(), n6->GetID(),
+ n12->GetID(), n23->GetID(), n31->GetID(),
+ n45->GetID(), n56->GetID(), n64->GetID(),
+ n14->GetID(), n25->GetID(), n36->GetID(),
+ ID);
+}
+//=======================================================================
+//function : AddVolume
+//purpose : 2nd order pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n12,
+ const SMDS_MeshNode * n23,
+ const SMDS_MeshNode * n31,
+ const SMDS_MeshNode * n45,
+ const SMDS_MeshNode * n56,
+ const SMDS_MeshNode * n64,
+ const SMDS_MeshNode * n14,
+ const SMDS_MeshNode * n25,
+ const SMDS_MeshNode * n36,
+ const SMDS_MeshNode * n1245,
+ const SMDS_MeshNode * n2356,
+ const SMDS_MeshNode * n1346)
+{
+ SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
+ n45,n56,n64,n14,n25,n36,
+ n1245, n2356, n1346);
+ if(anElem)
+ myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
+ n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
+ n12->GetID(), n23->GetID(), n31->GetID(),
+ n45->GetID(), n56->GetID(), n64->GetID(),
+ n14->GetID(), n25->GetID(), n36->GetID(),
+ n1245->GetID(), n2356->GetID(), n1346->GetID());
+ return anElem;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose : 2nd order pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
+ int n4, int n5, int n6,
+ int n12,int n23,int n31,
+ int n45,int n56,int n64,
+ int n14,int n25,int n36,
+ int n1245, int n2356, int n1346,
+ int ID)
+{
+ SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
+ n12,n23,n31,
+ n45,n56,n64,
+ n14,n25,n36,
+ n1245, n2356, n1346, ID);
+ if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
+ n45,n56,n64,n14,n25,n36, n1245, n2356, n1346);
+ return anElem;
+}
//=======================================================================
//function : AddVolumeWithID
-//purpose : 2d order Pentahedron with 15 nodes
+//purpose : 2d order Pentahedron with 18 nodes
//=======================================================================
SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
const SMDS_MeshNode * n2,
const SMDS_MeshNode * n14,
const SMDS_MeshNode * n25,
const SMDS_MeshNode * n36,
+ const SMDS_MeshNode * n1245,
+ const SMDS_MeshNode * n2356,
+ const SMDS_MeshNode * n1346,
int ID)
{
return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
n12->GetID(), n23->GetID(), n31->GetID(),
n45->GetID(), n56->GetID(), n64->GetID(),
n14->GetID(), n25->GetID(), n36->GetID(),
- ID);
+ n1245->GetID(), n2356->GetID(), n1346->GetID(), ID);
}
const SMDS_MeshNode * n25,
const SMDS_MeshNode * n36);
+ // 2d order Pentahedron with 18 nodes
+ virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3,
+ int n4, int n5, int n6,
+ int n12,int n23,int n31,
+ int n45,int n56,int n64,
+ int n14,int n25,int n36,
+ int n1245, int n2356, int n1346,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n12,
+ const SMDS_MeshNode * n23,
+ const SMDS_MeshNode * n31,
+ const SMDS_MeshNode * n45,
+ const SMDS_MeshNode * n56,
+ const SMDS_MeshNode * n64,
+ const SMDS_MeshNode * n14,
+ const SMDS_MeshNode * n25,
+ const SMDS_MeshNode * n36,
+ const SMDS_MeshNode * n1245,
+ const SMDS_MeshNode * n2356,
+ const SMDS_MeshNode * n1346,
+ int ID);
+ virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3,
+ const SMDS_MeshNode * n4,
+ const SMDS_MeshNode * n5,
+ const SMDS_MeshNode * n6,
+ const SMDS_MeshNode * n12,
+ const SMDS_MeshNode * n23,
+ const SMDS_MeshNode * n31,
+ const SMDS_MeshNode * n45,
+ const SMDS_MeshNode * n56,
+ const SMDS_MeshNode * n64,
+ const SMDS_MeshNode * n14,
+ const SMDS_MeshNode * n25,
+ const SMDS_MeshNode * n36,
+ const SMDS_MeshNode * n1245,
+ const SMDS_MeshNode * n2356,
+ const SMDS_MeshNode * n1346);
+
// 2d order Hexahedrons with 20 nodes
virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
int n5, int n6, int n7, int n8,
//function : AddVolume
//purpose :
//=======================================================================
+void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+ int n5,int n6, int n12, int n23, int n31,
+ int n45, int n56, int n64,
+ int n14, int n25, int n36,
+ int n1245, int n2356, int n1346)
+{
+ if(myIsEmbeddedMode){
+ myIsModified = true;
+ return;
+ }
+ getCommand(SMESHDS_AddBiQuadPentahedron)->AddVolume(NewVolID, n1,n2,n3,n4,n5,n6,
+ n12, n23, n31,
+ n45, n56, n64,
+ n14, n25, n36,
+ n1245, n2356, n1346);
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose :
+//=======================================================================
void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3,
int n4, int n5, int n6, int n7, int n8,
int n12, int n23, int n34, int n41,
int n12, int n23, int n31,
int n45, int n56, int n64,
int n14, int n25, int n36);
+ void AddVolume(int NewVolID, int n1, int n2, int n3,
+ int n4, int n5, int n6,
+ int n12, int n23, int n31,
+ int n45, int n56, int n64,
+ int n14, int n25, int n36,
+ int n1245, int n2356, int n1346);
void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
int n5, int n6, int n7, int n8,
int n12, int n23, int n34, int n41,
#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
#include CORBA_CLIENT_HEADER(SMESH_MeshEditor)
#include CORBA_CLIENT_HEADER(SMESH_Measurements)
+#include CORBA_CLIENT_HEADER(SMESH_Mesh)
// Qt includes
// #define INCLUDE_MENUITEM_DEF // VSR commented ????????
notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
notSupportedElemTypes.push_back( SMESH::Entity_Quad_Pyramid );
notSupportedElemTypes.push_back( SMESH::Entity_Quad_Penta );
+ notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Penta );
notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polyhedra );
"SMESH_TETRAHEDRA","SMESH_QUADRATIC_TETRAHEDRONS","SMESH_PYRAMIDS",
"SMESH_QUADRATIC_PYRAMIDS","SMESH_HEXAHEDRA","SMESH_QUADRATIC_HEXAHEDRONS",
"SMESH_TRIQUADRATIC_HEXAHEDRONS","SMESH_PENTAHEDRA","SMESH_QUADRATIC_PENTAHEDRONS",
+ "SMESH_BIQUADRATIC_PENTAHEDRONS",
"SMESH_OCTAHEDRA","SMESH_POLYEDRONS","SMESH_QUADRATIC_POLYEDRONS","SMESH_BALLS"
};
// is typeMsg complete? (compilation failure mains that enum SMDSAbs_EntityType changed)
const int nbTypes = sizeof( typeMsg ) / sizeof( const char* );
- int _assert[( nbTypes == SMESH::Entity_Last ) ? 2 : -1 ]; _assert[0]=_assert[1];
+ int _assert[( nbTypes == SMESH::Entity_Last ) ? 2 : -1 ]; _assert[0]=_assert[1]=0;
QString andStr = " " + QObject::tr("SMESH_AND") + " ", comma(", ");
for ( size_t iType = 0; iType < presentNotSupported.size(); ++iType ) {
// Get parameters of export operation
QString aFilename;
- SMESH::MED_VERSION aFormat = SMESH::MED_V2_2;
+ SMESH::MED_VERSION aFormat = SMESH::MED_LATEST;
// Init the parameters with the default values
bool aIsASCII_STL = true;
bool toCreateGroups = false;
}
else if ( isCGNS )// Export to CGNS
{
- SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
+ const char* theByTypeResource = "cgns_group_elems_by_type";
+ toCreateGroups = SMESHGUI::resourceMgr()->booleanValue( "SMESH", theByTypeResource, false );
+
+ QStringList checkBoxes;
+ checkBoxes << QObject::tr("CGNS_EXPORT_ELEMS_BY_TYPE");
+
+ SalomeApp_CheckFileDlg* fd =
+ new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true );
fd->setWindowTitle( aTitle );
fd->setNameFilter( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" );
if ( !anInitialPath.isEmpty() )
fd->selectFile(aMeshName);
SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd );
fd->setValidator( fv );
+ fd->SetChecked( toCreateGroups, 0 );
if ( fd->exec() )
aFilename = fd->selectedFile();
- toOverwrite = fv->isOverwrite();
+ toOverwrite = fv->isOverwrite();
+ toCreateGroups = fd->IsChecked(0);
+ SMESHGUI::resourceMgr()->setValue("SMESH", theByTypeResource, toCreateGroups );
delete fd;
}
else if ( isMED || isSAUV ) // Export to MED or SAUV
{
QMap<QString, SMESH::MED_VERSION> aFilterMap;
- //QString v21 (aMesh->GetVersionString(SMESH::MED_V2_1, 2));
if ( isMED ) {
QString v22 (aMesh->GetVersionString(SMESH::MED_V2_2, 2));
- //aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v21 ) + " (*.med)", SMESH::MED_V2_1 );
aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v22 ) + " (*.med)", SMESH::MED_V2_2 );
+ int minor = v22.split(".").last().toInt();
+ int vv= int(SMESH::MED_MINOR_0); // add all minor from 0 to current
+ for (int ii=0; ii<minor; ii++)
+ {
+ QString vs = aMesh->GetVersionString(SMESH::MED_VERSION(vv), 2);
+ aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( vs ) + " (*.med)", SMESH::MED_VERSION(vv));
+ vv = vv +1;
+ }
}
else { // isSAUV
aFilterMap.insert("All files (*)", SMESH::MED_V2_1 );
SMESHGUI_FieldSelectorWdg* fieldSelWdg = new SMESHGUI_FieldSelectorWdg();
QList< QWidget* > wdgList;
- if ( fieldSelWdg->GetAllFeilds( aMeshList, aFieldList ))
+ if ( fieldSelWdg->GetAllFields( aMeshList, aFieldList ))
wdgList.append( fieldSelWdg );
SalomeApp_CheckFileDlg* fd =
}
if( !toOverwrite ) {
// can't append to an existing using other format
- SMESH::MED_VERSION aVersion = SMESH::MED_V2_1;
+ SMESH::MED_VERSION aVersion = aFormat; //SMESH::MED_V2_1;
bool isVersionOk = SMESHGUI::GetSMESHGen()->GetMEDVersion( aFilename.toUtf8().constData(), aVersion );
if( !isVersionOk || aVersion != aFormat ) {
int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
}
toCreateGroups = fd->IsChecked(0);
toFindOutDim = fd->IsChecked(1);
- fieldSelWdg->GetSelectedFeilds();
+ fieldSelWdg->GetSelectedFields();
if ( !fieldSelWdg->parent() )
delete fieldSelWdg;
delete fd;
SMESH::SMESH_Mesh_var aMeshItem = aMeshOrGroup->GetMesh();
aMeshItem->ExportCGNS( aMeshOrGroup,
aFilename.toUtf8().data(),
- toOverwrite && aMeshIndex == 0 );
+ toOverwrite && aMeshIndex == 0,
+ toCreateGroups );
}
}
else if ( isGMF )
long nbVolumes = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra] +
info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] +
info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] +
- info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta] +
+ info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta] +
info[SMDSEntity_Polyhedra] +
info[SMDSEntity_Hexagonal_Prism];
long nbBalls = info[SMDSEntity_Ball];
if(checkLock(aStudy)) break;
SUIT_OverrideCursor wc;
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
SMESH::UpdateView();
}
catch (std::bad_alloc) { // PAL16774 (Crash after display of many groups)
case SMESHOp::OpQuadraticTetrahedron:
case SMESHOp::OpQuadraticPyramid:
case SMESHOp::OpQuadraticPentahedron:
+ case SMESHOp::OpBiQuadraticPentahedron:
case SMESHOp::OpQuadraticHexahedron:
case SMESHOp::OpTriQuadraticHexahedron:
{
case SMESHOp::OpQuadraticTetrahedron: type = SMDSEntity_Quad_Tetra; break;
case SMESHOp::OpQuadraticPyramid: type = SMDSEntity_Quad_Pyramid; break;
case SMESHOp::OpQuadraticPentahedron: type = SMDSEntity_Quad_Penta; break;
+ case SMESHOp::OpBiQuadraticPentahedron: type = SMDSEntity_BiQuad_Penta; break;
case SMESHOp::OpQuadraticHexahedron: type = SMDSEntity_Quad_Hexa; break;
case SMESHOp::OpTriQuadraticHexahedron: type = SMDSEntity_TriQuad_Hexa; break;
default: break;
createSMESHAction( SMESHOp::OpQuadraticTetrahedron, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" );
createSMESHAction( SMESHOp::OpQuadraticPyramid, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" );
createSMESHAction( SMESHOp::OpQuadraticPentahedron, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" );
+ createSMESHAction( SMESHOp::OpBiQuadraticPentahedron, "BIQUADRATIC_PENTAHEDRON", "ICON_DLG_BIQUADRATIC_PENTAHEDRON" );
createSMESHAction( SMESHOp::OpQuadraticHexahedron, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" );
createSMESHAction( SMESHOp::OpTriQuadraticHexahedron, "TRIQUADRATIC_HEXAHEDRON", "ICON_DLG_TRIQUADRATIC_HEXAHEDRON" );
createMenu( SMESHOp::OpQuadraticTetrahedron, addId, -1 );
createMenu( SMESHOp::OpQuadraticPyramid, addId, -1 );
createMenu( SMESHOp::OpQuadraticPentahedron, addId, -1 );
+ createMenu( SMESHOp::OpBiQuadraticPentahedron, addId, -1 );
createMenu( SMESHOp::OpQuadraticHexahedron, addId, -1 );
createMenu( SMESHOp::OpTriQuadraticHexahedron, addId, -1 );
createTool( SMESHOp::OpQuadraticTetrahedron, addNonElemTb );
createTool( SMESHOp::OpQuadraticPyramid, addNonElemTb );
createTool( SMESHOp::OpQuadraticPentahedron, addNonElemTb );
+ createTool( SMESHOp::OpBiQuadraticPentahedron, addNonElemTb );
createTool( SMESHOp::OpQuadraticHexahedron, addNonElemTb );
createTool( SMESHOp::OpTriQuadraticHexahedron, addNonElemTb );
case SMDSEntity_Quad_Penta:
anElementName = QString("QUADRATIC_PENTAHEDRON");
break;
+ case SMDSEntity_BiQuad_Penta:
+ anElementName = QString("BIQUADRATIC_PENTAHEDRON");
+ break;
case SMDSEntity_Quad_Hexa:
anElementName = QString("QUADRATIC_HEXAHEDRON");
break;
myNbCorners = 6;
myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
break;
+ case SMDSEntity_BiQuad_Penta:
+ aNumRows = 9;
+ myNbCorners = 6;
+ myNbMidFaceNodes = 3;
+ myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
+ break;
case SMDSEntity_Quad_Hexa:
aNumRows = 12;
myNbCorners = 8;
case SMDSEntity_Quad_Tetra:
case SMDSEntity_Quad_Pyramid:
case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
for ( int row = 0; row < myNbCorners; row++ )
case SMDSEntity_Quad_Tetra:
case SMDSEntity_Quad_Pyramid:
case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
anElementType = SMESH::VOLUME;
case SMDSEntity_Quad_Tetra:
case SMDSEntity_Quad_Pyramid:
case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
anElementType = SMESH::VOLUME; break;
aLastColIds = LastPyramidIds;
break;
case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
aFirstColIds = FirstPentahedronIds;
aLastColIds = LastPentahedronIds;
break;
currentCellChanged(); // to update buttons
}
}
- // show dialog and wait, becase Compute can be invoked from Preview operation
+ // show dialog and wait, because Compute can be invoked from Preview operation
//aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
aCompDlg->show();
}
SMESH::long_array_var aShapesId = new SMESH::long_array();
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
SMESH::MeshPreviewStruct_var previewData =
gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId);
}
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
// check if there are memory problems
for ( CORBA::ULong i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
}
SUIT_OverrideCursor aWaitCursor;
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
aRes = gen->Evaluate(myMesh, myMainShape);
}
catch(const SALOME::SALOME_Exception & S_ex){
}
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
}
catch(const SALOME::SALOME_Exception & S_ex){
currentCellChanged(); // to update buttons
}
}
- // show dialog and wait, becase Compute can be invoked from Preview operation
+ // show dialog and wait, because Compute can be invoked from Preview operation
//aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
aCompDlg->show();
}
bool hasBiQuad = ( nbElemOfType[SMDSEntity_BiQuad_Triangle ] ||
nbElemOfType[SMDSEntity_BiQuad_Quadrangle ] ||
+ nbElemOfType[SMDSEntity_BiQuad_Penta ] ||
nbElemOfType[SMDSEntity_TriQuad_Hexa ] );
bool hasLinBiQuad = ( nbElemOfType[SMDSEntity_Triangle ] ||
nbElemOfType[SMDSEntity_Quadrangle ] ||
hl->addWidget( nb0DElemsLab, 0, 1 );
my0DElemsTB->setEnabled( nbElements );
nb0DElemsLab->setEnabled( nbElements );
- myNbTypes += ( nbElements > 0 );
+ myNbTypes = ( nbElements > 0 );
// Edges
nbElements = myActor ? myActor->GetObject()->GetNbEntities( SMDSAbs_Edge ) : aMesh->NbEdges();
* \brief Retrieves all fields defined on geometry of given meshes
*/
bool SMESHGUI_FieldSelectorWdg::
-GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
+GetAllFields(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
QList< QPair< GEOM::ListOfFields_var, QString > >& fields)
{
myFields = & fields;
/*!
* \brief Filter off not selected fields from myFields
*/
-bool SMESHGUI_FieldSelectorWdg::GetSelectedFeilds()
+bool SMESHGUI_FieldSelectorWdg::GetSelectedFields()
{
int nbSelected = 0;
if ( myTree->isEnabled() )
public:
SMESHGUI_FieldSelectorWdg( QWidget* = 0 );
- bool GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
+ bool GetAllFields(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
QList< QPair< GEOM::ListOfFields_var, QString > >& fields);
- bool GetSelectedFeilds();
+ bool GetSelectedFields();
private slots:
-
+
void onItemCheck(QTreeWidgetItem * item, int column);
private:
#include <SMDS_Mesh.hxx>
#include <SMDSAbs_ElementType.hxx>
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_Filter, VTKViewer_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_FacesFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter, SMESHGUI_Filter)
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_Filter, VTKViewer_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_FacesFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter, SMESHGUI_Filter)
+IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter, SMESHGUI_Filter)
/*
Class : SMESHGUI_PredicateFilter
Standard_EXPORT virtual bool IsObjValid( const int ) const = 0;
public:
- OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_Filter,VTKViewer_Filter)
+ DEFINE_STANDARD_RTTIEXT(SMESHGUI_Filter,VTKViewer_Filter)
};
/*
SMESH::Predicate_var myPred;
public:
- OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter,SMESHGUI_Filter)
+ DEFINE_STANDARD_RTTIEXT(SMESHGUI_PredicateFilter,SMESHGUI_Filter)
};
/*
Standard_EXPORT virtual bool IsNodeFilter() const;
public:
- OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter,SMESHGUI_Filter)
+ DEFINE_STANDARD_RTTIEXT(SMESHGUI_QuadrangleFilter,SMESHGUI_Filter)
};
/*
Standard_EXPORT virtual bool IsNodeFilter() const;
public:
- OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter,SMESHGUI_Filter)
+ DEFINE_STANDARD_RTTIEXT(SMESHGUI_TriangleFilter,SMESHGUI_Filter)
};
/*
Standard_EXPORT virtual bool IsNodeFilter() const;
public:
- OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_FacesFilter,SMESHGUI_Filter)
+ DEFINE_STANDARD_RTTIEXT(SMESHGUI_FacesFilter,SMESHGUI_Filter)
};
/*
Standard_EXPORT virtual bool IsNodeFilter() const;
public:
- OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter,SMESHGUI_Filter)
+ DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumesFilter,SMESHGUI_Filter)
};
/*
Standard_EXPORT static int GetId( SMDSAbs_GeometryType geom );
public:
- OCCT_DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter,SMESHGUI_Filter)
+ DEFINE_STANDARD_RTTIEXT(SMESHGUI_VolumeShapeFilter,SMESHGUI_Filter)
};
#endif // SMESHGUI_FILTER_H
typeIds.append( SMDSEntity_TriQuad_Hexa );
typeIds.append( SMDSEntity_Penta );
typeIds.append( SMDSEntity_Quad_Penta );
+ typeIds.append( SMDSEntity_BiQuad_Penta );
typeIds.append( SMDSEntity_Hexagonal_Prism );
typeIds.append( SMDSEntity_Polyhedra );
//typeIds.append( SMDSEntity_Quad_Polyhedra );
{
if ( myFilter->_is_nil() ) return false;
- if (CORBA::is_nil(myGroupOnFilter)) { // creation
+ if (CORBA::is_nil(myGroupOnFilter)) // creation
+ {
if (myMesh->_is_nil())
return false;
myGroupOnFilter = myMesh->CreateGroupFromFilter(aType,
SMESH::toUtf8(myName->text()),
myFilter);
-
resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
isCreation = true;
}
anIsOk = true;
}
- if( anIsOk )
+ if ( anIsOk )
{
SALOMEDS::Color aColor = getGroupColor();
resultGroup->SetColor(aColor);
// Elem geom
- QGroupBox* elemsGrp = new QGroupBox( tr( "SMESH_ELEMENTS" ), mainFrame() );
+ QGroupBox* elemsGrp = new QGroupBox( tr( "ELEMENTS" ), mainFrame() );
+ elemsGrp->setToolTip( tr("ELEMENTS_TOOLTIP") );
QLabel* label = new QLabel( tr( "SMESH_GEOM" ), elemsGrp );
myElemGeomBtn = new QPushButton( elemsGrp );
myElemGeomBtn->setCheckable(true);
#endif
#ifdef WIN32
-#define LibHandle HMODULE
-#define LoadLib( name ) LoadLibrary( name )
-#define GetProc GetProcAddress
-#define UnLoadLib( handle ) FreeLibrary( handle );
-#else
-#define LibHandle void*
-#define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL )
-#define GetProc dlsym
-#define UnLoadLib( handle ) dlclose( handle );
-#endif
+ #define LibHandle HMODULE
+ #define LoadLib( name ) LoadLibrary( name )
+ #define GetProc GetProcAddress
+ #define UnLoadLib( handle ) FreeLibrary( handle );
+#else // WIN32
+ #define LibHandle void*
+ #ifdef DYNLOAD_LOCAL
+ #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_LOCAL )
+ #else // DYNLOAD_LOCAL
+ #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL )
+ #endif // DYNLOAD_LOCAL
+ #define GetProc dlsym
+ #define UnLoadLib( handle ) dlclose( handle );
+#endif // WIN32
#ifdef _DEBUG_
static int MYDEBUG = 0;
else if ( theNbNodes == 20 ) return VTK_QUADRATIC_HEXAHEDRON;
else if ( theNbNodes == 27 ) return VTK_TRIQUADRATIC_HEXAHEDRON;
else if ( theNbNodes == 15 ) return VTK_QUADRATIC_WEDGE;
+ else if ( theNbNodes == 18 ) return VTK_BIQUADRATIC_QUADRATIC_WEDGE;
else if ( theNbNodes == 13 ) return VTK_QUADRATIC_PYRAMID;//VTK_CONVEX_POINT_SET;
else return VTK_EMPTY_CELL;
namespace {
-const int SPACING = 6;
-const int MARGIN = 9;
-const int MAXITEMS = 10;
-const int GROUPS_ID = 100;
-const int SUBMESHES_ID = 200;
-const int SPACING_INFO = 2;
-
-enum InfoRole {
- TypeRole = Qt::UserRole + 10,
- IdRole,
-};
-
-enum InfoType {
- NodeConnectivity = 100,
- ElemConnectivity,
-};
+ const int SPACING = 6;
+ const int MARGIN = 9;
+ const int MAXITEMS = 10;
+ const int GROUPS_ID = 100;
+ const int SUBMESHES_ID = 200;
+ const int SPACING_INFO = 2;
+
+ const char* id_preview_resource = "id_preview_resource";
+
+ enum InfoRole {
+ TypeRole = Qt::UserRole + 10,
+ IdRole,
+ };
+
+ enum InfoType {
+ NodeConnectivity = 100,
+ ElemConnectivity,
+ };
} // namesapce
/*!
a3DPriLin->setObjectName("nbLinearPrism");
QLabel* a3DPriQuad = createField();
a3DPriQuad->setObjectName("nbQuadraticPrism");
+ QLabel* a3DPriBiQuad = createField();
+ a3DPriBiQuad->setObjectName("nbBiQuadraticPrism");
QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
QLabel* a3DHexPriTotal = createField();
a3DHexPriTotal->setObjectName("nbHexagonalPrism");
myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad;
myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
- myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
+ myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad << a3DPriBiQuad;
myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
l->addWidget( a3DPriTotal, 24, 1 );
l->addWidget( a3DPriLin, 24, 2 );
l->addWidget( a3DPriQuad, 24, 3 );
+ l->addWidget( a3DPriBiQuad, 24, 4 );
l->addWidget( a3DHexPriLab, 25, 0 );
l->addWidget( a3DHexPriTotal, 25, 1 );
l->addWidget( a3DPolLab, 26, 0 );
long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
- long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta];
+ long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta];
long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
- long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
+ long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_BiQuad_Penta];
long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal ));
myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ));
myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ));
myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ));
myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ));
+ myWidgets[i3DPrisms][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Penta] ));
myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ));
myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ));
long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
case SMDSEntity_Penta:
case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
case SMDSEntity_Hexagonal_Prism:
gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break;
case SMDSEntity_Penta:
case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break;
case SMDSEntity_Hexagonal_Prism:
gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break;
connect( myElemInfo, SIGNAL( itemInfo( int )), this, SLOT( showItemInfo( int )));
connect( myElemInfo, SIGNAL( itemInfo( QString )), this, SLOT( showItemInfo( QString )));
+ myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", id_preview_resource, false ));
+
updateSelection();
}
void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
{
myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
+ SMESHGUI::resourceMgr()->setValue("SMESH", id_preview_resource, isOn );
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
aViewWindow->Repaint();
}
myNbHexa(0), myNbLinHexa(0), myNbQuadHexa(0), myNbBiQuadHexa(0),
myNbTetra(0),myNbLinTetra(0),myNbQuadTetra(0),
myNbPyra(0), myNbLinPyra(0), myNbQuadPyra(0),
- myNbPrism(0),myNbLinPrism(0), myNbQuadPrism(0),
+ myNbPrism(0),myNbLinPrism(0), myNbQuadPrism(0), myNbBiQuadPrism(0),
myNbVolum(0), myNbLinVolum(0), myNbQuadVolum(0), myNbBiQuadVolum(0),
myNbHexaPrism(0),
myNbPolyh(0)
myNbQuadPrism = new QLabel( this );
l->addWidget( myNbQuadPrism, row, 3 );
// --
+ myNbBiQuadPrism = new QLabel( this );
+ l->addWidget( myNbBiQuadPrism, row, 4 );
+ // --
row++; // increment row count
// ... hexa prisms
lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAPRISM")), this );
theInfo[SMDSEntity_TriQuad_Hexa] +
theInfo[SMDSEntity_Penta] +
theInfo[SMDSEntity_Quad_Penta] +
+ theInfo[SMDSEntity_BiQuad_Penta] +
theInfo[SMDSEntity_Hexagonal_Prism] +
theInfo[SMDSEntity_Polyhedra] ));
myNbLinVolum ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] +
theInfo[SMDSEntity_Quad_Pyramid] +
theInfo[SMDSEntity_Quad_Hexa] +
theInfo[SMDSEntity_Quad_Penta] ));
- myNbBiQuadVolum->setText( QString("%1").arg( theInfo[SMDSEntity_TriQuad_Hexa] ));
+ myNbBiQuadVolum->setText( QString("%1").arg( theInfo[SMDSEntity_TriQuad_Hexa] +
+ theInfo[SMDSEntity_BiQuad_Penta] ));
if ( myFull )
{
myNbQuadPyra ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Pyramid] ));
// prisms
myNbPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] +
- theInfo[SMDSEntity_Quad_Penta] ));
- myNbLinPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] ));
- myNbQuadPrism->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Penta] ));
+ theInfo[SMDSEntity_Quad_Penta] +
+ theInfo[SMDSEntity_BiQuad_Penta] ));
+ myNbLinPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] ));
+ myNbQuadPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Penta] ));
+ myNbBiQuadPrism->setText( QString("%1").arg( theInfo[SMDSEntity_BiQuad_Penta] ));
// octahedra
myNbHexaPrism->setText( QString("%1").arg( theInfo[ SMDSEntity_Hexagonal_Prism ]));
// polyedres
QLabel* myNbPrism;
QLabel* myNbLinPrism;
QLabel* myNbQuadPrism;
+ QLabel* myNbBiQuadPrism;
QLabel* myNbVolum;
QLabel* myNbLinVolum;
QLabel* myNbQuadVolum;
//=======================================================================
// name : SMESHGUI_MultiEditDlg::getIds
-// Purpose : Retrive identifiers from list box or the whole object
+// Purpose : Retrieve identifiers from list box or the whole object
//=======================================================================
SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds(SMESH::SMESH_IDSource_var& obj)
}
if (entityType()) {
- if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
- aViewWindow->SetSelectionMode(VolumeSelection);
SMESH::SetFilter(new SMESHGUI_VolumesFilter());
- } else {
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
- aViewWindow->SetSelectionMode(FaceSelection);
+ aViewWindow->SetSelectionMode(VolumeSelection); // here myActor set to a filter
+ } else {
if (myFilterType == SMESH::TriaFilter)
SMESH::SetFilter(new SMESHGUI_TriangleFilter());
else if (myFilterType == SMESH::QuadFilter)
SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
else
SMESH::SetFilter(new SMESHGUI_FacesFilter());
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode(FaceSelection); // here myActor set to a filter
}
}
OpQuadraticTetrahedron = 4105, // MENU MODIFICATION - ADD - QUADRATIC TETRAHEDRON
OpQuadraticPyramid = 4106, // MENU MODIFICATION - ADD - QUADRATIC PYRAMID
OpQuadraticPentahedron = 4107, // MENU MODIFICATION - ADD - QUADRATIC PENTAHEDRON
- OpQuadraticHexahedron = 4108, // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON
- OpTriQuadraticHexahedron = 4109, // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON
- OpQuadraticPolygon = 4110, // MENU MODIFICATION - ADD - QUADRATIC POLYGON
+ OpBiQuadraticPentahedron = 4108, // MENU MODIFICATION - ADD - BIQUADRATIC PENTAHEDRON
+ OpQuadraticHexahedron = 4110, // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON
+ OpTriQuadraticHexahedron = 4111, // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON
+ OpQuadraticPolygon = 4112, // MENU MODIFICATION - ADD - QUADRATIC POLYGON
OpRemoveNodes = 4200, // MENU MODIFICATION - REMOVE - NODE
OpRemoveElements = 4201, // MENU MODIFICATION - REMOVE - ELEMENTS
OpRemoveOrphanNodes = 4202, // MENU MODIFICATION - REMOVE - ORPHAN NODES
void ModifiedMesh (_PTR(SObject) theSObject, bool theIsNotModif, bool isEmptyMesh)
{
_PTR(Study) aStudy = GetActiveStudyDocument();
- if (aStudy->GetProperties()->IsLocked())
+ if ( !aStudy || aStudy->GetProperties()->IsLocked() )
return;
_PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
<source>ICON_DLG_QUADRATIC_PENTAHEDRON</source>
<translation>mesh_quad_pentahedron.png</translation>
</message>
+ <message>
+ <source>ICON_DLG_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>mesh_quad_pentahedron.png</translation>
+ </message>
<message>
<source>ICON_DLG_QUADRATIC_PYRAMID</source>
<translation>mesh_quad_pyramid.png</translation>
<source>CGNS_FILES_FILTER</source>
<translation>CGNS files</translation>
</message>
+ <message>
+ <source>CGNS_EXPORT_ELEMS_BY_TYPE</source>
+ <translation>Group elements by type</translation>
+ </message>
<message>
<source>GMF_ASCII_FILES_FILTER</source>
<translation>GMF ASCII files</translation>
<source>MEN_QUADRATIC_PENTAHEDRON</source>
<translation>Quadratic Pentahedron</translation>
</message>
+ <message>
+ <source>MEN_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>BiQuadratic Pentahedron</translation>
+ </message>
<message>
<source>MEN_QUADRATIC_PYRAMID</source>
<translation>Quadratic Pyramid</translation>
<source>SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE</source>
<translation>Add Quadratic Pentahedron</translation>
</message>
+ <message>
+ <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON_TITLE</source>
+ <translation>Add BiQuadratic Pentahedron</translation>
+ </message>
<message>
<source>SMESH_ADD_QUADRATIC_PYRAMID_TITLE</source>
<translation>Add Quadratic Pyramid</translation>
<source>SMESH_QUADRATIC_PENTAHEDRON</source>
<translation>Quadratic Pentahedron</translation>
</message>
+ <message>
+ <source>SMESH_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>BiQuadratic Pentahedron</translation>
+ </message>
<message>
<source>SMESH_QUADRATIC_PENTAHEDRONS</source>
<translation>Quadratic Pentahedrons</translation>
</message>
+ <message>
+ <source>SMESH_BIQUADRATIC_PENTAHEDRONS</source>
+ <translation>BiQuadratic Pentahedrons</translation>
+ </message>
<message>
<source>SMESH_QUADRATIC_PYRAMID</source>
<translation>Quadratic Pyramid</translation>
<source>STB_QUADRATIC_PENTAHEDRON</source>
<translation>Quadratic Pentahedron</translation>
</message>
+ <message>
+ <source>STB_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>BiQuadratic Pentahedron</translation>
+ </message>
<message>
<source>STB_QUADRATIC_PYRAMID</source>
<translation>Quadratic Pyramid</translation>
<source>TOP_QUADRATIC_PENTAHEDRON</source>
<translation>Quadratic Pentahedron</translation>
</message>
+ <message>
+ <source>TOP_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>BiQuadratic Pentahedron</translation>
+ </message>
<message>
<source>TOP_QUADRATIC_PYRAMID</source>
<translation>Quadratic Pyramid</translation>
<source>SMESH_ADD_QUADRATIC_PENTAHEDRON</source>
<translation>Add Quadratic Pentahedron</translation>
</message>
+ <message>
+ <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>Add BiQuadratic Pentahedron</translation>
+ </message>
<message>
<source>SMESH_ADD_QUADRATIC_PYRAMID</source>
<translation>Add Quadratic Pyramid</translation>
</message>
<message>
<source>ENTITY_TYPE_21</source>
- <translation>OCTA12</translation>
+ <translation>PENTA18</translation>
</message>
<message>
<source>ENTITY_TYPE_22</source>
- <translation>POLYEDRE</translation>
+ <translation>OCTA12</translation>
</message>
<message>
<source>ENTITY_TYPE_23</source>
- <translation>QPOLYEDRE</translation>
+ <translation>POLYEDRE</translation>
</message>
<message>
<source>ENTITY_TYPE_24</source>
+ <translation>QPOLYEDRE</translation>
+ </message>
+ <message>
+ <source>ENTITY_TYPE_25</source>
<translation>BALL</translation>
</message>
<message>
<source>SMESH_CREATE_GROUP_FROM_GEOM</source>
<translation>Create Groups from Geometry</translation>
</message>
+ <message>
+ <source>ELEMENTS</source>
+ <translation>Elements</translation>
+ </message>
+ <message>
+ <source>ELEMENTS_TOOLTIP</source>
+ <translation>No 0D elements</translation>
+ </message>
</context>
<context>
<name>SMESHGUI_MeshOrderDlg</name>
<source>CGNS_FILES_FILTER</source>
<translation>Fichiers CGNS</translation>
</message>
+ <message>
+ <source>CGNS_EXPORT_ELEMS_BY_TYPE</source>
+ <translation>Groupe les éléments par type</translation>
+ </message>
<message>
<source>GMF_ASCII_FILES_FILTER</source>
<translation>Fichiers GMF ASCII</translation>
<source>MEN_DEL_GROUP</source>
<translation>Supprimer les groupes et leur contenu</translation>
</message>
+ <message>
+ <source>MEN_ADD_TO_GROUP</source>
+ <translation>Ajoute dans le groupe</translation>
+ </message>
+ <message>
+ <source>MEN_REMOVE_FROM_GROUP</source>
+ <translation>Supprime du groupe</translation>
+ </message>
+ <message>
+ <source>STB_ADD_TO_GROUP</source>
+ <translation>Ajoute dans le groupe les éléments sélectionnés</translation>
+ </message>
+ <message>
+ <source>STB_REMOVE_FROM_GROUP</source>
+ <translation>Supprime du groupe les éléments sélectionnés</translation>
+ </message>
<message>
<source>MEN_FACE_ORIENTATION</source>
<translation>Orientation des faces</translation>
<source>MEN_QUADRATIC_PENTAHEDRON</source>
<translation>Pentaèdre quadratique</translation>
</message>
+ <message>
+ <source>MEN_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>Pentaèdre biquadratique</translation>
+ </message>
<message>
<source>MEN_QUADRATIC_PYRAMID</source>
<translation>Pyramide quadratique</translation>
<source>SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE</source>
<translation>Ajouter un pentaèdre quadratique</translation>
</message>
+ <message>
+ <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON_TITLE</source>
+ <translation>Ajouter un pentaèdre biquadratique</translation>
+ </message>
<message>
<source>SMESH_ADD_QUADRATIC_PYRAMID_TITLE</source>
<translation>Ajouter une pyramide quadratique</translation>
<source>SMESH_QUADRATIC_PENTAHEDRON</source>
<translation>Pentaèdre quadratique</translation>
</message>
+ <message>
+ <source>SMESH_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>Pentaèdre biquadratique</translation>
+ </message>
<message>
<source>SMESH_QUADRATIC_PENTAHEDRONS</source>
<translation>Pentaèdres quadratiques</translation>
</message>
+ <message>
+ <source>SMESH_BIQUADRATIC_PENTAHEDRONS</source>
+ <translation>Pentaèdres biquadratiques</translation>
+ </message>
<message>
<source>SMESH_QUADRATIC_PYRAMID</source>
<translation>Pyramide quadratique</translation>
<source>STB_QUADRATIC_PENTAHEDRON</source>
<translation>Pentaèdre quadratique</translation>
</message>
+ <message>
+ <source>STB_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>Pentaèdre biquadratique</translation>
+ </message>
<message>
<source>STB_QUADRATIC_PYRAMID</source>
<translation>Pyramide quadratique</translation>
<source>TOP_QUADRATIC_PENTAHEDRON</source>
<translation>Pentaèdre quadratique</translation>
</message>
+ <message>
+ <source>TOP_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>Pentaèdre biquadratique</translation>
+ </message>
<message>
<source>TOP_QUADRATIC_PYRAMID</source>
<translation>Pyramide quadratique</translation>
<source>SMESH_ADD_QUADRATIC_PENTAHEDRON</source>
<translation>Ajouter un pentaèdre quadratique</translation>
</message>
+ <message>
+ <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>Ajouter un pentaèdre biquadratique</translation>
+ </message>
<message>
<source>SMESH_ADD_QUADRATIC_PYRAMID</source>
<translation>Ajouter une pyramide quadratique</translation>
<source>SEPARATE_CORNERS_AND_MEDIUM</source>
<translation>Pas de fusion du coin et des noeuds moyens des cellules quadratiques</translation>
</message>
+ <message>
+ <source>AVOID_MAKING_HOLES</source>
+ <translation>Evite de créer des trous</translation>
+ </message>
<message>
<source>KEEP_NODES</source>
<translation>Les noeuds à conserver pendant la fusion</translation>
</message>
<message>
<source>ENTITY_TYPE_21</source>
- <translation>OCTA12</translation>
+ <translation>PENTA18</translation>
</message>
<message>
<source>ENTITY_TYPE_22</source>
- <translation>POLYEDRE</translation>
+ <translation>OCTA12</translation>
</message>
<message>
<source>ENTITY_TYPE_23</source>
- <translation>QPOLYEDRE</translation>
+ <translation>POLYEDRE</translation>
</message>
<message>
<source>ENTITY_TYPE_24</source>
+ <translation>QPOLYEDRE</translation>
+ </message>
+ <message>
+ <source>ENTITY_TYPE_25</source>
<translation>BALL</translation>
</message>
<message>
<source>SMESH_CREATE_GROUP_FROM_GEOM</source>
<translation>Créer des groupes à partir de la géométrie</translation>
</message>
+ <message>
+ <source>ELEMENTS</source>
+ <translation>Eléments</translation>
+ </message>
+ <message>
+ <source>ELEMENTS_TOOLTIP</source>
+ <translation>Pas d'éléments 0D</translation>
+ </message>
</context>
<context>
<name>SMESHGUI_MeshOrderDlg</name>
<source>ELEM_MODE</source>
<translation>Elément</translation>
</message>
+ <message>
+ <source>SHOW_IDS</source>
+ <translation>Montre les IDs</translation>
+ </message>
<message>
<source>BUT_DUMP_MESH</source>
<translation>&Dump</translation>
<source>CGNS_FILES_FILTER</source>
<translation>CGNS ファイル</translation>
</message>
+ <message>
+ <source>CGNS_EXPORT_ELEMS_BY_TYPE</source>
+ <translation>タイプで要素をグループ化</translation>
+ </message>
<message>
<source>GMF_ASCII_FILES_FILTER</source>
<translation>GMFアスキーファイル</translation>
<source>MEN_DEL_GROUP</source>
<translation>グループとその内容を削除します。</translation>
</message>
+ <message>
+ <source>MEN_ADD_TO_GROUP</source>
+ <translation>グループに追加</translation>
+ </message>
+ <message>
+ <source>MEN_REMOVE_FROM_GROUP</source>
+ <translation>グループから削除</translation>
+ </message>
+ <message>
+ <source>STB_ADD_TO_GROUP</source>
+ <translation>選択要素をグループに追加</translation>
+ </message>
+ <message>
+ <source>STB_REMOVE_FROM_GROUP</source>
+ <translation>選択要素をグループから削除</translation>
+ </message>
<message>
<source>MEN_FACE_ORIENTATION</source>
<translation>フェースの向き</translation>
<source>MEN_QUADRATIC_PENTAHEDRON</source>
<translation>二次ウェッジ</translation>
</message>
+ <message>
+ <source>MEN_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>4次五面体</translation>
+ </message>
<message>
<source>MEN_QUADRATIC_PYRAMID</source>
<translation>四角錐</translation>
<source>SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE</source>
<translation>二次くさびを追加します。</translation>
</message>
+ <message>
+ <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON_TITLE</source>
+ <translation>4次五面体の追加</translation>
+ </message>
<message>
<source>SMESH_ADD_QUADRATIC_PYRAMID_TITLE</source>
<translation>四角錐を追加します。</translation>
<source>SMESH_QUADRATIC_PENTAHEDRON</source>
<translation>二次ウェッジ</translation>
</message>
+ <message>
+ <source>SMESH_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>4次五面体</translation>
+ </message>
<message>
<source>SMESH_QUADRATIC_PENTAHEDRONS</source>
<translation>二次ウェッジ</translation>
</message>
+ <message>
+ <source>SMESH_BIQUADRATIC_PENTAHEDRONS</source>
+ <translation>4次五面体</translation>
+ </message>
<message>
<source>SMESH_QUADRATIC_PYRAMID</source>
<translation>四角錐</translation>
<source>STB_QUADRATIC_PENTAHEDRON</source>
<translation>二次ウェッジ</translation>
</message>
+ <message>
+ <source>STB_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>4次五面体</translation>
+ </message>
<message>
<source>STB_QUADRATIC_PYRAMID</source>
<translation>四角錐</translation>
<source>TOP_QUADRATIC_PENTAHEDRON</source>
<translation>二次ウェッジ</translation>
</message>
+ <message>
+ <source>TOP_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>4次五面体</translation>
+ </message>
<message>
<source>TOP_QUADRATIC_PYRAMID</source>
<translation>四角錐</translation>
<source>SMESH_ADD_QUADRATIC_PENTAHEDRON</source>
<translation>二次くさびを追加します。</translation>
</message>
+ <message>
+ <source>SMESH_ADD_BIQUADRATIC_PENTAHEDRON</source>
+ <translation>4次五面体の追加</translation>
+ </message>
<message>
<source>SMESH_ADD_QUADRATIC_PYRAMID</source>
<translation>二次ピラミッドの追加</translation>
<source>SEPARATE_CORNERS_AND_MEDIUM</source>
<translation>2次セルのコーナ節点と中間節点をマージできません</translation>
</message>
+ <message>
+ <source>AVOID_MAKING_HOLES</source>
+ <translation>穴作成の回避</translation>
+ </message>
<message>
<source>KEEP_NODES</source>
<translation>維持節点</translation>
<source>ENTITY_TYPE_24</source>
<translation>ボール</translation>
</message>
+ <message>
+ <source>ENTITY_TYPE_25</source>
+ <translation>ボール</translation>
+ </message>
<message>
<source>GEOM_TYPE</source>
<translation>ジオメトリの種類</translation>
<source>SMESH_CREATE_GROUP_FROM_GEOM</source>
<translation>ジオメトリからグループを作成</translation>
</message>
+ <message>
+ <source>ELEMENTS</source>
+ <translation>要素</translation>
+ </message>
+ <message>
+ <source>ELEMENTS_TOOLTIP</source>
+ <translation>0D要素がない</translation>
+ </message>
</context>
<context>
<name>SMESHGUI_MeshOrderDlg</name>
<source>ELEM_MODE</source>
<translation>要素</translation>
</message>
+ <message>
+ <source>SHOW_IDS</source>
+ <translation>IDの表示</translation>
+ </message>
<message>
<source>BUT_DUMP_MESH</source>
<translation>書き出し(&D)</translation>
SMESH_MeshAlgos.hxx
SMESH_MAT2d.hxx
SMESH_ControlPnt.hxx
+ SMESH_Delaunay.hxx
)
# --- sources ---
SMESH_FreeBorders.cxx
SMESH_ControlPnt.cxx
SMESH_DeMerge.cxx
+ SMESH_Delaunay.cxx
)
# --- rules ---
--- /dev/null
+// Copyright (C) 2007-2016 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
+//
+// File : SMESH_Delaunay.cxx
+// Created : Wed Apr 19 15:41:15 2017
+// Author : Edward AGAPOV (eap)
+
+#include "SMESH_Delaunay.hxx"
+
+#include "SMESH_Comment.hxx"
+#include "SMESH_File.hxx"
+#include "SMESH_MeshAlgos.hxx"
+
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepMesh_Delaun.hxx>
+
+//================================================================================
+/*!
+ * \brief Construct a Delaunay triangulation of given boundary nodes
+ * \param [in] boundaryNodes - vector of nodes of a wire
+ * \param [in] face - the face
+ * \param [in] faceID - the face ID
+ * \param [in] nbNodesToVisit - nb of non-marked nodes on the face
+ */
+//================================================================================
+
+SMESH_Delaunay::SMESH_Delaunay(const std::vector< const UVPtStructVec* > & boundaryNodes,
+ const TopoDS_Face& face,
+ const int faceID)
+ : _face( face ), _faceID( faceID ), _scale( 1., 1. )
+{
+ // compute _scale
+ BRepAdaptor_Surface surf( face );
+ if ( surf.GetType() != GeomAbs_Plane )
+ {
+ const int nbDiv = 100;
+ const double uRange = surf.LastUParameter() - surf.FirstUParameter();
+ const double vRange = surf.LastVParameter() - surf.FirstVParameter();
+ const double dU = uRange / nbDiv;
+ const double dV = vRange / nbDiv;
+ double u = surf.FirstUParameter(), v = surf.FirstVParameter();
+ gp_Pnt p0U = surf.Value( u, v ), p0V = p0U;
+ double lenU = 0, lenV = 0;
+ for ( ; u < surf.LastUParameter(); u += dU, v += dV )
+ {
+ gp_Pnt p1U = surf.Value( u, surf.FirstVParameter() );
+ lenU += p1U.Distance( p0U );
+ p0U = p1U;
+ gp_Pnt p1V = surf.Value( surf.FirstUParameter(), v );
+ lenV += p1V.Distance( p0V );
+ p0V = p1V;
+ }
+ _scale.SetCoord( lenU / uRange, lenV / vRange );
+ }
+
+ // count boundary points
+ int iP = 1, nbP = 0;
+ for ( size_t iW = 0; iW < boundaryNodes.size(); ++iW ) // loop on wires
+ {
+ nbP += boundaryNodes[iW]->size();
+ if ( boundaryNodes[iW]->front().node == boundaryNodes[iW]->back().node )
+ --nbP; // 1st and last points coincide
+ }
+ _bndNodes.resize( nbP );
+
+ // fill boundary points
+ BRepMesh::Array1OfVertexOfDelaun bndVert( 1, 1 + nbP );
+ BRepMesh_Vertex v( 0, 0, BRepMesh_Frontier );
+ for ( size_t iW = 0; iW < boundaryNodes.size(); ++iW )
+ {
+ const UVPtStructVec& bndPnt = *boundaryNodes[iW];
+ int i = 0, nb = bndPnt.size();
+ if ( bndPnt[0].node == bndPnt.back().node )
+ --nb;
+ for ( ; i < nb; ++i, ++iP )
+ {
+ _bndNodes[ iP-1 ] = bndPnt[i].node;
+ bndPnt[i].node->setIsMarked( true );
+
+ v.ChangeCoord() = bndPnt[i].UV().Multiplied( _scale );
+ bndVert( iP ) = v;
+ }
+ }
+
+ // triangulate the srcFace in 2D
+ BRepMesh_Delaun Delaunay( bndVert );
+ _triaDS = Delaunay.Result();
+}
+
+//================================================================================
+/*!
+ * \brief Prepare to the exploration of nodes
+ */
+//================================================================================
+
+void SMESH_Delaunay::InitTraversal(const int nbNodesToVisit)
+{
+ _nbNodesToVisit = (size_t) nbNodesToVisit;
+ _nbVisitedNodes = _iBndNode = 0;
+ _noTriQueue.clear();
+}
+
+//================================================================================
+/*!
+ * \brief Return a node with its Barycentric Coordinates within the triangle
+ * defined by its node indices (zero based)
+ * \param [out] bc - Barycentric Coordinates of the returned node
+ * \param [out] triaNodes - indices of triangle nodes
+ * \return const SMDS_MeshNode* - the next node or NULL
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMESH_Delaunay::NextNode( double bc[3], int triaNodes[3] )
+{
+ while ( _nbVisitedNodes < _nbNodesToVisit )
+ {
+ while ( !_noTriQueue.empty() )
+ {
+ const SMDS_MeshNode* node = _noTriQueue.front().first;
+ const BRepMesh_Triangle* tria = _noTriQueue.front().second;
+ _noTriQueue.pop_front();
+ if ( node->isMarked() )
+ continue;
+ ++_nbVisitedNodes;
+ node->setIsMarked( true );
+
+ // find a Delaunay triangle containing the src node
+ gp_XY uv = getNodeUV( _face, node );
+ tria = FindTriangle( uv, tria, bc, triaNodes );
+ if ( tria )
+ {
+ addCloseNodes( node, tria, _faceID, _noTriQueue );
+ return node;
+ }
+ }
+ for ( ; _iBndNode < _bndNodes.size() && _noTriQueue.empty(); ++_iBndNode )
+ {
+ if ( const BRepMesh_Triangle* tria = GetTriangleNear( _iBndNode ))
+ addCloseNodes( _bndNodes[ _iBndNode ], tria, _faceID, _noTriQueue );
+ }
+ if ( _noTriQueue.empty() )
+ break;
+ }
+
+ // if ( _nbVisitedNodes < _nbNodesToVisit )
+ // _nbVisitedNodes = std::numeric_limits<int>::max();
+ return NULL;
+}
+
+//================================================================================
+/*!
+ * \brief Find a Delaunay triangle containing a given 2D point and return
+ * barycentric coordinates within the found triangle
+ */
+//================================================================================
+
+const BRepMesh_Triangle* SMESH_Delaunay::FindTriangle( const gp_XY& UV,
+ const BRepMesh_Triangle* tria,
+ double bc[3],
+ int triaNodes[3] )
+{
+ int nodeIDs[3];
+ gp_XY nodeUVs[3];
+ int linkIDs[3];
+ Standard_Boolean ori[3];
+
+ gp_XY uv = UV.Multiplied( _scale );
+
+ while ( tria )
+ {
+ // check if the uv is in tria
+
+ _triaDS->ElementNodes( *tria, nodeIDs );
+ nodeUVs[0] = _triaDS->GetNode( nodeIDs[0] ).Coord();
+ nodeUVs[1] = _triaDS->GetNode( nodeIDs[1] ).Coord();
+ nodeUVs[2] = _triaDS->GetNode( nodeIDs[2] ).Coord();
+
+ SMESH_MeshAlgos::GetBarycentricCoords( uv,
+ nodeUVs[0], nodeUVs[1], nodeUVs[2],
+ bc[0], bc[1] );
+ if ( bc[0] >= 0 && bc[1] >= 0 && bc[0] + bc[1] <= 1 )
+ {
+ if ( _triaDS->GetNode( nodeIDs[0] ).Movability() != BRepMesh_Frontier ||
+ _triaDS->GetNode( nodeIDs[1] ).Movability() != BRepMesh_Frontier ||
+ _triaDS->GetNode( nodeIDs[2] ).Movability() != BRepMesh_Frontier )
+ {
+ return 0;
+ }
+ bc[2] = 1 - bc[0] - bc[1];
+ triaNodes[0] = nodeIDs[0] - 1;
+ triaNodes[1] = nodeIDs[1] - 1;
+ triaNodes[2] = nodeIDs[2] - 1;
+ return tria;
+ }
+
+ // look for a neighbor triangle, which is adjacent to a link intersected
+ // by a segment( triangle center -> uv )
+
+ gp_XY gc = ( nodeUVs[0] + nodeUVs[1] + nodeUVs[2] ) / 3.;
+ gp_XY seg = uv - gc;
+
+ tria->Edges( linkIDs, ori );
+ int triaID = _triaDS->IndexOf( *tria );
+ tria = 0;
+
+ for ( int i = 0; i < 3; ++i )
+ {
+ const BRepMesh_PairOfIndex & triIDs = _triaDS->ElementsConnectedTo( linkIDs[i] );
+ if ( triIDs.Extent() < 2 )
+ continue; // no neighbor triangle
+
+ // check if a link intersects gc2uv
+ const BRepMesh_Edge & link = _triaDS->GetLink( linkIDs[i] );
+ const BRepMesh_Vertex & n1 = _triaDS->GetNode( link.FirstNode() );
+ const BRepMesh_Vertex & n2 = _triaDS->GetNode( link.LastNode() );
+ gp_XY uv1 = n1.Coord();
+ gp_XY lin = n2.Coord() - uv1; // link direction
+
+ double crossSegLin = seg ^ lin;
+ if ( Abs( crossSegLin ) < std::numeric_limits<double>::min() )
+ continue; // parallel
+
+ double uSeg = ( uv1 - gc ) ^ lin / crossSegLin;
+ if ( 0. <= uSeg && uSeg <= 1. )
+ {
+ tria = & _triaDS->GetElement( triIDs.Index( 1 + ( triIDs.Index(1) == triaID )));
+ if ( tria->Movability() != BRepMesh_Deleted )
+ break;
+ }
+ }
+ }
+ return tria;
+}
+
+//================================================================================
+/*!
+ * \brief Return a triangle sharing a given boundary node
+ * \param [in] iBndNode - index of the boundary node
+ * \return const BRepMesh_Triangle* - a found triangle
+ */
+//================================================================================
+
+const BRepMesh_Triangle* SMESH_Delaunay::GetTriangleNear( int iBndNode )
+{
+ int nodeIDs[3];
+ int nbNbNodes = _bndNodes.size();
+ const BRepMesh::ListOfInteger & linkIds = _triaDS->LinksConnectedTo( iBndNode + 1 );
+ BRepMesh::ListOfInteger::const_iterator iLink = linkIds.cbegin();
+ for ( ; iLink != linkIds.cend(); ++iLink )
+ {
+ const BRepMesh_PairOfIndex & triaIds = _triaDS->ElementsConnectedTo( *iLink );
+ {
+ const BRepMesh_Triangle& tria = _triaDS->GetElement( triaIds.Index(1) );
+ if ( tria.Movability() != BRepMesh_Deleted )
+ {
+ _triaDS->ElementNodes( tria, nodeIDs );
+ if ( nodeIDs[0]-1 < nbNbNodes &&
+ nodeIDs[1]-1 < nbNbNodes &&
+ nodeIDs[2]-1 < nbNbNodes )
+ return &tria;
+ }
+ }
+ if ( triaIds.Extent() > 1 )
+ {
+ const BRepMesh_Triangle& tria = _triaDS->GetElement( triaIds.Index(2) );
+ if ( tria.Movability() != BRepMesh_Deleted )
+ {
+ _triaDS->ElementNodes( tria, nodeIDs );
+ if ( nodeIDs[0]-1 < nbNbNodes &&
+ nodeIDs[1]-1 < nbNbNodes &&
+ nodeIDs[2]-1 < nbNbNodes )
+ return &tria;
+ }
+ }
+ }
+ return 0;
+}
+
+//================================================================================
+/*!
+ * \brief Return UV of the i-th source boundary node (zero based)
+ */
+//================================================================================
+
+gp_XY SMESH_Delaunay::GetBndUV(const int iNode) const
+{
+ return _triaDS->GetNode( iNode+1 ).Coord();
+}
+
+//================================================================================
+/*!
+ * \brief Add non-marked nodes surrounding a given one to a queue
+ */
+//================================================================================
+
+void SMESH_Delaunay::addCloseNodes( const SMDS_MeshNode* node,
+ const BRepMesh_Triangle* tria,
+ const int faceID,
+ TNodeTriaList & _noTriQueue )
+{
+ // find in-FACE nodes
+ SMDS_ElemIteratorPtr elems = node->GetInverseElementIterator(SMDSAbs_Face);
+ while ( elems->more() )
+ {
+ const SMDS_MeshElement* elem = elems->next();
+ if ( elem->getshapeId() == faceID )
+ {
+ for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
+ {
+ const SMDS_MeshNode* n = elem->GetNode( i );
+ if ( !n->isMarked() /*&& n->getshapeId() == faceID*/ )
+ _noTriQueue.push_back( std::make_pair( n, tria ));
+ }
+ }
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Write a python script that creates an equal mesh in Mesh module
+ */
+//================================================================================
+
+void SMESH_Delaunay::ToPython() const
+{
+ SMESH_Comment text;
+ text << "import salome, SMESH\n";
+ text << "salome.salome_init()\n";
+ text << "from salome.smesh import smeshBuilder\n";
+ text << "smesh = smeshBuilder.New(salome.myStudy)\n";
+ text << "mesh=smesh.Mesh()\n";
+ const char* endl = "\n";
+
+ for ( int i = 0; i < _triaDS->NbNodes(); ++i )
+ {
+ const BRepMesh_Vertex& v = _triaDS->GetNode( i+1 );
+ text << "mesh.AddNode( " << v.Coord().X() << ", " << v.Coord().Y() << ", 0 )" << endl;
+ }
+
+ int nodeIDs[3];
+ for ( int i = 0; i < _triaDS->NbElements(); ++i )
+ {
+ const BRepMesh_Triangle& t = _triaDS->GetElement( i+1 );
+ if ( t.Movability() == BRepMesh_Deleted )
+ continue;
+ _triaDS->ElementNodes( t, nodeIDs );
+ text << "mesh.AddFace([ " << nodeIDs[0] << ", " << nodeIDs[1] << ", " << nodeIDs[2] << " ])" << endl;
+ }
+
+ const char* fileName = "/tmp/Delaunay.py";
+ SMESH_File file( fileName, false );
+ file.remove();
+ file.openForWriting();
+ file.write( text.c_str(), text.size() );
+ cout << "execfile( '" << fileName << "')" << endl;
+}
--- /dev/null
+// Copyright (C) 2007-2016 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
+//
+// File : SMESH_Delaunay.hxx
+// Created : Wed Apr 19 15:42:54 2017
+// Author : Edward AGAPOV (eap)
+
+
+#ifndef __SMESH_Delaunay_HXX__
+#define __SMESH_Delaunay_HXX__
+
+#include "SMESH_TypeDefs.hxx"
+
+#include <BRepMesh_DataStructureOfDelaun.hxx>
+
+/*!
+ * \brief Create a Delaunay triangulation of nodes on a face boundary
+ * and provide exploration of nodes shared by elements lying on
+ * the face. For a returned node, also return a Delaunay triangle
+ * the node lies in and its Barycentric Coordinates within the triangle.
+ * Only non-marked nodes are visited. Boundary nodes given at the construction
+ * are not returned.
+ *
+ * For usage, this class needs to be subclassed to implement getNodeUV();
+ */
+class SMESHUtils_EXPORT SMESH_Delaunay
+{
+ public:
+
+ // construct a Delaunay triangulation of given boundary nodes
+ SMESH_Delaunay(const std::vector< const UVPtStructVec* > & boundaryNodes,
+ const TopoDS_Face& face,
+ const int faceID);
+
+ virtual ~SMESH_Delaunay() {}
+
+ // prepare to the exploration of nodes
+ void InitTraversal(const int nbNodesToVisit = -1);
+
+ // return a node with its Barycentric Coordinates within the triangle
+ // defined by its node indices (zero based)
+ const SMDS_MeshNode* NextNode( double bc[3], int triaNodes[3] );
+
+ // return nb of nodes returned by NextNode()
+ int NbVisitedNodes() const { return _nbVisitedNodes; }
+
+
+ // find a triangle containing an UV, starting from a given triangle;
+ // return barycentric coordinates of the UV and the found triangle (indices are zero based).
+ const BRepMesh_Triangle* FindTriangle( const gp_XY& uv,
+ const BRepMesh_Triangle* bmTria,
+ double bc[3],
+ int triaNodes[3]);
+
+ // return any Delaunay triangle neighboring a given boundary node (zero based)
+ const BRepMesh_Triangle* GetTriangleNear( int iBndNode );
+
+ // return source boundary nodes
+ const std::vector< const SMDS_MeshNode* >& GetBndNodes() const { return _bndNodes; }
+
+ // return UV of the i-th source boundary node (zero based)
+ gp_XY GetBndUV(const int iNode) const;
+
+ // return scale factor to convert real UV to/from UV used for Delauney meshing:
+ // delauney_UV = real_UV * scale
+ const gp_XY& GetScale() const { return _scale; }
+
+ void ToPython() const;
+
+ Handle(BRepMesh_DataStructureOfDelaun) GetDS() { return _triaDS; }
+
+ protected:
+
+ // container of a node and a triangle serving as a start while searching a
+ // triangle including the node UV
+ typedef std::list< std::pair< const SMDS_MeshNode*, const BRepMesh_Triangle* > > TNodeTriaList;
+
+ // return UV of a node on the face
+ virtual gp_XY getNodeUV( const TopoDS_Face& face, const SMDS_MeshNode* node ) const = 0;
+
+ // add non-marked nodes surrounding a given one to a queue
+ static void addCloseNodes( const SMDS_MeshNode* node,
+ const BRepMesh_Triangle* bmTria,
+ const int faceID,
+ TNodeTriaList & noTriQueue );
+
+ const TopoDS_Face& _face;
+ int _faceID;
+ std::vector< const SMDS_MeshNode* > _bndNodes;
+ gp_XY _scale;
+ Handle(BRepMesh_DataStructureOfDelaun) _triaDS;
+ size_t _nbNodesToVisit, _nbVisitedNodes, _iBndNode;
+ TNodeTriaList _noTriQueue;
+
+};
+
+#endif
SMDSAbs_ElementType elemType,
SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
double tolerance = NodeRadius );
- void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems );
- void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
- void getElementsInSphere ( const gp_XYZ& center,
- const double radius, TIDSortedElemSet& foundElems);
- size_t getSize() { return std::max( _size, _elements.size() ); }
- virtual ~ElementBndBoxTree();
+ void prepare(); // !!!call it before calling the following methods!!!
+ void getElementsNearPoint( const gp_Pnt& point, vector<const SMDS_MeshElement*>& foundElems );
+ void getElementsNearLine ( const gp_Ax1& line, vector<const SMDS_MeshElement*>& foundElems);
+ void getElementsInSphere ( const gp_XYZ& center,
+ const double radius,
+ vector<const SMDS_MeshElement*>& foundElems);
protected:
- ElementBndBoxTree():_size(0) {}
+ ElementBndBoxTree() {}
SMESH_Octree* newChild() const { return new ElementBndBoxTree; }
void buildChildrenData();
Bnd_B3d* buildRootBox();
struct ElementBox : public Bnd_B3d
{
const SMDS_MeshElement* _element;
- int _refCount; // an ElementBox can be included in several tree branches
- ElementBox(const SMDS_MeshElement* elem, double tolerance);
+ bool _isMarked;
+ void init(const SMDS_MeshElement* elem, double tolerance);
};
vector< ElementBox* > _elements;
- size_t _size;
+
+ typedef ObjectPool< ElementBox > TElementBoxPool;
+
+ //!< allocator of ElementBox's and SMESH_TreeLimit
+ struct LimitAndPool : public SMESH_TreeLimit
+ {
+ TElementBoxPool _elBoPool;
+ std::vector< ElementBox* > _markedElems;
+ LimitAndPool():SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ) {}
+ };
+ LimitAndPool* getLimitAndPool() const
+ {
+ SMESH_TreeLimit* limitAndPool = const_cast< SMESH_TreeLimit* >( myLimit );
+ return static_cast< LimitAndPool* >( limitAndPool );
+ }
};
//================================================================================
*/
//================================================================================
- ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance)
- :SMESH_Octree( new SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ))
+ ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh,
+ SMDSAbs_ElementType elemType,
+ SMDS_ElemIteratorPtr theElemIt,
+ double tolerance)
+ :SMESH_Octree( new LimitAndPool() )
{
int nbElems = mesh.GetMeshInfo().NbElements( elemType );
_elements.reserve( nbElems );
+ TElementBoxPool& elBoPool = getLimitAndPool()->_elBoPool;
+
SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
while ( elemIt->more() )
- _elements.push_back( new ElementBox( elemIt->next(),tolerance ));
-
+ {
+ ElementBox* eb = elBoPool.getNew();
+ eb->init( elemIt->next(), tolerance );
+ _elements.push_back( eb );
+ }
compute();
}
- //================================================================================
- /*!
- * \brief Destructor
- */
- //================================================================================
-
- ElementBndBoxTree::~ElementBndBoxTree()
- {
- for ( size_t i = 0; i < _elements.size(); ++i )
- if ( --_elements[i]->_refCount <= 0 )
- delete _elements[i];
- }
-
//================================================================================
/*!
* \brief Return the maximal box
for (int j = 0; j < 8; j++)
{
if ( !_elements[i]->IsOut( *myChildren[j]->getBox() ))
- {
- _elements[i]->_refCount++;
((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]);
- }
}
- _elements[i]->_refCount--;
}
- _size = _elements.size();
+ //_size = _elements.size();
SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory
for (int j = 0; j < 8; j++)
if ((int) child->_elements.size() <= MaxNbElemsInLeaf )
child->myIsLeaf = true;
- if ( child->_elements.capacity() - child->_elements.size() > 1000 )
+ if ( child->isLeaf() && child->_elements.capacity() > child->_elements.size() )
SMESHUtils::CompactVector( child->_elements );
}
}
+ //================================================================================
+ /*!
+ * \brief Un-mark all elements
+ */
+ //================================================================================
+
+ void ElementBndBoxTree::prepare()
+ {
+ // TElementBoxPool& elBoPool = getElementBoxPool();
+ // for ( size_t i = 0; i < elBoPool.nbElements(); ++i )
+ // const_cast< ElementBox* >( elBoPool[ i ])->_isMarked = false;
+ }
+
//================================================================================
/*!
* \brief Return elements which can include the point
*/
//================================================================================
- void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point,
- TIDSortedElemSet& foundElems)
+ void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point,
+ vector<const SMDS_MeshElement*>& foundElems)
{
if ( getBox()->IsOut( point.XYZ() ))
return;
if ( isLeaf() )
{
+ LimitAndPool* pool = getLimitAndPool();
+
for ( size_t i = 0; i < _elements.size(); ++i )
- if ( !_elements[i]->IsOut( point.XYZ() ))
- foundElems.insert( _elements[i]->_element );
+ if ( !_elements[i]->IsOut( point.XYZ() ) &&
+ !_elements[i]->_isMarked )
+ {
+ foundElems.push_back( _elements[i]->_element );
+ _elements[i]->_isMarked = true;
+ pool->_markedElems.push_back( _elements[i] );
+ }
}
else
{
for (int i = 0; i < 8; i++)
((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems );
+
+ if ( level() == 0 )
+ {
+ LimitAndPool* pool = getLimitAndPool();
+ for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+ pool->_markedElems[i]->_isMarked = false;
+ pool->_markedElems.clear();
+ }
}
}
*/
//================================================================================
- void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line,
- TIDSortedElemSet& foundElems)
+ void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line,
+ vector<const SMDS_MeshElement*>& foundElems)
{
if ( getBox()->IsOut( line ))
return;
if ( isLeaf() )
{
+ LimitAndPool* pool = getLimitAndPool();
+
for ( size_t i = 0; i < _elements.size(); ++i )
- if ( !_elements[i]->IsOut( line ))
- foundElems.insert( _elements[i]->_element );
+ if ( !_elements[i]->IsOut( line ) &&
+ !_elements[i]->_isMarked )
+ {
+ foundElems.push_back( _elements[i]->_element );
+ _elements[i]->_isMarked = true;
+ pool->_markedElems.push_back( _elements[i] );
+ }
}
else
{
for (int i = 0; i < 8; i++)
((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems );
+
+ if ( level() == 0 )
+ {
+ LimitAndPool* pool = getLimitAndPool();
+ for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+ pool->_markedElems[i]->_isMarked = false;
+ pool->_markedElems.clear();
+ }
}
}
*/
//================================================================================
- void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
- const double radius,
- TIDSortedElemSet& foundElems)
+ void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
+ const double radius,
+ vector<const SMDS_MeshElement*>& foundElems)
{
if ( getBox()->IsOut( center, radius ))
return;
if ( isLeaf() )
{
+ LimitAndPool* pool = getLimitAndPool();
+
for ( size_t i = 0; i < _elements.size(); ++i )
- if ( !_elements[i]->IsOut( center, radius ))
- foundElems.insert( _elements[i]->_element );
+ if ( !_elements[i]->IsOut( center, radius ) &&
+ !_elements[i]->_isMarked )
+ {
+ foundElems.push_back( _elements[i]->_element );
+ _elements[i]->_isMarked = true;
+ pool->_markedElems.push_back( _elements[i] );
+ }
}
else
{
for (int i = 0; i < 8; i++)
((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems );
+
+ if ( level() == 0 )
+ {
+ LimitAndPool* pool = getLimitAndPool();
+ for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+ pool->_markedElems[i]->_isMarked = false;
+ pool->_markedElems.clear();
+ }
}
}
*/
//================================================================================
- ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance)
+ void ElementBndBoxTree::ElementBox::init(const SMDS_MeshElement* elem, double tolerance)
{
_element = elem;
- _refCount = 1;
+ _isMarked = false;
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
while ( nIt->more() )
- Add( SMESH_TNodeXYZ( nIt->next() ));
+ Add( SMESH_NodeXYZ( nIt->next() ));
Enlarge( tolerance );
}
anExtCC.Init( lineCurve, edge.Value() );
if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
{
- Quantity_Parameter pl, pe;
+ Standard_Real pl, pe;
anExtCC.LowerDistanceParameters( pl, pe );
param += pl;
if ( ++nbInts == 2 )
{
_ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance );
}
- TIDSortedElemSet suspectElems;
+ else
+ {
+ _ebbTree[ type ]->prepare();
+ }
+ vector< const SMDS_MeshElement* > suspectElems;
_ebbTree[ type ]->getElementsNearPoint( point, suspectElems );
- TIDSortedElemSet::iterator elem = suspectElems.begin();
+ vector< const SMDS_MeshElement* >::iterator elem = suspectElems.begin();
for ( ; elem != suspectElems.end(); ++elem )
if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance ))
foundElements.push_back( *elem );
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt );
+ else
+ ebbTree->prepare();
- TIDSortedElemSet suspectElems;
+ vector<const SMDS_MeshElement*> suspectElems;
ebbTree->getElementsNearPoint( point, suspectElems );
if ( suspectElems.empty() && ebbTree->maxSize() > 0 )
radius = ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2;
while ( suspectElems.empty() )
{
+ ebbTree->prepare();
ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems );
radius *= 1.1;
}
}
double minDist = std::numeric_limits<double>::max();
multimap< double, const SMDS_MeshElement* > dist2face;
- TIDSortedElemSet::iterator elem = suspectElems.begin();
+ vector<const SMDS_MeshElement*>::iterator elem = suspectElems.begin();
for ( ; elem != suspectElems.end(); ++elem )
{
double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
ElementBndBoxTree*& ebbTree = _ebbTree[ SMDSAbs_Face ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+ else
+ ebbTree->prepare();
// Algo: analyse transition of a line starting at the point through mesh boundary;
// try three lines parallel to axis of the coordinate system and perform rough
gp_Ax1 lineAxis( point, axisDir[axis]);
gp_Lin line ( lineAxis );
- TIDSortedElemSet suspectFaces; // faces possibly intersecting the line
+ vector<const SMDS_MeshElement*> suspectFaces; // faces possibly intersecting the line
+ if ( axis > 0 ) ebbTree->prepare();
ebbTree->getElementsNearLine( lineAxis, suspectFaces );
// Intersect faces with the line
map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
- TIDSortedElemSet::iterator face = suspectFaces.begin();
+ vector<const SMDS_MeshElement*>::iterator face = suspectFaces.begin();
for ( ; face != suspectFaces.end(); ++face )
{
// get face plane
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+ else
+ ebbTree->prepare();
- TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
- ebbTree->getElementsNearLine( line, suspectFaces );
- foundElems.assign( suspectFaces.begin(), suspectFaces.end());
+ ebbTree->getElementsNearLine( line, foundElems );
}
//=======================================================================
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+ else
+ ebbTree->prepare();
- TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
- ebbTree->getElementsInSphere( center, radius, suspectFaces );
- foundElems.assign( suspectFaces.begin(), suspectFaces.end() );
+ ebbTree->getElementsInSphere( center, radius, foundElems );
}
//=======================================================================
#include <Utils_SALOME_Exception.hxx>
#include <Standard_Failure.hxx>
#include <Standard_ErrorHandler.hxx>
-#include <Basics_OCCTVersion.hxx>
#include <utilities.h>
// IMPORTANT: include this file _after_ OCC ones, else OCC_CATCH_SIGNALS can be undefined!
#define OCC_CATCH_SIGNALS
#endif
-// Define macros to catch and convert some of possible exceptions into text or SALOME_Exception
+// Define macros to catch and convert some of possible exceptions into text or SALOME_Exception.
+// WARNING: SALOME::SALOME_Exception (CORBA exception) is not treated here; to care about it add
+// #define SMY_OWN_CATCH catch ( SALOME::SALOME_Exception & e ) { do_something(e); }
+// before #include<SMESH_TryCatch.hxx>
+
//-------------------------------------------------------------------------------------
#define SMESH_TRY \
#include <unistd.h>
#endif
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyGroup ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyFilter ,_pyObject);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis);
-OCCT_IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient);
+IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient);
+IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient);
+IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyGroup ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyFilter ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis);
using namespace std;
using SMESH::TPythonDump;
"Entity_Polygon", "Entity_Quad_Polygon", "Entity_Tetra", "Entity_Quad_Tetra",
"Entity_Pyramid", "Entity_Quad_Pyramid",
"Entity_Hexa", "Entity_Quad_Hexa", "Entity_TriQuad_Hexa",
- "Entity_Penta", "Entity_Quad_Penta", "Entity_Hexagonal_Prism",
+ "Entity_Penta", "Entity_Quad_Penta", "Entity_BiQuad_Penta", "Entity_Hexagonal_Prism",
"Entity_Polyhedra", "Entity_Quad_Polyhedra", "Entity_Ball" };
if ( -1 < iGeom && iGeom < nbTypes )
Threshold = SMESH + types[ iGeom ];
#include <vector>
#include <set>
-#include <Basics_OCCTVersion.hxx>
-
#include <SALOMEconfig.h>
#include CORBA_CLIENT_HEADER(SALOMEDS)
bool AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod );
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyCommand,Standard_Transient)
+ DEFINE_STANDARD_RTTIEXT(_pyCommand,Standard_Transient)
};
// -------------------------------------------------------------------------------------
virtual void ClearCommands();
virtual void Free() {}
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyObject,Standard_Transient)
+ DEFINE_STANDARD_RTTIEXT(_pyObject,Standard_Transient)
};
// -------------------------------------------------------------------------------------
std::map< _AString, ExportedMeshData > myFile2ExportedMesh;
Handle( _pyHypothesisReader ) myHypReader;
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyGen,_pyObject)
+ DEFINE_STANDARD_RTTIEXT(_pyGen,_pyObject)
};
// -------------------------------------------------------------------------------------
static void AddMeshAccess( const Handle(_pyCommand)& theCommand )
{ theCommand->SetObject( theCommand->GetObject() + "." _pyMesh_ACCESS_METHOD ); }
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject)
+ DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject)
};
#undef _pyMesh_ACCESS_METHOD
virtual void Flush() {}
virtual bool CanClear();
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject)
+ DEFINE_STANDARD_RTTIEXT(_pyMesh,_pyObject)
};
// -------------------------------------------------------------------------------------
//void ComputeSaved ( const Handle(_pyCommand)& theComputeCommand );
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyHypothesis,_pyObject)
+ DEFINE_STANDARD_RTTIEXT(_pyHypothesis,_pyObject)
};
// -------------------------------------------------------------------------------------
virtual const char* AccessorMethod() const { return "GetAlgorithm()"; }
virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped; }
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyAlgorithm,_pyHypothesis)
+ DEFINE_STANDARD_RTTIEXT(_pyAlgorithm,_pyHypothesis)
};
// -------------------------------------------------------------------------------------
virtual void Process( const Handle(_pyCommand)& theCommand);
virtual void Flush();
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis)
+ DEFINE_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis)
};
DEFINE_STANDARD_HANDLE (_pyComplexParamHypo, _pyHypothesis);
const _pyID& theMesh);
virtual void Free() { my1dHyp.Nullify(); }
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis)
+ DEFINE_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis)
};
DEFINE_STANDARD_HANDLE (_pyLayerDistributionHypo, _pyHypothesis);
const _pyID& theMesh);
void Flush();
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis)
+ DEFINE_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis)
};
DEFINE_STANDARD_HANDLE (_pyNumberOfSegmentsHyp, _pyHypothesis);
_pySegmentLengthAroundVertexHyp(const Handle(_pyCommand)& theCrCmd): _pyHypothesis(theCrCmd) {}
virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
const _pyID& theMesh);
- OCCT_DEFINE_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis)
+ DEFINE_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis)
};
DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis);
virtual bool CanClear();
static bool IsAliveCmd( const Handle(_pyCommand)& theCmd );
- OCCT_DEFINE_STANDARD_RTTIEXT(_pySelfEraser,_pyObject)
+ DEFINE_STANDARD_RTTIEXT(_pySelfEraser,_pyObject)
};
DEFINE_STANDARD_HANDLE (_pySelfEraser, _pyObject);
void SetCreator( const Handle(_pyObject)& theCreator ) { myCreator = theCreator; }
static bool CanBeArgOfMethod(const _AString& theMethodName);
- OCCT_DEFINE_STANDARD_RTTIEXT(_pySubMesh,_pyObject)
+ DEFINE_STANDARD_RTTIEXT(_pySubMesh,_pyObject)
};
// -------------------------------------------------------------------------------------
/*!
//virtual void Free() { myUsers.clear(); }
const _pyID& GetNewID() const { return myNewID; }
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyFilter,_pyObject)
+ DEFINE_STANDARD_RTTIEXT(_pyFilter,_pyObject)
};
DEFINE_STANDARD_HANDLE (_pyFilter, _pyObject);
virtual bool CanClear();
void RemovedWithContents();
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyGroup,_pySubMesh)
+ DEFINE_STANDARD_RTTIEXT(_pyGroup,_pySubMesh)
};
// -------------------------------------------------------------------------------------
_pyHypothesisReader();
Handle(_pyHypothesis) GetHypothesis(const _AString& hypType,
const Handle(_pyCommand)& creationCmd) const;
- OCCT_DEFINE_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient)
+ DEFINE_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient)
};
#endif
case Entity_TriQuad_Hexa: myStream<<"Entity_TriQuad_Hexa"; break;
case Entity_Penta: myStream<<"Entity_Penta"; break;
case Entity_Quad_Penta: myStream<<"Entity_Quad_Penta"; break;
+ case Entity_BiQuad_Penta: myStream<<"Entity_BiQuad_Penta"; break;
case Entity_Hexagonal_Prism: myStream<<"Entity_Hexagonal_Prism"; break;
case Entity_Polyhedra: myStream<<"Entity_Polyhedra"; break;
case Entity_Quad_Polyhedra: myStream<<"Entity_Quad_Polyhedra"; break;
switch (theVersion) {
case SMESH::MED_V2_1: myStream << "SMESH.MED_V2_1"; break;
case SMESH::MED_V2_2: myStream << "SMESH.MED_V2_2"; break;
+ case SMESH::MED_LATEST: myStream << "SMESH.MED_LATEST"; break;
+ case SMESH::MED_MINOR_0: myStream << "SMESH.MED_MINOR_0"; break;
+ case SMESH::MED_MINOR_1: myStream << "SMESH.MED_MINOR_1"; break;
+ case SMESH::MED_MINOR_2: myStream << "SMESH.MED_MINOR_2"; break;
+ case SMESH::MED_MINOR_3: myStream << "SMESH.MED_MINOR_3"; break;
+ case SMESH::MED_MINOR_4: myStream << "SMESH.MED_MINOR_4"; break;
+ case SMESH::MED_MINOR_5: myStream << "SMESH.MED_MINOR_5"; break;
+ case SMESH::MED_MINOR_6: myStream << "SMESH.MED_MINOR_6"; break;
+ case SMESH::MED_MINOR_7: myStream << "SMESH.MED_MINOR_7"; break;
+ case SMESH::MED_MINOR_8: myStream << "SMESH.MED_MINOR_8"; break;
+ case SMESH::MED_MINOR_9: myStream << "SMESH.MED_MINOR_9"; break;
default: myStream << theVersion;
}
return *this;
#include <SALOMEDS_wrap.hxx>
#include <GEOM_wrap.hxx>
-#include <Basics_OCCTVersion.hxx>
-
#include <BRep_Tool.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_Plane.hxx>
if ( myFileName == 0 || strlen( myFileName ) == 0 )
return false;
-#if OCC_VERSION_MAJOR < 7
- FILE* aOutFile = fopen( myFileName, "wt" );
- if ( !aOutFile )
- return false;
-
- LDOM_XmlWriter aWriter( aOutFile );
- aWriter.SetIndentation( 2 );
- aWriter << myDoc;
- fclose( aOutFile );
-#else
std::filebuf fb;
fb.open( myFileName, std::ios::out );
aWriter.SetIndentation( 2 );
aWriter.Write( os, myDoc );
fb.close();
-#endif
TPythonDump()<<this<<".Save()";
return true;
#ifdef _DEBUG_
// check if functName is complete, compilation failure means that enum FunctorType changed
const int nbFunctors = sizeof(functName) / sizeof(const char*);
- int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 2 : -1 ]; _assert[0]=_assert[1];
+ int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 2 : -1 ]; _assert[0]=_assert[1]=0;
#endif
return functName;
#define LoadLib( name ) LoadLibrary( name )
#define GetProc GetProcAddress
#define UnLoadLib( handle ) FreeLibrary( handle );
-#else
+#else // WIN32
#define LibHandle void*
- #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL )
+ #ifdef DYNLOAD_LOCAL
+ #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_LOCAL )
+ #else // DYNLOAD_LOCAL
+ #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL )
+ #endif // DYNLOAD_LOCAL
#define GetProc dlsym
#define UnLoadLib( handle ) dlclose( handle );
-#endif
+#endif // WIN32
#include "SMESH_Gen_i.hxx"
#include "SMESH_version.h"
const char* typeNames[] = { "All","Nodes","Edges","Faces","Volumes","0DElems","Balls" };
{ // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed:
const int nbNames = sizeof(typeNames) / sizeof(const char*);
- int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 2 : -1 ]; _assert[0]=_assert[1];
+ int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 2 : -1 ]; _assert[0]=_assert[1]=0;
}
string groupName = "Gr";
SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, theMeshesArray[i] );
theVersion = SMESH::MED_V2_1;
MED::EVersion aVersion = MED::GetVersionId( theFileName );
switch( aVersion ) {
- case MED::eV2_1 : theVersion = SMESH::MED_V2_1; return true;
- case MED::eV2_2 : theVersion = SMESH::MED_V2_2; return true;
+ case MED::eV2_1 : theVersion = SMESH::MED_V2_1; return true;
+ case MED::eV2_2 : theVersion = SMESH::MED_V2_2; return true;
+ case MED::eLATEST : theVersion = SMESH::MED_LATEST; return true;
+ case MED::eMINOR_0 : theVersion = SMESH::MED_MINOR_0; return true;
+ case MED::eMINOR_1 : theVersion = SMESH::MED_MINOR_1; return true;
+ case MED::eMINOR_2 : theVersion = SMESH::MED_MINOR_2; return true;
+ case MED::eMINOR_3 : theVersion = SMESH::MED_MINOR_3; return true;
+ case MED::eMINOR_4 : theVersion = SMESH::MED_MINOR_4; return true;
+ case MED::eMINOR_5 : theVersion = SMESH::MED_MINOR_5; return true;
+ case MED::eMINOR_6 : theVersion = SMESH::MED_MINOR_6; return true;
+ case MED::eMINOR_7 : theVersion = SMESH::MED_MINOR_7; return true;
+ case MED::eMINOR_8 : theVersion = SMESH::MED_MINOR_8; return true;
+ case MED::eMINOR_9 : theVersion = SMESH::MED_MINOR_9; return true;
case MED::eVUnknown : return false;
}
return false;
{
int aSize = aGroupDS->Extent();
aRes->length(aSize);
- for (int i = 0; i < aSize; i++)
- aRes[i] = aGroupDS->GetID(i+1);
+ SMDS_ElemIteratorPtr it = aGroupDS->GetElements();
+ for (int i = 0; it->more(); i++)
+ aRes[i] = it->next()->GetID();
if ( 0 < aSize && aSize < 100 ) // for comfortable testing ;)
std::sort( &aRes[0], &aRes[0]+aSize );
#include <Utils_CorbaException.hxx>
#include <SALOMEDS_wrap.hxx>
#include <SALOME_GenericObj_i.hh>
-#include <Basics_OCCTVersion.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRep_Tool.hxx>
#include <gp_Ax2.hxx>
#include <gp_Vec.hxx>
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
#include <Standard_Failure.hxx>
-
-#ifdef NO_CAS_CATCH
#include <Standard_ErrorHandler.hxx>
-#endif
#include <sstream>
#include <limits>
n[8],n[9],n[10],n[11],n[12],n[13],n[14],
n[15],n[16],n[17],n[18],n[19]);
break;
+ case 18:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
+ n[8],n[9],n[10],n[11],n[12],n[13],n[14],
+ n[15],n[16],n[17]);
+ break;
case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
n[8],n[9],n[10],n[11],n[12],n[13],n[14],
n[15],n[16],n[17],n[18],n[19],
::SMESH_MeshEditor::PGroupIDs groupIds =
getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
- if ( theCopy && !myIsPreviewMode)
+ if ( !myIsPreviewMode )
{
if ( theTargetMesh )
- {
theTargetMesh->GetMeshDS()->Modified();
- }
else
- {
declareMeshModified( /*isReComputeSafe=*/false );
- }
}
+
return theMakeGroups ? getGroups(groupIds.get()) : 0;
SMESH_CATCH( SMESH::throwCorbaException );
::SMESH_MeshEditor::PGroupIDs groupIds =
getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
- if ( theCopy && !myIsPreviewMode )
+ if ( !myIsPreviewMode )
{
if ( theTargetMesh )
- {
theTargetMesh->GetMeshDS()->Modified();
- }
else
- {
declareMeshModified( /*isReComputeSafe=*/false );
- }
}
return theMakeGroups ? getGroups(groupIds.get()) : 0;
::SMESH_MeshEditor::PGroupIDs groupIds =
getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
- if ( theCopy && !myIsPreviewMode)
+ if ( !myIsPreviewMode)
{
if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
else declareMeshModified( /*isReComputeSafe=*/false );
};
gp_Trsf aTrsf;
-#if OCC_VERSION_LARGE > 0x06070100
// fight against orthogonalization
// aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
// 0, S[1], 0, thePoint.y * (1-S[1]),
thePoint.z * (1-S[2]));
M.SetDiagonal( S[0], S[1], S[2] );
-#else
- double tol = std::numeric_limits<double>::max();
- aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
- 0, S[1], 0, thePoint.y * (1-S[1]),
- 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
-#endif
-
TIDSortedElemSet copyElements;
TIDSortedElemSet* workElements = &elements;
if ( myIsPreviewMode )
::SMESH_MeshEditor::PGroupIDs groupIds =
getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
- if ( theCopy && !myIsPreviewMode )
+ if ( !myIsPreviewMode )
{
if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
else declareMeshModified( /*isReComputeSafe=*/false );
CORBA::Boolean autoDimension)
throw(SALOME::SALOME_Exception)
{
+ //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
SMESH_TRY;
if ( _preMeshInfo )
_preMeshInfo->FullLoadFromFile();
SMESH::MED_VERSION theVersion)
throw(SALOME::SALOME_Exception)
{
+ //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
ExportToMEDX(file,auto_groups,theVersion,true);
}
CORBA::Boolean auto_groups)
throw(SALOME::SALOME_Exception)
{
- ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
+ //MESSAGE("SMESH::MED_VERSION:"<< SMESH::MED_LATEST);
+ ExportToMEDX(file,auto_groups,SMESH::MED_LATEST,true);
}
//================================================================================
void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
const char* file,
- CORBA::Boolean overwrite)
+ CORBA::Boolean overwrite,
+ CORBA::Boolean groupElemsByType)
throw (SALOME::SALOME_Exception)
{
#ifdef WITH_CGNS
CORBA::String_var name = so->GetName();
meshName = name.in();
}
+ SMESH_TRY;
+
SMESH_MeshPartDS partDS( meshPart );
- _impl->ExportCGNS(file, &partDS, meshName.c_str() );
+ _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
+
+ SMESH_CATCH( SMESH::throwCorbaException );
TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
<< meshPart<< ", r'" << file << "', " << overwrite << ")";
return elemID;
}
+//================================================================================
+/*!
+ * \brief Return elements including all given nodes.
+ */
+//================================================================================
+
+SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
+ SMESH::ElementType elemType)
+{
+ if ( _preMeshInfo )
+ _preMeshInfo->FullLoadFromFile();
+
+ SMESH::long_array_var result = new SMESH::long_array();
+
+ if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
+ {
+ vector< const SMDS_MeshNode * > nn( nodes.length() );
+ for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
+ nn[i] = mesh->FindNode( nodes[i] );
+
+ std::vector<const SMDS_MeshElement *> elems;
+ mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
+ result->length( elems.size() );
+ for ( size_t i = 0; i < elems.size(); ++i )
+ result[i] = elems[i]->GetID();
+ }
+ return result._retn();
+}
+
//=============================================================================
/*!
* Returns true if given element is polygon
void ExportSTL( const char* file, bool isascii ) throw (SALOME::SALOME_Exception);
void ExportCGNS(SMESH::SMESH_IDSource_ptr meshPart,
const char* file,
- CORBA::Boolean overwrite) throw (SALOME::SALOME_Exception);
+ CORBA::Boolean overwrite,
+ CORBA::Boolean groupElemsByType) throw (SALOME::SALOME_Exception);
void ExportGMF(SMESH::SMESH_IDSource_ptr meshPart,
const char* file,
CORBA::Boolean withRequiredGroups) throw (SALOME::SALOME_Exception);
* Returns true if given node is medium node
* in one of quadratic elements
*/
- CORBA::Boolean IsMediumNodeOfAnyElem(CORBA::Long idn,
- SMESH::ElementType theElemType);
+ CORBA::Boolean IsMediumNodeOfAnyElem(CORBA::Long idn,
+ SMESH::ElementType elemType);
/*!
* Returns number of edges for given element
*/
CORBA::Long FindElementByNodes(const SMESH::long_array& nodes);
+ /*!
+ * Return elements including all given nodes.
+ */
+ SMESH::long_array* GetElementsByNodes(const SMESH::long_array& nodes,
+ SMESH::ElementType elemType);
+
/*!
* Returns true if given element is polygon
*/
}
bool ok = false;
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
ok = myPattern.Apply( aMesh, fset, theNodeIndexOnKeyPoint1, theReverse );
}
catch (Standard_Failure& exc) {
# scripts / static
SET(_bin_SCRIPTS
smesh.py
- batchmode_smesh.py
- batchmode_mefisto.py
ex00_all.py
ex01_cube2build.py
ex02_cube2primitive.py
+++ /dev/null
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2016 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
-#
-
-import os
-import re
-
-import batchmode_salome
-import batchmode_geompy
-import batchmode_smesh
-from salome.StdMeshers import StdMeshersBuilder
-
-smesh = batchmode_smesh.smesh
-smesh.SetCurrentStudy(batchmode_salome.myStudy)
-
-def CreateMesh (theFileName, area, len = None, nbseg = None):
-
- if not(os.path.isfile(theFileName)) or re.search("\.brep$", theFileName) is None :
- print "Incorrect file name !"
- return
-
- if (len is None) and (nbseg is None):
- print "Define length or number of segments !"
- return
-
- if (len is not None) and (nbseg is not None):
- print "Only one Hypothesis (from length and number of segments) can be defined !"
- return
-
-
- # ---- Import shape from BREP file and add it to the study
- shape_mesh = batchmode_geompy.Import(theFileName, "BREP")
- Id_shape = batchmode_geompy.addToStudy(shape_mesh, "shape_mesh")
-
-
- # ---- SMESH
- print "-------------------------- create mesh"
- mesh = smesh.Mesh(shape_mesh)
-
- print "-------------------------- create Hypothesis"
- if (len is not None):
- print "-------------------------- LocalLength"
- algoReg = mesh.Segment()
- hypLength1 = algoReg.LocalLength(len)
- print "Hypothesis type : ", hypLength1.GetName()
- print "Hypothesis ID : ", hypLength1.GetId()
- print "Hypothesis Value: ", hypLength1.GetLength()
-
- if (nbseg is not None):
- print "-------------------------- NumberOfSegments"
- algoReg = mesh.Segment()
- hypNbSeg1 = algoReg.NumberOfSegments(nbseg)
- print "Hypothesis type : ", hypNbSeg1.GetName()
- print "Hypothesis ID : ", hypNbSeg1.GetId()
- print "Hypothesis Value: ", hypNbSeg1.GetNumberOfSegments()
-
- if (area == "LengthFromEdges"):
- print "-------------------------- LengthFromEdges"
- algoMef = mesh.Triangle()
- hypLengthFromEdges = algoMef.LengthFromEdges(1)
- print "Hypothesis type : ", hypLengthFromEdges.GetName()
- print "Hypothesis ID : ", hypLengthFromEdges.GetId()
- print "LengthFromEdges Mode: ", hypLengthFromEdges.GetMode()
-
- else:
- print "-------------------------- MaxElementArea"
- algoMef = mesh.Triangle()
- hypArea1 = algoMef.MaxElementArea(area)
- print "Hypothesis type : ", hypArea1.GetName()
- print "Hypothesis ID : ", hypArea1.GetId()
- print "Hypothesis Value: ", hypArea1.GetMaxElementArea()
-
-
- print "-------------------------- Regular_1D"
- listHyp = algoReg.GetCompatibleHypothesis()
- for hyp in listHyp:
- print hyp
-
- print "Algo name: ", algoReg.GetName()
- print "Algo ID : ", algoReg.GetId()
-
- print "-------------------------- MEFISTO_2D"
- listHyp = algoMef.GetCompatibleHypothesis()
- for hyp in listHyp:
- print hyp
-
- print "Algo name: ", algoMef.GetName()
- print "Algo ID : ", algoMef.GetId()
-
-
- # ---- add hypothesis to shape
-
- print "-------------------------- compute mesh"
- ret = mesh.Compute()
- print "Compute Mesh .... ",
- print ret
- log = mesh.GetLog(0); # no erase trace
- #for linelog in log:
- # print linelog
-
- print "------------ INFORMATION ABOUT MESH ------------"
-
- print "Number of nodes : ", mesh.NbNodes()
- print "Number of edges : ", mesh.NbEdges()
- print "Number of faces : ", mesh.NbFaces()
- print "Number of triangles: ", mesh.NbTriangles()
-
- return mesh
+++ /dev/null
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2016 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
-#
-
-# File : batchmode_smesh.py
-# Author : Oksana TCHEBANOVA
-# Module : SMESH
-# $Header$
-#
-from batchmode_salome import *
-from batchmode_geompy import ShapeType
-import SMESH
-
-#--------------------------------------------------------------------------
-modulecatalog = naming_service.Resolve("/Kernel/ModulCatalog")
-
-smesh = lcc.FindOrLoadComponent("FactoryServer", "SMESH")
-smesh.SetCurrentStudy(myStudy)
-myStudyBuilder = myStudy.NewBuilder()
-
-if myStudyBuilder is None:
- raise RuntimeError, " Null myStudyBuilder"
-
-father = myStudy.FindComponent("SMESH")
-if father is None:
- father = myStudyBuilder.NewComponent("SMESH")
- FName = myStudyBuilder.FindOrCreateAttribute(father, "AttributeName")
- Comp = modulecatalog.GetComponent("SMESH")
- FName.SetValue(Comp._get_componentusername())
- aPixmap = myStudyBuilder.FindOrCreateAttribute(father, "AttributePixMap")
- aPixmap.SetPixMap("ICON_OBJBROWSER_Mesh")
-
-myStudyBuilder.DefineComponentInstance(father,smesh)
-
-mySComponentMesh = father._narrow(SALOMEDS.SComponent)
-
-Tag_HypothesisRoot = 1
-Tag_AlgorithmsRoot = 2
-
-Tag_RefOnShape = 1
-Tag_RefOnAppliedHypothesis = 2
-Tag_RefOnAppliedAlgorithms = 3
-
-Tag_SubMeshOnVertex = 4
-Tag_SubMeshOnEdge = 5
-Tag_SubMeshOnFace = 6
-Tag_SubMeshOnSolid = 7
-Tag_SubMeshOnCompound = 8
-
-Tag = {"HypothesisRoot":1,"AlgorithmsRoot":2,"RefOnShape":1,"RefOnAppliedHypothesis":2,"RefOnAppliedAlgorithms":3,"SubMeshOnVertex":4,"SubMeshOnEdge":5,"SubMeshOnFace":6,"SubMeshOnSolid":7,"SubMeshOnCompound":8}
-
-#------------------------------------------------------------
-def Init():
- pass
-#------------------------------------------------------------
-def AddNewMesh(IOR):
- # VSR: added temporarily - objects are published automatically by the engine
- aSO = myStudy.FindObjectIOR( IOR )
- if aSO is not None:
- return aSO.GetID()
- # VSR ######################################################################
-
- res,HypothesisRoot = mySComponentMesh.FindSubObject ( Tag_HypothesisRoot )
- if HypothesisRoot is None or res == 0:
- HypothesisRoot = myStudyBuilder.NewObjectToTag(mySComponentMesh, Tag_HypothesisRoot)
- aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName")
- aName.SetValue("Hypotheses")
- aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap")
- aPixmap.SetPixMap( "mesh_tree_hypo.png" )
- aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable")
- aSelAttr.SetSelectable(0)
-
- res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot)
- if AlgorithmsRoot is None or res == 0:
- AlgorithmsRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot)
- aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
- aName.SetValue("Algorithms")
- aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap")
- aPixmap.SetPixMap( "mesh_tree_algo.png" )
- aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable")
- aSelAttr.SetSelectable(0)
-
- HypothesisRoot = HypothesisRoot._narrow(SALOMEDS.SObject)
- newMesh = myStudyBuilder.NewObject(mySComponentMesh)
- aPixmap = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributePixMap")
- aPixmap.SetPixMap( "mesh_tree_mesh.png" )
- anIOR = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributeIOR")
- anIOR.SetValue(IOR)
- return newMesh.GetID()
-
-#------------------------------------------------------------
-def AddNewHypothesis(IOR):
- # VSR: added temporarily - objects are published automatically by the engine
- aSO = myStudy.FindObjectIOR( IOR )
- if aSO is not None:
- return aSO.GetID()
- # VSR ######################################################################
-
- res, HypothesisRoot = mySComponentMesh.FindSubObject (Tag_HypothesisRoot)
- if HypothesisRoot is None or res == 0:
- HypothesisRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot)
- aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName")
- aName.SetValue("Hypotheses")
- aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable")
- aSelAttr.SetSelectable(0)
- aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap")
- aPixmap.SetPixMap( "mesh_tree_hypo.png" )
-
- # Add New Hypothesis
- newHypo = myStudyBuilder.NewObject(HypothesisRoot)
- aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap")
- H = orb.string_to_object(IOR)
- aType = H.GetName()
- aPixmap.SetPixMap( "mesh_tree_hypo.png_" + aType )
- anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR")
- anIOR.SetValue(IOR)
- return newHypo.GetID()
-
-#------------------------------------------------------------
-def AddNewAlgorithms(IOR):
- # VSR: added temporarily - objects are published automatically by the engine
- aSO = myStudy.FindObjectIOR( IOR )
- if aSO is not None:
- return aSO.GetID()
- # VSR ######################################################################
-
- res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot)
- if AlgorithmsRoot is None or res == 0:
- AlgorithmsRoot = myStudyBuilde.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot)
- aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
- aName.SetValue("Algorithms")
- aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable")
- aSelAttr.SetSelectable(0)
- aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap")
- aPixmap.SetPixMap( "mesh_tree_algo.png" )
-
- # Add New Algorithms
- newHypo = myStudyBuilder.NewObject(AlgorithmsRoot)
- aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap")
- aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap)
- H = orb.string_to_object(IOR)
- aType = H.GetName(); #QString in fact
- aPixmap.SetPixMap( "mesh_tree_algo.png_" + aType )
- anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR")
- anIOR.SetValue(IOR)
- return newHypo.GetID()
-
-
-#------------------------------------------------------------
-def SetShape(ShapeEntry, MeshEntry):
- SO_MorSM = myStudy.FindObjectID( MeshEntry )
- SO_GeomShape = myStudy.FindObjectID( ShapeEntry )
-
- if SO_MorSM is not None and SO_GeomShape is not None :
- # VSR: added temporarily - shape reference is published automatically by the engine
- res, Ref = SO_MorSM.FindSubObject( Tag_RefOnShape )
- if res == 1 :
- return
- # VSR ######################################################################
-
- SO = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnShape)
- myStudyBuilder.Addreference (SO,SO_GeomShape)
-
-
-#------------------------------------------------------------
-def SetHypothesis(Mesh_Or_SubMesh_Entry, Hypothesis_Entry):
- SO_MorSM = myStudy.FindObjectID( Mesh_Or_SubMesh_Entry )
- SO_Hypothesis = myStudy.FindObjectID( Hypothesis_Entry )
-
- if SO_MorSM is not None and SO_Hypothesis is not None :
-
- #Find or Create Applied Hypothesis root
- res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedHypothesis)
- if AHR is None or res == 0:
- AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedHypothesis)
- aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName")
-
- # The same name as in SMESH_Mesh_i::AddHypothesis() ##################
- aName.SetValue("Applied hypotheses")
-
- aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable")
- aSelAttr.SetSelectable(0)
- aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap")
- aPixmap.SetPixMap( "mesh_tree_hypo.png" )
-
- # VSR: added temporarily - reference to applied hypothesis is published automatically by the engine
- else :
- it = myStudy.NewChildIterator(AHR)
- while it.More() :
- res, Ref = it.Value().ReferencedObject()
- if res and Ref is not None and Ref.GetID() == Hypothesis_Entry :
- return
- it.Next()
- # VSR ######################################################################
-
- SO = myStudyBuilder.NewObject(AHR)
- myStudyBuilder.Addreference (SO,SO_Hypothesis)
-
-#------------------------------------------------------------
-def SetAlgorithms(Mesh_Or_SubMesh_Entry, Algorithms_Entry):
- SO_MorSM = myStudy.FindObjectID( Mesh_Or_SubMesh_Entry )
- SO_Algorithms = myStudy.FindObjectID( Algorithms_Entry )
- if SO_MorSM != None and SO_Algorithms != None :
- #Find or Create Applied Algorithms root
- res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedAlgorithms)
- if AHR is None or res == 0:
- AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedAlgorithms)
- aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName")
-
- # The same name as in SMESH_Mesh_i::AddHypothesis() ##################
- aName.SetValue("Applied algorithms")
-
- aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable")
- aSelAttr.SetSelectable(0)
- aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap")
- aPixmap.SetPixMap( "mesh_tree_algo.png" )
-
- # VSR: added temporarily - reference to applied hypothesis is published automatically by the engine
- else :
- it = myStudy.NewChildIterator(AHR)
- while it.More() :
- res, Ref = it.Value().ReferencedObject()
- if res and Ref is not None and Ref.GetID() == Algorithms_Entry :
- return
- it.Next()
- # VSR ######################################################################
-
- SO = myStudyBuilder.NewObject(AHR)
- myStudyBuilder.Addreference (SO,SO_Algorithms)
-
-
-#------------------------------------------------------------
-def UnSetHypothesis( Applied_Hypothesis_Entry ):
- SO_Applied_Hypothesis = myStudy.FindObjectID( Applied_Hypothesis_Entry )
- if SO_Applied_Hypothesis :
- myStudyBuilder.RemoveObject(SO_Applied_Hypothesis)
-
-
-#------------------------------------------------------------
-def AddSubMesh ( SO_Mesh_Entry, SM_IOR, ST):
- # VSR: added temporarily - objects are published automatically by the engine
- aSO = myStudy.FindObjectIOR( SM_IOR )
- if aSO is not None:
- return aSO.GetID()
- # VSR ######################################################################
-
- SO_Mesh = myStudy.FindObjectID( SO_Mesh_Entry )
- if ( SO_Mesh ) :
-
- if ST == ShapeType["COMPSOLID"] :
- Tag_Shape = Tag_SubMeshOnSolid
- Name = "SubMeshes on Solid"
- elif ST == ShapeType["FACE"] :
- Tag_Shape = Tag_SubMeshOnFace
- Name = "SubMeshes on Face"
- elif ST == ShapeType["EDGE"] :
- Tag_Shape = Tag_SubMeshOnEdge
- Name = "SubMeshes on Edge"
- elif ST == ShapeType["VERTEX"] :
- Tag_Shape = Tag_SubMeshOnVertex
- Name = "SubMeshes on Vertex"
- else :
- Tag_Shape = Tag_SubMeshOnCompound
- Name = "SubMeshes on Compound"
-
- res, SubmeshesRoot = SO_Mesh.FindSubObject (Tag_Shape)
- if SubmeshesRoot is None or res == 0:
- SubmeshesRoot = myStudyBuilder.NewObjectToTag (SO_Mesh, Tag_Shape)
- aName = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeName")
- aName.SetValue(Name)
- aSelAttr = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeSelectable")
- aSelAttr.SetSelectable(0)
-
- SO = myStudyBuilder.NewObject (SubmeshesRoot)
- anIOR = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeIOR")
- anIOR.SetValue(SM_IOR)
- return SO.GetID()
-
- return None
-
-#------------------------------------------------------------
-def AddSubMeshOnShape (Mesh_Entry, GeomShape_Entry, SM_IOR, ST) :
- # VSR: added temporarily - objects are published automatically by the engine
- aSO = myStudy.FindObjectIOR( SM_IOR )
- if aSO is not None:
- return aSO.GetID()
- # VSR ######################################################################
- SO_GeomShape = myStudy.FindObjectID( GeomShape_Entry )
- if SO_GeomShape != None :
- SM_Entry = AddSubMesh (Mesh_Entry,SM_IOR,ST)
- SO_SM = myStudy.FindObjectID( SM_Entry )
-
- if SO_SM != None :
- SetShape (GeomShape_Entry, SM_Entry)
- return SM_Entry
-
- return None
-
-
-#------------------------------------------------------------
-def SetName(Entry, Name):
- SO = myStudy.FindObjectID( Entry )
- if SO != None :
- aName = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeName")
- aName.SetValue(Name)
# Values
# ------
+tmpDir = os.getenv('SALOME_TMP_DIR', '/tmp')
+print "Output directory:", tmpDir
+
# Path for ".med" files
-path = "/tmp/ex29_%s_" % os.getenv('USER','unknown')
+path = os.path.join( tmpDir, "ex29_%s_" % os.getenv('USER','unknown'))
# Name of the shape and the mesh
name = "Carre"
# @param auto_groups boolean parameter for creating/not creating
# the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
# the typical use is auto_groups=False.
- # @param version MED format version (MED_V2_1 or MED_V2_2,
- # the latter meaning any current version). The parameter is
- # obsolete since MED_V2_1 is no longer supported.
+ # @param version MED format version
+ # - MED_V2_1 is obsolete.
+ # - MED_V2_2 means current version (kept for compatibility reasons)
+ # - MED_LATEST means current version.
+ # - MED_MINOR_x where x from 0 to 9 indicates the minor version of MED
+ # to use for writing MED files, for backward compatibility :
+ # for instance, with SALOME 8.4 use MED 3.2 (minor=2) instead of 3.3,
+ # to allow the file to be read with SALOME 8.3.
# @param overwrite boolean parameter for overwriting/not overwriting the file
# @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
# @param autoDimension if @c True (default), a space dimension of a MED mesh can be either
# - 'f' stands for "_faces _" field;
# - 's' stands for "_solids _" field.
# @ingroup l2_impexp
- def ExportMED(self, f, auto_groups=0, version=MED_V2_2,
+ def ExportMED(self, f, auto_groups=0, version=MED_LATEST,
overwrite=1, meshPart=None, autoDimension=True, fields=[], geomAssocFields=''):
if meshPart or fields or geomAssocFields:
unRegister = genObjUnRegister()
# @param f is the file name
# @param overwrite boolean parameter for overwriting/not overwriting the file
# @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
+ # @param groupElemsByType if true all elements of same entity type are exported at ones,
+ # else elements are exported in order of their IDs which can cause creation
+ # of multiple cgns sections
# @ingroup l2_impexp
- def ExportCGNS(self, f, overwrite=1, meshPart=None):
+ def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
unRegister = genObjUnRegister()
if isinstance( meshPart, list ):
meshPart = self.GetIDSource( meshPart, SMESH.ALL )
meshPart = meshPart.mesh
elif not meshPart:
meshPart = self.mesh
- self.mesh.ExportCGNS(meshPart, f, overwrite)
+ self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
## Export the mesh in a file in GMF format.
# GMF files must have .mesh extension for the ASCII format and .meshb for
# Export the mesh in a file in MED format
# allowing to overwrite the file if it exists or add the exported data to its contents
# @param f the file name
- # @param version MED format version (MED_V2_1 or MED_V2_2,
- # the latter meaning any current version). The parameter is
- # obsolete since MED_V2_1 is no longer supported.
+ # @param version MED format version:
+ # - MED_V2_1 is obsolete.
+ # - MED_V2_2 means current version (kept for compatibility reasons)
+ # - MED_LATEST means current version.
+ # - MED_MINOR_x where x from 0 to 9 indicates the minor version of MED
+ # to use for writing MED files, for backward compatibility :
+ # for instance, with SALOME 8.4 use MED 3.2 (minor=2) instead of 3.3,
+ # to allow the file to be read with SALOME 8.3.
# @param opt boolean parameter for creating/not creating
# the groups Group_On_All_Nodes, Group_On_All_Faces, ...
# @param overwrite boolean parameter for overwriting/not overwriting the file
# - 3D in the rest cases.<br>
# If @a autoDimension is @c False, the space dimension is always 3.
# @ingroup l2_impexp
- def ExportToMED(self, f, version=MED_V2_2, opt=0, overwrite=1, autoDimension=True):
+ def ExportToMED(self, f, version=MED_LATEST, opt=0, overwrite=1, autoDimension=True):
self.mesh.ExportToMEDX(f, opt, version, overwrite, autoDimension)
# Operations with groups:
# @ingroup l2_grps_create
def MakeGroupByIds(self, groupName, elementType, elemIDs):
group = self.mesh.CreateGroup(elementType, groupName)
+ if isinstance( elemIDs, Mesh ):
+ elemIDs = elemIDs.GetMesh()
if hasattr( elemIDs, "GetIDs" ):
if hasattr( elemIDs, "SetMesh" ):
elemIDs.SetMesh( self.GetMesh() )
## Return an element based on all given nodes.
# @ingroup l1_meshinfo
- def FindElementByNodes(self,nodes):
+ def FindElementByNodes(self, nodes):
return self.mesh.FindElementByNodes(nodes)
+ ## Return elements including all given nodes.
+ # @ingroup l1_meshinfo
+ def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
+ return self.mesh.GetElementsByNodes( nodes, elemType )
+
## Return true if the given element is a polygon
# @ingroup l1_meshinfo
def IsPoly(self, id):
# - a GEOM point
# @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
scaleFactors=[], linearVariation=False, basePoint=[] ):
unRegister = genObjUnRegister()
# @param IsNodes is True if elements with given ids are nodes
# @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
n,e,f = [],[],[]
if IsNodes: n = IDsOfElements
# @return the list of created groups (SMESH_GroupBase) if \a MakeGroups=True,
# empty list otherwise.
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
unRegister = genObjUnRegister()
# @param IsNodes is True if elements to extrude are nodes
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
n,e,f = [],[],[]
if IsNodes: n = theObject
# @param MakeGroups to generate new groups from existing ones
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
# @param MakeGroups forces the generation of new groups from existing ones
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
# @param MakeGroups forces the generation of new groups from existing ones
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathX(self, Base, Path, NodeStart,
HasAngles=False, Angles=[], LinearVariation=False,
HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
MakeGroups=False, LinearVariation=False):
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
MakeGroups=False, LinearVariation=False):
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
MakeGroups=False, LinearVariation=False):
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
MakeGroups=False, LinearVariation=False):
## Private class used to bind methods creating algorithms to the class Mesh
#
class algoCreator:
- def __init__(self):
+ def __init__(self, method):
self.mesh = None
self.defaultAlgoType = ""
self.algoTypeToClass = {}
+ self.method = method
# Store a python class of algorithm
def add(self, algoClass):
# Create a copy of self and assign mesh to the copy
def copy(self, mesh):
- other = algoCreator()
+ other = algoCreator( self.method )
other.defaultAlgoType = self.defaultAlgoType
- other.algoTypeToClass = self.algoTypeToClass
+ other.algoTypeToClass = self.algoTypeToClass
other.mesh = mesh
return other
# Create an instance of algorithm
def __call__(self,algo="",geom=0,*args):
- algoType = self.defaultAlgoType
- for arg in args + (algo,geom):
- if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ):
- geom = arg
- if isinstance( arg, str ) and arg:
+ algoType = ""
+ shape = 0
+ if isinstance( algo, str ):
+ algoType = algo
+ elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
+ not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
+ shape = algo
+ elif algo:
+ args += (algo,)
+
+ if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
+ shape = geom
+ elif not algoType and isinstance( geom, str ):
+ algoType = geom
+ elif geom:
+ args += (geom,)
+ for arg in args:
+ if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
+ shape = arg
+ elif isinstance( arg, str ) and not algoType:
algoType = arg
+ else:
+ import traceback, sys
+ msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
+ sys.stderr.write( msg + '\n' )
+ tb = traceback.extract_stack(None,2)
+ traceback.print_list( [tb[0]] )
+ if not algoType:
+ algoType = self.defaultAlgoType
if not algoType and self.algoTypeToClass:
algoType = self.algoTypeToClass.keys()[0]
if self.algoTypeToClass.has_key( algoType ):
#print "Create algo",algoType
- return self.algoTypeToClass[ algoType ]( self.mesh, geom )
+ return self.algoTypeToClass[ algoType ]( self.mesh, shape )
raise RuntimeError, "No class found for algo type %s" % algoType
return None
if type( algo ).__name__ == 'classobj' and hasattr( algo, "meshMethod" ):
#print " meshMethod:" , str(algo.meshMethod)
if not hasattr( Mesh, algo.meshMethod ):
- setattr( Mesh, algo.meshMethod, algoCreator() )
+ setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
pass
getattr( Mesh, algo.meshMethod ).add( algo )
pass
SWIG_ADD_MODULE(libSMESH_Swig python ${SMESH_Swig_SOURCES})
SWIG_LINK_LIBRARIES(libSMESH_Swig ${_link_LIBRARIES})
+SWIG_CHECK_GENERATION(libSMESH_Swig)
IF(WIN32)
SET_TARGET_PROPERTIES(_libSMESH_Swig PROPERTIES DEBUG_OUTPUT_NAME _libSMESH_Swig_d)
ENDIF(WIN32)
#include <SalomeApp_Application.h>
#include <LightApp_SelectionMgr.h>
#include <SVTK_RenderWindowInteractor.h>
+#include <VTKViewer_Algorithm.h>
// OCCT includes
#include <TopAbs.hxx>
#include CORBA_SERVER_HEADER(SMESH_Gen)
#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+// VTK includes
+#include <vtkActorCollection.h>
+#include <vtkRenderer.h>
+
static CORBA::ORB_var anORB;
namespace
{}
virtual void Execute()
{
- SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
- if( !aSMESHGUI )
- return;
- LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( aSMESHGUI );
+ LightApp_SelectionMgr* selMgr = 0;
+ SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+ if( anApp )
+ selMgr = dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
+
if( !selMgr )
return;
selMgr->clearFilters();
- SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
+ SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
if(!aViewWindow)
return;
class TGetSelectionModeEvent : public SALOME_Event
{
public:
- typedef int TResult;
+ typedef SelectionMode TResult;
TResult myResult;
- TGetSelectionModeEvent() : myResult( -1 ) {}
+ TGetSelectionModeEvent() : myResult( Undefined ) {}
virtual void Execute()
{
- SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
- if( !aSMESHGUI )
- return;
-
- SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
+ SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( );
if(!aViewWindow)
return;
- myResult = aViewWindow->SelectionMode();
+ myResult = (SelectionMode) aViewWindow->SelectionMode();
}
};
/*!
\brief Get selection mode of the active VTK View window.
*/
-int SMESH_Swig::getSelectionMode() {
+SelectionMode SMESH_Swig::getSelectionMode() {
return ProcessEvent( new TGetSelectionModeEvent() );
}
+
+
+/*!
+ * Event to set selection mode
+*/
+class TSetSelectionModeEvent : public SALOME_Event
+{
+ SelectionMode mySelectionMode;
+
+public:
+
+ TSetSelectionModeEvent(const SelectionMode selectionMode) :
+ mySelectionMode(selectionMode)
+ {}
+
+ virtual void Execute()
+ {
+ SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+ if(!aViewWindow)
+ return;
+
+ Selection_Mode prevMode = aViewWindow->SelectionMode();
+ bool changePointRepresentation = ( prevMode == NodeSelection && mySelectionMode != Node ) ||
+ (prevMode != NodeSelection && mySelectionMode == Node);
+
+ if( changePointRepresentation ) {
+ vtkRenderer *aRenderer = aViewWindow->getRenderer();
+ VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+ vtkActorCollection *aCollection = aCopy.GetActors();
+ aCollection->InitTraversal();
+ while(vtkActor *anAct = aCollection->GetNextActor()){
+ if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+ if(anActor->GetVisibility()){
+ anActor->SetPointRepresentation(mySelectionMode == Node);
+ }
+ }
+ }
+ }
+ aViewWindow->SetSelectionMode(mySelectionMode);
+ }
+};
+
+void SMESH_Swig::setSelectionMode(SelectionMode selectionMode){
+ ProcessVoidEvent( new TSetSelectionModeEvent( selectionMode ) );
+}
+
+class TGetSelectedEvent : public SALOME_Event
+{
+public:
+ typedef std::vector<int> TResult;
+ TResult myResult;
+ const char* myId;
+
+ TGetSelectedEvent( const char* id) :
+ myResult( std::vector<int>() ),
+ myId(id)
+ {}
+
+ virtual void Execute()
+ {
+ SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+ if( !aViewWindow )
+ return;
+
+ SVTK_Selector* aSelector = aViewWindow->GetSelector();
+ if( !aSelector )
+ return;
+
+ SMESH_Actor* anActor = SMESH::FindActorByEntry( myId );
+
+ if ( !anActor || !anActor->hasIO() )
+ return;
+
+ TColStd_IndexedMapOfInteger aMapIndex;
+ aSelector->GetIndex(anActor->getIO(),aMapIndex);
+
+ for( int i = 1; i <= aMapIndex.Extent(); i++ )
+ myResult.push_back( aMapIndex( i ) );
+ }
+};
+
+std::vector<int> SMESH_Swig::getSelected( const char* Mesh_Entry ) {
+ return ProcessEvent( new TGetSelectedEvent(Mesh_Entry) );
+}
#include <SVTK_Selection.h>
-enum
+typedef enum
{
+ Undefined = -1,
Node = NodeSelection,
Cell = CellSelection,
EdgeOfCell = EdgeOfCellSelection,
Actor = ActorSelection,
Elem0D = Elem0DSelection,
Ball = BallSelection
- };
+ } SelectionMode;
typedef struct
{
actorAspect GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
void SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0 );
+ void setSelectionMode( SelectionMode selectionMode );
+ std::vector<int> getSelected( const char* Mesh_Entry );
+
// --------------------- for the test purposes -----------------------
- int getSelectionMode();
+ SelectionMode getSelectionMode();
void select( const char *id, std::vector<int> ids, bool append = false );
void select( const char *id, int id1, bool append = false );
/* Selection mode enumeration (corresponds to constants from the SALOME_Selection.h) */
-enum
+enum SelectionMode
{
- Node,
+ Undefined = -1,
+ Node = 0,
Cell,
EdgeOfCell,
Edge,
actorAspect GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
void SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0 );
+ void setSelectionMode( SelectionMode selectionMode);
+ std::vector<int> getSelected( const char* Mesh_Entry );
+
// --------------------- for the test purposes -----------------------
- int getSelectionMode();
+ SelectionMode getSelectionMode();
void select( const char *id, std::vector<int> ids, bool append = false );
void select( const char *id, int id1, bool append = false );
//=======================================================================
//function : LoadFrom
-//purpose : resore my parameters from a stream
+//purpose : restore my parameters from a stream
//=======================================================================
std::istream & StdMeshers_CartesianParameters3D::LoadFrom(std::istream & load)
#include <utilities.h>
#include <Utils_ExceptHandlers.hxx>
-#include <Basics_OCCTVersion.hxx>
#include <GEOMUtils.hxx>
}
if ( surf->IsKind( STANDARD_TYPE(Geom_BSplineSurface )) ||
surf->IsKind( STANDARD_TYPE(Geom_BezierSurface )))
-#if OCC_VERSION_MAJOR < 7
- if ( !noSafeTShapes.insert((const Standard_Transient*) _face.TShape() ).second )
-#else
if ( !noSafeTShapes.insert( _face.TShape().get() ).second )
-#endif
isSafe = false;
double f, l;
edgeIsSafe = false;
}
}
-#if OCC_VERSION_MAJOR < 7
- if ( !edgeIsSafe && !noSafeTShapes.insert((const Standard_Transient*) e.TShape() ).second )
-#else
if ( !edgeIsSafe && !noSafeTShapes.insert( e.TShape().get() ).second )
-#endif
isSafe = false;
}
return isSafe;
proj.Perform( testPnt );
if ( proj.IsDone() && proj.NbPoints() > 0 )
{
- Quantity_Parameter u,v;
+ Standard_Real u,v;
proj.LowerDistanceParameters( u,v );
if ( proj.LowerDistance() <= 0.1 * _grid->_tol )
#include <math_GaussSingleIntegration.hxx>
#include <utilities.h>
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
#include <Standard_Failure.hxx>
#include <Expr_NamedUnknown.hxx>
-
-#ifdef NO_CAS_CATCH
#include <Standard_ErrorHandler.hxx>
-#endif
using namespace std;
bool ok = true;
if (myConv == 0) {
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
f = pow( 10., f );
} catch(Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
f = 0.0;
ok = false;
}
{
bool ok = true;
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
myExpr = ExprIntrp_GenExp::Create();
myExpr->Process( ( Standard_CString )str );
} catch(Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
ok = false;
}
( ( TColStd_Array1OfReal& )myValues ).ChangeValue( 1 ) = t;
bool ok = true;
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
f = myExpr->Expression()->Evaluate( myVars, myValues );
} catch(Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
f = 0.0;
ok = false;
}
{
double res = 0.0;
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
math_GaussSingleIntegration _int
( *static_cast<math_Function*>( const_cast<FunctionExpr*> (this) ), a, b, 20 );
if( _int.IsDone() )
*/
//================================================================================
-StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
- std::list<TopoDS_Edge>& theEdges,
- SMESH_Mesh* theMesh,
- const bool theIsForward,
- const bool theIgnoreMediumNodes,
- SMESH_MesherHelper* theFaceHelper,
- SMESH_ProxyMesh::Ptr theProxyMesh)
+StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
+ const std::list<TopoDS_Edge>& theEdges,
+ SMESH_Mesh* theMesh,
+ const bool theIsForward,
+ const bool theIgnoreMediumNodes,
+ SMESH_MesherHelper* theFaceHelper,
+ SMESH_ProxyMesh::Ptr theProxyMesh)
{
int nbEdges = theEdges.size();
myEdge.resize ( nbEdges );
SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
int nbDegen = 0;
- std::list<TopoDS_Edge>::iterator edge = theEdges.begin();
+ std::list<TopoDS_Edge>::const_iterator edge = theEdges.begin();
for ( int index = 0; edge != theEdges.end(); ++index, ++edge )
{
int i = theIsForward ? index : nbEdges-index-1;
myC3dAdaptor[i].Load( C3d, 0, 0.5 * BRep_Tool::Tolerance( V ));
}
}
+ else if ( myEdgeLength[i] > DBL_MIN )
+ {
+ Handle(Geom_Curve) C3d = BRep_Tool::Curve(myEdge[i],myFirst[i], myLast[i] );
+ myC3dAdaptor[i].Load( C3d, myFirst[i], myLast[i] );
+ if ( myEdge[i].Orientation() == TopAbs_REVERSED )
+ std::swap( myFirst[i], myLast[i] );
+ }
+
// reverse a proxy sub-mesh
if ( !theIsForward )
reverseProxySubmesh( myEdge[i] );
// check parametrization of curve
if( !myIsUniform[i] )
{
- double aLen3dU = r * myEdgeLength[i] * ( myFirst[i]>myLast[i] ? -1. : 1.);
+ double aLen3dU = r * myEdgeLength[i] * ( myFirst[i] > myLast[i] ? -1. : 1. );
GCPnts_AbscissaPoint AbPnt
( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[i]), aLen3dU, myFirst[i] );
if( AbPnt.IsDone() ) {
/*!
* \brief Wrap several edges. Edges must be properly ordered and oriented.
*/
- StdMeshers_FaceSide(const TopoDS_Face& theFace,
- std::list<TopoDS_Edge>& theEdges,
- SMESH_Mesh* theMesh,
- const bool theIsForward,
- const bool theIgnoreMediumNodes,
- SMESH_MesherHelper* theFaceHelper = NULL,
- SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr());
+ StdMeshers_FaceSide(const TopoDS_Face& theFace,
+ const std::list<TopoDS_Edge>& theEdges,
+ SMESH_Mesh* theMesh,
+ const bool theIsForward,
+ const bool theIgnoreMediumNodes,
+ SMESH_MesherHelper* theFaceHelper = NULL,
+ SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr());
/*!
* \brief Simulate a side from a vertex using data from other FaceSide
*/
{ return StdMeshers_FaceSidePtr
( new StdMeshers_FaceSide( Face,Edge,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh ));
}
- static StdMeshers_FaceSidePtr New (const TopoDS_Face& Face,
- std::list<TopoDS_Edge>& Edges,
- SMESH_Mesh* Mesh,
- const bool IsForward,
- const bool IgnoreMediumNodes,
- SMESH_MesherHelper* FaceHelper = NULL,
- SMESH_ProxyMesh::Ptr ProxyMesh = SMESH_ProxyMesh::Ptr())
+ static StdMeshers_FaceSidePtr New (const TopoDS_Face& Face,
+ const std::list<TopoDS_Edge>& Edges,
+ SMESH_Mesh* Mesh,
+ const bool IsForward,
+ const bool IgnoreMediumNodes,
+ SMESH_MesherHelper* FaceHelper = NULL,
+ SMESH_ProxyMesh::Ptr ProxyMesh = SMESH_ProxyMesh::Ptr())
{ return StdMeshers_FaceSidePtr
( new StdMeshers_FaceSide( Face,Edges,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh ));
}
( new StdMeshers_FaceSide( Side,Node,Pnt2d1,Pnt2d2,C2d,UFirst,ULast ));
}
static StdMeshers_FaceSidePtr New (UVPtStructVec& theSideNodes,
- const TopoDS_Face& theFace = TopoDS_Face())
+ const TopoDS_Face& theFace = TopoDS_Face(),
+ const TopoDS_Edge& theEdge = TopoDS_Edge(),
+ SMESH_Mesh* theMesh = 0)
{
- return StdMeshers_FaceSidePtr( new StdMeshers_FaceSide( theSideNodes, theFace ));
+ return StdMeshers_FaceSidePtr( new StdMeshers_FaceSide( theSideNodes, theFace, theEdge, theMesh ));
}
/*!
virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
MapShapeNbElems& aResMap);
+ virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+ {
+ return IsApplicable( shape, toCheckAll );
+ }
static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
protected:
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Comment.hxx"
+#include "SMESH_ControlsDef.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Group.hxx"
#include "SMESH_Mesh.hxx"
SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
const TopoDS_Face& geomFace = TopoDS::Face( theShape );
- const double faceTol = helper.MaxTolerance( geomFace );
- const int shapeID = tgtMesh->ShapeToIndex( geomFace );
+ const double faceTol = helper.MaxTolerance( geomFace );
+ const int shapeID = tgtMesh->ShapeToIndex( geomFace );
const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
map<TLink, int>::iterator link2Nb;
double minGroupTol = Precision::Infinite();
+ SMESH::Controls::ElementsOnShape onEdgeClassifier;
+ if ( helper.HasSeam() )
+ {
+ TopoDS_Compound edgesCompound;
+ BRep_Builder builder;
+ builder.MakeCompound( edgesCompound );
+ for ( size_t iE = 0; iE < edges.size(); ++iE )
+ builder.Add( edgesCompound, edges[ iE ]);
+ onEdgeClassifier.SetShape( edgesCompound, SMDSAbs_Node );
+ }
+
// =========================
// Import faces from groups
// =========================
StdMeshers_Import_1D::TNodeNodeMap* n2n;
StdMeshers_Import_1D::TElemElemMap* e2e;
+ StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt;
+ pair< StdMeshers_Import_1D::TNodeNodeMap::iterator, bool > it_isnew;
vector<TopAbs_State> nodeState;
vector<const SMDS_MeshNode*> newNodes; // of a face
set <const SMDS_MeshNode*> bndNodes; // nodes classified ON
// S.VResolution( 0.1 * groupTol ));
const double clsfTol = BRep_Tool::Tolerance( geomFace );
- StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt;
- pair< StdMeshers_Import_1D::TNodeNodeMap::iterator, bool > it_isnew;
+ if ( helper.HasSeam() )
+ onEdgeClassifier.SetMesh( srcMesh->GetMeshDS() );
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
while ( srcElems->more() ) // loop on group contents
gp_XY uv( Precision::Infinite(), 0 );
isOut = ( !helper.CheckNodeUV( geomFace, *node, uv, groupTol, /*force=*/true ) ||
bndBox2d.IsOut( uv ));
+ //int iCoo;
if ( !isOut && !isIn ) // classify
{
classifier.Perform( geomFace, uv, clsfTol );
nodeState[i] = classifier.State();
isOut = ( nodeState[i] == TopAbs_OUT );
+ if ( isOut && helper.IsOnSeam( uv ) && onEdgeClassifier.IsSatisfy( (*node)->GetID() ))
+ {
+ // uv.SetCoord( iCoo, helper.GetOtherParam( uv.Coord( iCoo )));
+ // classifier.Perform( geomFace, uv, clsfTol );
+ // nodeState[i] = classifier.State();
+ // isOut = ( nodeState[i] == TopAbs_OUT );
+ nodeState[i] = TopAbs_ON;
+ isOut = false;
+ }
}
if ( !isOut ) // create a new node
{
}
if ( nodeState[i] == TopAbs_ON )
bndNodes.insert( *node );
- else
+ else if ( nodeState[i] != TopAbs_UNKNOWN )
isNodeIn[ newNode->GetID() ] = isIn = true;
}
}
if ( !(newNodes[i] = newNode ) || isOut )
break;
- }
+
+ } // loop on face nodes
if ( !newNodes.back() )
continue; // not all nodes of the face lie on theShape
proj.Perform( gc );
if ( !proj.IsDone() || proj.NbPoints() < 1 )
continue;
- Quantity_Parameter U,V;
+ Standard_Real U,V;
proj.LowerDistanceParameters(U,V);
gp_XY uv( U,V );
classifier.Perform( geomFace, uv, clsfTol );
medium = newNodes[i+nbCorners];
link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first;
++link2Nb->second;
- // if ( link2Nb->second == 1 )
- // {
- // // measure link length
- // double len2 = SMESH_TNodeXYZ( n1 ).SquareDistance( n2 );
- // if ( len2 < minGroupTol )
- // minGroupTol = len2;
- // }
}
- }
+ } // loop on group contents
+
// Remove OUT nodes from n2n map
for ( n2nIt = n2n->begin(); n2nIt != n2n->end(); )
if ( !n2nIt->second )
n2n->erase( n2nIt++ );
else
++n2nIt;
- }
+ } // loop on src groups
+
+ // remove free nodes created on EDGEs
+ {
+ set<const SMDS_MeshNode*>::iterator node = bndNodes.begin();
+ for ( ; node != bndNodes.end(); ++node )
+ {
+ n2nIt = n2n->find( *node );
+ const SMDS_MeshNode* newNode = n2nIt->second;
+ if ( newNode && newNode->NbInverseElements() == 0 )
+ {
+ tgtMesh->RemoveFreeNode( newNode, 0, false );
+ n2n->erase( n2nIt );
+ }
+ }
+ }
// ==========================================================
// Put nodes on geom edges and create edges on them;
#include <TopExp.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
#include <Standard_Failure.hxx>
-
-#ifdef NO_CAS_CATCH
#include <Standard_ErrorHandler.hxx>
-#endif
#include <Basics_Utils.hxx>
if( _convMode==0 )
{
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
val = pow( 10.0, val );
}
catch(Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
throw SALOME_Exception( LOCALIZED( "invalid value"));
return;
}
bool parsed_ok = true;
Handle( ExprIntrp_GenExp ) myExpr;
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
myExpr = ExprIntrp_GenExp::Create();
myExpr->Process( str.ToCString() );
} catch(Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
parsed_ok = false;
}
#include <Geom2d_Line.hxx>
#include <GeomLib_IsPlanarSurface.hxx>
#include <Geom_Curve.hxx>
+#include <Standard_ErrorHandler.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
algo->myProxyMesh.reset( new SMESH_ProxyMesh( *helper->GetMesh() ));
algo->myQuadList.clear();
+ algo->myHelper = 0;
if ( helper )
algo->_quadraticMesh = helper->GetIsQuadratic();
return nbSides;
}
+ //================================================================================
+ /*!
+ * \brief Set/get wire index to FaceQuadStruct
+ */
+ //================================================================================
+
+ void setWireIndex( TFaceQuadStructPtr& quad, int iWire )
+ {
+ quad->iSize = iWire;
+ }
+ int getWireIndex( const TFaceQuadStructPtr& quad )
+ {
+ return quad->iSize;
+ }
+
+ //================================================================================
+ /*!
+ * \brief Print Python commands adding given points to a mesh
+ */
+ //================================================================================
+
void pointsToPython(const std::vector<gp_XYZ>& p)
{
#ifdef _DEBUG_
//myProjectTriangles = false;
mySetErrorToSM = true; // to pass an error to a sub-mesh of a current solid or not
+ myPrevBottomSM = 0; // last treated bottom sub-mesh with a suitable algorithm
}
//================================================================================
const TopoDS_Shape& aShape,
SMESH_Hypothesis::Hypothesis_Status& aStatus)
{
- // Check shape geometry
-/* PAL16229
- aStatus = SMESH_Hypothesis::HYP_BAD_GEOMETRY;
-
- // find not quadrangle faces
- list< TopoDS_Shape > notQuadFaces;
- int nbEdge, nbWire, nbFace = 0;
- TopExp_Explorer exp( aShape, TopAbs_FACE );
- for ( ; exp.More(); exp.Next() ) {
- ++nbFace;
- const TopoDS_Shape& face = exp.Current();
- nbEdge = NSProjUtils::Count( face, TopAbs_EDGE, 0 );
- nbWire = NSProjUtils::Count( face, TopAbs_WIRE, 0 );
- if ( nbEdge!= 4 || nbWire!= 1 ) {
- if ( !notQuadFaces.empty() ) {
- if ( NSProjUtils::Count( notQuadFaces.back(), TopAbs_EDGE, 0 ) != nbEdge ||
- NSProjUtils::Count( notQuadFaces.back(), TopAbs_WIRE, 0 ) != nbWire )
- RETURN_BAD_RESULT("Different not quad faces");
- }
- notQuadFaces.push_back( face );
- }
- }
- if ( !notQuadFaces.empty() )
- {
- if ( notQuadFaces.size() != 2 )
- RETURN_BAD_RESULT("Bad nb not quad faces: " << notQuadFaces.size());
-
- // check total nb faces
- nbEdge = NSProjUtils::Count( notQuadFaces.back(), TopAbs_EDGE, 0 );
- if ( nbFace != nbEdge + 2 )
- RETURN_BAD_RESULT("Bad nb of faces: " << nbFace << " but must be " << nbEdge + 2);
- }
-*/
// no hypothesis
aStatus = SMESH_Hypothesis::HYP_OK;
return true;
{
SMESH_MesherHelper helper( theMesh );
myHelper = &helper;
+ myPrevBottomSM = 0;
int nbSolids = helper.Count( theShape, TopAbs_SOLID, /*skipSame=*/false );
if ( nbSolids < 1 )
list< TopoDS_Edge >::iterator edge = thePrism.myBottomEdges.begin();
std::list< int >::iterator nbE = thePrism.myNbEdgesInWires.begin();
std::list< int > nbQuadsPerWire;
- int iE = 0;
+ int iE = 0, iWire = 0;
while ( edge != thePrism.myBottomEdges.end() )
{
++iE;
return toSM( error(TCom("Composite 'horizontal' edges are not supported")));
}
if ( faceMap.Add( face ))
+ {
+ setWireIndex( quadList.back(), iWire ); // for use in makeQuadsForOutInProjection()
thePrism.myWallQuads.push_back( quadList );
+ }
break;
}
}
if ( iE == *nbE )
{
iE = 0;
+ ++iWire;
++nbE;
int nbQuadPrev = std::accumulate( nbQuadsPerWire.begin(), nbQuadsPerWire.end(), 0 );
nbQuadsPerWire.push_back( thePrism.myWallQuads.size() - nbQuadPrev );
return toSM( error( SMESH_ComputeError::New(COMPERR_CANCELED)));
// Assure the bottom is meshed
- SMESH_subMesh * botSM = myHelper->GetMesh()->GetSubMesh( thePrism.myBottom );
- if (( botSM->IsEmpty() ) &&
- ( ! botSM->GetAlgo() ||
- ! _gen->Compute( *botSM->GetFather(), botSM->GetSubShape(), /*shapeOnly=*/true )))
- return error( COMPERR_BAD_INPUT_MESH,
- TCom( "No mesher defined to compute the base face #")
- << shapeID( thePrism.myBottom ));
+ if ( !computeBase( thePrism ))
+ return false;
// Make all side FACEs of thePrism meshed with quads
if ( !computeWalls( thePrism ))
// else if ( !trsf.empty() )
// bottomToTopTrsf = trsf.back();
- // To compute coordinates of a node inside a block, it is necessary to know
+ // To compute coordinates of a node inside a block using "block approach",
+ // it is necessary to know
// 1. normalized parameters of the node by which
// 2. coordinates of node projections on all block sub-shapes are computed
// Projections on the top and bottom faces are taken from nodes existing
// on these faces; find correspondence between bottom and top nodes
- myUseBlock = false;
+ myUseBlock = false; // is set to true if projection is done using "block approach"
myBotToColumnMap.clear();
if ( !assocOrProjBottom2Top( bottomToTopTrsf, thePrism ) ) // it also fills myBotToColumnMap
return false;
// Create nodes inside the block
- // use transformation (issue 0020680, IPAL0052499)
- StdMeshers_Sweeper sweeper;
- double tol;
- bool allowHighBndError;
-
if ( !myUseBlock )
{
+ // use transformation (issue 0020680, IPAL0052499) or a "straight line" approach
+ StdMeshers_Sweeper sweeper;
+ sweeper.myHelper = myHelper;
+ sweeper.myBotFace = thePrism.myBottom;
+ sweeper.myTopFace = thePrism.myTop;
+
// load boundary nodes into sweeper
bool dummy;
+ std::set< const SMDS_MeshNode* > usedEndNodes;
list< TopoDS_Edge >::const_iterator edge = thePrism.myBottomEdges.begin();
for ( ; edge != thePrism.myBottomEdges.end(); ++edge )
{
int edgeID = meshDS->ShapeToIndex( *edge );
TParam2ColumnMap* u2col = const_cast<TParam2ColumnMap*>
( myBlock.GetParam2ColumnMap( edgeID, dummy ));
- TParam2ColumnMap::iterator u2colIt = u2col->begin();
- for ( ; u2colIt != u2col->end(); ++u2colIt )
+
+ TParam2ColumnMap::iterator u2colIt = u2col->begin(), u2colEnd = u2col->end();
+ const SMDS_MeshNode* n0 = u2colIt->second[0];
+ const SMDS_MeshNode* n1 = u2col->rbegin()->second[0];
+ if ( !usedEndNodes.insert ( n0 ).second ) ++u2colIt;
+ if ( !usedEndNodes.insert ( n1 ).second ) --u2colEnd;
+
+ for ( ; u2colIt != u2colEnd; ++u2colIt )
sweeper.myBndColumns.push_back( & u2colIt->second );
}
- // load node columns inside the bottom face
+ // load node columns inside the bottom FACE
+ sweeper.myIntColumns.reserve( myBotToColumnMap.size() );
TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin();
for ( ; bot_column != myBotToColumnMap.end(); ++bot_column )
sweeper.myIntColumns.push_back( & bot_column->second );
- tol = getSweepTolerance( thePrism );
- allowHighBndError = !isSimpleBottom( thePrism );
- }
+ myHelper->SetElementsOnShape( true );
- if ( !myUseBlock && sweeper.ComputeNodes( *myHelper, tol, allowHighBndError ))
- {
+ // If all "vertical" EDGEs are straight, then all nodes of an internal node column
+ // are located on a line connecting the top node and the bottom node.
+ bool isStrightColunm = allVerticalEdgesStraight( thePrism );
+ if ( !isStrightColunm )
+ {
+ double tol = getSweepTolerance( thePrism );
+ bool allowHighBndError = !isSimpleBottom( thePrism );
+ myUseBlock = !sweeper.ComputeNodesByTrsf( tol, allowHighBndError );
+ }
+ else if ( sweeper.CheckSameZ() )
+ {
+ myUseBlock = !sweeper.ComputeNodesOnStraightSameZ();
+ }
+ else
+ {
+ myUseBlock = !sweeper.ComputeNodesOnStraight();
+ }
+ myHelper->SetElementsOnShape( false );
}
- else // use block approach
+
+ if ( myUseBlock ) // use block approach
{
// loop on nodes inside the bottom face
Prism_3D::TNode prevBNode;
// column nodes; middle part of the column are zero pointers
TNodeColumn& column = bot_column->second;
+ // check if a column is already computed using non-block approach
+ size_t i;
+ for ( i = 0; i < column.size(); ++i )
+ if ( !column[ i ])
+ break;
+ if ( i == column.size() )
+ continue; // all nodes created
+
gp_XYZ botParams, topParams;
if ( !tBotNode.HasParams() )
{
return true;
}
+//=======================================================================
+//function : computeBase
+//purpose : Compute the base face of a prism
+//=======================================================================
+
+bool StdMeshers_Prism_3D::computeBase(const Prism_3D::TPrismTopo& thePrism)
+{
+ SMESH_Mesh* mesh = myHelper->GetMesh();
+ SMESH_subMesh* botSM = mesh->GetSubMesh( thePrism.myBottom );
+ if (( botSM->IsEmpty() ) &&
+ ( ! botSM->GetAlgo() ||
+ ! _gen->Compute( *botSM->GetFather(), botSM->GetSubShape(), /*shapeOnly=*/true )))
+ {
+ // find any applicable algorithm assigned to any FACE of the main shape
+ std::vector< TopoDS_Shape > faces;
+ if ( myPrevBottomSM &&
+ myPrevBottomSM->GetAlgo()->IsApplicableToShape( thePrism.myBottom, /*all=*/false ))
+ faces.push_back( myPrevBottomSM->GetSubShape() );
+
+ TopExp_Explorer faceIt( mesh->GetShapeToMesh(), TopAbs_FACE );
+ for ( ; faceIt.More(); faceIt.Next() )
+ faces.push_back( faceIt.Current() );
+
+ faces.push_back( TopoDS_Shape() ); // to try quadrangle algorithm
+
+ SMESH_Algo* algo = 0;
+ for ( size_t i = 0; i < faces.size() && botSM->IsEmpty(); ++i )
+ {
+ if ( faces[i].IsNull() ) algo = TQuadrangleAlgo::instance( this, myHelper );
+ else algo = mesh->GetSubMesh( faces[i] )->GetAlgo();
+ if ( algo && algo->IsApplicableToShape( thePrism.myBottom, /*all=*/false ))
+ {
+ // try to compute the bottom FACE
+ if ( algo->NeedDiscreteBoundary() )
+ {
+ // compute sub-shapes
+ SMESH_subMeshIteratorPtr smIt = botSM->getDependsOnIterator(false,false);
+ bool subOK = true;
+ while ( smIt->more() && subOK )
+ {
+ SMESH_subMesh* sub = smIt->next();
+ sub->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+ subOK = sub->IsMeshComputed();
+ }
+ if ( !subOK )
+ continue;
+ }
+ try {
+ OCC_CATCH_SIGNALS;
+ algo->InitComputeError();
+ algo->Compute( *mesh, botSM->GetSubShape() );
+ }
+ catch (...) {
+ }
+ }
+ }
+ }
+
+ if ( botSM->IsEmpty() )
+ return error( COMPERR_BAD_INPUT_MESH,
+ TCom( "No mesher defined to compute the base face #")
+ << shapeID( thePrism.myBottom ));
+
+ if ( botSM->GetAlgo() )
+ myPrevBottomSM = botSM;
+
+ return true;
+}
+
//=======================================================================
//function : computeWalls
//purpose : Compute 2D mesh on walls FACEs of a prism
for ( ; quad != thePrism.myWallQuads[iW].end(); ++quad )
{
StdMeshers_FaceSidePtr lftSide = (*quad)->side[ QUAD_LEFT_SIDE ];
+ lftSide->Reverse(); // to go up
for ( int i = 0; i < lftSide->NbEdges(); ++i )
{
++wgt[ iW ];
for ( size_t iW = 0; iW != nbWalls; ++iW )
wgt2quad.insert( make_pair( wgt[ iW ], iW ));
+ // artificial quads to do outer <-> inner wall projection
+ std::map< int, FaceQuadStruct > iW2oiQuads;
+ std::map< int, FaceQuadStruct >::iterator w2oiq;
+ makeQuadsForOutInProjection( thePrism, wgt2quad, iW2oiQuads );
+
// Project 'vertical' EDGEs, from left to right
multimap< int, int >::reverse_iterator w2q = wgt2quad.rbegin();
for ( ; w2q != wgt2quad.rend(); ++w2q )
if ( swapLeftRight )
std::swap( lftSide, rgtSide );
+ bool isArtificialQuad = (( w2oiq = iW2oiQuads.find( iW )) != iW2oiQuads.end() );
+ if ( isArtificialQuad )
+ {
+ // reset sides to perform the outer <-> inner projection
+ FaceQuadStruct& oiQuad = w2oiq->second;
+ rgtSide = oiQuad.side[ QUAD_RIGHT_SIDE ];
+ lftSide = oiQuad.side[ QUAD_LEFT_SIDE ];
+ iW2oiQuads.erase( w2oiq );
+ }
+
// assure that all the source (left) EDGEs are meshed
int nbSrcSegments = 0;
for ( int i = 0; i < lftSide->NbEdges(); ++i )
{
+ if ( isArtificialQuad )
+ {
+ nbSrcSegments = lftSide->NbPoints()-1;
+ continue;
+ }
const TopoDS_Edge& srcE = lftSide->Edge(i);
SMESH_subMesh* srcSM = mesh->GetSubMesh( srcE );
if ( !srcSM->IsMeshComputed() ) {
const UVPtStructVec& srcNodeStr = lftSide->GetUVPtStruct();
if ( srcNodeStr.size() == 0 )
return toSM( error( TCom("Invalid node positions on edge #") <<
- shapeID( lftSide->Edge(0) )));
+ lftSide->EdgeID(0) ));
vector< SMDS_MeshNode* > newNodes( srcNodeStr.size() );
for ( int is2ndV = 0; is2ndV < 2; ++is2ndV )
{
TopoDS_Vertex v = myHelper->IthVertex( is2ndV, E );
mesh->GetSubMesh( v )->ComputeStateEngine( SMESH_subMesh::COMPUTE );
const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, meshDS );
- newNodes[ is2ndV ? 0 : newNodes.size()-1 ] = (SMDS_MeshNode*) n;
+ newNodes[ is2ndV ? newNodes.size()-1 : 0 ] = (SMDS_MeshNode*) n;
}
// compute nodes on target EDGEs
DBGOUT( "COMPUTE V edge (proj) " << shapeID( lftSide->Edge(0)));
- rgtSide->Reverse(); // direct it same as the lftSide
+ //rgtSide->Reverse(); // direct it same as the lftSide
myHelper->SetElementsOnShape( false ); // myHelper holds the prism shape
TopoDS_Edge tgtEdge;
for ( size_t iN = 1; iN < srcNodeStr.size()-1; ++iN ) // add nodes
}
//=======================================================================
-/*!
- * \brief Returns a source EDGE of propagation to a given EDGE
- */
+//function : findPropagationSource
+//purpose : Returns a source EDGE of propagation to a given EDGE
//=======================================================================
TopoDS_Edge StdMeshers_Prism_3D::findPropagationSource( const TopoDS_Edge& E )
return TopoDS_Edge();
}
+//=======================================================================
+//function : makeQuadsForOutInProjection
+//purpose : Create artificial wall quads for vertical projection between
+// the outer and inner walls
+//=======================================================================
+
+void StdMeshers_Prism_3D::makeQuadsForOutInProjection( const Prism_3D::TPrismTopo& thePrism,
+ multimap< int, int >& wgt2quad,
+ map< int, FaceQuadStruct >& iQ2oiQuads)
+{
+ if ( thePrism.NbWires() <= 1 )
+ return;
+
+ std::set< int > doneWires; // processed wires
+
+ SMESH_Mesh* mesh = myHelper->GetMesh();
+ const bool isForward = true;
+ const bool skipMedium = myHelper->GetIsQuadratic();
+
+ // make a source side for all projections
+
+ multimap< int, int >::reverse_iterator w2q = wgt2quad.rbegin();
+ const int iQuad = w2q->second;
+ const int iWire = getWireIndex( thePrism.myWallQuads[ iQuad ].front() );
+ doneWires.insert( iWire );
+
+ UVPtStructVec srcNodes;
+
+ Prism_3D::TQuadList::const_iterator quad = thePrism.myWallQuads[ iQuad ].begin();
+ for ( ; quad != thePrism.myWallQuads[ iQuad ].end(); ++quad )
+ {
+ StdMeshers_FaceSidePtr lftSide = (*quad)->side[ QUAD_LEFT_SIDE ];
+
+ // assure that all the source (left) EDGEs are meshed
+ for ( int i = 0; i < lftSide->NbEdges(); ++i )
+ {
+ const TopoDS_Edge& srcE = lftSide->Edge(i);
+ SMESH_subMesh* srcSM = mesh->GetSubMesh( srcE );
+ if ( !srcSM->IsMeshComputed() ) {
+ srcSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE );
+ srcSM->ComputeStateEngine ( SMESH_subMesh::COMPUTE );
+ }
+ if ( !srcSM->IsMeshComputed() )
+ return;
+ }
+ const UVPtStructVec& subNodes = lftSide->GetUVPtStruct();
+ UVPtStructVec::const_iterator subBeg = subNodes.begin(), subEnd = subNodes.end();
+ if ( !srcNodes.empty() ) ++subBeg;
+ srcNodes.insert( srcNodes.end(), subBeg, subEnd );
+ }
+ StdMeshers_FaceSidePtr srcSide = StdMeshers_FaceSide::New( srcNodes );
+
+ // make the quads
+
+ list< TopoDS_Edge > sideEdges;
+ TopoDS_Face face;
+ for ( ++w2q; w2q != wgt2quad.rend(); ++w2q )
+ {
+ const int iQuad = w2q->second;
+ const Prism_3D::TQuadList& quads = thePrism.myWallQuads[ iQuad ];
+ const int iWire = getWireIndex( quads.front() );
+ if ( !doneWires.insert( iWire ).second )
+ continue;
+
+ sideEdges.clear();
+ for ( quad = quads.begin(); quad != quads.end(); ++quad )
+ {
+ StdMeshers_FaceSidePtr lftSide = (*quad)->side[ QUAD_LEFT_SIDE ];
+ for ( int i = 0; i < lftSide->NbEdges(); ++i )
+ sideEdges.push_back( lftSide->Edge( i ));
+ face = lftSide->Face();
+ }
+ StdMeshers_FaceSidePtr tgtSide =
+ StdMeshers_FaceSide::New( face, sideEdges, mesh, isForward, skipMedium, myHelper );
+
+ FaceQuadStruct& newQuad = iQ2oiQuads[ iQuad ];
+ newQuad.side.resize( 4 );
+ newQuad.side[ QUAD_LEFT_SIDE ] = srcSide;
+ newQuad.side[ QUAD_RIGHT_SIDE ] = tgtSide;
+
+ wgt2quad.insert( *w2q ); // to process this quad after processing the newQuad
+ }
+}
+
//=======================================================================
//function : Evaluate
-//purpose :
+//purpose :
//=======================================================================
bool StdMeshers_Prism_3D::Evaluate(SMESH_Mesh& theMesh,
TNode2ColumnMap::iterator bN_col =
myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first;
TNodeColumn & column = bN_col->second;
- column.resize( zSize );
+ column.resize( zSize, 0 );
column.front() = botNode;
column.back() = topNode;
}
// Check the projected mesh
- if ( thePrism.myNbEdgesInWires.size() > 1 && // there are holes
+ if ( thePrism.NbWires() > 1 && // there are holes
topHelper.IsDistorted2D( topSM, /*checkUV=*/false ))
{
SMESH_MeshEditor editor( topHelper.GetMesh() );
//=======================================================================
//function : isSimpleQuad
-//purpose : check if the bottom FACE is meshable with nice qudrangles,
+//purpose : check if the bottom FACE is meshable with nice quadrangles,
// if so the block aproach can work rather fast.
// This is a temporary mean caused by problems in StdMeshers_Sweeper
//=======================================================================
bool StdMeshers_Prism_3D::isSimpleBottom( const Prism_3D::TPrismTopo& thePrism )
{
- if ( thePrism.myBottomEdges.size() != 4 )
+ if ( thePrism.myNbEdgesInWires.front() != 4 )
return false;
// analyse angles between edges
return true;
}
+//=======================================================================
+//function : allVerticalEdgesStraight
+//purpose : Defines if all "vertical" EDGEs are straight
+//=======================================================================
+
+bool StdMeshers_Prism_3D::allVerticalEdgesStraight( const Prism_3D::TPrismTopo& thePrism )
+{
+ for ( size_t i = 0; i < thePrism.myWallQuads.size(); ++i )
+ {
+ const Prism_3D::TQuadList& quads = thePrism.myWallQuads[i];
+ Prism_3D::TQuadList::const_iterator quadIt = quads.begin();
+ TopoDS_Edge prevQuadEdge;
+ for ( ; quadIt != quads.end(); ++quadIt )
+ {
+ StdMeshers_FaceSidePtr rightSide = (*quadIt)->side[ QUAD_RIGHT_SIDE ];
+
+ if ( !prevQuadEdge.IsNull() &&
+ !SMESH_Algo::IsContinuous( rightSide->Edge( 0 ), prevQuadEdge ))
+ return false;
+
+ for ( int iE = 0; iE < rightSide->NbEdges(); ++iE )
+ {
+ const TopoDS_Edge & rightE = rightSide->Edge( iE );
+ if ( !SMESH_Algo::IsStraight( rightE, /*degenResult=*/true ))
+ return false;
+
+ if ( iE > 0 &&
+ !SMESH_Algo::IsContinuous( rightSide->Edge( iE-1 ), rightE ))
+ return false;
+
+ prevQuadEdge = rightE;
+ }
+ }
+ }
+ return true;
+}
+
//=======================================================================
//function : project2dMesh
//purpose : Project mesh faces from a source FACE of one prism (theSrcFace)
if ( !myHelper->LoadNodeColumns( faceColumns, (*quad)->face, quadBot, meshDS ))
return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ")
<< "on a side face #" << MeshDS()->ShapeToIndex( (*quad)->face ));
-
- if ( !faceColumns.empty() && (int)faceColumns.begin()->second.size() != VerticalSize() )
- return error(COMPERR_BAD_INPUT_MESH, "Different 'vertical' discretization");
}
+ if ( !faceColumns.empty() && (int)faceColumns.begin()->second.size() != VerticalSize() )
+ return error(COMPERR_BAD_INPUT_MESH, "Different 'vertical' discretization");
+
// edge columns
int id = MeshDS()->ShapeToIndex( *edgeIt );
bool isForward = true; // meaningless for intenal wires
const vector< gp_XYZ >& toBndPoints,
const vector< gp_XYZ >& fromIntPoints,
vector< gp_XYZ >& toIntPoints,
+ const double r,
NSProjUtils::TrsfFinder3D& trsf,
vector< gp_XYZ > * bndError)
{
(*bndError)[ iP ] = toBndPoints[ iP ] - fromTrsf;
}
}
- return true;
-}
-
-//================================================================================
-/*!
- * \brief Add boundary error to ineternal points
- */
-//================================================================================
-void StdMeshers_Sweeper::applyBoundaryError(const vector< gp_XYZ >& bndPoints,
- const vector< gp_XYZ >& bndError1,
- const vector< gp_XYZ >& bndError2,
- const double r,
- vector< gp_XYZ >& intPoints,
- vector< double >& int2BndDist)
-{
- // fix each internal point
- const double eps = 1e-100;
- for ( size_t iP = 0; iP < intPoints.size(); ++iP )
+ // apply boundary error
+ if ( bndError && toIntPoints.size() == myTopBotTriangles.size() )
{
- gp_XYZ & intPnt = intPoints[ iP ];
-
- // compute distance from intPnt to each boundary node
- double int2BndDistSum = 0;
- for ( size_t iBnd = 0; iBnd < bndPoints.size(); ++iBnd )
- {
- int2BndDist[ iBnd ] = 1 / (( intPnt - bndPoints[ iBnd ]).SquareModulus() + eps );
- int2BndDistSum += int2BndDist[ iBnd ];
- }
-
- // apply bndError
- for ( size_t iBnd = 0; iBnd < bndPoints.size(); ++iBnd )
+ for ( size_t iP = 0; iP < toIntPoints.size(); ++iP )
{
- intPnt += bndError1[ iBnd ] * ( 1 - r ) * int2BndDist[ iBnd ] / int2BndDistSum;
- intPnt += bndError2[ iBnd ] * r * int2BndDist[ iBnd ] / int2BndDistSum;
+ const TopBotTriangles& tbTrias = myTopBotTriangles[ iP ];
+ for ( int i = 0; i < 3; ++i ) // boundary errors at 3 triangle nodes
+ {
+ toIntPoints[ iP ] +=
+ ( (*bndError)[ tbTrias.myBotTriaNodes[i] ] * tbTrias.myBotBC[i] * ( 1 - r ) +
+ (*bndError)[ tbTrias.myTopTriaNodes[i] ] * tbTrias.myTopBC[i] * ( r ));
+ }
}
}
+
+ return true;
}
//================================================================================
/*!
- * \brief Creates internal nodes of the prism
+ * \brief Create internal nodes of the prism by computing an affine transformation
+ * from layer to layer
*/
//================================================================================
-bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper,
- const double tol,
- const bool allowHighBndError)
+bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
+ const bool allowHighBndError)
{
const size_t zSize = myBndColumns[0]->size();
const size_t zSrc = 0, zTgt = zSize-1;
intPntsOfLayer[ zTgt ][ iP ] = intPoint( iP, zTgt );
}
+ // for each internal column find boundary nodes whose error to use for correction
+ prepareTopBotDelaunay();
+ bool isErrorCorrectable = findDelaunayTriangles();
+
// compute coordinates of internal nodes by projecting (transfroming) src and tgt
// nodes towards the central layer
}
if (! projectIntPoints( fromSrcBndPnts, toSrcBndPnts,
intPntsOfLayer[ zS-1 ], intPntsOfLayer[ zS ],
+ zS / ( zSize - 1.),
trsfOfLayer [ zS-1 ], & bndError[ zS-1 ]))
return false;
if (! projectIntPoints( fromTgtBndPnts, toTgtBndPnts,
intPntsOfLayer[ zT+1 ], intPntsOfLayer[ zT ],
+ zT / ( zSize - 1.),
trsfOfLayer [ zT+1 ], & bndError[ zT+1 ]))
return false;
fromSrcBndPnts.swap( toSrcBndPnts );
}
+ // Evaluate an error of boundary points
+
+ if ( !isErrorCorrectable && !allowHighBndError )
+ {
+ for ( size_t iP = 0; iP < myBndColumns.size(); ++iP )
+ {
+ double sumError = 0;
+ for ( size_t z = 1; z < zS; ++z ) // loop on layers
+ sumError += ( bndError[ z-1 ][ iP ].Modulus() +
+ bndError[ zSize-z ][ iP ].Modulus() );
+
+ if ( sumError > tol )
+ return false;
+ }
+ }
+
// Compute two projections of internal points to the central layer
// in order to evaluate an error of internal points
}
if (! projectIntPoints( fromSrcBndPnts, toSrcBndPnts,
intPntsOfLayer[ zS-1 ], centerSrcIntPnts,
+ zS / ( zSize - 1.),
trsfOfLayer [ zS-1 ], & bndError[ zS-1 ]))
return false;
if (! projectIntPoints( fromTgtBndPnts, toTgtBndPnts,
intPntsOfLayer[ zT+1 ], centerTgtIntPnts,
+ zT / ( zSize - 1.),
trsfOfLayer [ zT+1 ], & bndError[ zT+1 ]))
return false;
(intPntsOfLayer[ zS-1 ][ iP ] - centerTgtIntPnts[ iP ]).SquareModulus() < tol*tol;
}
- // Evaluate an error of boundary points
-
- bool bndErrorIsSmall = true;
- for ( size_t iP = 0; ( iP < myBndColumns.size() && bndErrorIsSmall ); ++iP )
- {
- double sumError = 0;
- for ( size_t z = 1; z < zS; ++z ) // loop on layers
- sumError += ( bndError[ z-1 ][ iP ].Modulus() +
- bndError[ zSize-z ][ iP ].Modulus() );
-
- bndErrorIsSmall = ( sumError < tol );
- }
-
- if ( !bndErrorIsSmall && !allowHighBndError )
- return false;
-
// compute final points on the central layer
- std::vector< double > int2BndDist( myBndColumns.size() ); // work array of applyBoundaryError()
double r = zS / ( zSize - 1.);
if ( zS == zT )
{
intPntsOfLayer[ zS ][ iP ] =
( 1 - r ) * centerSrcIntPnts[ iP ] + r * centerTgtIntPnts[ iP ];
}
- if ( !bndErrorIsSmall )
- {
- applyBoundaryError( toSrcBndPnts, bndError[ zS-1 ], bndError[ zS+1 ], r,
- intPntsOfLayer[ zS ], int2BndDist );
- }
}
else
{
intPntsOfLayer[ zT ][ iP ] =
r * intPntsOfLayer[ zT ][ iP ] + ( 1 - r ) * centerTgtIntPnts[ iP ];
}
- if ( !bndErrorIsSmall )
- {
- applyBoundaryError( toSrcBndPnts, bndError[ zS-1 ], bndError[ zS+1 ], r,
- intPntsOfLayer[ zS ], int2BndDist );
- applyBoundaryError( toTgtBndPnts, bndError[ zT+1 ], bndError[ zT-1 ], r,
- intPntsOfLayer[ zT ], int2BndDist );
- }
}
- centerIntErrorIsSmall = true; // 3D_mesh_Extrusion_00/A3
- bndErrorIsSmall = true;
if ( !centerIntErrorIsSmall )
{
// Compensate the central error; continue adding projection
}
projectIntPoints( fromSrcBndPnts, toSrcBndPnts,
fromSrcIntPnts, toSrcIntPnts,
+ zS / ( zSize - 1.),
trsfOfLayer[ zS+1 ], & srcBndError );
projectIntPoints( fromTgtBndPnts, toTgtBndPnts,
fromTgtIntPnts, toTgtIntPnts,
+ zT / ( zSize - 1.),
trsfOfLayer[ zT-1 ], & tgtBndError );
// if ( zS == zTgt - 1 )
zTIntPnts[ iP ] = r * zTIntPnts[ iP ] + ( 1 - r ) * toTgtIntPnts[ iP ];
}
- // compensate bnd error
- if ( !bndErrorIsSmall )
- {
- applyBoundaryError( toSrcBndPnts, srcBndError, bndError[ zS+1 ], r,
- intPntsOfLayer[ zS ], int2BndDist );
- applyBoundaryError( toTgtBndPnts, tgtBndError, bndError[ zT-1 ], r,
- intPntsOfLayer[ zT ], int2BndDist );
- }
-
fromSrcBndPnts.swap( toSrcBndPnts );
fromSrcIntPnts.swap( toSrcIntPnts );
fromTgtBndPnts.swap( toTgtBndPnts );
}
} // if ( !centerIntErrorIsSmall )
- else if ( !bndErrorIsSmall )
- {
- zS = zSrc + 1;
- zT = zTgt - 1;
- for ( ; zS < zT; ++zS, --zT ) // vertical loop on layers
- {
- for ( size_t iP = 0; iP < myBndColumns.size(); ++iP )
- {
- toSrcBndPnts[ iP ] = bndPoint( iP, zS );
- toTgtBndPnts[ iP ] = bndPoint( iP, zT );
- }
- // compensate bnd error
- applyBoundaryError( toSrcBndPnts, bndError[ zS-1 ], bndError[ zS-1 ], 0.5,
- intPntsOfLayer[ zS ], int2BndDist );
- applyBoundaryError( toTgtBndPnts, bndError[ zT+1 ], bndError[ zT+1 ], 0.5,
- intPntsOfLayer[ zT ], int2BndDist );
- }
- }
- // cout << "centerIntErrorIsSmall = " << centerIntErrorIsSmall<< endl;
- // cout << "bndErrorIsSmall = " << bndErrorIsSmall<< endl;
+ //cout << "centerIntErrorIsSmall = " << centerIntErrorIsSmall<< endl;
// Create nodes
for ( size_t iP = 0; iP < myIntColumns.size(); ++iP )
for ( size_t z = zSrc + 1; z < zTgt; ++z ) // vertical loop on layers
{
const gp_XYZ & xyz = intPntsOfLayer[ z ][ iP ];
- if ( !( nodeCol[ z ] = helper.AddNode( xyz.X(), xyz.Y(), xyz.Z() )))
+ if ( !( nodeCol[ z ] = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z() )))
return false;
}
}
return true;
}
+
+//================================================================================
+/*!
+ * \brief Check if all nodes of each layers have same logical Z
+ */
+//================================================================================
+
+bool StdMeshers_Sweeper::CheckSameZ()
+{
+ myZColumns.resize( myBndColumns.size() );
+ fillZColumn( myZColumns[0], *myBndColumns[0] );
+
+ bool sameZ = true;
+ const double tol = 0.1 * 1./ myBndColumns[0]->size();
+
+ // check columns based on VERTEXes
+
+ vector< int > vertexIndex;
+ vertexIndex.push_back( 0 );
+ for ( size_t iC = 1; iC < myBndColumns.size() && sameZ; ++iC )
+ {
+ if ( myBndColumns[iC]->front()->GetPosition()->GetDim() > 0 )
+ continue; // not on VERTEX
+
+ vertexIndex.push_back( iC );
+ fillZColumn( myZColumns[iC], *myBndColumns[iC] );
+
+ for ( size_t iZ = 0; iZ < myZColumns[0].size() && sameZ; ++iZ )
+ sameZ = ( Abs( myZColumns[0][iZ] - myZColumns[iC][iZ]) < tol );
+ }
+
+ // check columns based on EDGEs, one per EDGE
+
+ for ( size_t i = 1; i < vertexIndex.size() && sameZ; ++i )
+ {
+ if ( vertexIndex[i] - vertexIndex[i-1] < 2 )
+ continue;
+
+ int iC = ( vertexIndex[i] + vertexIndex[i-1] ) / 2;
+ fillZColumn( myZColumns[iC], *myBndColumns[iC] );
+
+ for ( size_t iZ = 0; iZ < myZColumns[0].size() && sameZ; ++iZ )
+ sameZ = ( Abs( myZColumns[0][iZ] - myZColumns[iC][iZ]) < tol );
+ }
+
+ if ( sameZ )
+ {
+ myZColumns.resize(1);
+ }
+ else
+ {
+ for ( size_t iC = 1; iC < myBndColumns.size(); ++iC )
+ fillZColumn( myZColumns[iC], *myBndColumns[iC] );
+ }
+
+ return sameZ;
+}
+
+//================================================================================
+/*!
+ * \brief Create internal nodes of the prism all located on straight lines with
+ * the same distribution along the lines.
+ */
+//================================================================================
+
+bool StdMeshers_Sweeper::ComputeNodesOnStraightSameZ()
+{
+ TZColumn& z = myZColumns[0];
+
+ for ( size_t i = 0; i < myIntColumns.size(); ++i )
+ {
+ TNodeColumn& nodes = *myIntColumns[i];
+ SMESH_NodeXYZ n0( nodes[0] ), n1( nodes.back() );
+
+ for ( size_t iZ = 0; iZ < z.size(); ++iZ )
+ {
+ gp_XYZ p = n0 * ( 1 - z[iZ] ) + n1 * z[iZ];
+ nodes[ iZ+1 ] = myHelper->AddNode( p.X(), p.Y(), p.Z() );
+ }
+ }
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Create internal nodes of the prism all located on straight lines with
+ * different distributions along the lines.
+ */
+//================================================================================
+
+bool StdMeshers_Sweeper::ComputeNodesOnStraight()
+{
+ prepareTopBotDelaunay();
+
+ const SMDS_MeshNode *botNode, *topNode;
+ const BRepMesh_Triangle *topTria;
+ double botBC[3], topBC[3]; // barycentric coordinates
+ int botTriaNodes[3], topTriaNodes[3];
+ bool checkUV = true;
+
+ int nbInternalNodes = myIntColumns.size();
+ myBotDelaunay->InitTraversal( nbInternalNodes );
+
+ while (( botNode = myBotDelaunay->NextNode( botBC, botTriaNodes )))
+ {
+ TNodeColumn* column = myIntColumns[ myNodeID2ColID( botNode->GetID() )];
+
+ // find a Delaunay triangle containing the topNode
+ topNode = column->back();
+ gp_XY topUV = myHelper->GetNodeUV( myTopFace, topNode, NULL, &checkUV );
+ // get a starting triangle basing on that top and bot boundary nodes have same index
+ topTria = myTopDelaunay->GetTriangleNear( botTriaNodes[0] );
+ topTria = myTopDelaunay->FindTriangle( topUV, topTria, topBC, topTriaNodes );
+ if ( !topTria )
+ return false;
+
+ // create nodes along a line
+ SMESH_NodeXYZ botP( botNode ), topP( topNode );
+ for ( size_t iZ = 0; iZ < myZColumns[0].size(); ++iZ )
+ {
+ // use barycentric coordinates as weight of Z of boundary columns
+ double botZ = 0, topZ = 0;
+ for ( int i = 0; i < 3; ++i )
+ {
+ botZ += botBC[i] * myZColumns[ botTriaNodes[i] ][ iZ ];
+ topZ += topBC[i] * myZColumns[ topTriaNodes[i] ][ iZ ];
+ }
+ double rZ = double( iZ + 1 ) / ( myZColumns[0].size() + 1 );
+ double z = botZ * ( 1 - rZ ) + topZ * rZ;
+ gp_XYZ p = botP * ( 1 - z ) + topP * z;
+ (*column)[ iZ+1 ] = myHelper->AddNode( p.X(), p.Y(), p.Z() );
+ }
+ }
+
+ return myBotDelaunay->NbVisitedNodes() == nbInternalNodes;
+}
+
+//================================================================================
+/*!
+ * \brief Compute Z of nodes of a straight column
+ */
+//================================================================================
+
+void StdMeshers_Sweeper::fillZColumn( TZColumn& zColumn,
+ TNodeColumn& nodes )
+{
+ if ( zColumn.size() == nodes.size() - 2 )
+ return;
+
+ gp_Pnt p0 = SMESH_NodeXYZ( nodes[0] );
+ gp_Vec line( p0, SMESH_NodeXYZ( nodes.back() ));
+ double len2 = line.SquareMagnitude();
+
+ zColumn.resize( nodes.size() - 2 );
+ for ( size_t i = 0; i < zColumn.size(); ++i )
+ {
+ gp_Vec vec( p0, SMESH_NodeXYZ( nodes[ i+1] ));
+ zColumn[i] = ( line * vec ) / len2; // param [0,1] on the line
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Initialize *Delaunay members
+ */
+//================================================================================
+
+void StdMeshers_Sweeper::prepareTopBotDelaunay()
+{
+ UVPtStructVec botUV( myBndColumns.size() );
+ UVPtStructVec topUV( myBndColumns.size() );
+ for ( size_t i = 0; i < myBndColumns.size(); ++i )
+ {
+ TNodeColumn& nodes = *myBndColumns[i];
+ botUV[i].node = nodes[0];
+ botUV[i].SetUV( myHelper->GetNodeUV( myBotFace, nodes[0] ));
+ topUV[i].node = nodes.back();
+ topUV[i].SetUV( myHelper->GetNodeUV( myTopFace, nodes.back() ));
+ botUV[i].node->setIsMarked( true );
+ }
+ TopoDS_Edge dummyE;
+ SMESH_Mesh* mesh = myHelper->GetMesh();
+ TSideVector botWires( 1, StdMeshers_FaceSide::New( botUV, myBotFace, dummyE, mesh ));
+ TSideVector topWires( 1, StdMeshers_FaceSide::New( topUV, myTopFace, dummyE, mesh ));
+
+ // Delaunay mesh on the FACEs.
+ bool checkUV = false;
+ myBotDelaunay.reset( new NSProjUtils::Delaunay( botWires, checkUV ));
+ myTopDelaunay.reset( new NSProjUtils::Delaunay( topWires, checkUV ));
+
+ if ( myHelper->GetIsQuadratic() )
+ {
+ // mark all medium nodes of faces on botFace to avoid their treating
+ SMESHDS_SubMesh* smDS = myHelper->GetMeshDS()->MeshElements( myBotFace );
+ SMDS_ElemIteratorPtr eIt = smDS->GetElements();
+ while ( eIt->more() )
+ {
+ const SMDS_MeshElement* e = eIt->next();
+ for ( int i = e->NbCornerNodes(), nb = e->NbNodes(); i < nb; ++i )
+ e->GetNode( i )->setIsMarked( true );
+ }
+ }
+
+ // map to get a node column by a bottom node
+ myNodeID2ColID.Clear(/*doReleaseMemory=*/false);
+ myNodeID2ColID.ReSize( myIntColumns.size() );
+
+ // un-mark nodes to treat (internal bottom nodes) to be returned by myBotDelaunay
+ for ( size_t i = 0; i < myIntColumns.size(); ++i )
+ {
+ const SMDS_MeshNode* botNode = myIntColumns[i]->front();
+ botNode->setIsMarked( false );
+ myNodeID2ColID.Bind( botNode->GetID(), i );
+ }
+}
+
+//================================================================================
+/*!
+ * \brief For each internal node column, find Delaunay triangles including it
+ * and Barycentric Coordinates within the triangles. Fill in myTopBotTriangles
+ */
+//================================================================================
+
+bool StdMeshers_Sweeper::findDelaunayTriangles()
+{
+ const SMDS_MeshNode *botNode, *topNode;
+ const BRepMesh_Triangle *topTria;
+ TopBotTriangles tbTrias;
+ bool checkUV = true;
+
+ int nbInternalNodes = myIntColumns.size();
+ myTopBotTriangles.resize( nbInternalNodes );
+
+ myBotDelaunay->InitTraversal( nbInternalNodes );
+
+ while (( botNode = myBotDelaunay->NextNode( tbTrias.myBotBC, tbTrias.myBotTriaNodes )))
+ {
+ int colID = myNodeID2ColID( botNode->GetID() );
+ TNodeColumn* column = myIntColumns[ colID ];
+
+ // find a Delaunay triangle containing the topNode
+ topNode = column->back();
+ gp_XY topUV = myHelper->GetNodeUV( myTopFace, topNode, NULL, &checkUV );
+ // get a starting triangle basing on that top and bot boundary nodes have same index
+ topTria = myTopDelaunay->GetTriangleNear( tbTrias.myBotTriaNodes[0] );
+ topTria = myTopDelaunay->FindTriangle( topUV, topTria,
+ tbTrias.myTopBC, tbTrias.myTopTriaNodes );
+ if ( !topTria )
+ tbTrias.SetTopByBottom();
+
+ myTopBotTriangles[ colID ] = tbTrias;
+ }
+
+ if ( myBotDelaunay->NbVisitedNodes() < nbInternalNodes )
+ {
+ myTopBotTriangles.clear();
+ return false;
+ }
+
+ myBotDelaunay.reset();
+ myTopDelaunay.reset();
+ myNodeID2ColID.Clear();
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Initialize fields
+ */
+//================================================================================
+
+StdMeshers_Sweeper::TopBotTriangles::TopBotTriangles()
+{
+ myBotBC[0] = myBotBC[1] = myBotBC[2] = myTopBC[0] = myTopBC[1] = myTopBC[2] = 0.;
+ myBotTriaNodes[0] = myBotTriaNodes[1] = myBotTriaNodes[2] = 0;
+ myTopTriaNodes[0] = myTopTriaNodes[1] = myTopTriaNodes[2] = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Set top data equal to bottom data
+ */
+//================================================================================
+
+void StdMeshers_Sweeper::TopBotTriangles::SetTopByBottom()
+{
+ for ( int i = 0; i < 3; ++i )
+ {
+ myTopBC[i] = myBotBC[i];
+ myTopTriaNodes[i] = myBotTriaNodes[0];
+ }
+}
#include "SMESH_StdMeshers.hxx"
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_TypeOfPosition.hxx"
#include "SMESHDS_Mesh.hxx"
-#include "SMESH_Algo.hxx"
#include "SMESH_Block.hxx"
#include "SMESH_Comment.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_TypeDefs.hxx"
#include "SMESH_subMesh.hxx"
+#include "StdMeshers_ProjectionUtils.hxx"
#include <Adaptor2d_Curve2d.hxx>
#include <Adaptor3d_Curve.hxx>
#include <Adaptor3d_Surface.hxx>
#include <BRepAdaptor_Surface.hxx>
+#include <TColStd_DataMapOfIntegerInteger.hxx>
#include <TopTools_IndexedMapOfOrientedShape.hxx>
#include <TopoDS_Face.hxx>
#include <gp_Trsf.hxx>
struct TNode;
struct TPrismTopo;
}
-namespace StdMeshers_ProjectionUtils
-{
- class TrsfFinder3D;
-}
class SMESHDS_SubMesh;
class TopoDS_Edge;
TopoDS_Face myBottom;
TopoDS_Face myTop;
std::list< TopoDS_Edge > myBottomEdges;
- std::vector< TQuadList> myWallQuads; // wall sides can be vertically composite
+ std::vector< TQuadList> myWallQuads; // wall sides can be vertically composite
std::vector< int > myRightQuadIndex; // index of right neighbour wall quad
std::list< int > myNbEdgesInWires;
bool myNotQuadOnTop;
+ size_t NbWires() const { return myNbEdgesInWires.size(); }
+
void Clear();
void SetUpsideDown();
};
*/
struct StdMeshers_Sweeper
{
+ // input data
+ SMESH_MesherHelper* myHelper;
+ TopoDS_Face myBotFace;
+ TopoDS_Face myTopFace;
std::vector< TNodeColumn* > myBndColumns; // boundary nodes
+ // output data
std::vector< TNodeColumn* > myIntColumns; // internal nodes
- bool ComputeNodes( SMESH_MesherHelper& helper,
- const double tol,
- const bool allowHighBndError );
+ bool ComputeNodesByTrsf( const double tol,
+ const bool allowHighBndError );
+
+ bool CheckSameZ();
+
+ bool ComputeNodesOnStraightSameZ();
+
+ bool ComputeNodesOnStraight();
private:
gp_XYZ intPoint( int iP, int z ) const
{ return SMESH_TNodeXYZ( (*myIntColumns[ iP ])[ z ]); }
- static bool projectIntPoints(const std::vector< gp_XYZ >& fromBndPoints,
- const std::vector< gp_XYZ >& toBndPoints,
- const std::vector< gp_XYZ >& fromIntPoints,
- std::vector< gp_XYZ >& toIntPoints,
- StdMeshers_ProjectionUtils::TrsfFinder3D& trsf,
- std::vector< gp_XYZ > * bndError);
-
- static void applyBoundaryError(const std::vector< gp_XYZ >& bndPoints,
- const std::vector< gp_XYZ >& bndError1,
- const std::vector< gp_XYZ >& bndError2,
- const double r,
- std::vector< gp_XYZ >& toIntPoints,
- std::vector< double >& int2BndDist);
+ bool projectIntPoints(const std::vector< gp_XYZ >& fromBndPoints,
+ const std::vector< gp_XYZ >& toBndPoints,
+ const std::vector< gp_XYZ >& fromIntPoints,
+ std::vector< gp_XYZ >& toIntPoints,
+ const double r,
+ StdMeshers_ProjectionUtils::TrsfFinder3D& trsf,
+ std::vector< gp_XYZ > * bndError);
+
+ typedef std::vector< double > TZColumn;
+ static void fillZColumn( TZColumn& zColumn,
+ TNodeColumn& nodes );
+
+ void prepareTopBotDelaunay();
+ bool findDelaunayTriangles();
+
+ std::vector< TZColumn > myZColumns; // Z distribution of boundary nodes
+
+ StdMeshers_ProjectionUtils::DelaunayPtr myTopDelaunay;
+ StdMeshers_ProjectionUtils::DelaunayPtr myBotDelaunay;
+ TColStd_DataMapOfIntegerInteger myNodeID2ColID;
+
+ // top and bottom Delaulay triangles including an internal column
+ struct TopBotTriangles
+ {
+ double myBotBC[3], myTopBC[3]; // barycentric coordinates of a node within a triangle
+ int myBotTriaNodes[3], myTopTriaNodes[3]; // indices of boundary columns
+ TopBotTriangles();
+ void SetTopByBottom();
+ };
+ std::vector< TopBotTriangles> myTopBotTriangles;
};
// ===============================================
SMESH_MesherHelper* helper);
static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
+ virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+ {
+ return IsApplicable( shape, toCheckAll );
+ }
private:
*/
bool compute(const Prism_3D::TPrismTopo& thePrism);
+ /*!
+ * \brief Compute the base face of a prism
+ */
+ bool computeBase(const Prism_3D::TPrismTopo& thePrism);
+
/*!
* \brief Compute 2D mesh on walls FACEs of a prism
*/
bool computeWalls(const Prism_3D::TPrismTopo& thePrism);
+ /*!
+ * \brief Create artificial wall quads for vertical projection between the outer and inner walls
+ */
+ void makeQuadsForOutInProjection( const Prism_3D::TPrismTopo& thePrism,
+ std::multimap< int, int >& wgt2quad,
+ std::map< int, FaceQuadStruct >& iW2oiQuads);
/*!
* \brief Returns a source EDGE of propagation to a given EDGE
*/
*/
bool isSimpleBottom( const Prism_3D::TPrismTopo& thePrism );
+ /*!
+ * \brief Defines if all "vertical" EDGEs are straight
+ */
+ bool allVerticalEdgesStraight( const Prism_3D::TPrismTopo& thePrism );
+
/*!
* \brief Project mesh faces from a source FACE of one prism to
* a source FACE of another prism
StdMeshers_PrismAsBlock myBlock;
SMESH_MesherHelper* myHelper;
+ SMESH_subMesh* myPrevBottomSM;
std::vector<gp_XYZ> myShapeXYZ; // point on each sub-shape of the block
#include "StdMeshers_ProjectionUtils.hxx"
#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Algo.hxx"
#include "SMESH_Block.hxx"
#include "utilities.h"
#include <BRepAdaptor_Surface.hxx>
+#include <BRepMesh_Delaun.hxx>
#include <BRepTools.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <BRep_Builder.hxx>
return !allBndEdges.empty();
}
+ /*!
+ * \brief Convertor used in Delaunay constructor
+ */
+ struct SideVector2UVPtStructVec
+ {
+ std::vector< const UVPtStructVec* > _uvVecs;
+
+ SideVector2UVPtStructVec( const TSideVector& wires )
+ {
+ _uvVecs.resize( wires.size() );
+ for ( size_t i = 0; i < wires.size(); ++i )
+ _uvVecs[ i ] = & wires[i]->GetUVPtStruct();
+ }
+
+ operator const std::vector< const UVPtStructVec* > & () const
+ {
+ return _uvVecs;
+ }
+ };
+
} // namespace
//=======================================================================
RETURN_BAD_RESULT("edge2 does not belong to theShape2");
}
//
- // Look for 2 corresponing faces:
+ // Look for 2 corresponding faces:
//
TopoDS_Shape F1, F2;
// take care of proper association of propagated edges
bool same1 = edge1.IsSame( edges1.front() );
bool same2 = edge2.IsSame( edges2.front() );
+ if ( !same1 && !same2 )
+ {
+ same1 = ( edges1.back().Orientation() == edge1.Orientation() );
+ same2 = ( edges2.back().Orientation() == edge2.Orientation() );
+ }
if ( same1 != same2 )
{
reverseEdges(edges2, nbE);
}
return true;
}
-}
+
+ //================================================================================
+ /*!
+ * \brief triangulate the srcFace in 2D
+ * \param [in] srcWires - boundary of the src FACE
+ */
+ //================================================================================
+
+ Morph::Morph(const TSideVector& srcWires):
+ _delaunay( srcWires, /*checkUV=*/true )
+ {
+ _srcSubMesh = srcWires[0]->GetMesh()->GetSubMesh( srcWires[0]->Face() );
+ }
+
+ //================================================================================
+ /*!
+ * \brief Move non-marked target nodes
+ * \param [in,out] tgtHelper - helper
+ * \param [in] tgtWires - boundary nodes of the target FACE; must be in the
+ * same order as the nodes in srcWires given in the constructor
+ * \param [in] src2tgtNodes - map of src -> tgt nodes
+ * \param [in] moveAll - to move all nodes; if \c false, move only non-marked nodes
+ * \return bool - Ok or not
+ */
+ //================================================================================
+
+ bool Morph::Perform(SMESH_MesherHelper& tgtHelper,
+ const TSideVector& tgtWires,
+ Handle(ShapeAnalysis_Surface) tgtSurface,
+ const TNodeNodeMap& src2tgtNodes,
+ const bool moveAll)
+ {
+ // get tgt boundary points corresponding to src boundary nodes
+ size_t nbP = 0;
+ for ( size_t iW = 0; iW < tgtWires.size(); ++iW )
+ nbP += tgtWires[iW]->NbPoints() - 1; // 1st and last points coincide
+ if ( nbP != _delaunay.GetBndNodes().size() )
+ return false;
+
+ std::vector< gp_XY > tgtUV( nbP );
+ for ( size_t iW = 0, iP = 0; iW < tgtWires.size(); ++iW )
+ {
+ const UVPtStructVec& tgtPnt = tgtWires[iW]->GetUVPtStruct();
+ for ( int i = 0, nb = tgtPnt.size() - 1; i < nb; ++i, ++iP )
+ {
+ tgtUV[ iP ] = tgtPnt[i].UV();
+ }
+ }
+
+ SMESHDS_Mesh* tgtMesh = tgtHelper.GetMeshDS();
+ const SMDS_MeshNode *srcNode, *tgtNode;
+
+ // un-mark internal src nodes in order iterate them using _delaunay
+ int nbSrcNodes = 0;
+ SMDS_NodeIteratorPtr nIt = _srcSubMesh->GetSubMeshDS()->GetNodes();
+ if ( !nIt || !nIt->more() ) return true;
+ if ( moveAll )
+ {
+ nbSrcNodes = _srcSubMesh->GetSubMeshDS()->NbNodes();
+ while ( nIt->more() )
+ nIt->next()->setIsMarked( false );
+ }
+ else
+ {
+ while ( nIt->more() )
+ nbSrcNodes += int( !nIt->next()->isMarked() );
+ }
+
+ // Move tgt nodes
+
+ double bc[3]; // barycentric coordinates
+ int nodeIDs[3]; // nodes of a delaunay triangle
+ const SMDS_FacePosition* pos;
+
+ _delaunay.InitTraversal( nbSrcNodes );
+
+ while (( srcNode = _delaunay.NextNode( bc, nodeIDs )))
+ {
+ // compute new coordinates for a corresponding tgt node
+ gp_XY uvNew( 0., 0. ), nodeUV;
+ for ( int i = 0; i < 3; ++i )
+ uvNew += bc[i] * tgtUV[ nodeIDs[i]];
+ gp_Pnt xyz = tgtSurface->Value( uvNew );
+
+ // find and move tgt node
+ TNodeNodeMap::const_iterator n2n = src2tgtNodes.find( srcNode );
+ if ( n2n == src2tgtNodes.end() ) continue;
+ tgtNode = n2n->second;
+ tgtMesh->MoveNode( tgtNode, xyz.X(), xyz.Y(), xyz.Z() );
+
+ if (( pos = dynamic_cast< const SMDS_FacePosition* >( tgtNode->GetPosition() )))
+ const_cast<SMDS_FacePosition*>( pos )->SetParameters( uvNew.X(), uvNew.Y() );
+
+ --nbSrcNodes;
+ }
+
+ return nbSrcNodes == 0;
+
+ } // Morph::Perform
+
+ //=======================================================================
+ //function : Delaunay
+ //purpose : construct from face sides
+ //=======================================================================
+
+ Delaunay::Delaunay( const TSideVector& wires, bool checkUV ):
+ SMESH_Delaunay( SideVector2UVPtStructVec( wires ),
+ TopoDS::Face( wires[0]->FaceHelper()->GetSubShape() ),
+ wires[0]->FaceHelper()->GetSubShapeID() )
+ {
+ _wire = wires[0]; // keep a wire to assure _helper to keep alive
+ _helper = _wire->FaceHelper();
+ _checkUVPtr = checkUV ? & _checkUV : 0;
+ }
+
+ //=======================================================================
+ //function : Delaunay
+ //purpose : construct from UVPtStructVec's
+ //=======================================================================
+
+ Delaunay::Delaunay( const std::vector< const UVPtStructVec* > & boundaryNodes,
+ SMESH_MesherHelper& faceHelper,
+ bool checkUV):
+ SMESH_Delaunay( boundaryNodes,
+ TopoDS::Face( faceHelper.GetSubShape() ),
+ faceHelper.GetSubShapeID() )
+ {
+ _helper = & faceHelper;
+ _checkUVPtr = checkUV ? & _checkUV : 0;
+ }
+
+ //=======================================================================
+ //function : getNodeUV
+ //purpose :
+ //=======================================================================
+
+ gp_XY Delaunay::getNodeUV( const TopoDS_Face& face, const SMDS_MeshNode* node ) const
+ {
+ return _helper->GetNodeUV( face, node, 0, _checkUVPtr );
+ }
+
+
+} // namespace StdMeshers_ProjectionUtils
#include "SMESH_StdMeshers.hxx"
#include "SMDS_MeshElement.hxx"
+#include "SMESH_Delaunay.hxx"
+#include "StdMeshers_FaceSide.hxx"
+#include <ShapeAnalysis_Surface.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
class SMESH_subMesh;
class TopoDS_Shape;
+//-----------------------------------------------------------------------------------------
/*!
* \brief Struct used instead of a sole TopTools_DataMapOfShapeShape to avoid
* problems with bidirectional bindings
TIDCompare> TNodeNodeMap;
+ //-----------------------------------------------------------------------------------------
/*!
* \brief Finds transformation between two sets of 2D points using
* a least square approximation
bool IsIdentity() const { return ( _trsf.Form() == gp_Identity ); }
};
+ //-----------------------------------------------------------------------------------------
/*!
* \brief Finds transformation between two sets of 3D points using
* a least square approximation
bool Invert();
};
+ //-----------------------------------------------------------------------------------------
+ /*!
+ * \brief Create a Delaunay triangulation of nodes on a face boundary
+ * and provide exploration of nodes shared by elements lying on
+ * the face. For a returned node, also return a Delaunay triangle
+ * the node lies in and its Barycentric Coordinates within the triangle.
+ * Only non-marked nodes are visited.
+ *
+ * The main methods are defined in ../SMESHUtils/SMESH_Delaunay.hxx
+ */
+ class Delaunay : public SMESH_Delaunay
+ {
+ public:
+
+ Delaunay( const TSideVector& wires, bool checkUV = false );
+
+ Delaunay( const std::vector< const UVPtStructVec* > & boundaryNodes,
+ SMESH_MesherHelper& faceHelper,
+ bool checkUV = false);
+
+ protected:
+ virtual gp_XY getNodeUV( const TopoDS_Face& face, const SMDS_MeshNode* node ) const;
+
+ private:
+ SMESH_MesherHelper* _helper;
+ StdMeshers_FaceSidePtr _wire;
+ bool *_checkUVPtr, _checkUV;
+ };
+ typedef boost::shared_ptr< Delaunay > DelaunayPtr;
+
+ //-----------------------------------------------------------------------------------------
+ /*!
+ * \brief Morph mesh on the target FACE to lie within FACE boundary w/o distortion
+ */
+ class Morph
+ {
+ Delaunay _delaunay;
+ SMESH_subMesh* _srcSubMesh;
+ public:
+
+ Morph(const TSideVector& srcWires);
+
+ bool Perform(SMESH_MesherHelper& tgtHelper,
+ const TSideVector& tgtWires,
+ Handle(ShapeAnalysis_Surface) tgtSurface,
+ const TNodeNodeMap& src2tgtNodes,
+ const bool moveAll);
+ };
+
+ //-----------------------------------------------------------------------------------------
/*!
* \brief Looks for association of all sub-shapes of two shapes
* \param theShape1 - shape 1
{
SMESH_subMesh* faceSM = helper.GetMesh()->GetSubMesh( helper.GetSubShape() );
- if ( helper.IsDistorted2D( faceSM, /*checkUV=*/true ))
+ //if ( helper.IsDistorted2D( faceSM, /*checkUV=*/true ))
{
SMESH_MeshEditor editor( helper.GetMesh() );
SMESHDS_SubMesh* smDS = faceSM->GetSubMeshDS();
return true;
}
- typedef list< pair< const SMDS_MeshNode*, const BRepMesh_Triangle* > > TNodeTriaList;
-
- //================================================================================
- /*!
- * \brief Add in-FACE nodes surrounding a given node to a queue
- */
- //================================================================================
-
- void addCloseNodes( const SMDS_MeshNode* srcNode,
- const BRepMesh_Triangle* bmTria,
- const int srcFaceID,
- TNodeTriaList & noTriQueue )
- {
- // find in-FACE nodes
- SMDS_ElemIteratorPtr elems = srcNode->GetInverseElementIterator(SMDSAbs_Face);
- while ( elems->more() )
- {
- const SMDS_MeshElement* elem = elems->next();
- if ( elem->getshapeId() == srcFaceID )
- {
- for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
- {
- const SMDS_MeshNode* n = elem->GetNode( i );
- if ( !n->isMarked() )
- noTriQueue.push_back( make_pair( n, bmTria ));
- }
- }
- }
- }
-
- //================================================================================
- /*!
- * \brief Find a delauney triangle containing a given 2D point and return
- * barycentric coordinates within the found triangle
- */
- //================================================================================
-
- const BRepMesh_Triangle* findTriangle( const gp_XY& uv,
- const BRepMesh_Triangle* bmTria,
- Handle(BRepMesh_DataStructureOfDelaun)& triaDS,
- double bc[3] )
- {
- int nodeIDs[3];
- gp_XY nodeUVs[3];
- int linkIDs[3];
- Standard_Boolean ori[3];
-
- while ( bmTria )
- {
- // check bmTria
-
- triaDS->ElementNodes( *bmTria, nodeIDs );
- nodeUVs[0] = triaDS->GetNode( nodeIDs[0] ).Coord();
- nodeUVs[1] = triaDS->GetNode( nodeIDs[1] ).Coord();
- nodeUVs[2] = triaDS->GetNode( nodeIDs[2] ).Coord();
-
- SMESH_MeshAlgos::GetBarycentricCoords( uv,
- nodeUVs[0], nodeUVs[1], nodeUVs[2],
- bc[0], bc[1] );
- if ( bc[0] >= 0 && bc[1] >= 0 && bc[0] + bc[1] <= 1 )
- {
- bc[2] = 1 - bc[0] - bc[1];
- return bmTria;
- }
-
- // look for a neighbor triangle, which is adjacent to a link intersected
- // by a segment( triangle center -> uv )
-
- gp_XY gc = ( nodeUVs[0] + nodeUVs[1] + nodeUVs[2] ) / 3.;
- gp_XY seg = uv - gc;
-
- bmTria->Edges( linkIDs, ori );
- int triaID = triaDS->IndexOf( *bmTria );
- bmTria = 0;
-
- for ( int i = 0; i < 3; ++i )
- {
- const BRepMesh_PairOfIndex & triIDs = triaDS->ElementsConnectedTo( linkIDs[i] );
- if ( triIDs.Extent() < 2 )
- continue; // no neighbor triangle
-
- // check if a link intersects gc2uv
- const BRepMesh_Edge & link = triaDS->GetLink( linkIDs[i] );
- const BRepMesh_Vertex & n1 = triaDS->GetNode( link.FirstNode() );
- const BRepMesh_Vertex & n2 = triaDS->GetNode( link.LastNode() );
- gp_XY uv1 = n1.Coord();
- gp_XY lin = n2.Coord() - uv1; // link direction
-
- double crossSegLin = seg ^ lin;
- if ( Abs( crossSegLin ) < std::numeric_limits<double>::min() )
- continue; // parallel
-
- double uSeg = ( uv1 - gc ) ^ lin / crossSegLin;
- if ( 0. <= uSeg && uSeg <= 1. )
- {
- bmTria = & triaDS->GetElement( triIDs.Index( 1 + ( triIDs.Index(1) == triaID )));
- break;
- }
- }
- }
- return bmTria;
- }
-
- //================================================================================
- /*!
- * \brief Morph mesh on the target face to lie within FACE boundary w/o distortion
- *
- * algo:
- * - make a CDT on the src FACE
- * - find a triangle containing a src node and get its barycentric coordinates
- * - move the node to a point with the same barycentric coordinates in a corresponding
- * tgt triangle
- */
- //================================================================================
-
- bool morph( SMESH_MesherHelper& tgtHelper,
- const TopoDS_Face& tgtFace,
- const TopoDS_Face& srcFace,
- const TSideVector& tgtWires,
- const TSideVector& srcWires,
- const TAssocTool::TNodeNodeMap& src2tgtNodes )
- {
- if ( srcWires.size() != tgtWires.size() ) return false;
- if ( srcWires.size() == 1 ) return false; // tmp
-
- // count boundary points
- int iP = 1, nbP = 0;
- for ( size_t iW = 0; iW < srcWires.size(); ++iW )
- nbP += srcWires[iW]->NbPoints() - 1; // 1st and last points coincide
-
- // fill boundary points
- BRepMesh::Array1OfVertexOfDelaun srcVert( 1, 1 + nbP ), tgtVert( 1, 1 + nbP );
- vector< const SMDS_MeshNode* > bndSrcNodes( nbP + 1 ); bndSrcNodes[0] = 0;
- BRepMesh_Vertex v( 0, 0, BRepMesh_Frontier );
- for ( size_t iW = 0; iW < srcWires.size(); ++iW )
- {
- const UVPtStructVec& srcPnt = srcWires[iW]->GetUVPtStruct();
- const UVPtStructVec& tgtPnt = tgtWires[iW]->GetUVPtStruct();
- if ( srcPnt.size() != tgtPnt.size() ) return false;
-
- for ( int i = 0, nb = srcPnt.size() - 1; i < nb; ++i, ++iP )
- {
- bndSrcNodes[ iP ] = srcPnt[i].node;
- srcPnt[i].node->setIsMarked( true );
-
- v.ChangeCoord() = srcPnt[i].UV();
- srcVert( iP ) = v;
- v.ChangeCoord() = tgtPnt[i].UV();
- tgtVert( iP ) = v;
- }
- }
- // triangulate the srcFace in 2D
- BRepMesh_Delaun delauney( srcVert );
- Handle(BRepMesh_DataStructureOfDelaun) triaDS = delauney.Result();
-
- Handle(ShapeAnalysis_Surface) tgtSurface = tgtHelper.GetSurface( tgtFace );
- SMESHDS_Mesh* srcMesh = srcWires[0]->GetMesh()->GetMeshDS();
- SMESHDS_Mesh* tgtMesh = tgtHelper.GetMeshDS();
- const SMDS_MeshNode *srcNode, *tgtNode;
- const BRepMesh_Triangle *bmTria;
-
- // un-mark internal src nodes; later we will mark moved nodes
- SMDS_NodeIteratorPtr nIt = srcMesh->MeshElements( srcFace )->GetNodes();
- if ( !nIt || !nIt->more() ) return true;
- while ( nIt->more() )
- ( srcNode = nIt->next() )->setIsMarked( false );
-
- // initialize a queue of nodes with starting triangles
- const int srcFaceID = srcNode->getshapeId();
- TNodeTriaList noTriQueue;
- size_t iBndSrcN = 1;
- for ( ; iBndSrcN < bndSrcNodes.size() && noTriQueue.empty(); ++iBndSrcN )
- {
- // get a triangle
- const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN );
- const BRepMesh_PairOfIndex & triaIds = triaDS->ElementsConnectedTo( linkIds.First() );
- const BRepMesh_Triangle& tria = triaDS->GetElement( triaIds.Index(1) );
-
- addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue );
- }
-
- // Move tgt nodes
-
- double bc[3]; // barycentric coordinates
- int nodeIDs[3];
- bool checkUV = true;
- const SMDS_FacePosition* pos;
-
- while ( !noTriQueue.empty() )
- {
- srcNode = noTriQueue.front().first;
- bmTria = noTriQueue.front().second;
- noTriQueue.pop_front();
- if ( srcNode->isMarked() )
- continue;
- srcNode->setIsMarked( true );
-
- // find a delauney triangle containing the src node
- gp_XY uv = tgtHelper.GetNodeUV( srcFace, srcNode, NULL, &checkUV );
- bmTria = findTriangle( uv, bmTria, triaDS, bc );
- if ( !bmTria )
- continue;
-
- // compute new coordinates for a corresponding tgt node
- gp_XY uvNew( 0., 0. ), nodeUV;
- triaDS->ElementNodes( *bmTria, nodeIDs );
- for ( int i = 0; i < 3; ++i )
- uvNew += bc[i] * tgtVert( nodeIDs[i]).Coord();
- gp_Pnt xyz = tgtSurface->Value( uvNew );
-
- // find and move tgt node
- TAssocTool::TNodeNodeMap::const_iterator n2n = src2tgtNodes.find( srcNode );
- if ( n2n == src2tgtNodes.end() ) continue;
- tgtNode = n2n->second;
- tgtMesh->MoveNode( tgtNode, xyz.X(), xyz.Y(), xyz.Z() );
-
- if (( pos = dynamic_cast< const SMDS_FacePosition* >( tgtNode->GetPosition() )))
- const_cast<SMDS_FacePosition*>( pos )->SetParameters( uvNew.X(), uvNew.Y() );
-
- addCloseNodes( srcNode, bmTria, srcFaceID, noTriQueue );
-
- // assure that all src nodes are visited
- for ( ; iBndSrcN < bndSrcNodes.size() && noTriQueue.empty(); ++iBndSrcN )
- {
- const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN );
- const BRepMesh_PairOfIndex & triaIds = triaDS->ElementsConnectedTo( linkIds.First() );
- const BRepMesh_Triangle& tria = triaDS->GetElement( triaIds.Index(1) );
- addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue );
- }
- }
-
- return true;
- }
-
//=======================================================================
/*
* Set initial association of VERTEXes for the case of projection
TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front();
TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 );
reverse = ( ! srcE1.IsSame( srcE1bis ));
- if ( reverse &&
- //_sourceHypo->HasVertexAssociation() &&
+ if ( ( reverse || srcE1.Orientation() != srcE1bis.Orientation() ) &&
nbEdgesInWires.front() > 2 &&
helper.IsRealSeam( tgtEdges.front() ))
{
+ if ( srcE1.Orientation() != srcE1bis.Orientation() )
+ reverse = true;
// projection to a face with seam EDGE; pb is that GetOrderedEdges()
// always puts a seam EDGE first (if possible) and as a result
// we can't use only theReverse flag to correctly associate source
// ----------------------------------------------------------------
if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false, &helper ))
{
- morph( helper, tgtFace, srcFace, tgtWires, srcWires, _src2tgtNodes );
+ TAssocTool::Morph morph( srcWires );
+ morph.Perform( helper, tgtWires, helper.GetSurface( tgtFace ),
+ _src2tgtNodes, /*moveAll=*/true );
if ( !fixDistortedFaces( helper, tgtWires ))
return error("Invalid mesh generated");
*/
virtual void SetEventListener(SMESH_subMesh* whenSetToSubMesh);
+ virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+ {
+ return IsApplicable( shape, toCheckAll );
+ }
static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
protected:
virtual void SetEventListener(SMESH_subMesh* subMesh);
+ virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+ {
+ return IsApplicable( shape, toCheckAll );
+ }
static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
class Algo1D;
#include <Geom_Surface.hxx>
#include <NCollection_DefineArray2.hxx>
#include <Precision.hxx>
-#include <Quantity_Parameter.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <TColgp_SequenceOfXY.hxx>
#include "utilities.h"
#include "Utils_ExceptHandlers.hxx"
-#ifndef StdMeshers_Array2OfNode_HeaderFile
-#define StdMeshers_Array2OfNode_HeaderFile
-typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
-typedef NCollection_Array2<SMDS_MeshNodePtr> StdMeshers_Array2OfNode;
-#endif
+#include <boost/container/flat_set.hpp>
-using namespace std;
+typedef NCollection_Array2<const SMDS_MeshNode*> StdMeshers_Array2OfNode;
typedef gp_XY gp_UV;
typedef SMESH_Comment TComm;
+using namespace std;
+
//=============================================================================
/*!
*
continue;
}
- int nbNoDegenEdges = 0;
+ int nbNoDegenEdges = 0, totalNbEdges = 0;
TopExp_Explorer eExp( aFace, TopAbs_EDGE );
- for ( ; eExp.More() && nbNoDegenEdges < 3; eExp.Next() ) {
+ for ( ; eExp.More() && nbNoDegenEdges < 3; eExp.Next(), ++totalNbEdges ) {
if ( !SMESH_Algo::isDegenerated( TopoDS::Edge( eExp.Current() )))
++nbNoDegenEdges;
}
- if ( toCheckAll && nbNoDegenEdges < 3 ) return false;
- if ( !toCheckAll && nbNoDegenEdges >= 3 ) return true;
+ if ( toCheckAll && ( totalNbEdges < 4 && nbNoDegenEdges < 3 )) return false;
+ if ( !toCheckAll && ( totalNbEdges >= 4 || nbNoDegenEdges >= 3 )) return true;
}
return ( toCheckAll && nbFoundFaces != 0 );
}
}
}
}
- else
+ else //if ( !myHelper || !myHelper->IsRealSeam( edge ))
{
sideEdges.push_back( edge );
}
{
// "smooth" by computing node positions using 3D TFI and further projection
- int nbhoriz = quad->iSize;
- int nbvertic = quad->jSize;
+ list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin();
+ for ( ; q != myQuadList.end() ; ++q )
+ {
+ quad = *q;
+ int nbhoriz = quad->iSize;
+ int nbvertic = quad->jSize;
- SMESH_TNodeXYZ a0( quad->UVPt( 0, 0 ).node );
- SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0 ).node );
- SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node );
- SMESH_TNodeXYZ a3( quad->UVPt( 0, nbvertic-1 ).node );
+ SMESH_TNodeXYZ a0( quad->UVPt( 0, 0 ).node );
+ SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0 ).node );
+ SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node );
+ SMESH_TNodeXYZ a3( quad->UVPt( 0, nbvertic-1 ).node );
- for (int i = 1; i < nbhoriz-1; i++)
- {
- SMESH_TNodeXYZ p0( quad->UVPt( i, 0 ).node );
- SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node );
- for (int j = 1; j < nbvertic-1; j++)
+ for (int i = 1; i < nbhoriz-1; i++)
{
- SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node );
- SMESH_TNodeXYZ p3( quad->UVPt( 0, j ).node );
+ SMESH_TNodeXYZ p0( quad->UVPt( i, 0 ).node );
+ SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node );
+ for (int j = 1; j < nbvertic-1; j++)
+ {
+ SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node );
+ SMESH_TNodeXYZ p3( quad->UVPt( 0, j ).node );
- UVPtStruct& uvp = quad->UVPt( i, j );
+ UVPtStruct& uvp = quad->UVPt( i, j );
- gp_Pnt p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3);
- gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol );
- gp_Pnt pnew = surface->Value( uv );
+ gp_Pnt p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3);
+ gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol );
+ gp_Pnt pnew = surface->Value( uv );
- meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() );
- uvp.u = uv.X();
- uvp.v = uv.Y();
+ meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() );
+ uvp.u = uv.X();
+ uvp.v = uv.Y();
+ }
}
}
- return;
}
+ else
+ {
+ // Get nodes to smooth
- // Get nodes to smooth
-
- typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap;
- TNo2SmooNoMap smooNoMap;
+ typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap;
+ TNo2SmooNoMap smooNoMap;
- // fixed nodes
- set< const SMDS_MeshNode* > fixedNodes;
- for ( size_t i = 0; i < myForcedPnts.size(); ++i )
- {
- fixedNodes.insert( myForcedPnts[i].node );
- if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() )
+ // fixed nodes
+ boost::container::flat_set< const SMDS_MeshNode* > fixedNodes;
+ for ( size_t i = 0; i < myForcedPnts.size(); ++i )
{
- TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ];
- sNode._uv = myForcedPnts[i].uv;
- sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node );
+ fixedNodes.insert( myForcedPnts[i].node );
+ if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() )
+ {
+ TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ];
+ sNode._uv = myForcedPnts[i].uv;
+ sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node );
+ }
}
- }
- SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face );
- SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes();
- while ( nIt->more() ) // loop on nodes bound to a FACE
- {
- const SMDS_MeshNode* node = nIt->next();
- TSmoothNode & sNode = smooNoMap[ node ];
- sNode._uv = myHelper->GetNodeUV( quad->face, node );
- sNode._xyz = SMESH_TNodeXYZ( node );
- if ( fixedNodes.count( node ))
- continue; // fixed - no triangles
-
- // set sNode._triangles
- SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face );
- while ( fIt->more() )
+ SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face );
+ SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes();
+ while ( nIt->more() ) // loop on nodes bound to a FACE
{
- const SMDS_MeshElement* face = fIt->next();
- const int nbN = face->NbCornerNodes();
- const int nInd = face->GetNodeIndex( node );
- const int prevInd = myHelper->WrapIndex( nInd - 1, nbN );
- const int nextInd = myHelper->WrapIndex( nInd + 1, nbN );
- const SMDS_MeshNode* prevNode = face->GetNode( prevInd );
- const SMDS_MeshNode* nextNode = face->GetNode( nextInd );
- sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ],
- & smooNoMap[ nextNode ]));
- }
- }
- // set _uv of smooth nodes on FACE boundary
- set< StdMeshers_FaceSide* > sidesOnEdge;
- list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin();
- for ( ; q != myQuadList.end() ; ++q )
- for ( size_t i = 0; i < (*q)->side.size(); ++i )
- if ( ! (*q)->side[i].grid->Edge(0).IsNull() &&
- //(*q)->nbNodeOut( i ) == 0 &&
- sidesOnEdge.insert( (*q)->side[i].grid.get() ).second )
+ const SMDS_MeshNode* node = nIt->next();
+ TSmoothNode & sNode = smooNoMap[ node ];
+ sNode._uv = myHelper->GetNodeUV( quad->face, node );
+ sNode._xyz = SMESH_TNodeXYZ( node );
+ if ( fixedNodes.count( node ))
+ continue; // fixed - no triangles
+
+ // set sNode._triangles
+ SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face );
+ while ( fIt->more() )
{
- const vector<UVPtStruct>& uvVec = (*q)->side[i].grid->GetUVPtStruct();
- for ( unsigned j = 0; j < uvVec.size(); ++j )
+ const SMDS_MeshElement* face = fIt->next();
+ const int nbN = face->NbCornerNodes();
+ const int nInd = face->GetNodeIndex( node );
+ const int prevInd = myHelper->WrapIndex( nInd - 1, nbN );
+ const int nextInd = myHelper->WrapIndex( nInd + 1, nbN );
+ const SMDS_MeshNode* prevNode = face->GetNode( prevInd );
+ const SMDS_MeshNode* nextNode = face->GetNode( nextInd );
+ sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ],
+ & smooNoMap[ nextNode ]));
+ }
+ }
+ // set _uv of smooth nodes on FACE boundary
+ set< StdMeshers_FaceSide* > sidesOnEdge;
+ list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin();
+ for ( ; q != myQuadList.end() ; ++q )
+ for ( size_t i = 0; i < (*q)->side.size(); ++i )
+ if ( ! (*q)->side[i].grid->Edge(0).IsNull() &&
+ //(*q)->nbNodeOut( i ) == 0 &&
+ sidesOnEdge.insert( (*q)->side[i].grid.get() ).second )
{
- TSmoothNode & sNode = smooNoMap[ uvVec[j].node ];
- sNode._uv = uvVec[j].UV();
- sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node );
+ const vector<UVPtStruct>& uvVec = (*q)->side[i].grid->GetUVPtStruct();
+ for ( unsigned j = 0; j < uvVec.size(); ++j )
+ {
+ TSmoothNode & sNode = smooNoMap[ uvVec[j].node ];
+ sNode._uv = uvVec[j].UV();
+ sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node );
+ }
}
- }
- // define reference orientation in 2D
- TNo2SmooNoMap::iterator n2sn = smooNoMap.begin();
- for ( ; n2sn != smooNoMap.end(); ++n2sn )
- if ( !n2sn->second._triangles.empty() )
- break;
- if ( n2sn == smooNoMap.end() ) return;
- const TSmoothNode & sampleNode = n2sn->second;
- const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv ));
+ // define reference orientation in 2D
+ TNo2SmooNoMap::iterator n2sn = smooNoMap.begin();
+ for ( ; n2sn != smooNoMap.end(); ++n2sn )
+ if ( !n2sn->second._triangles.empty() )
+ break;
+ if ( n2sn == smooNoMap.end() ) return;
+ const TSmoothNode & sampleNode = n2sn->second;
+ const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv ));
- // Smoothing
+ // Smoothing
- for ( int iLoop = 0; iLoop < 5; ++iLoop )
- {
- for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
+ for ( int iLoop = 0; iLoop < 5; ++iLoop )
{
- TSmoothNode& sNode = n2sn->second;
- if ( sNode._triangles.empty() )
- continue; // not movable node
+ for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
+ {
+ TSmoothNode& sNode = n2sn->second;
+ if ( sNode._triangles.empty() )
+ continue; // not movable node
- gp_XY newUV;
- bool isValid = false;
- bool use3D = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D
+ gp_XY newUV;
+ bool isValid = false;
+ bool use3D = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D
- if ( use3D )
- {
- // compute a new XYZ
- gp_XYZ newXYZ (0,0,0);
- for ( size_t i = 0; i < sNode._triangles.size(); ++i )
- newXYZ += sNode._triangles[i]._n1->_xyz;
- newXYZ /= sNode._triangles.size();
-
- // compute a new UV by projection
- newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY();
-
- // check validity of the newUV
- for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i )
- isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
- }
- if ( !isValid )
- {
- // compute a new UV by averaging
- newUV.SetCoord(0.,0.);
- for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
- newUV += sNode._triangles[i]._n1->_uv;
- newUV /= sNode._triangles.size();
-
- // check validity of the newUV
- isValid = true;
- for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
- isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
- }
- if ( isValid )
- {
- sNode._uv = newUV;
- sNode._xyz = surface->Value( newUV ).XYZ();
+ if ( use3D )
+ {
+ // compute a new XYZ
+ gp_XYZ newXYZ (0,0,0);
+ for ( size_t i = 0; i < sNode._triangles.size(); ++i )
+ newXYZ += sNode._triangles[i]._n1->_xyz;
+ newXYZ /= sNode._triangles.size();
+
+ // compute a new UV by projection
+ newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY();
+
+ // check validity of the newUV
+ for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i )
+ isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
+ }
+ if ( !isValid )
+ {
+ // compute a new UV by averaging
+ newUV.SetCoord(0.,0.);
+ for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
+ newUV += sNode._triangles[i]._n1->_uv;
+ newUV /= sNode._triangles.size();
+
+ // check validity of the newUV
+ isValid = true;
+ for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
+ isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
+ }
+ if ( isValid )
+ {
+ sNode._uv = newUV;
+ sNode._xyz = surface->Value( newUV ).XYZ();
+ }
}
}
- }
- // Set new XYZ to the smoothed nodes
+ // Set new XYZ to the smoothed nodes
- for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
- {
- TSmoothNode& sNode = n2sn->second;
- if ( sNode._triangles.empty() )
- continue; // not movable node
+ for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
+ {
+ TSmoothNode& sNode = n2sn->second;
+ if ( sNode._triangles.empty() )
+ continue; // not movable node
- SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first );
- gp_Pnt xyz = surface->Value( sNode._uv );
- meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
+ SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first );
+ gp_Pnt xyz = surface->Value( sNode._uv );
+ meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
- // store the new UV
- node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() )));
+ // store the new UV
+ node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() )));
+ }
}
// Move medium nodes in quadratic mesh
meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
}
}
+ return;
}
//================================================================================
if ( myHelper->HasSeam() )
for ( int i = 0; i < nbN && !nInFace; ++i )
if ( !myHelper->IsSeamShape( nn[i]->getshapeId() ))
+ {
nInFace = nn[i];
+ gp_XY uv = myHelper->GetNodeUV( geomFace, nInFace );
+ if ( myHelper->IsOnSeam( uv ))
+ nInFace = NULL;
+ }
toCheckUV = true;
for ( int i = 0; i < nbN; ++i )
uv[ i ] = myHelper->GetNodeUV( geomFace, nn[i], nInFace, &toCheckUV );
+ bool isBad = false;
switch ( nbN ) {
case 4:
{
if ( sign1 * sign2 < 0 )
continue; // this should not happen
}
- if ( sign1 * okSign < 0 )
- badFaces.push_back ( f );
+ isBad = ( sign1 * okSign < 0 );
break;
}
case 3:
{
double sign = getArea( uv[0], uv[1], uv[2] );
- if ( sign * okSign < 0 )
- badFaces.push_back ( f );
+ isBad = ( sign * okSign < 0 );
break;
}
default:;
}
+
+ // if ( isBad && myHelper->HasRealSeam() )
+ // {
+ // // detect a case where a face intersects the seam
+ // for ( int iPar = 1; iPar < 3; ++iPar )
+ // if ( iPar & myHelper->GetPeriodicIndex() )
+ // {
+ // double min = uv[0].Coord( iPar ), max = uv[0].Coord( iPar );
+ // for ( int i = 1; i < nbN; ++i )
+ // {
+ // min = Min( min, uv[i].Coord( iPar ));
+ // max = Max( max, uv[i].Coord( iPar ));
+ // }
+ // }
+ // }
+ if ( isBad )
+ badFaces.push_back ( f );
}
if ( !badFaces.empty() )
if ( SMESH_Algo::isDegenerated( prevE ))
{
list<TopoDS_Edge>::reverse_iterator edge = ++theWire.rbegin();
- while ( SMESH_Algo::isDegenerated( *edge ))
+ while ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/)
++edge;
if ( edge == theWire.rend() )
return false;
list<TopoDS_Edge>::iterator edge = theWire.begin();
for ( int iE = 0; edge != theWire.end(); ++edge, ++iE )
{
- if ( SMESH_Algo::isDegenerated( *edge ))
+ if ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/)
{
++theNbDegenEdges;
continue;
const bool considerMesh = false,
SMESH_MesherHelper* aFaceHelper = 0);
+ virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+ {
+ return IsApplicable( shape, toCheckAll );
+ }
static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
protected:
#include "StdMeshers_RadialPrism_3D.hxx"
-#include <Basics_OCCTVersion.hxx>
-
#include "StdMeshers_ProjectionUtils.hxx"
#include "StdMeshers_NumberOfLayers.hxx"
#include "StdMeshers_LayerDistribution.hxx"
virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
MapShapeNbElems& aResMap);
+ virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+ {
+ return IsApplicable( shape, toCheckAll );
+ }
static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
protected:
return true;
}
// -----------------------------------------------------------------------------
- //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments
+ //! Make mesh on an adge using assigned 1d hyp or default nb of segments
bool ComputeCircularEdge( SMESH_Mesh& aMesh,
const StdMeshers_FaceSidePtr& aSide )
{
return ok;
}
// -----------------------------------------------------------------------------
- //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments
+ //! Make mesh on an adge using assigned 1d hyp or default nb of segments
bool EvaluateCircularEdge(SMESH_Mesh& aMesh,
const StdMeshers_FaceSidePtr aSide,
MapShapeNbElems& aResMap)
*/
virtual void SubmeshRestored(SMESH_subMesh* subMesh);
+ virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const
+ {
+ return IsApplicable( shape, toCheckAll );
+ }
static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
-protected:
+ protected:
int computeLayerPositions(StdMeshers_FaceSidePtr linSide,
std::vector< double >& positions,
if ( !nFirst || !nLast )
return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
- // remove elements created by e.g. patern mapping (PAL21999)
+ // remove elements created by e.g. pattern mapping (PAL21999)
// CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp
// so TEMPORARY solution is to clean the submesh manually
if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape))
#include <string>
#ifdef _DEBUG_
-//#define __myDEBUG
+#define __myDEBUG
//#define __NOT_INVALIDATE_BAD_SMOOTH
//#define __NODES_AT_POS
#endif
enum UIndex { U_TGT = 1, U_SRC, LEN_TGT };
const double theMinSmoothCosin = 0.1;
- const double theSmoothThickToElemSizeRatio = 0.3;
+ const double theSmoothThickToElemSizeRatio = 0.6;
const double theMinSmoothTriaAngle = 30;
const double theMinSmoothQuadAngle = 45;
enum EFlags { TO_SMOOTH = 0x0000001,
MOVED = 0x0000002, // set by _neibors[i]->SetNewLength()
- SMOOTHED = 0x0000004, // set by this->Smooth()
+ SMOOTHED = 0x0000004, // set by _LayerEdge::Smooth()
DIFFICULT = 0x0000008, // near concave VERTEX
ON_CONCAVE_FACE = 0x0000010,
BLOCKED = 0x0000020, // not to inflate any more
INTERSECTED = 0x0000040, // close intersection with a face found
NORMAL_UPDATED = 0x0000080,
- MARKED = 0x0000100, // local usage
- MULTI_NORMAL = 0x0000200, // a normal is invisible by some of surrounding faces
- NEAR_BOUNDARY = 0x0000400, // is near FACE boundary forcing smooth
- SMOOTHED_C1 = 0x0000800, // is on _eosC1
- DISTORTED = 0x0001000, // was bad before smoothing
- RISKY_SWOL = 0x0002000, // SWOL is parallel to a source FACE
- SHRUNK = 0x0004000, // target node reached a tgt position while shrink()
- UNUSED_FLAG = 0x0100000 // to add use flags after
+ UPD_NORMAL_CONV = 0x0000100, // to update normal on boundary of concave FACE
+ MARKED = 0x0000200, // local usage
+ MULTI_NORMAL = 0x0000400, // a normal is invisible by some of surrounding faces
+ NEAR_BOUNDARY = 0x0000800, // is near FACE boundary forcing smooth
+ SMOOTHED_C1 = 0x0001000, // is on _eosC1
+ DISTORTED = 0x0002000, // was bad before smoothing
+ RISKY_SWOL = 0x0004000, // SWOL is parallel to a source FACE
+ SHRUNK = 0x0008000, // target node reached a tgt position while shrink()
+ UNUSED_FLAG = 0x0100000 // to add user flags after
};
bool Is ( int flag ) const { return _flags & flag; }
void Set ( int flag ) { _flags |= flag; }
const gp_XYZ& PrevPos() const { return _pos[ _pos.size() - 2 ]; }
gp_XYZ PrevCheckPos( _EdgesOnShape* eos=0 ) const;
gp_Ax1 LastSegment(double& segLen, _EdgesOnShape& eos) const;
- gp_XY LastUV( const TopoDS_Face& F, _EdgesOnShape& eos ) const;
+ gp_XY LastUV( const TopoDS_Face& F, _EdgesOnShape& eos, int which=-1 ) const;
bool IsOnEdge() const { return _2neibors; }
+ bool IsOnFace() const { return ( _nodes[0]->GetPosition()->GetDim() == 2 ); }
+ int BaseShapeDim() const { return _nodes[0]->GetPosition()->GetDim(); }
gp_XYZ Copy( _LayerEdge& other, _EdgesOnShape& eos, SMESH_MesherHelper& helper );
void SetCosin( double cosin );
void SetNormal( const gp_XYZ& n ) { _normal = n; }
+ void SetMaxLen( double l ) { _maxLen = l; }
int NbSteps() const { return _pos.size() - 1; } // nb inlation steps
bool IsNeiborOnEdge( const _LayerEdge* edge ) const;
void SetSmooLen( double len ) { // set _len at which smoothing is needed
_SolidData* _data; // parent SOLID
+ _LayerEdge* operator[](size_t i) const { return (_LayerEdge*) _edges[i]; }
+ size_t size() const { return _edges.size(); }
TopAbs_ShapeEnum ShapeType() const
{ return _shape.IsNull() ? TopAbs_SHAPE : _shape.ShapeType(); }
TopAbs_ShapeEnum SWOLType() const
//--------------------------------------------------------------------------------
/*!
- * \brief Convex FACE whose radius of curvature is less than the thickness of
+ * \brief Convex FACE whose radius of curvature is less than the thickness of
* layers. It is used to detect distortion of prisms based on a convex
* FACE and to update normals to enable further increasing the thickness
*/
// map a sub-shape to _SolidData::_edgesOnShape
map< TGeomID, _EdgesOnShape* > _subIdToEOS;
+ bool _isTooCurved;
bool _normalsFixed;
+ bool _normalsFixedOnBorders; // used in putOnOffsetSurface()
+
+ double GetMaxCurvature( _SolidData& data,
+ _EdgesOnShape& eof,
+ BRepLProp_SLProps& surfProp,
+ SMESH_MesherHelper& helper);
bool GetCenterOfCurvature( _LayerEdge* ledge,
BRepLProp_SLProps& surfProp,
int _nbShapesToSmooth;
- //map< TGeomID,Handle(Geom_Curve)> _edge2curve;
-
vector< _CollisionEdges > _collisionEdges;
set< TGeomID > _concaveFaces;
void Append( const gp_Pnt& center, _LayerEdge* ledge )
{
+ if ( ledge->Is( _LayerEdge::MULTI_NORMAL ))
+ return;
if ( _curvaCenters.size() > 0 )
_segLength2.push_back( center.SquareDistance( _curvaCenters.back() ));
_curvaCenters.push_back( center );
const gp_XY& uvToFix,
const double refSign );
};
+ struct PyDump;
//--------------------------------------------------------------------------------
/*!
* \brief Builder of viscous layers
void makeOffsetSurface( _EdgesOnShape& eos, SMESH_MesherHelper& );
void putOnOffsetSurface( _EdgesOnShape& eos, int infStep,
vector< _EdgesOnShape* >& eosC1,
- int smooStep=0, bool moveAll=false );
+ int smooStep=0, int moveAll=false );
void findCollisionEdges( _SolidData& data, SMESH_MesherHelper& helper );
+ void findEdgesToUpdateNormalNearConvexFace( _ConvexFace & convFace,
+ _SolidData& data,
+ SMESH_MesherHelper& helper );
void limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelper& helper );
void limitMaxLenByCurvature( _LayerEdge* e1, _LayerEdge* e2,
_EdgesOnShape& eos1, _EdgesOnShape& eos2,
- SMESH_MesherHelper& helper );
+ const bool isSmoothable );
bool updateNormals( _SolidData& data, SMESH_MesherHelper& helper, int stepNb, double stepSize );
bool updateNormalsOfConvexFaces( _SolidData& data,
SMESH_MesherHelper& helper,
TopTools_MapOfShape _shrinkedFaces;
int _tmpFaceID;
+ PyDump* _pyDump;
};
//--------------------------------------------------------------------------------
/*!
size_t _iSeg[2]; // index of segment where extreme tgt node is projected
_EdgesOnShape& _eos;
double _curveLen; // length of the EDGE
+ std::pair<int,int> _eToSmooth[2]; // <from,to> indices of _LayerEdge's in _eos
static Handle(Geom_Curve) CurveForSmooth( const TopoDS_Edge& E,
_EdgesOnShape& eos,
bool Perform(_SolidData& data,
Handle(ShapeAnalysis_Surface)& surface,
const TopoDS_Face& F,
- SMESH_MesherHelper& helper )
- {
- if ( _leParams.empty() || ( !isAnalytic() && _offPoints.empty() ))
- prepare( data );
+ SMESH_MesherHelper& helper );
- if ( isAnalytic() )
- return smoothAnalyticEdge( data, surface, F, helper );
- else
- return smoothComplexEdge ( data, surface, F, helper );
- }
void prepare(_SolidData& data );
+ void findEdgesToSmooth();
+
+ bool isToSmooth( int iE );
+
bool smoothAnalyticEdge( _SolidData& data,
Handle(ShapeAnalysis_Surface)& surface,
const TopoDS_Face& F,
SMESH_MesherHelper& helper);
-
bool smoothComplexEdge( _SolidData& data,
Handle(ShapeAnalysis_Surface)& surface,
const TopoDS_Face& F,
SMESH_MesherHelper& helper);
-
gp_XYZ getNormalNormal( const gp_XYZ & normal,
const gp_XYZ& edgeDir);
-
_LayerEdge* getLEdgeOnV( bool is2nd )
{
return _eos._edges[ is2nd ? _eos._edges.size()-1 : 0 ]->_2neibors->_edges[ is2nd ];
}
bool isAnalytic() const { return !_anaCurve.IsNull(); }
+
+ void offPointsToPython() const; // debug
};
//--------------------------------------------------------------------------------
/*!
// look for two neighbor not in-FACE nodes of face
for ( int i = 0; i < 2; ++i )
{
- if ( nNext[i]->GetPosition()->GetDim() != 2 &&
- nNext[i]->GetID() < nodeOnEdge->GetID() )
+ if (( nNext[i]->GetPosition()->GetDim() != 2 ) &&
+ ( nodeOnEdge->GetPosition()->GetDim() == 0 || nNext[i]->GetID() < nodeOnEdge->GetID() ))
{
// look for an in-FACE node
for ( int iN = 0; iN < nbN; ++iN )
// HOWTO use: run python commands written in a console to see
// construction steps of viscous layers
#ifdef __myDEBUG
- ofstream* py;
- int theNbPyFunc;
- struct PyDump {
+ ostream* py;
+ int theNbPyFunc;
+ struct PyDump
+ {
PyDump(SMESH_Mesh& m) {
int tag = 3 + m.GetId();
const char* fname = "/tmp/viscous.py";
cout << "execfile('"<<fname<<"')"<<endl;
- py = new ofstream(fname);
+ py = _pyStream = new ofstream(fname);
*py << "import SMESH" << endl
<< "from salome.smesh import smeshBuilder" << endl
<< "smesh = smeshBuilder.New(salome.myStudy)" << endl
delete py; py=0;
}
~PyDump() { Finish(); cout << "NB FUNCTIONS: " << theNbPyFunc << endl; }
+ struct MyStream : public ostream
+ {
+ template <class T> ostream & operator<<( const T &anything ) { return *this ; }
+ };
+ void Pause() { py = &_mystream; }
+ void Resume() { py = _pyStream; }
+ MyStream _mystream;
+ ostream* _pyStream;
};
#define dumpFunction(f) { _dumpFunction(f, __LINE__);}
#define dumpMove(n) { _dumpMove(n, __LINE__);}
#else
- struct PyDump { PyDump(SMESH_Mesh&) {} void Finish() {} };
+ struct PyDump { PyDump(SMESH_Mesh&) {} void Finish() {} void Pause() {} void Resume() {} };
#define dumpFunction(f) f
#define dumpMove(n)
#define dumpMoveComm(n,txt)
return SMESH_ComputeErrorPtr(); // everything already computed
PyDump debugDump( theMesh );
+ _pyDump = &debugDump;
// TODO: ignore already computed SOLIDs
if ( !findSolidsWithLayers())
for ( TopoDS_Iterator vIt( edge ); vIt.More(); vIt.Next() )
{
TGeomID vID = getMeshDS()->ShapeToIndex( vIt.Value() );
- bool noShrinkV = false;
+ bool noShrinkV = false, noShrinkIfAdjMeshed = false;
if ( iSolid < _sdVec.size() )
{
i2S = _sdVec[i ]._shrinkShape2Shape.find( vID );
i2SAdj = _sdVec[iSolid]._shrinkShape2Shape.find( vID );
if ( i2SAdj == _sdVec[iSolid]._shrinkShape2Shape.end() )
- noShrinkV = ( i2S->second.ShapeType() == TopAbs_EDGE || isStructured );
+ noShrinkV = (( isStructured ) ||
+ ( noShrinkIfAdjMeshed = i2S->second.ShapeType() == TopAbs_EDGE ));
else
noShrinkV = ( ! i2S->second.IsSame( i2SAdj->second ));
}
else
{
// the adjacent SOLID has NO layers at all
- noShrinkV = ( isStructured ||
- _sdVec[i]._shrinkShape2Shape[ vID ].ShapeType() == TopAbs_EDGE );
+ if ( isStructured )
+ {
+ noShrinkV = true;
+ }
+ else
+ {
+ noShrinkV = noShrinkIfAdjMeshed =
+ ( _sdVec[i]._shrinkShape2Shape[ vID ].ShapeType() == TopAbs_EDGE );
+ }
+ }
+
+ if ( noShrinkV && noShrinkIfAdjMeshed )
+ {
+ // noShrinkV if FACEs in the adjacent SOLID are meshed
+ PShapeIteratorPtr fIt = helper.GetAncestors( _sdVec[i]._shrinkShape2Shape[ vID ],
+ *_mesh, TopAbs_FACE, &solid );
+ while ( fIt->more() )
+ {
+ const TopoDS_Shape* f = fIt->next();
+ if ( !f->IsSame( fWOL ))
+ {
+ noShrinkV = ! _mesh->GetSubMesh( *f )->IsEmpty();
+ break;
+ }
+ }
}
if ( noShrinkV )
_sdVec[i]._noShrinkShapes.insert( vID );
{
SMESH_MesherHelper helper( *_mesh );
- const int nbTestPnt = 5; // on a FACE sub-shape
-
BRepLProp_SLProps surfProp( 2, 1e-6 );
data._convexFaces.clear();
continue;
TopoDS_Face F = TopoDS::Face( eof._shape );
- SMESH_subMesh * sm = eof._subMesh;
const TGeomID faceID = eof._shapeID;
BRepAdaptor_Surface surface( F, false );
surfProp.SetSurface( surface );
- bool isTooCurved = false;
-
_ConvexFace cnvFace;
- const double oriFactor = ( F.Orientation() == TopAbs_REVERSED ? +1. : -1. );
- SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true);
- while ( smIt->more() )
- {
- sm = smIt->next();
- const TGeomID subID = sm->GetId();
- // find _LayerEdge's of a sub-shape
- _EdgesOnShape* eos;
- if (( eos = data.GetShapeEdges( subID )))
- cnvFace._subIdToEOS.insert( make_pair( subID, eos ));
- else
- continue;
- // check concavity and curvature and limit data._stepSize
- const double minCurvature =
- 1. / ( eos->_hyp.GetTotalThickness() * ( 1 + theThickToIntersection ));
- size_t iStep = Max( 1, eos->_edges.size() / nbTestPnt );
- for ( size_t i = 0; i < eos->_edges.size(); i += iStep )
- {
- gp_XY uv = helper.GetNodeUV( F, eos->_edges[ i ]->_nodes[0] );
- surfProp.SetParameters( uv.X(), uv.Y() );
- if ( !surfProp.IsCurvatureDefined() )
- continue;
- if ( surfProp.MaxCurvature() * oriFactor > minCurvature )
- {
- limitStepSize( data, 0.9 / surfProp.MaxCurvature() * oriFactor );
- isTooCurved = true;
- }
- if ( surfProp.MinCurvature() * oriFactor > minCurvature )
- {
- limitStepSize( data, 0.9 / surfProp.MinCurvature() * oriFactor );
- isTooCurved = true;
- }
- }
- } // loop on sub-shapes of the FACE
+ cnvFace._face = F;
+ cnvFace._normalsFixed = false;
+ cnvFace._isTooCurved = false;
- if ( !isTooCurved ) continue;
+ double maxCurvature = cnvFace.GetMaxCurvature( data, eof, surfProp, helper );
+ if ( maxCurvature > 0 )
+ {
+ limitStepSize( data, 0.9 / maxCurvature );
+ findEdgesToUpdateNormalNearConvexFace( cnvFace, data, helper );
+ }
+ if ( !cnvFace._isTooCurved ) continue;
_ConvexFace & convFace =
data._convexFaces.insert( make_pair( faceID, cnvFace )).first->second;
- convFace._face = F;
- convFace._normalsFixed = false;
-
// skip a closed surface (data._convexFaces is useful anyway)
bool isClosedF = false;
helper.SetSubShape( F );
if ( isClosedF )
{
// limit _LayerEdge::_maxLen on the FACE
+ const double oriFactor = ( F.Orientation() == TopAbs_REVERSED ? +1. : -1. );
const double minCurvature =
1. / ( eof._hyp.GetTotalThickness() * ( 1 + theThickToIntersection ));
map< TGeomID, _EdgesOnShape* >::iterator id2eos = cnvFace._subIdToEOS.find( faceID );
_LayerEdge* ledge = eos._edges[ i ];
gp_XY uv = helper.GetNodeUV( F, ledge->_nodes[0] );
surfProp.SetParameters( uv.X(), uv.Y() );
- if ( !surfProp.IsCurvatureDefined() )
- continue;
-
- if ( surfProp.MaxCurvature() * oriFactor > minCurvature )
- ledge->_maxLen = Min( ledge->_maxLen, 1. / surfProp.MaxCurvature() * oriFactor );
-
- if ( surfProp.MinCurvature() * oriFactor > minCurvature )
- ledge->_maxLen = Min( ledge->_maxLen, 1. / surfProp.MinCurvature() * oriFactor );
+ if ( surfProp.IsCurvatureDefined() )
+ {
+ double curvature = Max( surfProp.MaxCurvature() * oriFactor,
+ surfProp.MinCurvature() * oriFactor );
+ if ( curvature > minCurvature )
+ ledge->SetMaxLen( Min( ledge->_maxLen, 1. / curvature ));
+ }
}
}
continue;
for ( size_t j = 0; j < ledge->_simplices.size(); ++j )
if ( ledge->_simplices[j]._nNext->GetPosition()->GetDim() < 2 )
{
- convFace._simplexTestEdges.push_back( ledge );
+ // do not select _LayerEdge's neighboring sharp EDGEs
+ bool sharpNbr = false;
+ for ( size_t iN = 0; iN < ledge->_neibors.size() && !sharpNbr; ++iN )
+ sharpNbr = ( ledge->_neibors[iN]->_cosin > theMinSmoothCosin );
+ if ( !sharpNbr )
+ convFace._simplexTestEdges.push_back( ledge );
break;
}
}
// define allowed thickness
computeGeomSize( data ); // compute data._geomSize and _LayerEdge::_maxLen
- data._maxThickness = 0;
- data._minThickness = 1e100;
- list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin();
- for ( ; hyp != data._hyps.end(); ++hyp )
- {
- data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() );
- data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() );
- }
- //const double tgtThick = /*Min( 0.5 * data._geomSize, */data._maxThickness;
// Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's
// boundary inclined to the shape at a sharp angle
- //list< TGeomID > shapesToSmooth;
TopTools_MapOfShape edgesOfSmooFaces;
-
SMESH_MesherHelper helper( *_mesh );
bool ok = true;
continue;
double tgtThick = eos._hyp.GetTotalThickness();
- TopExp_Explorer eExp( edgesByGeom[iS]._shape, TopAbs_EDGE );
- for ( ; eExp.More() && !eos._toSmooth; eExp.Next() )
+ SMESH_subMeshIteratorPtr subIt = eos._subMesh->getDependsOnIterator(/*includeSelf=*/false );
+ while ( subIt->more() && !eos._toSmooth )
{
- TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() );
- vector<_LayerEdge*>& eE = edgesByGeom[ iE ]._edges;
- if ( eE.empty() ) continue;
+ TGeomID iSub = subIt->next()->GetId();
+ const vector<_LayerEdge*>& eSub = edgesByGeom[ iSub ]._edges;
+ if ( eSub.empty() ) continue;
double faceSize;
- for ( size_t i = 0; i < eE.size() && !eos._toSmooth; ++i )
- if ( eE[i]->_cosin > theMinSmoothCosin )
+ for ( size_t i = 0; i < eSub.size() && !eos._toSmooth; ++i )
+ if ( eSub[i]->_cosin > theMinSmoothCosin )
{
- SMDS_ElemIteratorPtr fIt = eE[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
+ SMDS_ElemIteratorPtr fIt = eSub[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
while ( fIt->more() && !eos._toSmooth )
{
const SMDS_MeshElement* face = fIt->next();
if ( face->getshapeId() == eos._shapeID &&
- getDistFromEdge( face, eE[i]->_nodes[0], faceSize ))
+ getDistFromEdge( face, eSub[i]->_nodes[0], faceSize ))
{
- eos._toSmooth = needSmoothing( eE[i]->_cosin, tgtThick, faceSize );
+ eos._toSmooth = needSmoothing( eSub[i]->_cosin,
+ tgtThick * eSub[i]->_lenFactor,
+ faceSize);
}
}
}
}
if ( eos._toSmooth )
{
- for ( eExp.ReInit(); eExp.More(); eExp.Next() )
+ for ( TopExp_Explorer eExp( edgesByGeom[iS]._shape, TopAbs_EDGE ); eExp.More(); eExp.Next() )
edgesOfSmooFaces.Add( eExp.Current() );
data.PrepareEdgesToSmoothOnFace( &edgesByGeom[iS], /*substituteSrcNodes=*/false );
if ( endSeg->getshapeId() == (int) iS )
{
double segLen =
- SMESH_TNodeXYZ( endSeg->GetNode(0) ).Distance( endSeg->GetNode(1 ));
- eos._toSmooth = needSmoothing( cosinAbs, tgtThick, segLen );
+ SMESH_TNodeXYZ( endSeg->GetNode( 0 )).Distance( endSeg->GetNode( 1 ));
+ eos._toSmooth = needSmoothing( cosinAbs, tgtThick * eV[0]->_lenFactor, segLen );
}
}
if ( eos._toSmooth )
{
eos._edgeSmoother = new _Smoother1D( curve, eos );
- for ( size_t i = 0; i < eos._edges.size(); ++i )
- eos._edges[i]->Set( _LayerEdge::TO_SMOOTH );
+ // for ( size_t i = 0; i < eos._edges.size(); ++i )
+ // eos._edges[i]->Set( _LayerEdge::TO_SMOOTH );
}
}
}
if ( !eos._hyp.ToSmooth() )
for ( size_t i = 0; i < eos._edges.size(); ++i )
- eos._edges[i]->SetCosin( 0 );
+ //eos._edges[i]->SetCosin( 0 ); // keep _cosin to use in limitMaxLenByCurvature()
+ eos._edges[i]->_lenFactor = 1;
}
{
_EdgesOnShape* eof = data.GetShapeEdges( *face );
if ( !eof ) continue; // other solid
- if ( !eos.HasC1( eoe ))
- {
- eos._eosC1.push_back( eoe );
- eoe->_toSmooth = false;
- data.PrepareEdgesToSmoothOnFace( eoe, /*substituteSrcNodes=*/false );
- }
- if ( eos._shapeID != eof->_shapeID && !eos.HasC1( eof ))
+ if ( eos._shapeID == eof->_shapeID ) continue;
+ if ( !eos.HasC1( eof ))
{
+ // check the FACEs
eos._eosC1.push_back( eof );
eof->_toSmooth = false;
data.PrepareEdgesToSmoothOnFace( eof, /*substituteSrcNodes=*/false );
smQueue.push_back( eof->_subMesh );
}
+ if ( !eos.HasC1( eoe ))
+ {
+ eos._eosC1.push_back( eoe );
+ eoe->_toSmooth = false;
+ data.PrepareEdgesToSmoothOnFace( eoe, /*substituteSrcNodes=*/false );
+ }
}
}
}
if ( eos.ShapeType() == TopAbs_FACE ) // get normals to elements on a FACE
{
SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+ if ( !smDS ) return;
eos._faceNormals.resize( smDS->NbElements() );
SMDS_ElemIteratorPtr eIt = smDS->GetElements();
}
// find _normal
+ bool fromVonF = false;
if ( useGeometry )
{
- bool fromVonF = ( eos.ShapeType() == TopAbs_VERTEX &&
- eos.SWOLType() == TopAbs_FACE &&
- totalNbFaces > 1 );
+ fromVonF = ( eos.ShapeType() == TopAbs_VERTEX &&
+ eos.SWOLType() == TopAbs_FACE &&
+ totalNbFaces > 1 );
if ( onShrinkShape && !fromVonF ) // one of faces the node is on has no layers
{
break;
}
case TopAbs_VERTEX: {
- //if ( eos.SWOLType() != TopAbs_FACE ) // else _cosin is set by getFaceDir()
+ if ( fromVonF )
+ {
+ getFaceDir( TopoDS::Face( eos._sWOL ), TopoDS::Vertex( eos._shape ),
+ node, helper, normOK, &edge._cosin );
+ }
+ else if ( eos.SWOLType() != TopAbs_FACE ) // else _cosin is set by getFaceDir()
{
TopoDS_Vertex V = TopoDS::Vertex( eos._shape );
gp_Vec inFaceDir = getFaceDir( F, V, node, helper, normOK );
double angle = inFaceDir.Angle( edge._normal ); // [0,PI]
edge._cosin = Cos( angle );
if ( totalNbFaces > 2 || helper.IsSeamShape( node->getshapeId() ))
- for ( int iF = totalNbFaces-2; iF >=0; --iF )
+ for ( int iF = 1; iF < totalNbFaces; ++iF )
{
F = face2Norm[ iF ].first;
inFaceDir = getFaceDir( F, V, node, helper, normOK=true );
getMeshDS()->RemoveFreeNode( edge._nodes.back(), 0, /*fromGroups=*/false );
edge._nodes.resize( 1 );
edge._normal.SetCoord( 0,0,0 );
- edge._maxLen = 0;
+ edge.SetMaxLen( 0 );
}
// Set the rest data
isOK = false;
return p.XYZ();
}
- Quantity_Parameter U,V;
+ Standard_Real U,V;
projector.LowerDistanceParameters(U,V);
uv.SetCoord( U,V );
}
{
if ( eos.ShapeType() != TopAbs_EDGE )
return;
+ if ( _curvature && Is( SMOOTHED_C1 ))
+ return;
gp_XYZ pos = SMESH_TNodeXYZ( _nodes[0] );
gp_XYZ vec1 = pos - SMESH_TNodeXYZ( n1 );
_EdgesOnShape& eos = data._edgesOnShape[ iS ];
if ( eos._edges.empty() )
continue;
- // get neighbor faces intersection with which should not be considered since
+ // get neighbor faces, intersection with which should not be considered since
// collisions are avoided by means of smoothing
set< TGeomID > neighborFaces;
if ( eos._hyp.ToSmooth() )
for ( size_t i = 0; i < eos._edges.size(); ++i )
{
if ( eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
- eos._edges[i]->_maxLen = thinkness;
+ eos._edges[i]->SetMaxLen( thinkness );
eos._edges[i]->FindIntersection( *searcher, intersecDist, data._epsilon, eos, &face );
if ( intersecDist > 0 && face )
{
data._geomSize = Min( data._geomSize, intersecDist );
if ( !neighborFaces.count( face->getshapeId() ))
- eos._edges[i]->_maxLen = Min( thinkness, intersecDist / ( face->GetID() < 0 ? 3. : 2. ));
+ eos[i]->SetMaxLen( Min( thinkness, intersecDist / ( face->GetID() < 0 ? 3. : 2. )));
}
}
}
+
+ data._maxThickness = 0;
+ data._minThickness = 1e100;
+ list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin();
+ for ( ; hyp != data._hyps.end(); ++hyp )
+ {
+ data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() );
+ data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() );
+ }
+
+ // Limit inflation step size by geometry size found by intersecting
+ // normals of _LayerEdge's with mesh faces
+ if ( data._stepSize > 0.3 * data._geomSize )
+ limitStepSize( data, 0.3 * data._geomSize );
+
+ if ( data._stepSize > data._minThickness )
+ limitStepSize( data, data._minThickness );
+
+
+ // -------------------------------------------------------------------------
+ // Detect _LayerEdge which can't intersect with opposite or neighbor layer,
+ // so no need in detecting intersection at each inflation step
+ // -------------------------------------------------------------------------
+
+ int nbSteps = data._maxThickness / data._stepSize;
+ if ( nbSteps < 3 || nbSteps * data._n2eMap.size() < 100000 )
+ return;
+
+ vector< const SMDS_MeshElement* > closeFaces;
+ int nbDetected = 0;
+
+ for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
+ {
+ _EdgesOnShape& eos = data._edgesOnShape[ iS ];
+ if ( eos._edges.empty() || eos.ShapeType() != TopAbs_FACE )
+ continue;
+
+ for ( size_t i = 0; i < eos.size(); ++i )
+ {
+ SMESH_NodeXYZ p( eos[i]->_nodes[0] );
+ double radius = data._maxThickness + 2 * eos[i]->_maxLen;
+ closeFaces.clear();
+ searcher->GetElementsInSphere( p, radius, SMDSAbs_Face, closeFaces );
+
+ bool toIgnore = true;
+ for ( size_t iF = 0; iF < closeFaces.size() && toIgnore; ++iF )
+ if ( !( toIgnore = ( closeFaces[ iF ]->getshapeId() == eos._shapeID ||
+ data._ignoreFaceIds.count( closeFaces[ iF ]->getshapeId() ))))
+ {
+ // check if a _LayerEdge will inflate in a direction opposite to a direction
+ // toward a close face
+ bool allBehind = true;
+ for ( int iN = 0; iN < closeFaces[ iF ]->NbCornerNodes() && allBehind; ++iN )
+ {
+ SMESH_NodeXYZ pi( closeFaces[ iF ]->GetNode( iN ));
+ allBehind = (( pi - p ) * eos[i]->_normal < 0.1 * data._stepSize );
+ }
+ toIgnore = allBehind;
+ }
+
+
+ if ( toIgnore ) // no need to detect intersection
+ {
+ eos[i]->Set( _LayerEdge::INTERSECTED );
+ ++nbDetected;
+ }
+ }
+ }
+
+ debugMsg( "Nb LE to intersect " << data._n2eMap.size()-nbDetected << ", ignore " << nbDetected );
+
+ return;
}
//================================================================================
{
SMESH_MesherHelper helper( *_mesh );
- // Limit inflation step size by geometry size found by itersecting
- // normals of _LayerEdge's with mesh faces
- if ( data._stepSize > 0.3 * data._geomSize )
- limitStepSize( data, 0.3 * data._geomSize );
-
const double tgtThick = data._maxThickness;
- if ( data._stepSize > data._minThickness )
- limitStepSize( data, data._minThickness );
if ( data._stepSize < 1. )
data._epsilon = data._stepSize * 1e-7;
debugMsg( "-- geomSize = " << data._geomSize << ", stepSize = " << data._stepSize );
+ _pyDump->Pause();
findCollisionEdges( data, helper );
limitMaxLenByCurvature( data, helper );
+ _pyDump->Resume();
+
// limit length of _LayerEdge's around MULTI_NORMAL _LayerEdge's
for ( size_t i = 0; i < data._edgesOnShape.size(); ++i )
if ( data._edgesOnShape[i].ShapeType() == TopAbs_VERTEX &&
break;
}
#endif
+
// new step size
limitStepSize( data, 0.25 * distToIntersection );
if ( data._stepSizeNodes[0] )
_LayerEdge* edge = eos._edges[i];
if ( edge->_nodes.size() < 2 ) continue;
SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back();
+ //SMESH_TNodeXYZ prevXYZ = edge->_nodes[0];
gp_XYZ prevXYZ = edge->PrevCheckPos( &eos );
//const gp_XYZ& prevXYZ = edge->PrevPos();
for ( size_t j = 0; j < edge->_simplices.size(); ++j )
const SMDS_MeshElement* intFace = 0;
const SMDS_MeshElement* closestFace = 0;
_LayerEdge* le = 0;
+ bool is1stBlocked = true; // dbg
for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
{
_EdgesOnShape& eos = data._edgesOnShape[ iS ];
// ignore intersection of a _LayerEdge based on a _ConvexFace with a face
// lying on this _ConvexFace
if ( _ConvexFace* convFace = data.GetConvexFace( intFace->getshapeId() ))
- if ( convFace->_subIdToEOS.count ( eos._shapeID ))
+ if ( convFace->_isTooCurved && convFace->_subIdToEOS.count ( eos._shapeID ))
continue;
// ignore intersection of a _LayerEdge based on a FACE with an element on this FACE
continue;
// ignore intersection with intFace of an adjacent FACE
- if ( dist > 0 )
+ if ( dist > 0.1 * eos._edges[i]->_len )
{
bool toIgnore = false;
- if ( eos._edges[i]->Is( _LayerEdge::TO_SMOOTH ))
+ if ( eos._toSmooth )
{
const TopoDS_Shape& S = getMeshDS()->IndexToShape( intFace->getshapeId() );
if ( !S.IsNull() && S.ShapeType() == TopAbs_FACE )
{
- TopExp_Explorer edge( eos._shape, TopAbs_EDGE );
- for ( ; !toIgnore && edge.More(); edge.Next() )
- // is adjacent - has a common EDGE
- toIgnore = ( helper.IsSubShape( edge.Current(), S ));
+ TopExp_Explorer sub( eos._shape,
+ eos.ShapeType() == TopAbs_FACE ? TopAbs_EDGE : TopAbs_VERTEX );
+ for ( ; !toIgnore && sub.More(); sub.Next() )
+ // is adjacent - has a common EDGE or VERTEX
+ toIgnore = ( helper.IsSubShape( sub.Current(), S ));
if ( toIgnore ) // check angle between normals
{
if ( toBlockInfaltion &&
dist < ( eos._edges[i]->_len * theThickToIntersection ))
{
+ if ( is1stBlocked ) { is1stBlocked = false; // debug
+ dumpFunction(SMESH_Comment("blockIntersected") <<data._index<<"_InfStep"<<infStep);
+ }
eos._edges[i]->Set( _LayerEdge::INTERSECTED ); // not to intersect
eos._edges[i]->Block( data ); // not to inflate
} // loop on eos._edges
} // loop on data._edgesOnShape
+ if ( !is1stBlocked )
+ dumpFunctionEnd();
+
if ( closestFace && le )
{
#ifdef __myDEBUG
SMDS_MeshElement::iterator nIt = closestFace->begin_nodes();
- cout << "Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID()
+ cout << "#Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID()
<< " src " << le->_nodes[0]->GetID()<< ", intersection with face ("
<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()
<< ") distance = " << distToIntersection<< endl;
try
{
- BRepOffsetAPI_MakeOffsetShape offsetMaker( eos._shape, -offset, Precision::Confusion() );
+ BRepOffsetAPI_MakeOffsetShape offsetMaker;
+ offsetMaker.PerformByJoin( eos._shape, -offset, Precision::Confusion() );
if ( !offsetMaker.IsDone() ) return;
TopExp_Explorer fExp( offsetMaker.Shape(), TopAbs_FACE );
int infStep,
vector< _EdgesOnShape* >& eosC1,
int smooStep,
- bool moveAll )
+ int moveAll )
{
_EdgesOnShape * eof = & eos;
if ( eos.ShapeType() != TopAbs_FACE ) // eos is a boundary of C1 FACE, look for the FACE eos
edge->Unset( _LayerEdge::MARKED );
if ( edge->Is( _LayerEdge::BLOCKED ) || !edge->_curvature )
continue;
- if ( !moveAll && !edge->Is( _LayerEdge::MOVED ))
+ if ( moveAll == _LayerEdge::UPD_NORMAL_CONV )
+ {
+ if ( !edge->Is( _LayerEdge::UPD_NORMAL_CONV ))
continue;
+ }
+ else if ( !moveAll && !edge->Is( _LayerEdge::MOVED ))
+ continue;
int nbBlockedAround = 0;
for ( size_t iN = 0; iN < edge->_neibors.size(); ++iN )
gp_Pnt tgtP = SMESH_TNodeXYZ( edge->_nodes.back() );
gp_Pnt2d uv = eof->_offsetSurf->NextValueOfUV( edge->_curvature->_uv, tgtP, preci );
- if ( eof->_offsetSurf->Gap() > edge->_len ) continue; // NextValueOfUV() bug
+ if ( eof->_offsetSurf->Gap() > edge->_len ) continue; // NextValueOfUV() bug
edge->_curvature->_uv = uv;
if ( eof->_offsetSurf->Gap() < 10 * preci ) continue; // same pos
edge->_pos.back() = newP;
edge->Set( _LayerEdge::MARKED );
+ if ( moveAll == _LayerEdge::UPD_NORMAL_CONV )
+ {
+ edge->_normal = ( newP - prevP ).Normalized();
+ }
}
}
+
+
#ifdef _DEBUG_
// dumpMove() for debug
size_t i = 0;
break;
if ( i < eos._edges.size() )
{
- dumpFunction(SMESH_Comment("putOnOffsetSurface_F") << eos._shapeID
+ dumpFunction(SMESH_Comment("putOnOffsetSurface_S") << eos._shapeID
<< "_InfStep" << infStep << "_" << smooStep );
for ( ; i < eos._edges.size(); ++i )
{
dumpFunctionEnd();
}
#endif
+
+ _ConvexFace* cnvFace;
+ if ( moveAll != _LayerEdge::UPD_NORMAL_CONV &&
+ eos.ShapeType() == TopAbs_FACE &&
+ (cnvFace = eos.GetData().GetConvexFace( eos._shapeID )) &&
+ !cnvFace->_normalsFixedOnBorders )
+ {
+ // put on the surface nodes built on FACE boundaries
+ SMESH_subMeshIteratorPtr smIt = eos._subMesh->getDependsOnIterator(/*includeSelf=*/false);
+ while ( smIt->more() )
+ {
+ SMESH_subMesh* sm = smIt->next();
+ _EdgesOnShape* subEOS = eos.GetData().GetShapeEdges( sm->GetId() );
+ if ( !subEOS->_sWOL.IsNull() ) continue;
+ if ( std::find( eosC1.begin(), eosC1.end(), subEOS ) != eosC1.end() ) continue;
+
+ putOnOffsetSurface( *subEOS, infStep, eosC1, smooStep, _LayerEdge::UPD_NORMAL_CONV );
+ }
+ cnvFace->_normalsFixedOnBorders = true;
+ }
}
//================================================================================
return Handle(Geom_Curve)();
}
+//================================================================================
+/*!
+ * \brief Smooth edges on EDGE
+ */
+//================================================================================
+
+bool _Smoother1D::Perform(_SolidData& data,
+ Handle(ShapeAnalysis_Surface)& surface,
+ const TopoDS_Face& F,
+ SMESH_MesherHelper& helper )
+{
+ if ( _leParams.empty() || ( !isAnalytic() && _offPoints.empty() ))
+ prepare( data );
+
+ findEdgesToSmooth();
+ if ( isAnalytic() )
+ return smoothAnalyticEdge( data, surface, F, helper );
+ else
+ return smoothComplexEdge ( data, surface, F, helper );
+}
+
+//================================================================================
+/*!
+ * \brief Find edges to smooth
+ */
+//================================================================================
+
+void _Smoother1D::findEdgesToSmooth()
+{
+ _LayerEdge* leOnV[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
+ for ( int iEnd = 0; iEnd < 2; ++iEnd )
+ if ( leOnV[iEnd]->Is( _LayerEdge::NORMAL_UPDATED ))
+ _leOnV[iEnd]._cosin = Abs( _edgeDir[iEnd].Normalized() * leOnV[iEnd]->_normal );
+
+ _eToSmooth[0].first = _eToSmooth[0].second = 0;
+
+ for ( size_t i = 0; i < _eos.size(); ++i )
+ {
+ if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH ))
+ {
+ if ( needSmoothing( _leOnV[0]._cosin,
+ _eos[i]->_len * leOnV[0]->_lenFactor, _curveLen * _leParams[i] ) ||
+ isToSmooth( i )
+ )
+ _eos[i]->Set( _LayerEdge::TO_SMOOTH );
+ else
+ break;
+ }
+ _eToSmooth[0].second = i+1;
+ }
+
+ _eToSmooth[1].first = _eToSmooth[1].second = _eos.size();
+
+ for ( int i = _eos.size() - 1; i >= _eToSmooth[0].second; --i )
+ {
+ if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH ))
+ {
+ if ( needSmoothing( _leOnV[1]._cosin,
+ _eos[i]->_len * leOnV[1]->_lenFactor, _curveLen * ( 1.-_leParams[i] )) ||
+ isToSmooth( i ))
+ _eos[i]->Set( _LayerEdge::TO_SMOOTH );
+ else
+ break;
+ }
+ _eToSmooth[1].first = i;
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Check if iE-th _LayerEdge needs smoothing
+ */
+//================================================================================
+
+bool _Smoother1D::isToSmooth( int iE )
+{
+ SMESH_NodeXYZ pi( _eos[iE]->_nodes[0] );
+ SMESH_NodeXYZ p0( _eos[iE]->_2neibors->srcNode(0) );
+ SMESH_NodeXYZ p1( _eos[iE]->_2neibors->srcNode(1) );
+ gp_XYZ seg0 = pi - p0;
+ gp_XYZ seg1 = p1 - pi;
+ gp_XYZ tangent = seg0 + seg1;
+ double tangentLen = tangent.Modulus();
+ double segMinLen = Min( seg0.Modulus(), seg1.Modulus() );
+ if ( tangentLen < std::numeric_limits<double>::min() )
+ return false;
+ tangent /= tangentLen;
+
+ for ( size_t i = 0; i < _eos[iE]->_neibors.size(); ++i )
+ {
+ _LayerEdge* ne = _eos[iE]->_neibors[i];
+ if ( !ne->Is( _LayerEdge::TO_SMOOTH ) ||
+ ne->_nodes.size() < 2 ||
+ ne->_nodes[0]->GetPosition()->GetDim() != 2 )
+ continue;
+ gp_XYZ edgeVec = SMESH_NodeXYZ( ne->_nodes.back() ) - SMESH_NodeXYZ( ne->_nodes[0] );
+ double proj = edgeVec * tangent;
+ if ( needSmoothing( 1., proj, segMinLen ))
+ return true;
+ }
+ return false;
+}
+
//================================================================================
/*!
* \brief smooth _LayerEdge's on a staight EDGE or circular EDGE
{
if ( !isAnalytic() ) return false;
- const size_t iFrom = 0, iTo = _eos._edges.size();
+ size_t iFrom = 0, iTo = _eos._edges.size();
if ( _anaCurve->IsKind( STANDARD_TYPE( Geom_Line )))
{
if ( F.IsNull() ) // 3D
{
- SMESH_TNodeXYZ p0 ( _eos._edges[iFrom]->_2neibors->tgtNode(0) );
- SMESH_TNodeXYZ p1 ( _eos._edges[iTo-1]->_2neibors->tgtNode(1) );
SMESH_TNodeXYZ pSrc0( _eos._edges[iFrom]->_2neibors->srcNode(0) );
SMESH_TNodeXYZ pSrc1( _eos._edges[iTo-1]->_2neibors->srcNode(1) );
- gp_XYZ newPos, lineDir = pSrc1 - pSrc0;
- _LayerEdge* vLE0 = _eos._edges[iFrom]->_2neibors->_edges[0];
- _LayerEdge* vLE1 = _eos._edges[iTo-1]->_2neibors->_edges[1];
- bool shiftOnly = ( vLE0->Is( _LayerEdge::NORMAL_UPDATED ) ||
- vLE0->Is( _LayerEdge::BLOCKED ) ||
- vLE1->Is( _LayerEdge::NORMAL_UPDATED ) ||
- vLE1->Is( _LayerEdge::BLOCKED ));
- for ( size_t i = iFrom; i < iTo; ++i )
- {
- _LayerEdge* edge = _eos._edges[i];
- SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( edge->_nodes.back() );
- newPos = p0 * ( 1. - _leParams[i] ) + p1 * _leParams[i];
-
- if ( shiftOnly || edge->Is( _LayerEdge::NORMAL_UPDATED ))
- {
- gp_XYZ curPos = SMESH_TNodeXYZ ( tgtNode );
- double shift = ( lineDir * ( newPos - pSrc0 ) -
- lineDir * ( curPos - pSrc0 ));
- newPos = curPos + lineDir * shift / lineDir.SquareModulus();
- }
- if ( edge->Is( _LayerEdge::BLOCKED ))
+ //const gp_XYZ lineDir = pSrc1 - pSrc0;
+ //_LayerEdge* vLE0 = getLEdgeOnV( 0 );
+ //_LayerEdge* vLE1 = getLEdgeOnV( 1 );
+ // bool shiftOnly = ( vLE0->Is( _LayerEdge::NORMAL_UPDATED ) ||
+ // vLE0->Is( _LayerEdge::BLOCKED ) ||
+ // vLE1->Is( _LayerEdge::NORMAL_UPDATED ) ||
+ // vLE1->Is( _LayerEdge::BLOCKED ));
+ for ( int iEnd = 0; iEnd < 2; ++iEnd )
+ {
+ iFrom = _eToSmooth[ iEnd ].first, iTo = _eToSmooth[ iEnd ].second;
+ if ( iFrom >= iTo ) continue;
+ SMESH_TNodeXYZ p0( _eos[iFrom]->_2neibors->tgtNode(0) );
+ SMESH_TNodeXYZ p1( _eos[iTo-1]->_2neibors->tgtNode(1) );
+ double param0 = ( iFrom == 0 ) ? 0. : _leParams[ iFrom-1 ];
+ double param1 = _leParams[ iTo ];
+ for ( size_t i = iFrom; i < iTo; ++i )
{
- SMESH_TNodeXYZ pSrc( edge->_nodes[0] );
- double curThick = pSrc.SquareDistance( tgtNode );
- double newThink = ( pSrc - newPos ).SquareModulus();
- if ( newThink > curThick )
- continue;
+ _LayerEdge* edge = _eos[i];
+ SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( edge->_nodes.back() );
+ double param = ( _leParams[i] - param0 ) / ( param1 - param0 );
+ gp_XYZ newPos = p0 * ( 1. - param ) + p1 * param;
+
+ // if ( shiftOnly || edge->Is( _LayerEdge::NORMAL_UPDATED ))
+ // {
+ // gp_XYZ curPos = SMESH_TNodeXYZ ( tgtNode );
+ // double shift = ( lineDir * ( newPos - pSrc0 ) -
+ // lineDir * ( curPos - pSrc0 ));
+ // newPos = curPos + lineDir * shift / lineDir.SquareModulus();
+ // }
+ if ( edge->Is( _LayerEdge::BLOCKED ))
+ {
+ SMESH_TNodeXYZ pSrc( edge->_nodes[0] );
+ double curThick = pSrc.SquareDistance( tgtNode );
+ double newThink = ( pSrc - newPos ).SquareModulus();
+ if ( newThink > curThick )
+ continue;
+ }
+ edge->_pos.back() = newPos;
+ tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+ dumpMove( tgtNode );
}
- edge->_pos.back() = newPos;
- tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
- dumpMove( tgtNode );
}
}
else // 2D
{
- _LayerEdge* e0 = getLEdgeOnV( 0 );
- _LayerEdge* e1 = getLEdgeOnV( 1 );
- gp_XY uv0 = e0->LastUV( F, *data.GetShapeEdges( e0 ));
- gp_XY uv1 = e1->LastUV( F, *data.GetShapeEdges( e1 ));
- if ( e0->_nodes.back() == e1->_nodes.back() ) // closed edge
+ _LayerEdge* eV0 = getLEdgeOnV( 0 );
+ _LayerEdge* eV1 = getLEdgeOnV( 1 );
+ gp_XY uvV0 = eV0->LastUV( F, *data.GetShapeEdges( eV0 ));
+ gp_XY uvV1 = eV1->LastUV( F, *data.GetShapeEdges( eV1 ));
+ if ( eV0->_nodes.back() == eV1->_nodes.back() ) // closed edge
{
int iPeriodic = helper.GetPeriodicIndex();
if ( iPeriodic == 1 || iPeriodic == 2 )
{
- uv1.SetCoord( iPeriodic, helper.GetOtherParam( uv1.Coord( iPeriodic )));
- if ( uv0.Coord( iPeriodic ) > uv1.Coord( iPeriodic ))
- std::swap( uv0, uv1 );
+ uvV1.SetCoord( iPeriodic, helper.GetOtherParam( uvV1.Coord( iPeriodic )));
+ if ( uvV0.Coord( iPeriodic ) > uvV1.Coord( iPeriodic ))
+ std::swap( uvV0, uvV1 );
}
}
- const gp_XY rangeUV = uv1 - uv0;
- for ( size_t i = iFrom; i < iTo; ++i )
- {
- if ( _eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
- gp_XY newUV = uv0 + _leParams[i] * rangeUV;
- _eos._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 );
+ for ( int iEnd = 0; iEnd < 2; ++iEnd )
+ {
+ iFrom = _eToSmooth[ iEnd ].first, iTo = _eToSmooth[ iEnd ].second;
+ if ( iFrom >= iTo ) continue;
+ _LayerEdge* e0 = _eos[iFrom]->_2neibors->_edges[0];
+ _LayerEdge* e1 = _eos[iTo-1]->_2neibors->_edges[1];
+ gp_XY uv0 = ( e0 == eV0 ) ? uvV0 : e0->LastUV( F, _eos );
+ gp_XY uv1 = ( e1 == eV1 ) ? uvV1 : e1->LastUV( F, _eos );
+ double param0 = ( iFrom == 0 ) ? 0. : _leParams[ iFrom-1 ];
+ double param1 = _leParams[ iTo ];
+ gp_XY rangeUV = uv1 - uv0;
+ for ( size_t i = iFrom; i < iTo; ++i )
+ {
+ if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue;
+ double param = ( _leParams[i] - param0 ) / ( param1 - param0 );
+ gp_XY newUV = uv0 + param * rangeUV;
- gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() );
- SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _eos._edges[i]->_nodes.back() );
- tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
- dumpMove( tgtNode );
+ gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() );
+ SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _eos[i]->_nodes.back() );
+ tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+ dumpMove( tgtNode );
- SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
- pos->SetUParameter( newUV.X() );
- pos->SetVParameter( newUV.Y() );
+ SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
+ pos->SetUParameter( newUV.X() );
+ pos->SetVParameter( newUV.Y() );
+
+ gp_XYZ newUV0( newUV.X(), newUV.Y(), 0 );
+
+ if ( !_eos[i]->Is( _LayerEdge::SMOOTHED ))
+ {
+ _eos[i]->Set( _LayerEdge::SMOOTHED ); // to check in refine() (IPAL54237)
+ if ( _eos[i]->_pos.size() > 2 )
+ {
+ // modify previous positions to make _LayerEdge less sharply bent
+ vector<gp_XYZ>& uvVec = _eos[i]->_pos;
+ const gp_XYZ uvShift = newUV0 - uvVec.back();
+ const double len2 = ( uvVec.back() - uvVec[ 0 ] ).SquareModulus();
+ int iPrev = uvVec.size() - 2;
+ while ( iPrev > 0 )
+ {
+ double r = ( uvVec[ iPrev ] - uvVec[0] ).SquareModulus() / len2;
+ uvVec[ iPrev ] += uvShift * r;
+ --iPrev;
+ }
+ }
+ }
+ _eos[i]->_pos.back() = newUV0;
+ }
}
}
return true;
if ( uLast < 0 )
uLast += 2 * M_PI;
- for ( size_t i = iFrom; i < iTo; ++i )
+ for ( size_t i = 0; i < _eos.size(); ++i )
{
- if ( _eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
+ if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue;
+ //if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) continue;
double u = uLast * _leParams[i];
gp_Pnt p = ElCLib::Value( u, newCirc );
_eos._edges[i]->_pos.back() = p.XYZ();
gp_Ax2d axis( center, vec0 );
gp_Circ2d circ( axis, radius );
- for ( size_t i = iFrom; i < iTo; ++i )
+ for ( size_t i = 0; i < _eos.size(); ++i )
{
- if ( _eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
+ if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue;
+ //if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) continue;
double newU = uLast * _leParams[i];
gp_Pnt2d newUV = ElCLib::Value( newU, circ );
_eos._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 );
SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
pos->SetUParameter( newUV.X() );
pos->SetVParameter( newUV.Y() );
+
+ _eos[i]->Set( _LayerEdge::SMOOTHED ); // to check in refine() (IPAL54237)
}
}
return true;
if ( _offPoints.empty() )
return false;
+ // ----------------------------------------------
// move _offPoints along normals of _LayerEdge's
+ // ----------------------------------------------
_LayerEdge* e[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED ))
}
}
+ // -----------------------------------------------------------------
// project tgt nodes of extreme _LayerEdge's to the offset segments
+ // -----------------------------------------------------------------
- if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[0] = 0;
- if ( e[1]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[1] = _offPoints.size()-2;
+ const int updatedOrBlocked = _LayerEdge::NORMAL_UPDATED | _LayerEdge::BLOCKED;
+ if ( e[0]->Is( updatedOrBlocked )) _iSeg[0] = 0;
+ if ( e[1]->Is( updatedOrBlocked )) _iSeg[1] = _offPoints.size()-2;
gp_Pnt pExtreme[2], pProj[2];
+ bool isProjected[2];
for ( int is2nd = 0; is2nd < 2; ++is2nd )
{
pExtreme[ is2nd ] = SMESH_TNodeXYZ( e[is2nd]->_nodes.back() );
int i = _iSeg[ is2nd ];
int di = is2nd ? -1 : +1;
- bool projected = false;
+ bool & projected = isProjected[ is2nd ];
+ projected = false;
double uOnSeg, distMin = Precision::Infinite(), dist, distPrev = 0;
int nbWorse = 0;
do {
gp_Vec vDiv0( pExtreme[0], pProj[0] );
gp_Vec vDiv1( pExtreme[1], pProj[1] );
double d0 = vDiv0.Magnitude();
- double d1 = vDiv1.Magnitude();
- if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0;
- else e[0]->_len -= d0;
- if ( e[1]->_normal * vDiv1.XYZ() < 0 ) e[1]->_len += d1;
- else e[1]->_len -= d1;
+ double d1 = isProjected[1] ? vDiv1.Magnitude() : 0;
+ if ( e[0]->Is( _LayerEdge::BLOCKED )) {
+ if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0;
+ else e[0]->_len -= d0;
+ }
+ if ( e[1]->Is( _LayerEdge::BLOCKED )) {
+ if ( e[1]->_normal * vDiv1.XYZ() < 0 ) e[1]->_len += d1;
+ else e[1]->_len -= d1;
+ }
+ // ---------------------------------------------------------------------------------
// compute normalized length of the offset segments located between the projections
+ // ---------------------------------------------------------------------------------
+
+ // temporary replace extreme _offPoints by pExtreme
+ gp_XYZ opXYZ[2] = { _offPoints[ _iSeg[0] ]._xyz,
+ _offPoints[ _iSeg[1]+1 ]._xyz };
+ _offPoints[ _iSeg[0] ]._xyz = pExtreme[0].XYZ();
+ _offPoints[ _iSeg[1]+ 1]._xyz = pExtreme[1].XYZ();
size_t iSeg = 0, nbSeg = _iSeg[1] - _iSeg[0] + 1;
vector< double > len( nbSeg + 1 );
len[ iSeg++ ] = 0;
- len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz )/* * e[0]->_lenFactor*/;
+ len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz );
for ( size_t i = _iSeg[0]+1; i <= _iSeg[1]; ++i, ++iSeg )
{
len[ iSeg ] = len[ iSeg-1 ] + _offPoints[i].Distance( _offPoints[i+1] );
}
- len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz )/* * e[1]->_lenFactor*/;
+ // if ( isProjected[ 1 ])
+ // len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz );
+ // else
+ // len[ nbSeg ] += pExtreme[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz );
- // d0 *= e[0]->_lenFactor;
- // d1 *= e[1]->_lenFactor;
double fullLen = len.back() - d0 - d1;
for ( iSeg = 0; iSeg < len.size(); ++iSeg )
len[iSeg] = ( len[iSeg] - d0 ) / fullLen;
- // temporary replace extreme _offPoints by pExtreme
- gp_XYZ op[2] = { _offPoints[ _iSeg[0] ]._xyz,
- _offPoints[ _iSeg[1]+1 ]._xyz };
- _offPoints[ _iSeg[0] ]._xyz = pExtreme[0].XYZ();
- _offPoints[ _iSeg[1]+ 1]._xyz = pExtreme[1].XYZ();
-
+ // -------------------------------------------------------------
// distribute tgt nodes of _LayerEdge's between the projections
+ // -------------------------------------------------------------
iSeg = 0;
- for ( size_t i = 0; i < _eos._edges.size(); ++i )
+ for ( size_t i = 0; i < _eos.size(); ++i )
{
- if ( _eos._edges[i]->Is( _LayerEdge::BLOCKED )) continue;
+ if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue;
+ //if ( !_eos[i]->Is( _LayerEdge::TO_SMOOTH )) continue;
while ( iSeg+2 < len.size() && _leParams[i] > len[ iSeg+1 ] )
iSeg++;
double r = ( _leParams[i] - len[ iSeg ]) / ( len[ iSeg+1 ] - len[ iSeg ]);
if ( surface.IsNull() )
{
- _eos._edges[i]->_pos.back() = p;
+ _eos[i]->_pos.back() = p;
}
else // project a new node position to a FACE
{
- gp_Pnt2d uv ( _eos._edges[i]->_pos.back().X(), _eos._edges[i]->_pos.back().Y() );
+ gp_Pnt2d uv ( _eos[i]->_pos.back().X(), _eos[i]->_pos.back().Y() );
gp_Pnt2d uv2( surface->NextValueOfUV( uv, p, fTol ));
p = surface->Value( uv2 ).XYZ();
- _eos._edges[i]->_pos.back().SetCoord( uv2.X(), uv2.Y(), 0 );
+ _eos[i]->_pos.back().SetCoord( uv2.X(), uv2.Y(), 0 );
}
- SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _eos._edges[i]->_nodes.back() );
+ SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _eos[i]->_nodes.back() );
tgtNode->setXYZ( p.X(), p.Y(), p.Z() );
dumpMove( tgtNode );
}
- _offPoints[ _iSeg[0] ]._xyz = op[0];
- _offPoints[ _iSeg[1]+1 ]._xyz = op[1];
+ _offPoints[ _iSeg[0] ]._xyz = opXYZ[0];
+ _offPoints[ _iSeg[1]+1 ]._xyz = opXYZ[1];
return true;
}
double fullLen = _leParams.back() + pPrev.Distance( SMESH_TNodeXYZ( getLEdgeOnV(1)->_nodes[0]));
for ( size_t i = 0; i < _leParams.size()-1; ++i )
_leParams[i] = _leParams[i+1] / fullLen;
+ _leParams.back() = 1.;
}
+ _LayerEdge* leOnV[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
+
+ // get cosin to use in findEdgesToSmooth()
+ _edgeDir[0] = getEdgeDir( E, leOnV[0]->_nodes[0], data.GetHelper() );
+ _edgeDir[1] = getEdgeDir( E, leOnV[1]->_nodes[0], data.GetHelper() );
+ _leOnV[0]._cosin = Abs( leOnV[0]->_cosin );
+ _leOnV[1]._cosin = Abs( leOnV[1]->_cosin );
+ if ( _eos._sWOL.IsNull() ) // 3D
+ for ( int iEnd = 0; iEnd < 2; ++iEnd )
+ _leOnV[iEnd]._cosin = Abs( _edgeDir[iEnd].Normalized() * leOnV[iEnd]->_normal );
+
if ( isAnalytic() )
return;
// divide E to have offset segments with low deflection
BRepAdaptor_Curve c3dAdaptor( E );
- const double curDeflect = 0.1; //0.3; // 0.01; // Curvature deflection
- const double angDeflect = 0.1; //0.2; // 0.09; // Angular deflection
+ const double curDeflect = 0.1; //0.01; // Curvature deflection == |p1p2]*sin(p1p2,p1pM)
+ const double angDeflect = 0.1; //0.09; // Angular deflection == sin(p1pM,pMp2)
GCPnts_TangentialDeflection discret(c3dAdaptor, angDeflect, curDeflect);
if ( discret.NbPoints() <= 2 )
{
const double u0 = c3dAdaptor.FirstParameter();
gp_Pnt p; gp_Vec tangent;
- _offPoints.resize( discret.NbPoints() );
- for ( size_t i = 0; i < _offPoints.size(); i++ )
+ if ( discret.NbPoints() >= (int) _eos.size() + 2 )
{
- double u = discret.Parameter( i+1 );
- c3dAdaptor.D1( u, p, tangent );
- _offPoints[i]._xyz = p.XYZ();
- _offPoints[i]._edgeDir = tangent.XYZ();
- _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen;
+ _offPoints.resize( discret.NbPoints() );
+ for ( size_t i = 0; i < _offPoints.size(); i++ )
+ {
+ double u = discret.Parameter( i+1 );
+ c3dAdaptor.D1( u, p, tangent );
+ _offPoints[i]._xyz = p.XYZ();
+ _offPoints[i]._edgeDir = tangent.XYZ();
+ _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen;
+ }
}
+ else
+ {
+ std::vector< double > params( _eos.size() + 2 );
- _LayerEdge* leOnV[2] = { getLEdgeOnV(0), getLEdgeOnV(1) };
+ params[0] = data.GetHelper().GetNodeU( E, leOnV[0]->_nodes[0] );
+ params.back() = data.GetHelper().GetNodeU( E, leOnV[1]->_nodes[0] );
+ for ( size_t i = 0; i < _eos.size(); i++ )
+ params[i+1] = data.GetHelper().GetNodeU( E, _eos[i]->_nodes[0] );
+
+ if ( params[1] > params[ _eos.size() ] )
+ std::reverse( params.begin() + 1, params.end() - 1 );
+
+ _offPoints.resize( _eos.size() + 2 );
+ for ( size_t i = 0; i < _offPoints.size(); i++ )
+ {
+ const double u = params[i];
+ c3dAdaptor.D1( u, p, tangent );
+ _offPoints[i]._xyz = p.XYZ();
+ _offPoints[i]._edgeDir = tangent.XYZ();
+ _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen;
+ }
+ }
// set _2edges
_offPoints [0]._2edges.set( &_leOnV[0], &_leOnV[0], 0.5, 0.5 );
int iLBO = _offPoints.size() - 2; // last but one
- _edgeDir[0] = getEdgeDir( E, leOnV[0]->_nodes[0], data.GetHelper() );
- _edgeDir[1] = getEdgeDir( E, leOnV[1]->_nodes[0], data.GetHelper() );
-
- _leOnV[ 0 ]._normal = getNormalNormal( leOnV[0]->_normal, _edgeDir[0] );
- _leOnV[ 1 ]._normal = getNormalNormal( leOnV[1]->_normal, _edgeDir[1] );
+ if ( leOnV[ 0 ]->Is( _LayerEdge::MULTI_NORMAL ))
+ _leOnV[ 0 ]._normal = getNormalNormal( _eos._edges[1]->_normal, _edgeDir[0] );
+ else
+ _leOnV[ 0 ]._normal = getNormalNormal( leOnV[0]->_normal, _edgeDir[0] );
+ if ( leOnV[ 1 ]->Is( _LayerEdge::MULTI_NORMAL ))
+ _leOnV[ 1 ]._normal = getNormalNormal( _eos._edges.back()->_normal, _edgeDir[1] );
+ else
+ _leOnV[ 1 ]._normal = getNormalNormal( leOnV[1]->_normal, _edgeDir[1] );
_leOnV[ 0 ]._len = 0;
_leOnV[ 1 ]._len = 0;
_leOnV[ 0 ]._lenFactor = _offPoints[1 ]._2edges._edges[1]->_lenFactor;
//================================================================================
/*!
- * \brief set _normal of _leOnV[is2nd] to be normal to the EDGE
+ * \brief return _normal of _leOnV[is2nd] normal to the EDGE
*/
//================================================================================
gp_XYZ norm = edgeDir ^ cross;
double size = norm.Modulus();
+ // if ( size == 0 ) // MULTI_NORMAL _LayerEdge
+ // return gp_XYZ( 1e-100, 1e-100, 1e-100 );
+
return norm / size;
}
+//================================================================================
+/*!
+ * \brief Writes a script creating a mesh composed of _offPoints
+ */
+//================================================================================
+
+void _Smoother1D::offPointsToPython() const
+{
+ const char* fname = "/tmp/offPoints.py";
+ cout << "execfile('"<<fname<<"')"<<endl;
+ ofstream py(fname);
+ py << "import SMESH" << endl
+ << "from salome.smesh import smeshBuilder" << endl
+ << "smesh = smeshBuilder.New(salome.myStudy)" << endl
+ << "mesh = smesh.Mesh( 'offPoints' )"<<endl;
+ for ( size_t i = 0; i < _offPoints.size(); i++ )
+ {
+ py << "mesh.AddNode( "
+ << _offPoints[i]._xyz.X() << ", "
+ << _offPoints[i]._xyz.Y() << ", "
+ << _offPoints[i]._xyz.Z() << " )" << endl;
+ }
+}
+
//================================================================================
/*!
* \brief Sort _LayerEdge's by a parameter on a given EDGE
}
// SetSmooLen() to _LayerEdge's on FACE
- for ( size_t i = 0; i < eos->_edges.size(); ++i )
- {
- eos->_edges[i]->SetSmooLen( Precision::Infinite() );
- }
- SMESH_subMeshIteratorPtr smIt = eos->_subMesh->getDependsOnIterator(/*includeSelf=*/false);
- while ( smIt->more() ) // loop on sub-shapes of the FACE
- {
- _EdgesOnShape* eoe = GetShapeEdges( smIt->next()->GetId() );
- if ( !eoe ) continue;
-
- vector<_LayerEdge*>& eE = eoe->_edges;
- for ( size_t iE = 0; iE < eE.size(); ++iE ) // loop on _LayerEdge's on EDGE or VERTEX
- {
- if ( eE[iE]->_cosin <= theMinSmoothCosin )
- continue;
+ // for ( size_t i = 0; i < eos->_edges.size(); ++i )
+ // {
+ // eos->_edges[i]->SetSmooLen( Precision::Infinite() );
+ // }
+ // SMESH_subMeshIteratorPtr smIt = eos->_subMesh->getDependsOnIterator(/*includeSelf=*/false);
+ // while ( smIt->more() ) // loop on sub-shapes of the FACE
+ // {
+ // _EdgesOnShape* eoe = GetShapeEdges( smIt->next()->GetId() );
+ // if ( !eoe ) continue;
- SMDS_ElemIteratorPtr segIt = eE[iE]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge);
- while ( segIt->more() )
- {
- const SMDS_MeshElement* seg = segIt->next();
- if ( !eos->_subMesh->DependsOn( seg->getshapeId() ))
- continue;
- if ( seg->GetNode(0) != eE[iE]->_nodes[0] )
- continue; // not to check a seg twice
- for ( size_t iN = 0; iN < eE[iE]->_neibors.size(); ++iN )
- {
- _LayerEdge* eN = eE[iE]->_neibors[iN];
- if ( eN->_nodes[0]->getshapeId() != eos->_shapeID )
- continue;
- double dist = SMESH_MeshAlgos::GetDistance( seg, SMESH_TNodeXYZ( eN->_nodes[0] ));
- double smooLen = getSmoothingThickness( eE[iE]->_cosin, dist );
- eN->SetSmooLen( Min( smooLen, eN->GetSmooLen() ));
- eN->Set( _LayerEdge::NEAR_BOUNDARY );
- }
- }
- }
- }
+ // vector<_LayerEdge*>& eE = eoe->_edges;
+ // for ( size_t iE = 0; iE < eE.size(); ++iE ) // loop on _LayerEdge's on EDGE or VERTEX
+ // {
+ // if ( eE[iE]->_cosin <= theMinSmoothCosin )
+ // continue;
+
+ // SMDS_ElemIteratorPtr segIt = eE[iE]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge);
+ // while ( segIt->more() )
+ // {
+ // const SMDS_MeshElement* seg = segIt->next();
+ // if ( !eos->_subMesh->DependsOn( seg->getshapeId() ))
+ // continue;
+ // if ( seg->GetNode(0) != eE[iE]->_nodes[0] )
+ // continue; // not to check a seg twice
+ // for ( size_t iN = 0; iN < eE[iE]->_neibors.size(); ++iN )
+ // {
+ // _LayerEdge* eN = eE[iE]->_neibors[iN];
+ // if ( eN->_nodes[0]->getshapeId() != eos->_shapeID )
+ // continue;
+ // double dist = SMESH_MeshAlgos::GetDistance( seg, SMESH_TNodeXYZ( eN->_nodes[0] ));
+ // double smooLen = getSmoothingThickness( eE[iE]->_cosin, dist );
+ // eN->SetSmooLen( Min( smooLen, eN->GetSmooLen() ));
+ // eN->Set( _LayerEdge::NEAR_BOUNDARY );
+ // }
+ // }
+ // }
+ // }
} // if ( eos->ShapeType() == TopAbs_FACE )
for ( size_t i = 0; i < eos->_edges.size(); ++i )
avgLen /= edge->_simplices.size();
if (( edge->_curvature = _Curvature::New( avgNormProj, avgLen )))
{
+ edge->Set( _LayerEdge::SMOOTHED_C1 );
isCurved = true;
SMDS_FacePosition* fPos = dynamic_cast<SMDS_FacePosition*>( edge->_nodes[0]->GetPosition() );
if ( !fPos )
if ( eI->_nodes[0]->GetID() < eN->_nodes[0]->GetID() ) // treat this pair once
{
_EdgesOnShape* eosN = data.GetShapeEdges( eN );
- limitMaxLenByCurvature( eI, eN, eosI, *eosN, helper );
+ limitMaxLenByCurvature( eI, eN, eosI, *eosN, eosI._hyp.ToSmooth() );
}
}
}
for ( size_t i = 1; i < eosI._edges.size(); ++i )
{
_LayerEdge* eI = eosI._edges[i];
- limitMaxLenByCurvature( eI, e0, eosI, eosI, helper );
+ limitMaxLenByCurvature( eI, e0, eosI, eosI, eosI._hyp.ToSmooth() );
e0 = eI;
}
}
*/
//================================================================================
-void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge* e1,
- _LayerEdge* e2,
- _EdgesOnShape& eos1,
- _EdgesOnShape& eos2,
- SMESH_MesherHelper& helper )
+void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge* e1,
+ _LayerEdge* e2,
+ _EdgesOnShape& eos1,
+ _EdgesOnShape& eos2,
+ const bool isSmoothable )
{
+ if (( e1->_nodes[0]->GetPosition()->GetDim() !=
+ e2->_nodes[0]->GetPosition()->GetDim() ) &&
+ ( e1->_cosin < 0.75 ))
+ return; // angle > 90 deg at e1
+
gp_XYZ plnNorm = e1->_normal ^ e2->_normal;
double norSize = plnNorm.SquareModulus();
if ( norSize < std::numeric_limits<double>::min() )
double ovl = ( u1 * e1->_normal * dir12 -
u2 * e2->_normal * dir12 ) / dir12.SquareModulus();
if ( ovl > theSmoothThickToElemSizeRatio )
- {
- e1->_maxLen = Min( e1->_maxLen, 0.75 * u1 / e1->_lenFactor );
- e2->_maxLen = Min( e2->_maxLen, 0.75 * u2 / e2->_lenFactor );
+ {
+ const double coef = 0.75;
+ e1->SetMaxLen( Min( e1->_maxLen, coef * u1 / e1->_lenFactor ));
+ e2->SetMaxLen( Min( e2->_maxLen, coef * u2 / e2->_lenFactor ));
}
}
}
// else
// {
// double shortLen = 0.75 * ( Min( dist1, dist2 ) / edge->_lenFactor );
- // edge->_maxLen = Min( shortLen, edge->_maxLen );
+ // edge->SetMaxLen( Min( shortLen, edge->_maxLen ));
// }
}
}
}
+//================================================================================
+/*!
+ * \brief Find _LayerEdge's located on boundary of a convex FACE whose normal
+ * will be updated at each inflation step
+ */
+//================================================================================
+
+void _ViscousBuilder::findEdgesToUpdateNormalNearConvexFace( _ConvexFace & convFace,
+ _SolidData& data,
+ SMESH_MesherHelper& helper )
+{
+ const TGeomID convFaceID = getMeshDS()->ShapeToIndex( convFace._face );
+ const double preci = BRep_Tool::Tolerance( convFace._face );
+ Handle(ShapeAnalysis_Surface) surface = helper.GetSurface( convFace._face );
+
+ bool edgesToUpdateFound = false;
+
+ map< TGeomID, _EdgesOnShape* >::iterator id2eos = convFace._subIdToEOS.begin();
+ for ( ; id2eos != convFace._subIdToEOS.end(); ++id2eos )
+ {
+ _EdgesOnShape& eos = * id2eos->second;
+ if ( !eos._sWOL.IsNull() ) continue;
+ if ( !eos._hyp.ToSmooth() ) continue;
+ for ( size_t i = 0; i < eos._edges.size(); ++i )
+ {
+ _LayerEdge* ledge = eos._edges[ i ];
+ if ( ledge->Is( _LayerEdge::UPD_NORMAL_CONV )) continue; // already checked
+ if ( ledge->Is( _LayerEdge::MULTI_NORMAL )) continue; // not inflatable
+
+ gp_XYZ tgtPos = ( SMESH_NodeXYZ( ledge->_nodes[0] ) +
+ ledge->_normal * ledge->_lenFactor * ledge->_maxLen );
+
+ // the normal must be updated if distance from tgtPos to surface is less than
+ // target thickness
+
+ // find an initial UV for search of a projection of tgtPos to surface
+ const SMDS_MeshNode* nodeInFace = 0;
+ SMDS_ElemIteratorPtr fIt = ledge->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
+ while ( fIt->more() && !nodeInFace )
+ {
+ const SMDS_MeshElement* f = fIt->next();
+ if ( convFaceID != f->getshapeId() ) continue;
+
+ SMDS_ElemIteratorPtr nIt = f->nodesIterator();
+ while ( nIt->more() && !nodeInFace )
+ {
+ const SMDS_MeshElement* n = nIt->next();
+ if ( n->getshapeId() == convFaceID )
+ nodeInFace = static_cast< const SMDS_MeshNode* >( n );
+ }
+ }
+ if ( !nodeInFace )
+ continue;
+ gp_XY uv = helper.GetNodeUV( convFace._face, nodeInFace );
+
+ // projection
+ surface->NextValueOfUV( uv, tgtPos, preci );
+ double dist = surface->Gap();
+ if ( dist < 0.95 * ledge->_maxLen )
+ {
+ ledge->Set( _LayerEdge::UPD_NORMAL_CONV );
+ if ( !ledge->_curvature ) ledge->_curvature = new _Curvature;
+ ledge->_curvature->_uv.SetCoord( uv.X(), uv.Y() );
+ edgesToUpdateFound = true;
+ }
+ }
+ }
+
+ if ( !convFace._isTooCurved && edgesToUpdateFound )
+ {
+ data._convexFaces.insert( make_pair( convFaceID, convFace )).first->second;
+ }
+}
+
//================================================================================
/*!
* \brief Modify normals of _LayerEdge's on EDGE's to avoid intersection with
// compute new _normals
for ( size_t i = 0; i < intEdgesDist.size(); ++i )
{
- _LayerEdge* edge2 = intEdgesDist[i].first;
- double distWgt = edge1->_len / intEdgesDist[i].second;
+ _LayerEdge* edge2 = intEdgesDist[i].first;
+ double distWgt = edge1->_len / intEdgesDist[i].second;
// if ( edge1->Is( _LayerEdge::BLOCKED ) &&
// edge2->Is( _LayerEdge::BLOCKED )) continue;
if ( edge2->Is( _LayerEdge::MARKED )) continue;
e2neIt = edge2newEdge.insert( make_pair( edge1, zeroEdge )).first;
e2neIt->second._normal += distWgt * newNormal;
e2neIt->second._cosin = newCos;
- e2neIt->second._maxLen = 0.7 * minIntDist / edge1->_lenFactor;
+ e2neIt->second.SetMaxLen( 0.7 * minIntDist / edge1->_lenFactor );
if ( iter > 0 && sgn1 * sgn2 < 0 && edge1->_cosin < 0 )
e2neIt->second._normal += dir2;
+
e2neIt = edge2newEdge.insert( make_pair( edge2, zeroEdge )).first;
e2neIt->second._normal += distWgt * newNormal;
- e2neIt->second._cosin = edge2->_cosin;
+ if ( Precision::IsInfinite( zeroEdge._maxLen ))
+ {
+ e2neIt->second._cosin = edge2->_cosin;
+ e2neIt->second.SetMaxLen( 1.3 * minIntDist / edge1->_lenFactor );
+ }
if ( iter > 0 && sgn1 * sgn2 < 0 && edge2->_cosin < 0 )
e2neIt->second._normal += dir1;
}
for ( e2neIt = edge2newEdge.begin(); e2neIt != edge2newEdge.end(); ++e2neIt )
{
_LayerEdge* edge = e2neIt->first;
- if ( edge->Is( _LayerEdge::BLOCKED )) continue;
_LayerEdge& newEdge = e2neIt->second;
_EdgesOnShape* eos = data.GetShapeEdges( edge );
+ if ( edge->Is( _LayerEdge::BLOCKED && newEdge._maxLen > edge->_len ))
+ continue;
// Check if a new _normal is OK:
newEdge._normal.Normalize();
if ( newEdge._maxLen < edge->_len && iter > 0 ) // limit _maxLen
{
edge->InvalidateStep( stepNb + 1, *eos, /*restoreLength=*/true );
- edge->_maxLen = newEdge._maxLen;
+ edge->SetMaxLen( newEdge._maxLen );
edge->SetNewLength( newEdge._maxLen, *eos, helper );
}
continue; // the new _normal is bad
for ( ; id2face != data._convexFaces.end(); ++id2face )
{
_ConvexFace & convFace = (*id2face).second;
+ convFace._normalsFixedOnBorders = false; // to update at each inflation step
+
if ( convFace._normalsFixed )
continue; // already fixed
if ( convFace.CheckPrisms() )
return true;
}
+//================================================================================
+/*!
+ * \brief Return max curvature of a FACE
+ */
+//================================================================================
+
+double _ConvexFace::GetMaxCurvature( _SolidData& data,
+ _EdgesOnShape& eof,
+ BRepLProp_SLProps& surfProp,
+ SMESH_MesherHelper& helper)
+{
+ double maxCurvature = 0;
+
+ TopoDS_Face F = TopoDS::Face( eof._shape );
+
+ const int nbTestPnt = 5;
+ const double oriFactor = ( F.Orientation() == TopAbs_REVERSED ? +1. : -1. );
+ SMESH_subMeshIteratorPtr smIt = eof._subMesh->getDependsOnIterator(/*includeSelf=*/true);
+ while ( smIt->more() )
+ {
+ SMESH_subMesh* sm = smIt->next();
+ const TGeomID subID = sm->GetId();
+
+ // find _LayerEdge's of a sub-shape
+ _EdgesOnShape* eos;
+ if (( eos = data.GetShapeEdges( subID )))
+ this->_subIdToEOS.insert( make_pair( subID, eos ));
+ else
+ continue;
+
+ // check concavity and curvature and limit data._stepSize
+ const double minCurvature =
+ 1. / ( eos->_hyp.GetTotalThickness() * ( 1 + theThickToIntersection ));
+ size_t iStep = Max( 1, eos->_edges.size() / nbTestPnt );
+ for ( size_t i = 0; i < eos->_edges.size(); i += iStep )
+ {
+ gp_XY uv = helper.GetNodeUV( F, eos->_edges[ i ]->_nodes[0] );
+ surfProp.SetParameters( uv.X(), uv.Y() );
+ if ( surfProp.IsCurvatureDefined() )
+ {
+ double curvature = Max( surfProp.MaxCurvature() * oriFactor,
+ surfProp.MinCurvature() * oriFactor );
+ maxCurvature = Max( maxCurvature, curvature );
+
+ if ( curvature > minCurvature )
+ this->_isTooCurved = true;
+ }
+ }
+ } // loop on sub-shapes of the FACE
+
+ return maxCurvature;
+}
+
//================================================================================
/*!
* \brief Finds a center of curvature of a surface at a _LayerEdge
gp_XYZ _LayerEdge::PrevCheckPos( _EdgesOnShape* eos ) const
{
- size_t i = Is( NORMAL_UPDATED ) ? _pos.size()-2 : 0;
+ size_t i = Is( NORMAL_UPDATED ) && IsOnFace() ? _pos.size()-2 : 0;
if ( !eos || eos->_sWOL.IsNull() )
return _pos[ i ];
//================================================================================
/*!
- * \brief Return the last position of the target node on a FACE.
+ * \brief Return the last (or \a which) position of the target node on a FACE.
* \param [in] F - the FACE this _LayerEdge is inflated along
+ * \param [in] which - index of position
* \return gp_XY - result UV
*/
//================================================================================
-gp_XY _LayerEdge::LastUV( const TopoDS_Face& F, _EdgesOnShape& eos ) const
+gp_XY _LayerEdge::LastUV( const TopoDS_Face& F, _EdgesOnShape& eos, int which ) const
{
if ( F.IsSame( eos._sWOL )) // F is my FACE
return gp_XY( _pos.back().X(), _pos.back().Y() );
return gp_XY( 1e100, 1e100 );
// _sWOL is EDGE of F; _pos.back().X() is the last U on the EDGE
- double f, l, u = _pos.back().X();
+ double f, l, u = _pos[ which < 0 ? _pos.size()-1 : which ].X();
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( TopoDS::Edge(eos._sWOL), F, f,l);
if ( !C2d.IsNull() && f <= u && u <= l )
return C2d->Value( u ).XY();
* \param [in] eov - EOS of the VERTEX
* \param [in] eos - EOS of the FACE
* \param [in] step - inflation step
- * \param [in,out] badSmooEdges - not untangled _LayerEdge's
+ * \param [in,out] badSmooEdges - tangled _LayerEdge's
*/
//================================================================================
//if ( Is( BLOCKED )) return;
Set( BLOCKED );
- _maxLen = _len;
+ SMESH_Comment msg( "#BLOCK shape=");
+ msg << data.GetShapeEdges( this )->_shapeID
+ << ", nodes " << _nodes[0]->GetID() << ", " << _nodes.back()->GetID();
+ dumpCmd( msg + " -- BEGIN");
+
+ SetMaxLen( _len );
std::queue<_LayerEdge*> queue;
queue.push( this );
double newMaxLen = edge->_maxLen + 0.5 * Sqrt( minDist );
//if ( edge->_nodes[0]->getshapeId() == neibor->_nodes[0]->getshapeId() ) viscous_layers_00/A3
{
- newMaxLen *= edge->_lenFactor / neibor->_lenFactor;
+ //newMaxLen *= edge->_lenFactor / neibor->_lenFactor;
+ // newMaxLen *= Min( edge->_lenFactor / neibor->_lenFactor,
+ // neibor->_lenFactor / edge->_lenFactor );
}
if ( neibor->_maxLen > newMaxLen )
{
- neibor->_maxLen = newMaxLen;
+ neibor->SetMaxLen( newMaxLen );
if ( neibor->_maxLen < neibor->_len )
{
_EdgesOnShape* eos = data.GetShapeEdges( neibor );
+ int lastStep = neibor->Is( BLOCKED ) ? 1 : 0;
while ( neibor->_len > neibor->_maxLen &&
- neibor->NbSteps() > 1 )
+ neibor->NbSteps() > lastStep )
neibor->InvalidateStep( neibor->NbSteps(), *eos, /*restoreLength=*/true );
neibor->SetNewLength( neibor->_maxLen, *eos, data.GetHelper() );
//neibor->Block( data );
}
}
}
+ dumpCmd( msg + " -- END");
}
//================================================================================
if ( restoreLength )
{
- _len -= ( nXYZ.XYZ() - curXYZ ).Modulus() / _lenFactor;
+ if ( NbSteps() == 0 )
+ _len = 0.;
+ else if ( IsOnFace() && Is( MOVED ))
+ _len = ( nXYZ.XYZ() - SMESH_NodeXYZ( _nodes[0] )) * _normal;
+ else
+ _len -= ( nXYZ.XYZ() - curXYZ ).Modulus() / _lenFactor;
}
}
+ return;
}
//================================================================================
int iSmoothed = GetSmoothedPos( tol );
if ( !iSmoothed ) return;
- //if ( 1 || Is( DISTORTED ))
+ gp_XYZ normal = _normal;
+ if ( Is( NORMAL_UPDATED ))
{
- gp_XYZ normal = _normal;
- if ( Is( NORMAL_UPDATED ))
+ double minDot = 1;
+ for ( size_t i = 0; i < _neibors.size(); ++i )
+ {
+ if ( _neibors[i]->IsOnFace() )
+ {
+ double dot = _normal * _neibors[i]->_normal;
+ if ( dot < minDot )
+ {
+ normal = _neibors[i]->_normal;
+ minDot = dot;
+ }
+ }
+ }
+ if ( minDot == 1. )
for ( size_t i = 1; i < _pos.size(); ++i )
{
normal = _pos[i] - _pos[0];
break;
}
}
- const double r = 0.2;
- for ( int iter = 0; iter < 50; ++iter )
+ }
+ const double r = 0.2;
+ for ( int iter = 0; iter < 50; ++iter )
+ {
+ double minDot = 1;
+ for ( size_t i = Max( 1, iSmoothed-1-iter ); i < _pos.size()-1; ++i )
{
- double minDot = 1;
- for ( size_t i = Max( 1, iSmoothed-1-iter ); i < _pos.size()-1; ++i )
- {
- gp_XYZ midPos = 0.5 * ( _pos[i-1] + _pos[i+1] );
- gp_XYZ newPos = ( 1-r ) * midPos + r * _pos[i];
- _pos[i] = newPos;
- double midLen = 0.5 * ( segLen[i-1] + segLen[i+1] );
- double newLen = ( 1-r ) * midLen + r * segLen[i];
- const_cast< double& >( segLen[i] ) = newLen;
- // check angle between normal and (_pos[i+1], _pos[i] )
- gp_XYZ posDir = _pos[i+1] - _pos[i];
- double size = posDir.SquareModulus();
- if ( size > RealSmall() )
- minDot = Min( minDot, ( normal * posDir ) * ( normal * posDir ) / size );
- }
- if ( minDot > 0.5 * 0.5 )
- break;
+ gp_XYZ midPos = 0.5 * ( _pos[i-1] + _pos[i+1] );
+ gp_XYZ newPos = ( 1-r ) * midPos + r * _pos[i];
+ _pos[i] = newPos;
+ double midLen = 0.5 * ( segLen[i-1] + segLen[i+1] );
+ double newLen = ( 1-r ) * midLen + r * segLen[i];
+ const_cast< double& >( segLen[i] ) = newLen;
+ // check angle between normal and (_pos[i+1], _pos[i] )
+ gp_XYZ posDir = _pos[i+1] - _pos[i];
+ double size = posDir.SquareModulus();
+ if ( size > RealSmall() )
+ minDot = Min( minDot, ( normal * posDir ) * ( normal * posDir ) / size );
}
+ if ( minDot > 0.5 * 0.5 )
+ break;
}
- // else
- // {
- // for ( size_t i = 1; i < _pos.size()-1; ++i )
- // {
- // if ((int) i < iSmoothed && ( segLen[i] / segLen.back() < 0.5 ))
- // continue;
-
- // double wgt = segLen[i] / segLen.back();
- // gp_XYZ normPos = _pos[0] + _normal * wgt * _len;
- // gp_XYZ tgtPos = ( 1 - wgt ) * _pos[0] + wgt * _pos.back();
- // gp_XYZ newPos = ( 1 - wgt ) * normPos + wgt * tgtPos;
- // _pos[i] = newPos;
- // }
- // }
+ return;
}
//================================================================================
case BLOCKED: dump << "BLOCKED"; break;
case INTERSECTED: dump << "INTERSECTED"; break;
case NORMAL_UPDATED: dump << "NORMAL_UPDATED"; break;
+ case UPD_NORMAL_CONV: dump << "UPD_NORMAL_CONV"; break;
case MARKED: dump << "MARKED"; break;
case MULTI_NORMAL: dump << "MULTI_NORMAL"; break;
case NEAR_BOUNDARY: dump << "NEAR_BOUNDARY"; break;
return dump;
}
+
//================================================================================
/*!
- case brief:
- default:
-*/
+ * \brief Create layers of prisms
+ */
//================================================================================
bool _ViscousBuilder::refine(_SolidData& data)
double f,l, u = 0;
gp_XY uv;
vector< gp_XYZ > pos3D;
- bool isOnEdge;
+ bool isOnEdge, isTooConvexFace = false;
TGeomID prevBaseId = -1;
TNode2Edge* n2eMap = 0;
TNode2Edge::iterator n2e;
surface = helper.GetSurface( geomFace );
// propagate _toSmooth back to _eosC1, which was unset in findShapesToSmooth()
for ( size_t i = 0; i < eos._eosC1.size(); ++i )
- {
eos._eosC1[ i ]->_toSmooth = true;
- for ( size_t j = 0; j < eos._eosC1[i]->_edges.size(); ++j )
- eos._eosC1[i]->_edges[j]->Set( _LayerEdge::SMOOTHED_C1 );
- }
+
+ isTooConvexFace = false;
+ if ( _ConvexFace* cf = data.GetConvexFace( eos._shapeID ))
+ isTooConvexFace = cf->_isTooCurved;
}
vector< double > segLen;
if ( eos._sWOL.IsNull() )
{
bool useNormal = true;
- bool usePos = false;
- bool smoothed = false;
+ bool usePos = false;
+ bool smoothed = false;
double preci = 0.1 * edge._len;
if ( eos._toSmooth && edge._pos.size() > 2 )
{
}
if ( smoothed )
{
- if ( !surface.IsNull() &&
- !data._convexFaces.count( eos._shapeID )) // edge smoothed on FACE
+ if ( !surface.IsNull() && !isTooConvexFace ) // edge smoothed on FACE
{
useNormal = usePos = false;
gp_Pnt2d uv = helper.GetNodeUV( geomFace, edge._nodes[0] );
}
else if ( eos._isRegularSWOL ) // usual SWOL
{
- for ( size_t j = 1; j < edge._pos.size(); ++j )
- segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus();
+ if ( edge.Is( _LayerEdge::SMOOTHED ))
+ {
+ SMESH_NodeXYZ p0( edge._nodes[0] );
+ for ( size_t j = 1; j < edge._pos.size(); ++j )
+ {
+ gp_XYZ pj = surface->Value( edge._pos[j].X(), edge._pos[j].Y() ).XYZ();
+ segLen[j] = ( pj - p0 ) * edge._normal;
+ }
+ }
+ else
+ {
+ for ( size_t j = 1; j < edge._pos.size(); ++j )
+ segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus();
+ }
}
else if ( !surface.IsNull() ) // SWOL surface with singularities
{
const SMDS_MeshNode* tgtN0 = ledges[0]->_nodes.back();
const SMDS_MeshNode* tgtN1 = ledges[1]->_nodes.back();
int nbSharedPyram = 0;
- SMDS_ElemIteratorPtr vIt = tgtN0->GetInverseElementIterator(SMDSAbs_Volume);
+ SMDS_ElemIteratorPtr vIt = tgtN1->GetInverseElementIterator(SMDSAbs_Volume);
while ( vIt->more() )
{
const SMDS_MeshElement* v = vIt->next();
- nbSharedPyram += int( v->GetNodeIndex( tgtN1 ) >= 0 );
+ nbSharedPyram += int( v->GetNodeIndex( tgtN0 ) >= 0 );
}
if ( nbSharedPyram > 1 )
continue; // not free border of the pyramid
faceProj->Perform( p );
if ( !faceProj->IsDone() || faceProj->NbPoints() < 1 )
return setLayerEdgeData( lEdge, u, pcurve, curve, p, reverse, NULL );
- Quantity_Parameter U,V;
+ Standard_Real U,V;
faceProj->LowerDistanceParameters(U,V);
lEdge._normal2D.SetCoord( U - uv.X(), V - uv.Y() );
lEdge._normal2D.Normalize();
#include <Expr_NamedUnknown.hxx>
#include <Expr_GeneralExpression.hxx>
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
#include <Standard_Failure.hxx>
-
-#ifdef NO_CAS_CATCH
#include <Standard_ErrorHandler.hxx>
-#endif
#ifdef WIN32
# include <algorithm>
x = y = 0;
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
replot();
} catch(Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
}
}
Kernel_Utils::Localizer loc;
bool parsed_ok = true;
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
myExpr = ExprIntrp_GenExp::Create();
myExpr->Process( ( Standard_CString ) str.toLatin1().data() );
} catch(Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
parsed_ok = false;
}
ok = true;
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
res = myExpr->Expression()->Evaluate( myVars, myValues );
} catch(Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
ok = false;
res = 0.0;
}
case EXPONENT:
{
try {
-#ifdef NO_CAS_CATCH
OCC_CATCH_SIGNALS;
-#endif
// in StdMeshers_NumberOfSegments.cc
// const double PRECISION = 1e-7;
//
if(v < -7) v = -7.0;
v = pow( 10.0, v );
} catch(Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
v = 0.0;
ok = false;
}
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
IF(SALOME_BUILD_DOC)
ADD_SUBDIRECTORY(doc)
ENDIF(SALOME_BUILD_DOC)
-INCLUDE(UsePyQt)
+IF(SALOME_BUILD_GUI)
+ INCLUDE(UsePyQt)
+ENDIF(SALOME_BUILD_GUI)
# --- scripts ---
# scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
MGCleanerMonPlugDialog.py
MGCleanerMonViewText.py
MGCleanerplug_plugin.py
)
-# --- resources ---
-
-# uic files / to be processed by pyuic
-SET(_pyuic_files
- MGCleanerPlugDialog.ui
- MGCleanerViewText.ui
-)
-
-# scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+IF(SALOME_BUILD_GUI)
+ # uic files / to be processed by pyuic
+ SET(_pyuic_FILES
+ MGCleanerPlugDialog.ui
+ MGCleanerViewText.ui
+ )
+ # scripts / pyuic wrappings
+ PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
+ENDIF(SALOME_BUILD_GUI)
# --- rules ---
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
IF(SALOME_BUILD_GUI)
- SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
-ENDIF(SALOME_BUILD_GUI)
\ No newline at end of file
+ SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS} TARGET_NAME _target_name_pyuic_py)
+ # add dependency of compiled py files on uic files in order
+ # to avoid races problems when compiling in parallel
+ ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
+ENDIF(SALOME_BUILD_GUI)
# --- scripts ---
# scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
meshcut_plugin.py
)
)
IF(SALOME_BUILD_GUI)
- # --- resources ---
-
# uic files / to be processed by pyuic
- SET(_pyuic_files
+ SET(_pyuic_FILES
MeshCutDialog.ui
)
-
# scripts / pyuic wrappings
- PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
-
+ PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
ENDIF(SALOME_BUILD_GUI)
# --- rules ---
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
ADD_EXECUTABLE(MeshCut ${MeshCut_SOURCES})
TARGET_LINK_LIBRARIES(MeshCut ${_link_LIBRARIES})
INSTALL(TARGETS MeshCut EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS})
IF(SALOME_BUILD_GUI)
- INSTALL(FILES ${_pyuic_SCRIPTS} DESTINATION ${SALOME_INSTALL_BINS})
+ SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_BINS} TARGET_NAME _target_name_pyuic_py)
+ # add dependency of compiled py files on uic files in order
+ # to avoid races problems when compiling in parallel
+ ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
ENDIF(SALOME_BUILD_GUI)
# --- scripts ---
# scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
maFenetreChoix.py
monEditor.py
monNomBase.py
__init__.py
)
-# --- resources ---
-
# uic files / to be processed by pyuic
-SET(_pyuic_files
+SET(_pyuic_FILES
desFenetreChoix.ui
desStat.ui
myMainTotale.ui
nomBase.ui
tousLesJobs.ui
)
-
# scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
# --- rules ---
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui)
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui)
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui)
+SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/Verima/Gui TARGET_NAME _target_name_pyuic_py)
+# add dependency of compiled py files on uic files in order
+# to avoid races problems when compiling in parallel
+ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
'Entity_Quad_Pyramid':1,
'Entity_Penta ':1,
'Entity_Quad_Penta':1,
+'Entity_BiQuad_Penta':1,
'Entity_Hexagonal_Prism':1,
'Entity_Polyhedra':1,
'Entity_Quad_Polyhedra':1,
ADD_SUBDIRECTORY(doc)
ENDIF(SALOME_BUILD_DOC)
-INCLUDE(UsePyQt)
+IF(SALOME_BUILD_GUI)
+ INCLUDE(UsePyQt)
+ENDIF(SALOME_BUILD_GUI)
# --- scripts ---
# scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
monYamsPlugDialog.py
monViewText.py
yamsplug_plugin.py
)
-# --- resources ---
-
-# uic files / to be processed by pyuic
-SET(_pyuic_files
- YamsPlugDialog.ui
- ViewText.ui
-)
-
-# scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+IF(SALOME_BUILD_GUI)
+ # uic files / to be processed by pyuic
+ SET(_pyuic_FILES
+ YamsPlugDialog.ui
+ ViewText.ui
+ )
+ # scripts / pyuic wrappings
+ PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
+ENDIF(SALOME_BUILD_GUI)
# --- rules ---
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS})
\ No newline at end of file
+IF(SALOME_BUILD_GUI)
+ SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS} TARGET_NAME _target_name_pyuic_py)
+ # add dependency of compiled py files on uic files in order
+ # to avoid races problems when compiling in parallel
+ ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
+ENDIF(SALOME_BUILD_GUI)
- **Ridge detection**
if not set (ridge detection disabled ), MeshGems-SurfOpt will not try to detect any new ridge edge by its own mechanism :
-it will consider as ridge only the ridges given in the mesh. All non-ridge edges that would have been detected as ridge by the Ridge angle paramaeter (see below split edge) will be considered as part of the same continuous patch. This option should not be checked when all the known ridges of the mesh are given and when all other possible ridges are not geometric ridges to take into account.
+it will consider as ridge only the ridges given in the mesh. All non-ridge edges that would have been detected as ridge by the Ridge angle parameter (see below split edge) will be considered as part of the same continuous patch. This option should not be checked when all the known ridges of the mesh are given and when all other possible ridges are not geometric ridges to take into account.
- **Point smoothing**
When not set (point smoothing is disabled), MeshGems-SurfOpt will not try to move the initial given vertices (along an edge, a ridge or onto the surface), hence MeshGems-SurfOpt will only swap edges, remove vertices or add vertices (refines) to change the mesh.
- **Mesh gradation**
-This paramater P controls the element size variation : MeshGems-SurfOpt will avoid having two adjacent egdes which sizes vary more than th given gradation. a size correction is applied to the size map : if two adjacent edges are respectively e1 and e2 long and e2 > Pxe1, then, the new size for the second edge will be set to P x e1.
-**This procedure is desactived if P=-1**
+This parameter P controls the element size variation : MeshGems-SurfOpt will avoid having two adjacent egdes which sizes vary more than th given gradation. A size correction is applied to the size map : if two adjacent edges are respectively e1 and e2 long and e2 > Pxe1, then, the new size for the second edge will be set to P x e1.
+**This procedure is deactived if P=-1**
- relative : the maximal chordal deviation - epsilon max - is set to *s x the parameter* where *s* is the size
of the bounding box longest diagonal.
By default, the parameter is set to 0.001 and the maximum deviation is then set to 0.001 x s,
- which is equivalent to say that, for a bouding box of 1 meter, the maximal deviation is 1 mm.
+ which is equivalent to say that, for a bounding box of 1 meter, the maximal deviation is 1 mm.
- absolute : the maximal chordal deviation is the parameter itself. eg if the parameter equals 2, the maximal chordal deviation will be 2 (mm if the point coordonates are given in mm).
Following that criterion:
ADD_SUBDIRECTORY(casTests)
-INCLUDE(UsePyQt)
+IF(SALOME_BUILD_GUI)
+ INCLUDE(UsePyQt)
+ENDIF(SALOME_BUILD_GUI)
# --- scripts ---
# scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
__init__.py
ellipse.py
genereCrack.py
Zset.py
)
-SET(command_SCRIPTS
+SET(_command_SCRIPTS
zcracksLaunch.py
)
-# --- resources ---
-
-# uic files / to be processed by pyuic
-SET(_pyuic_files
- zcracks.ui
-)
-
-# scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+IF(SALOME_BUILD_GUI)
+ # uic files / to be processed by pyuic
+ SET(_pyuic_FILES
+ zcracks.ui
+ )
+ # scripts / pyuic wrappings
+ PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
+ENDIF(SALOME_BUILD_GUI)
# --- rules ---
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks)
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks)
-SALOME_INSTALL_SCRIPTS("${command_SCRIPTS}" ${SALOME_INSTALL_BINS})
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks)
+SALOME_INSTALL_SCRIPTS("${_command_SCRIPTS}" ${SALOME_INSTALL_BINS})
+IF(SALOME_BUILD_GUI)
+ SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks TARGET_NAME _target_name_pyuic_py)
+ # add dependency of compiled py files on uic files in order
+ # to avoid races problems when compiling in parallel
+ ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
+ENDIF(SALOME_BUILD_GUI)
+
<item row="2" column="0">
<widget class="QLabel" name="txtExtractLength">
<property name="toolTip">
- <string>Extraction length (optionnal)</string>
+ <string>Extraction length (optional)</string>
</property>
<property name="text">
<string>Extraction length</string>
# --- scripts ---
# scripts / static
-SET(plugin_SCRIPTS
+SET(_plugin_SCRIPTS
__init__.py
fissureCoude_ihm.py
fissureCoude_plugin.py
dialogFissureCoude.dic
)
-# --- resources ---
-
# uic files / to be processed by pyuic
-SET(_pyuic_files
+SET(_pyuic_FILES
fissureCoude.ui
fissureGenerale.ui
)
-
# scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
# --- rules ---
-SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm)
+SALOME_INSTALL_SCRIPTS("${_plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm)
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm)
+SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/blocFissure/ihm TARGET_NAME _target_name_pyuic_py)
+# add dependency of compiled py files on uic files in order
+# to avoid races problems when compiling in parallel
+ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
// Specification of the working spaces:
//
// - local_directory: can be used to specify where to find the input
- // files on the local resource. It's optionnal if you specify the
+ // files on the local resource. It's optional if you specify the
// absolute path name of input files.
//
// - result_directory: must be used to specify where to download the
# --- scripts ---
# scripts / static
-SET(py_SCRIPTS
+SET(_py_SCRIPTS
__init__.py
plugindialog.py
inputdialog.py
# --- resources ---
# uic files / to be processed by pyuic
-SET(spadderpy_DATA
+SET(_spadderpy_DATA
parameters.png
input.png
select.png
steelbar.png
)
-SET(_pyuic_files
+SET(_pyuic_FILES
plugindialog.ui
inputframe.ui
)
# scripts / pyuic wrappings
-PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic)
# --- rules ---
-SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)
-SALOME_INSTALL_SCRIPTS("${py_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)
-INSTALL(FILES ${spadderpy_DATA} DESTINATION ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)
+SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui TARGET_NAME _target_name_pyuic_py)
+# add dependency of compiled py files on uic files in order
+# to avoid races problems when compiling in parallel
+ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic})
+
+SALOME_INSTALL_SCRIPTS("${_py_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)
+
+INSTALL(FILES ${_spadderpy_DATA} DESTINATION ${SALOME_INSTALL_PYTHON}/salome/smesh/spadder/gui)