From: jfa Date: Mon, 13 Mar 2006 15:29:49 +0000 (+0000) Subject: Join modifications from branch OCC_development_for_3_2_0a2 X-Git-Tag: T2_3_2_0a2~1 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=4ff5bd61540272713e48de1eee75625028c32155 Join modifications from branch OCC_development_for_3_2_0a2 --- diff --git a/Makefile.in b/Makefile.in index f3a90dfb5..ded60d8ed 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,7 +14,7 @@ VPATH=.:@srcdir@:@top_srcdir@/bin:@top_srcdir@/resources:./bin:@top_srcdir@/idl @COMMENCE@ -SUBDIRS = idl src doc +SUBDIRS = idl src doc adm_local RESOURCES_FILES = \ delete.png \ @@ -131,7 +131,14 @@ mesh_pattern.png \ pattern_sample_2d.png \ pattern_sample_3D.png \ mesh_add.png \ -mesh_remove.png +mesh_remove.png \ +mesh_quad_edge.png \ +mesh_quad_triangle.png \ +mesh_quad_quadrangle.png \ +mesh_quad_tetrahedron.png \ +mesh_quad_pyramid.png \ +mesh_quad_pentahedron.png \ +mesh_quad_hexahedron.png BIN_SCRIPT= \ VERSION diff --git a/adm_local/Makefile.in b/adm_local/Makefile.in new file mode 100644 index 000000000..9b5e810db --- /dev/null +++ b/adm_local/Makefile.in @@ -0,0 +1,41 @@ +# source path +top_srcdir=@top_srcdir@ +top_builddir=.. +srcdir=@srcdir@ +VPATH=.:$(srcdir)/adm_local + + +all: resources + +install: + cp -rf @top_srcdir@/adm_local @prefix@ + +bin: + +resources : + cp -rf @top_srcdir@/adm_local $(top_builddir) + +inc: + +lib: + +depend: + +depend_idl: + +install-end: + +install-include: + +install-bin: + +uninstall: + +uninstall-idl: + +distclean: + +clean: + +distclean-other: + diff --git a/adm_local/unix/config_files/check_Geom.m4 b/adm_local/unix/config_files/check_Geom.m4 deleted file mode 100644 index 13f3be40c..000000000 --- a/adm_local/unix/config_files/check_Geom.m4 +++ /dev/null @@ -1,45 +0,0 @@ -# Check availability of Geom binary distribution -# -# Author : Nicolas REJNERI (OPEN CASCADE, 2003) -# - -AC_DEFUN([CHECK_GEOM],[ - -AC_CHECKING(for Geom) - -Geom_ok=no - -AC_ARG_WITH(geom, - [ --with-geom=DIR root directory path of GEOM installation ], - GEOM_DIR="$withval",GEOM_DIR="") - -if test "x$GEOM_DIR" == "x" ; then - -# no --with-geom-dir option used - - if test "x$GEOM_ROOT_DIR" != "x" ; then - - # GEOM_ROOT_DIR environment variable defined - GEOM_DIR=$GEOM_ROOT_DIR - - fi -# -fi - -if test -f ${GEOM_DIR}/lib/salome/libGEOMClient.so ; then - Geom_ok=yes - AC_MSG_RESULT(Using Geom module distribution in ${GEOM_DIR}) - - if test "x$GEOM_ROOT_DIR" == "x" ; then - GEOM_ROOT_DIR=${GEOM_DIR} - fi - AC_SUBST(GEOM_ROOT_DIR) - -else - AC_MSG_WARN("Cannot find compiled Geom module distribution") -fi - -AC_MSG_RESULT(for Geom: $Geom_ok) - -])dnl - diff --git a/adm_local/unix/config_files/check_Med.m4 b/adm_local/unix/config_files/check_Med.m4 deleted file mode 100644 index 727bf4381..000000000 --- a/adm_local/unix/config_files/check_Med.m4 +++ /dev/null @@ -1,45 +0,0 @@ -# Check availability of Med binary distribution -# -# Author : Nicolas REJNERI (OPEN CASCADE, 2003) -# - -AC_DEFUN([CHECK_MED],[ - -AC_CHECKING(for Med) - -Med_ok=no - -AC_ARG_WITH(med, - [ --with-med=DIR root directory path of MED installation ], - MED_DIR="$withval",MED_DIR="") - -if test "x$MED_DIR" == "x" ; then - -# no --with-med-dir option used - - if test "x$MED_ROOT_DIR" != "x" ; then - - # MED_ROOT_DIR environment variable defined - MED_DIR=$MED_ROOT_DIR - - fi -# -fi - -if test -f ${MED_DIR}/idl/salome/MED.idl ; then - Med_ok=yes - AC_MSG_RESULT(Using Med module distribution in ${MED_DIR}) - - if test "x$MED_ROOT_DIR" == "x" ; then - MED_ROOT_DIR=${MED_DIR} - fi - AC_SUBST(MED_ROOT_DIR) - -else - AC_MSG_WARN("Cannot find Med module sources") -fi - -AC_MSG_RESULT(for Med: $Med_ok) - -])dnl - diff --git a/adm_local/unix/config_files/check_SMESH.m4 b/adm_local/unix/config_files/check_SMESH.m4 new file mode 100644 index 000000000..86a8264b2 --- /dev/null +++ b/adm_local/unix/config_files/check_SMESH.m4 @@ -0,0 +1,54 @@ +# Check availability of SMesh binary distribution +# +# Author : Nicolas REJNERI (OPEN CASCADE, 2003) +# + +AC_DEFUN([CHECK_SMESH],[ + +AC_CHECKING(for SMesh) + +SMesh_ok=no + +AC_ARG_WITH(smesh, + [ --with-smesh=DIR root directory path of SMESH installation ], + SMESH_DIR="$withval",SMESH_DIR="") + +if test "x$SMESH_DIR" == "x" ; then + +# no --with-smesh option used + + if test "x$SMESH_ROOT_DIR" != "x" ; then + + # SMESH_ROOT_DIR environment variable defined + SMESH_DIR=$SMESH_ROOT_DIR + + else + + # search SMESH binaries in PATH variable + AC_PATH_PROG(TEMP, libSMESH_Swig.py) + if test "x$TEMP" != "x" ; then + SMESH_BIN_DIR=`dirname $TEMP` + SMESH_DIR=`dirname $SMESH_BIN_DIR` + fi + + fi +# +fi + +if test -f ${SMESH_DIR}/bin/salome/libSMESH_Swig.py ; then + SMesh_ok=yes + AC_MSG_RESULT(Using SMesh module distribution in ${SMESH_DIR}) + + if test "x$SMESH_ROOT_DIR" == "x" ; then + SMESH_ROOT_DIR=${SMESH_DIR} + fi + AC_SUBST(SMESH_ROOT_DIR) + +else + AC_MSG_WARN("Cannot find compiled SMesh module distribution") +fi + +AC_MSG_RESULT(for SMesh: $SMesh_ok) + +])dnl + diff --git a/adm_local/unix/config_files/check_f77.m4 b/adm_local/unix/config_files/check_f77.m4 new file mode 100644 index 000000000..1b74a8532 --- /dev/null +++ b/adm_local/unix/config_files/check_f77.m4 @@ -0,0 +1,29 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +AC_DEFUN([CHECK_F77],[ + +AC_PROG_F77 + +AC_F77_LIBRARY_LDFLAGS +AC_F77_WRAPPERS + +])dnl diff --git a/adm_local/unix/make_commence.in b/adm_local/unix/make_commence.in index 5e556548e..7f57ab3d8 100644 --- a/adm_local/unix/make_commence.in +++ b/adm_local/unix/make_commence.in @@ -240,14 +240,27 @@ $(top_srcdir)/configure.in: $(top_srcdir)/configure.in.base ACLOCAL_SRC = \ -ac_cxx_bool.m4 check_corba.m4 check_vtk.m4 \ +ac_cxx_bool.m4 check_corba.m4 \ ac_cxx_depend_flag.m4 check_hdf5.m4 enable_pthreads.m4 \ ac_cxx_mutable.m4 check_mico.m4 libtool.m4 \ ac_cxx_namespaces.m4 check_omniorb.m4 pyembed.m4 \ -ac_cxx_partial_specialization.m4 check_opengl.m4 python.m4 \ +ac_cxx_partial_specialization.m4 python.m4 \ ac_cxx_typename.m4 check_pthreads.m4 check_cas.m4 \ -ac_cc_warnings.m4 check_qt.m4 check_boost.m4 \ -check_swig.m4 - -$(top_srcdir)/aclocal.m4: $(ACLOCAL_SRC:%=@KERNEL_ROOT_DIR@/salome_adm/unix/config_files/%) - cd $(top_srcdir) ; aclocal --acdir=adm_local/unix/config_files -I @KERNEL_ROOT_DIR@/salome_adm/unix/config_files +ac_cc_warnings.m4 check_boost.m4 check_swig.m4 + +ACLOCAL_GUI = \ +check_vtk.m4 check_opengl.m4 check_qt.m4 \ +check_GUI.m4 check_corba_in_GUI.m4 + +ACLOCAL_MED = check_Med.m4 +ACLOCAL_GEOM = check_GEOM.m4 + +$(top_srcdir)/aclocal.m4: $(ACLOCAL_SRC:%=@KERNEL_ROOT_DIR@/salome_adm/unix/config_files/%) \ + $(ACLOCAL_GUI:%=@GUI_ROOT_DIR@/adm_local/unix/config_files/%) \ + $(ACLOCAL_MED:%=@MED_ROOT_DIR@/adm_local/unix/config_files/%) \ + $(ACLOCAL_GEOM:%=@GEOM_ROOT_DIR@/adm_local/unix/config_files/%) + cd $(top_srcdir) ; aclocal --acdir=adm_local/unix/config_files -I @KERNEL_ROOT_DIR@/salome_adm/unix/config_files \ + -I @GUI_ROOT_DIR@/adm_local/unix/config_files \ + -I @MED_ROOT_DIR@/adm_local/unix/config_files \ + -I @GEOM_ROOT_DIR@/adm_local/unix/config_files + \ No newline at end of file diff --git a/build_configure b/build_configure index b884b1757..2d81c7eae 100755 --- a/build_configure +++ b/build_configure @@ -26,6 +26,31 @@ fi # echo "failed : KERNEL_SRC variable is not correct !" # exit #fi + +######################################################################## +# Test if the GUI_ROOT_DIR is set correctly + +if test ! -d "${GUI_ROOT_DIR}"; then + echo "failed : GUI_ROOT_DIR variable is not correct !" + exit +fi + +######################################################################## +# Test if the MED_ROOT_DIR is set correctly + +if test ! -d "${MED_ROOT_DIR}"; then + echo "failed : MED_ROOT_DIR variable is not correct !" + exit +fi + +######################################################################## +# Test if the GEOM_ROOT_DIR is set correctly + +if test ! -d "${GEOM_ROOT_DIR}"; then + echo "failed : GEOM_ROOT_DIR variable is not correct !" + exit +fi + ######################################################################## # find_in - utility function # @@ -203,7 +228,10 @@ else echo -n "Creating 'configure' script ... " fi -aclocal --acdir=adm_local/unix/config_files -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files +aclocal -I adm_local/unix/config_files -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ + -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \ + -I ${MED_ROOT_DIR}/adm_local/unix/config_files \ + -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files if autoconf then echo "done" diff --git a/configure.in.base b/configure.in.base index d81e49771..d0105c7b0 100644 --- a/configure.in.base +++ b/configure.in.base @@ -265,6 +265,26 @@ echo CHECK_HTML_GENERATORS +echo +echo --------------------------------------------- +echo Testing GUI +echo --------------------------------------------- +echo + +CHECK_SALOME_GUI + +echo +echo --------------------------------------------- +echo Testing full GUI +echo --------------------------------------------- +echo + +CHECK_CORBA_IN_GUI +if test "x${CORBA_IN_GUI}" != "xyes"; then + echo "failed : For configure SMESH module necessary full GUI !" + exit +fi + echo echo --------------------------------------------- echo Testing Kernel diff --git a/doc/salome/gui/SMESH/defining_hypotheses_tui.htm b/doc/salome/gui/SMESH/defining_hypotheses_tui.htm index 581805053..0874e4507 100755 --- a/doc/salome/gui/SMESH/defining_hypotheses_tui.htm +++ b/doc/salome/gui/SMESH/defining_hypotheses_tui.htm @@ -284,58 +284,54 @@ else

# create vertices

-

px   = - geompy.MakeVertex(100., 0.  , - 0.  )

+

px   =geompy.MakeVertex(100., 0.  ,0.  )

-

py   = - geompy.MakeVertex(0.  , - 100., 0.  )

+

py   =geompy.MakeVertex(0.  ,100., 0.  )

-

pz   = - geompy.MakeVertex(0.  , - 0.  , 100.)

+

pz   =geompy.MakeVertex(0.  ,0.  , 100.)

 

# create a vector from two points

-

vxy = geompy.MakeVector(px, - py)

+

vxy = geompy.MakeVector(px,py)

 

# create an arc from three points

-

arc = geompy.MakeArc(py, - pz, px)

+

arc = geompy.MakeArc(py, pz, px)

 

# create a wire

-

wire = geompy.MakeWire([vxy, - arc])

+

wire = geompy.MakeWire([vxy,arc])

isPlanarFace = 1

 

-

# create a face from - the wire

+

# create a face from the wire

-

face1 = geompy.MakeFace(wire, - isPlanarFace)

+

face1 = geompy.MakeFace(wire,isPlanarFace)

 

-

# add objects in the - study

+

# get edges from the face

+ +

vxy, arc = geompy.SubShapeAll(face1, geompy.ShapeType["EDGE"])

+ +

 

+ +

# add objects in the study

id_face1 = geompy.addToStudy(face1,"Face1")

+

id_arc = geompy.addToStudyInFather(face1,arc,"Arc Edge")

+

 

# display faces

@@ -350,44 +346,34 @@ else

# create hexahedral mesh

-

hexa = smesh.Mesh(face1, - "Face compound : hexahedrical mesh")

+

hexa = smesh.Mesh(face1,"Face compound : hexahedrical mesh")

algo = hexa.Triangle()

 

-

# define "MaxElementArea" - hypothesis to be applied  to - each triangle

+

# define "MaxElementArea"hypothesis

algo.MaxElementArea(30)

 

-

# create a quadrangle - 2D algorithm for faces

- -

hexa.Quadrangle()

- -

 

- -

# create a local hypothesis

+

# create a local hypothesis on the wire

algo = hexa.Segment(wire)

 

-

# define "NumberOfSegments" - hypothesis to cut an edge in a fixed number of segments

+

# define "NumberOfSegments"hypothesis to cut +a straight edge in a fixed number of segments

algo.NumberOfSegments(6)

 

-

# define "Deflection1D" - hypothesis

+

# define a local "Deflection1D"hypothesis on the arc

+

algo = hexa.Segment(arc)

algo.Deflection1D(1)

 

diff --git a/idl/SMESH_BasicHypothesis.idl b/idl/SMESH_BasicHypothesis.idl index b6367b75d..7880020e7 100644 --- a/idl/SMESH_BasicHypothesis.idl +++ b/idl/SMESH_BasicHypothesis.idl @@ -286,6 +286,20 @@ module StdMeshers { }; + /*! + * StdMeshers_QuadraticMesh: interface of "QuadraticMesh" hypothesis. + * This is an auxiliary 1D hypothesis whose presence forces construction + * of quadratic edges. + * If the 2D mesher sees that all boundary edges are quadratic ones, + * it generates quadratic faces, else it generates linear faces using + * medium nodes as if they were vertex ones. + * The 3D mesher generates quadratic volumes only if all boundary faces + * are quadratic ones, else it fails. + */ + interface StdMeshers_QuadraticMesh : SMESH::SMESH_Hypothesis + { + }; + /*! * StdMeshers_Regular_1D: interface of "Wire discretisation" algorithm diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index bc6edfb72..ee234b95e 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -59,6 +59,16 @@ module SMESH SMESH_Pattern GetPattern(); + /*! + Set the current mode + */ + void SetEmbeddedMode( in boolean theMode ); + + /*! + Get the current mode + */ + boolean IsEmbeddedMode(); + /*! Set the current study */ diff --git a/idl/SMESH_Group.idl b/idl/SMESH_Group.idl index 37657674b..3cbb606da 100644 --- a/idl/SMESH_Group.idl +++ b/idl/SMESH_Group.idl @@ -84,6 +84,16 @@ module SMESH * Returns the mesh object this group belongs to */ SMESH_Mesh GetMesh(); + + /*! + * Sets group color number + */ + void SetColorNumber( in long color ); + + /*! + * Returns group color number + */ + long GetColorNumber(); }; /*! diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 1fe2f2dd8..4b7b54707 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -69,7 +69,14 @@ module SMESH MOVE_NODE, CHANGE_ELEMENT_NODES, CHANGE_POLYHEDRON_NODES, - RENUMBER + RENUMBER, + ADD_QUADEDGE, + ADD_QUADTRIANGLE, + ADD_QUADQUADRANGLE, + ADD_QUADTETRAHEDRON, + ADD_QUADPYRAMID, + ADD_QUADPENTAHEDRON, + ADD_QUADHEXAHEDRON }; struct log_block @@ -119,7 +126,8 @@ module SMESH HYP_INCOMPATIBLE, // hypothesis does not fit algo HYP_NOTCONFORM, // not conform mesh is produced appling a hypothesis HYP_ALREADY_EXIST,// such hypothesis already exist - HYP_BAD_DIM // bad dimension + HYP_BAD_DIM, // bad dimension + HYP_BAD_SUBSHAPE // shape is neither the main one, nor its subshape, nor a group }; /*! @@ -335,6 +343,11 @@ module SMESH SMESH_MeshEditor GetMeshEditor() raises (SALOME::SALOME_Exception); + /*! Check group names for duplications. + * Consider maximum group name length stored in MED file. + */ + boolean HasDuplicatedGroupNamesMED(); + /*! * Export Mesh to different MED Formats * @params @@ -434,6 +447,12 @@ module SMESH * Get mesh description */ string Dump(); + + /*! + * Get mesh pointer + */ + long GetMeshPtr(); + }; interface SMESH_subMesh : SALOME::GenericObj, SMESH_IDSource @@ -514,6 +533,8 @@ module SMESH boolean AddFace(in long_array IDsOfNodes); + boolean AddPolygonalFace(in long_array IdsOfNodes); + boolean AddVolume(in long_array IDsOfNodes); /*! diff --git a/resources/StdMeshers.xml b/resources/StdMeshers.xml index 2c1cd12cc..6daf06253 100644 --- a/resources/StdMeshers.xml +++ b/resources/StdMeshers.xml @@ -57,6 +57,12 @@ icon-id="mesh_algo_quad.png" dim="2"/> + + FindElement( theId ); - if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 ) + if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge/* || anEdge->NbNodes() != 2 */) return 0; - TColStd_MapOfInteger aMap; - - int aResult = 0; - SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); - if ( anIter != 0 ) { - while( anIter->more() ) { - const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); - if ( aNode == 0 ) - return 0; - SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); - while( anElemIter->more() ) { - const SMDS_MeshElement* anElem = anElemIter->next(); - if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { - int anId = anElem->GetID(); - - if ( anIter->more() ) // i.e. first node - aMap.Add( anId ); - else if ( aMap.Contains( anId ) ) - aResult++; - } - } + // for each pair of nodes in anEdge (there are 2 pairs in a quadratic edge) + // count elements containing both nodes of the pair. + // Note that there may be such cases for a quadratic edge (a horizontal line): + // + // Case 1 Case 2 + // | | | | | + // | | | | | + // +-----+------+ +-----+------+ + // | | | | + // | | | | + // result sould be 2 in both cases + // + int aResult0 = 0, aResult1 = 0; + // last node, it is a medium one in a quadratic edge + const SMDS_MeshNode* aLastNode = anEdge->GetNode( anEdge->NbNodes() - 1 ); + const SMDS_MeshNode* aNode0 = anEdge->GetNode( 0 ); + const SMDS_MeshNode* aNode1 = anEdge->GetNode( 1 ); + if ( aNode1 == aLastNode ) aNode1 = 0; + + SMDS_ElemIteratorPtr anElemIter = aLastNode->GetInverseElementIterator(); + while( anElemIter->more() ) { + const SMDS_MeshElement* anElem = anElemIter->next(); + if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + while ( anIter->more() ) { + if ( const SMDS_MeshElement* anElemNode = anIter->next() ) { + if ( anElemNode == aNode0 ) { + aResult0++; + if ( !aNode1 ) break; // not a quadratic edge + } + else if ( anElemNode == aNode1 ) + aResult1++; + } + } } } + int aResult = max ( aResult0, aResult1 ); + +// TColStd_MapOfInteger aMap; + +// SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); +// if ( anIter != 0 ) { +// while( anIter->more() ) { +// const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); +// if ( aNode == 0 ) +// return 0; +// SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); +// while( anElemIter->more() ) { +// const SMDS_MeshElement* anElem = anElemIter->next(); +// if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { +// int anId = anElem->GetID(); + +// if ( anIter->more() ) // i.e. first node +// aMap.Add( anId ); +// else if ( aMap.Contains( anId ) ) +// aResult++; +// } +// } +// } +// } return aResult; } @@ -154,23 +193,41 @@ bool NumericalFunctor::GetPoints(const int theId, } bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, - TSequenceOfXYZ& theRes ) + TSequenceOfXYZ& theRes ) { theRes.clear(); if ( anElem == 0) return false; + theRes.reserve( anElem->NbNodes() ); + // Get nodes of the element - SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); - if ( anIter != 0 ) - { - while( anIter->more() ) - { - const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); - if ( aNode != 0 ){ + SMDS_ElemIteratorPtr anIter; + + if ( anElem->IsQuadratic() ) { + switch ( anElem->GetType() ) { + case SMDSAbs_Edge: + anIter = static_cast + (anElem)->interlacedNodesElemIterator(); + break; + case SMDSAbs_Face: + anIter = static_cast + (anElem)->interlacedNodesElemIterator(); + break; + default: + anIter = anElem->nodesIterator(); + //return false; + } + } + else { + anIter = anElem->nodesIterator(); + } + + if ( anIter ) { + while( anIter->more() ) { + if ( const SMDS_MeshNode* aNode = static_cast( anIter->next() )) theRes.push_back( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); - } } } @@ -285,6 +342,7 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) // According to "Mesh quality control" by Nadir Bouhamau referring to // Pascal Jean Frey and Paul-Louis George. Maillages, applications aux elements finis. // Hermes Science publications, Paris 1999 ISBN 2-7462-0024-4 + // PAL10872 int nbNodes = P.size(); @@ -840,22 +898,21 @@ SMDSAbs_ElementType Skew::GetType() const */ double Area::GetValue( const TSequenceOfXYZ& P ) { - double aArea = 0; - if ( P.size() == 3 ) - return getArea( P( 1 ), P( 2 ), P( 3 ) ); - else if (P.size() > 3) - aArea = getArea( P( 1 ), P( 2 ), P( 3 ) ); - else - return 0; - - for (int i=4; i<=P.size(); i++) - aArea += getArea(P(1),P(i-1),P(i)); - return aArea; + gp_Vec aVec1( P(2) - P(1) ); + gp_Vec aVec2( P(3) - P(1) ); + gp_Vec SumVec = aVec1 ^ aVec2; + for (int i=4; i<=P.size(); i++) { + gp_Vec aVec1( P(i-1) - P(1) ); + gp_Vec aVec2( P(i) - P(1) ); + gp_Vec tmp = aVec1 ^ aVec2; + SumVec.Add(tmp); + } + return SumVec.Magnitude() * 0.5; } double Area::GetBadRate( double Value, int /*nbNodes*/ ) const { - // meaningless as it is not quality control functor + // meaningless as it is not a quality control functor return Value; } @@ -871,7 +928,11 @@ SMDSAbs_ElementType Area::GetType() const */ double Length::GetValue( const TSequenceOfXYZ& P ) { - return ( P.size() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0 ); + switch ( P.size() ) { + case 2: return getDistance( P( 1 ), P( 2 ) ); + case 3: return getDistance( P( 1 ), P( 2 ) ) + getDistance( P( 2 ), P( 3 ) ); + default: return 0.; + } } double Length::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -894,7 +955,10 @@ double Length2D::GetValue( long theElementId) { TSequenceOfXYZ P; + //cout<<"Length2D::GetValue"<FindElement( theElementId ); @@ -908,7 +972,11 @@ double Length2D::GetValue( long theElementId) case SMDSAbs_Edge: if (len == 2){ aVal = getDistance( P( 1 ), P( 2 ) ); - break; + break; + } + else if (len == 3){ // quadratic edge + aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 )); + break; } case SMDSAbs_Face: if (len == 3){ // triangles @@ -926,6 +994,22 @@ double Length2D::GetValue( long theElementId) aVal = Max(Max(L1,L2),Max(L3,L4)); break; } + if (len == 6){ // quadratic triangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); + aVal = Max(L1,Max(L2,L3)); + //cout<<"L1="<NbNodes(); /* Combien de mailles, faces ou aretes ? */ - int nb_of_nodes, nb_of_edges, nb_of_faces, nb_of_volumes; + int /*nb_of_nodes,*/ nb_of_edges, nb_of_faces, nb_of_volumes; nb_of_edges = myMesh->NbEdges(); nb_of_faces = myMesh->NbFaces(); nb_of_volumes = myMesh->NbVolumes(); diff --git a/src/DriverMED/DriverMED_Family.cxx b/src/DriverMED/DriverMED_Family.cxx index 47a923dbd..0da2c4cff 100644 --- a/src/DriverMED/DriverMED_Family.cxx +++ b/src/DriverMED/DriverMED_Family.cxx @@ -32,6 +32,103 @@ using namespace std; +//============================================================================= +/*! + * Default constructor + */ +//============================================================================= +DriverMED_Family +::DriverMED_Family(): + myGroupAttributVal(0) +{} + + +//============================================================================= +const ElementsSet& +DriverMED_Family +::GetElements () const +{ + return myElements; +} + +int +DriverMED_Family +::GetId () const +{ + return myId; +} + +void +DriverMED_Family +::SetId (const int theId) +{ + myId = theId; +} + +void +DriverMED_Family +::AddElement(const SMDS_MeshElement* theElement) +{ + myElements.insert(theElement); +} + +void +DriverMED_Family +::AddGroupName(std::string theGroupName) +{ + myGroupNames.insert(theGroupName); +} + +void +DriverMED_Family +::SetType(const SMDSAbs_ElementType theType) +{ + myType = theType; +} + +SMDSAbs_ElementType +DriverMED_Family +::GetType() +{ + return myType; +} + +bool +DriverMED_Family +::MemberOf(std::string theGroupName) const +{ + return myGroupNames.find(theGroupName) != myGroupNames.end(); +} + +const MED::TStringSet& +DriverMED_Family +::GetGroupNames () const +{ + return myGroupNames; +} + + +int +DriverMED_Family +::GetGroupAttributVal() const +{ + return myGroupAttributVal; +} + +void +DriverMED_Family +::SetGroupAttributVal( int theValue) +{ + myGroupAttributVal = theValue; +} + +bool +DriverMED_Family +::IsEmpty () const +{ + return myElements.empty(); +} + //============================================================================= /*! * Split each group from list on some parts (families) @@ -39,15 +136,16 @@ using namespace std; * Resulting families have no common elements. */ //============================================================================= -list DriverMED_Family::MakeFamilies - (const map & theSubMeshes, - const list& theGroups, - const bool doGroupOfNodes, - const bool doGroupOfEdges, - const bool doGroupOfFaces, - const bool doGroupOfVolumes) +DriverMED_FamilyPtrList +DriverMED_Family +::MakeFamilies(const SMESHDS_SubMeshPtrMap& theSubMeshes, + const SMESHDS_GroupBasePtrList& theGroups, + const bool doGroupOfNodes, + const bool doGroupOfEdges, + const bool doGroupOfFaces, + const bool doGroupOfVolumes) { - list aFamilies; + DriverMED_FamilyPtrList aFamilies; string anAllNodesGroupName = "Group_Of_All_Nodes"; string anAllEdgesGroupName = "Group_Of_All_Edges"; @@ -61,22 +159,23 @@ list DriverMED_Family::MakeFamilies int aElemFamId = FIRST_ELEM_FAMILY; // Process sub-meshes - map::const_iterator aSMIter = theSubMeshes.begin(); + SMESHDS_SubMeshPtrMap::const_iterator aSMIter = theSubMeshes.begin(); for (; aSMIter != theSubMeshes.end(); aSMIter++) { - if ( aSMIter->second->IsComplexSubmesh() ) + const int anId = aSMIter->first; + SMESHDS_SubMesh* aSubMesh = aSMIter->second; + if ( aSubMesh->IsComplexSubmesh() ) continue; // submesh containing other submeshs - list aSMFams = SplitByType((*aSMIter).second, (*aSMIter).first); - list::iterator aSMFamsIter = aSMFams.begin(); + DriverMED_FamilyPtrList aSMFams = SplitByType(aSubMesh,anId); + DriverMED_FamilyPtrList::iterator aSMFamsIter = aSMFams.begin(); for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++) { DriverMED_FamilyPtr aFam2 = (*aSMFamsIter); - - list::iterator aFamsIter = aFamilies.begin(); + DriverMED_FamilyPtrList::iterator aFamsIter = aFamilies.begin(); while (aFamsIter != aFamilies.end()) { DriverMED_FamilyPtr aFam1 = *aFamsIter; - list::iterator aCurrIter = aFamsIter++; + DriverMED_FamilyPtrList::iterator aCurrIter = aFamsIter++; if (aFam1->myType == aFam2->myType) { DriverMED_FamilyPtr aCommon (new DriverMED_Family); @@ -89,7 +188,8 @@ list DriverMED_Family::MakeFamilies { aFamilies.erase(aCurrIter); } - if (aFam2->IsEmpty()) break; + if (aFam2->IsEmpty()) + break; } } // The rest elements of family @@ -101,30 +201,32 @@ list DriverMED_Family::MakeFamilies } // Process groups - list::const_iterator aGroupsIter = theGroups.begin(); + SMESHDS_GroupBasePtrList::const_iterator aGroupsIter = theGroups.begin(); for (; aGroupsIter != theGroups.end(); aGroupsIter++) { DriverMED_FamilyPtr aFam2 (new DriverMED_Family); aFam2->Init(*aGroupsIter); - list::iterator aFamsIter = aFamilies.begin(); + DriverMED_FamilyPtrList::iterator aFamsIter = aFamilies.begin(); while (aFamsIter != aFamilies.end()) { DriverMED_FamilyPtr aFam1 = *aFamsIter; - list::iterator aCurrIter = aFamsIter++; + DriverMED_FamilyPtrList::iterator aCurrIter = aFamsIter++; if (aFam1->myType == aFam2->myType) { DriverMED_FamilyPtr aCommon (new DriverMED_Family); aFam1->Split(aFam2, aCommon); if (!aCommon->IsEmpty()) { + aCommon->SetGroupAttributVal(0); aFamilies.push_back(aCommon); } if (aFam1->IsEmpty()) { aFamilies.erase(aCurrIter); } - if (aFam2->IsEmpty()) break; + if (aFam2->IsEmpty()) + break; } } // The rest elements of group @@ -134,7 +236,7 @@ list DriverMED_Family::MakeFamilies } } - list::iterator aFamsIter = aFamilies.begin(); + DriverMED_FamilyPtrList::iterator aFamsIter = aFamilies.begin(); for (; aFamsIter != aFamilies.end(); aFamsIter++) { DriverMED_FamilyPtr aFam = *aFamsIter; @@ -210,33 +312,33 @@ MED::PFamilyInfo DriverMED_Family::GetFamilyInfo(const MED::PWrapper& theWrapper, const MED::PMeshInfo& theMeshInfo) const { - string aValue; - ostringstream aStr; - aStr << "FAM_" << myId; set::const_iterator aGrIter = myGroupNames.begin(); - for (; aGrIter != myGroupNames.end(); aGrIter++) - { + for(; aGrIter != myGroupNames.end(); aGrIter++){ aStr << "_" << *aGrIter; } - aValue = aStr.str(); - /* - MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description, - MED::TIntVector anAttrIds (1, myId); // Id=0, - MED::TIntVector anAttrVals (1, myId); // Value=0 - */ - - MED::PFamilyInfo anInfo = theWrapper->CrFamilyInfo(theMeshInfo, - aValue, - myId, - myGroupNames); -/* - anAttrDescs, - anAttrIds, - anAttrVals); -*/ + MED::PFamilyInfo anInfo; + string aValue = aStr.str(); + if(myId == 0){ + anInfo = theWrapper->CrFamilyInfo(theMeshInfo, + aValue, + myId, + myGroupNames); + }else{ + MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description, + MED::TIntVector anAttrIds (1, myId); // Id=0, + MED::TIntVector anAttrVals (1); + anAttrVals[0] = myGroupAttributVal != 0? myGroupAttributVal: myId; + anInfo = theWrapper->CrFamilyInfo(theMeshInfo, + aValue, + myId, + myGroupNames, + anAttrDescs, + anAttrIds, + anAttrVals); + } // cout << endl; // cout << "Groups: "; @@ -279,6 +381,14 @@ void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup) // Groups list myGroupNames.clear(); myGroupNames.insert(string(theGroup->GetStoreName())); + + myGroupAttributVal = 0; + + if (theGroup->GetColorGroup()!=0) + { + myGroupAttributVal = theGroup->GetColorGroup(); + } + } //============================================================================= @@ -287,10 +397,12 @@ void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup) * on the basis of the elements type. */ //============================================================================= -list DriverMED_Family::SplitByType (SMESHDS_SubMesh* theSubMesh, - const int theId) +DriverMED_FamilyPtrList +DriverMED_Family +::SplitByType (SMESHDS_SubMesh* theSubMesh, + const int theId) { - list aFamilies; + DriverMED_FamilyPtrList aFamilies; DriverMED_FamilyPtr aNodesFamily (new DriverMED_Family); DriverMED_FamilyPtr anEdgesFamily (new DriverMED_Family); DriverMED_FamilyPtr aFacesFamily (new DriverMED_Family); @@ -361,7 +473,7 @@ void DriverMED_Family::Split (DriverMED_FamilyPtr by, DriverMED_FamilyPtr common) { // Elements - set::iterator anIter = by->myElements.begin(); + ElementsSet::iterator anIter = by->myElements.begin(); while ( anIter != by->myElements.end()) { if (myElements.find(*anIter) != myElements.end()) @@ -378,7 +490,7 @@ void DriverMED_Family::Split (DriverMED_FamilyPtr by, { // Groups list common->myGroupNames = myGroupNames; - set::iterator aGrNamesIter = by->myGroupNames.begin(); + MED::TStringSet::iterator aGrNamesIter = by->myGroupNames.begin(); for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++) { common->myGroupNames.insert(*aGrNamesIter); diff --git a/src/DriverMED/DriverMED_Family.h b/src/DriverMED/DriverMED_Family.h index 1632ccb3b..6a3622755 100644 --- a/src/DriverMED/DriverMED_Family.h +++ b/src/DriverMED/DriverMED_Family.h @@ -45,76 +45,92 @@ class DriverMED_Family; typedef boost::shared_ptr DriverMED_FamilyPtr; +typedef std::list DriverMED_FamilyPtrList; +typedef std::map SMESHDS_SubMeshPtrMap; +typedef std::list SMESHDS_GroupBasePtrList; +typedef std::set ElementsSet; class DriverMED_Family { public: - // Methods for groups storing to MED - - static std::list MakeFamilies (const std::map & theSubMeshes, - const std::list& theGroups, - const bool doGroupOfNodes, - const bool doGroupOfEdges, - const bool doGroupOfFaces, - const bool doGroupOfVolumes); - // Split each group from list and each sub-mesh from list - // on some parts (families) on the basis of the elements membership in other groups - // from and other sub-meshes from . - // Resulting families have no common elements. - - MED::PFamilyInfo GetFamilyInfo (const MED::PWrapper& theWrapper, - const MED::PMeshInfo& theMeshInfo) const; - // Create TFamilyInfo for this family - - const std::set& GetElements () const { return myElements; } - // Returns elements of this family - - int GetId () const { return myId; } - // Returns a family ID + DriverMED_Family(); + + //! Methods for groups storing to MED + /*! + Split each group from list and each sub-mesh from list + on some parts (families) on the basis of the elements membership in other groups + from and other sub-meshes from . + Resulting families have no common elements. + */ + static + DriverMED_FamilyPtrList + MakeFamilies (const SMESHDS_SubMeshPtrMap& theSubMeshes, + const SMESHDS_GroupBasePtrList& theGroups, + const bool doGroupOfNodes, + const bool doGroupOfEdges, + const bool doGroupOfFaces, + const bool doGroupOfVolumes); + + //! Create TFamilyInfo for this family + MED::PFamilyInfo + GetFamilyInfo (const MED::PWrapper& theWrapper, + const MED::PMeshInfo& theMeshInfo) const; + + //! Returns elements of this family + const ElementsSet& GetElements () const; + + //! Returns a family ID + int GetId () const; + + //! Sets a family ID + void SetId (const int theId); public: // Methods for groups reading from MED - void AddElement (const SMDS_MeshElement* theElement) { myElements.insert(theElement); } + void AddElement(const SMDS_MeshElement* theElement); - void AddGroupName (std::string theGroupName) { myGroupNames.insert(theGroupName); } + const MED::TStringSet& GetGroupNames() const; + void AddGroupName(std::string theGroupName); - void SetType (const SMDSAbs_ElementType theType) { myType = theType; } - SMDSAbs_ElementType GetType () { return myType; } + void SetType(const SMDSAbs_ElementType theType); + SMDSAbs_ElementType GetType(); - bool MemberOf (std::string theGroupName) const - { return (myGroupNames.find(theGroupName) != myGroupNames.end()); } + bool MemberOf(std::string theGroupName) const; - const MED::TStringSet& GetGroupNames () const { return myGroupNames; } - - void SetId (const int theId) { myId = theId; } - // Sets a family ID + int GetGroupAttributVal() const; + void SetGroupAttributVal( int theValue); private: + //! Initialize the tool by SMESHDS_GroupBase void Init (SMESHDS_GroupBase* group); - // Initialize the tool by SMESHDS_GroupBase - static std::list SplitByType (SMESHDS_SubMesh* theSubMesh, - const int theId); - // Split on some parts (families) - // on the basis of the elements type. + //! Split on some parts (families) on the basis of the elements type. + static + DriverMED_FamilyPtrList + SplitByType(SMESHDS_SubMesh* theSubMesh, + const int theId); + + /*! Remove from elements, common with , + Remove from elements, common with , + Create family from common elements, with combined groups list. + */ void Split (DriverMED_FamilyPtr by, DriverMED_FamilyPtr common); - // Remove from elements, common with , - // Remove from elements, common with , - // Create family from common elements, with combined groups list. - bool IsEmpty () const { return myElements.empty(); } - // Check, if this family has empty list of elements + //! Check, if this family has empty list of elements + bool IsEmpty () const; + private: int myId; SMDSAbs_ElementType myType; - std::set myElements; + ElementsSet myElements; MED::TStringSet myGroupNames; + int myGroupAttributVal; }; #endif diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx index 44e05bf77..49c645f47 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx @@ -41,6 +41,7 @@ #ifdef _DEBUG_ static int MYDEBUG = 0; +//#define _DEXCEPT_ #else static int MYDEBUG = 0; #endif @@ -69,10 +70,12 @@ DriverMED_R_SMESHDS_Mesh ::Perform() { Status aResult = DRS_FAIL; +#ifndef _DEXCEPT_ try{ +#endif myFamilies.clear(); if(MYDEBUG) MESSAGE("Perform - myFile : "<GetNbMeshes()){ @@ -195,7 +198,9 @@ DriverMED_R_SMESHDS_Mesh SMDS_MeshElement* anElement = NULL; TInt aFamNum = aPolygoneInfo->GetFamNum(iElem); +#ifndef _DEXCEPT_ try{ +#endif if(anIsElemNum){ TInt anElemId = aPolygoneInfo->GetElemNum(iElem); anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId); @@ -207,12 +212,13 @@ DriverMED_R_SMESHDS_Mesh anElement = myMesh->AddPolygonalFace(aNodes); isRenum = anIsElemNum; } +#ifndef _DEXCEPT_ }catch(const std::exception& exc){ aResult = DRS_FAIL; }catch (...){ aResult = DRS_FAIL; } - +#endif if(!anElement){ aResult = DRS_WARN_SKIP_ELEM; }else{ @@ -265,7 +271,9 @@ DriverMED_R_SMESHDS_Mesh SMDS_MeshElement* anElement = NULL; TInt aFamNum = aPolyedreInfo->GetFamNum(iElem); +#ifndef _DEXCEPT_ try{ +#endif if(anIsElemNum){ TInt anElemId = aPolyedreInfo->GetElemNum(iElem); anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId); @@ -277,12 +285,13 @@ DriverMED_R_SMESHDS_Mesh anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities); isRenum = anIsElemNum; } +#ifndef _DEXCEPT_ }catch(const std::exception& exc){ aResult = DRS_FAIL; }catch(...){ aResult = DRS_FAIL; } - +#endif if(!anElement){ aResult = DRS_WARN_SKIP_ELEM; }else{ @@ -302,238 +311,388 @@ DriverMED_R_SMESHDS_Mesh break; } default: { - PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom); - EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX; - TInt aNbElems = aCellInfo->GetNbElem(); - if(MYDEBUG) MESSAGE("Perform - anEntity = "<GetFamNum(iElem); - try{ - //MESSAGE("Try to create element # " << iElem << " with id = " - // << aCellInfo->GetElemNum(iElem)); - switch(aGeom){ - case eSEG2: - case eSEG3: - if(anIsElemNum) - anElement = myMesh->AddEdgeWithID(aNodeIds[0], - aNodeIds[1], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1])); - isRenum = anIsElemNum; - } - break; - case eTRIA3: - case eTRIA6: - aNbNodes = 3; - if(anIsElemNum) - anElement = myMesh->AddFaceWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1]), - FindNode(myMesh,aNodeIds[2])); - isRenum = anIsElemNum; - } - break; - case eQUAD4: - case eQUAD8: - aNbNodes = 4; - // There is some differnce between SMDS and MED - if(anIsElemNum) - anElement = myMesh->AddFaceWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1]), - FindNode(myMesh,aNodeIds[2]), - FindNode(myMesh,aNodeIds[3])); - isRenum = anIsElemNum; - } - break; - case eTETRA4: - case eTETRA10: - aNbNodes = 4; - if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aCellInfo->GetElemNum(iElem)); - if (!anElement) { - anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), - FindNode(myMesh,aNodeIds[1]), - FindNode(myMesh,aNodeIds[2]), - FindNode(myMesh,aNodeIds[3])); - isRenum = anIsElemNum; - } - break; - case ePYRA5: - case ePYRA13: - aNbNodes = 5; - // There is some differnce between SMDS and MED - if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aNodeIds[4], - 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])); - isRenum = anIsElemNum; - } - break; - case ePENTA6: - case ePENTA15: - aNbNodes = 6; - if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aNodeIds[4], - aNodeIds[5], - 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])); - isRenum = anIsElemNum; - } - break; - case eHEXA8: - case eHEXA20: - aNbNodes = 8; - if(anIsElemNum) - anElement = myMesh->AddVolumeWithID(aNodeIds[0], - aNodeIds[1], - aNodeIds[2], - aNodeIds[3], - aNodeIds[4], - aNodeIds[5], - aNodeIds[6], - aNodeIds[7], - 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])); - isRenum = anIsElemNum; - } - break; - } - }catch(const std::exception& exc){ - //INFOS("Follow exception was cought:\n\t"<AddElement(anElement); - myFamilies[aFamNum]->SetType(anElement->GetType()); - } - } - } - }} - } - } + anIsValidConnect = true; +#ifndef _DEXCEPT_ + }catch(const std::exception& exc){ + //INFOS("Follow exception was cought:\n\t"<GetFamNum(iElem); +#ifndef _DEXCEPT_ + try{ +#endif + //MESSAGE("Try to create element # " << iElem << " with id = " + // << aCellInfo->GetElemNum(iElem)); + switch(aGeom){ + case eSEG2: + if(anIsElemNum) + anElement = myMesh->AddEdgeWithID(aNodeIds[0], + aNodeIds[1], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1])); + isRenum = anIsElemNum; + } + break; + case eSEG3: + if(anIsElemNum) + anElement = myMesh->AddEdgeWithID(aNodeIds[0], + aNodeIds[1], + aNodeIds[2], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2])); + isRenum = anIsElemNum; + } + break; + case eTRIA3: + aNbNodes = 3; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], + aNodeIds[1], + aNodeIds[2], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2])); + isRenum = anIsElemNum; + } + break; + case eTRIA6: + aNbNodes = 6; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3]), + FindNode(myMesh,aNodeIds[4]), + FindNode(myMesh,aNodeIds[5])); + isRenum = anIsElemNum; + } + break; + case eQUAD4: + aNbNodes = 4; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3])); + isRenum = anIsElemNum; + } + break; + case eQUAD8: + aNbNodes = 8; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], aNodeIds[5], + aNodeIds[6], aNodeIds[7], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(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])); + isRenum = anIsElemNum; + } + break; + case eTETRA4: + aNbNodes = 4; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]), + FindNode(myMesh,aNodeIds[1]), + FindNode(myMesh,aNodeIds[2]), + FindNode(myMesh,aNodeIds[3])); + isRenum = anIsElemNum; + } + break; + case eTETRA10: + aNbNodes = 10; + 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], + 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])); + isRenum = anIsElemNum; + } + break; + case ePYRA5: + aNbNodes = 5; + // There is some differnce between SMDS and MED + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1], + aNodeIds[2], aNodeIds[3], + aNodeIds[4], + 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])); + isRenum = anIsElemNum; + } + break; + case ePYRA13: + aNbNodes = 13; + // There is some differnce between SMDS and MED + 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], + 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])); + isRenum = anIsElemNum; + } + break; + case ePENTA6: + aNbNodes = 6; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], + aNodeIds[1], + aNodeIds[2], + aNodeIds[3], + aNodeIds[4], + aNodeIds[5], + 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])); + isRenum = anIsElemNum; + } + break; + case ePENTA15: + aNbNodes = 15; + 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], + 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])); + isRenum = anIsElemNum; + } + break; + case eHEXA8: + aNbNodes = 8; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds[0], + aNodeIds[1], + aNodeIds[2], + aNodeIds[3], + aNodeIds[4], + aNodeIds[5], + aNodeIds[6], + aNodeIds[7], + 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])); + isRenum = anIsElemNum; + } + break; + case eHEXA20: + aNbNodes = 20; + 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], + aNodeIds[18], aNodeIds[19], + 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]), + FindNode(myMesh,aNodeIds[18]), + FindNode(myMesh,aNodeIds[19])); + isRenum = anIsElemNum; + } + break; + } +#ifndef _DEXCEPT_ + }catch(const std::exception& exc){ + //INFOS("Follow exception was cought:\n\t"<AddElement(anElement); + myFamilies[aFamNum]->SetType(anElement->GetType()); + } + } + } + }} + } + } } } +#ifndef _DEXCEPT_ }catch(const std::exception& exc){ INFOS("Follow exception was cought:\n\t"<first; const TRecord& aRec = anIter->second; - if(IsBeam(aRec.fe_descriptor_id)){ - anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], - aRec.node_labels[1], - aLabel); - }else if(IsFace(aRec.fe_descriptor_id)){ + if(IsBeam(aRec.fe_descriptor_id)) { + if(aRec.fe_descriptor_id == 11) { + // edge with two nodes + anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], + aRec.node_labels[1], + aLabel); + } + else { + // quadratic edge (with 3 nodes) + anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], + aRec.node_labels[1], + aRec.node_labels[2], + aLabel); + } + } + else if(IsFace(aRec.fe_descriptor_id)) { switch(aRec.fe_descriptor_id){ case 71: // TRI3 case 72: @@ -76,18 +87,31 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() case 41: // Plane Stress Linear Triangle - TRI3 case 91: // Thin Shell Linear Triangle - TRI3 + anElement = myMesh->AddFaceWithID(aRec.node_labels[0], + aRec.node_labels[1], + aRec.node_labels[2], + aLabel); + break; case 42: // Plane Stress Quadratic Triangle - TRI6 case 92: // Thin Shell Quadratic Triangle - TRI6 - anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[1], aRec.node_labels[2], + aRec.node_labels[3], + aRec.node_labels[4], + aRec.node_labels[5], aLabel); break; case 44: // Plane Stress Linear Quadrilateral - QUAD4 case 94: // Thin Shell Linear Quadrilateral - QUAD4 + anElement = myMesh->AddFaceWithID(aRec.node_labels[0], + aRec.node_labels[1], + aRec.node_labels[2], + aRec.node_labels[3], + aLabel); + break; case 45: // Plane Stress Quadratic Quadrilateral - QUAD8 case 95: // Thin Shell Quadratic Quadrilateral - QUAD8 @@ -95,24 +119,40 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aRec.node_labels[1], aRec.node_labels[2], aRec.node_labels[3], + aRec.node_labels[4], + aRec.node_labels[5], + aRec.node_labels[6], + aRec.node_labels[7], aLabel); break; } - }else if(IsVolume(aRec.fe_descriptor_id)){ + } + else if(IsVolume(aRec.fe_descriptor_id)){ switch(aRec.fe_descriptor_id){ case 111: // Solid Linear Tetrahedron - TET4 + anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], + aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[3], + aLabel); + break; + case 118: // Solid Quadratic Tetrahedron - TET10 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[1], aRec.node_labels[3], + aRec.node_labels[6], + aRec.node_labels[5], + aRec.node_labels[4], + aRec.node_labels[7], + aRec.node_labels[9], + aRec.node_labels[8], aLabel); break; case 112: // Solid Linear Prism - PRISM6 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[1], @@ -123,13 +163,21 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() break; case 113: // Solid Quadratic Prism - PRISM15 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], - aRec.node_labels[4], aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[3], + aRec.node_labels[5], + aRec.node_labels[4], + aRec.node_labels[8], + aRec.node_labels[7], + aRec.node_labels[6], + aRec.node_labels[11], + aRec.node_labels[10], aRec.node_labels[9], + aRec.node_labels[12], + aRec.node_labels[14], aRec.node_labels[13], - aRec.node_labels[11], aLabel); break; @@ -146,26 +194,57 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() break; case 116: // Solid Quadratic Brick - HEX20 - anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], - aRec.node_labels[6], - aRec.node_labels[4], + aRec.node_labels[3], aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[4], + aRec.node_labels[7], + aRec.node_labels[6], + aRec.node_labels[5], + aRec.node_labels[11], + aRec.node_labels[10], + aRec.node_labels[9], + aRec.node_labels[8], + aRec.node_labels[15], + aRec.node_labels[14], + aRec.node_labels[13], aRec.node_labels[12], - aRec.node_labels[18], aRec.node_labels[16], - aRec.node_labels[14], + aRec.node_labels[19], + aRec.node_labels[18], + aRec.node_labels[17], + aLabel); + break; + + case 114: // pyramid of 13 nodes (quadratic) - PIRA13 + anElement = myMesh->AddVolumeWithID(aRec.node_labels[0], + aRec.node_labels[3], + aRec.node_labels[2], + aRec.node_labels[1], + aRec.node_labels[4], + aRec.node_labels[8], + aRec.node_labels[7], + aRec.node_labels[6], + aRec.node_labels[5], + aRec.node_labels[9], + aRec.node_labels[12], + aRec.node_labels[11], + aRec.node_labels[10], aLabel); break; + } } if(!anElement) MESSAGE("DriverUNV_R_SMDS_Mesh::Perform - can not add element with ID = "<next(); aRec.node_labels.push_back(aNode->GetID()); } - aRec.fe_descriptor_id = 11; + if(aNbNodes==2) + aRec.fe_descriptor_id = 11; + else + aRec.fe_descriptor_id = 21; aDataSet2412.insert(TDataSet::value_type(aLabel,aRec)); } MESSAGE("Perform - aDataSet2412.size() = "<RegisterCellsWithType(VTK_TRIANGLE); aFilter->RegisterCellsWithType(VTK_POLYGON); aFilter->RegisterCellsWithType(VTK_QUAD); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); my3DActor = SMESH_DeviceActor::New(); my3DActor->SetUserMatrix(aMatrix); @@ -164,6 +166,8 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter->RegisterCellsWithType(VTK_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_WEDGE); aFilter->RegisterCellsWithType(VTK_PYRAMID); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); //Definition 1D divice of the actor @@ -185,6 +189,7 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter = my1DActor->GetExtractUnstructuredGrid(); aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); my1DProp = vtkProperty::New(); my1DProp->DeepCopy(myEdgeProp); @@ -210,6 +215,7 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter = my1DExtActor->GetExtractUnstructuredGrid(); aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); //Definition 0D divice of the actor @@ -263,8 +269,6 @@ SMESH_ActorDef::SMESH_ActorDef() myHighlitableActor->PickableOff(); myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe); - SetShrinkFactor( SMESH::GetFloat( "SMESH:shrink_coeff", 0.75 ) ); - myName = ""; myIO = NULL; @@ -748,13 +752,15 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj, my2DActor->GetPolygonOffsetParameters(aFactor,aUnits); my2DActor->SetPolygonOffsetParameters(aFactor,aUnits*0.75); - //SetIsShrunkable(theGrid->GetNumberOfCells() > 10); - SetIsShrunkable(true); - SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); if( !mgr ) return false; + //SetIsShrunkable(theGrid->GetNumberOfCells() > 10); + SetIsShrunkable(true); + + SetShrinkFactor( SMESH::GetFloat( "SMESH:shrink_coeff", 0.75 ) ); + int aMode = mgr->integerValue( "SMESH", "display_mode" ); SetRepresentation(-1); @@ -835,6 +841,8 @@ bool SMESH_ActorDef::IsInfinitive(){ void SMESH_ActorDef::SetIsShrunkable(bool theShrunkable){ + if ( myIsShrinkable == theShrunkable ) + return; myIsShrinkable = theShrunkable; Modified(); } @@ -1015,6 +1023,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){ if(myEntityMode & eEdges){ if (MYDEBUG) MESSAGE("EDGES"); aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); } if(myEntityMode & eFaces){ @@ -1022,6 +1031,8 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){ aFilter->RegisterCellsWithType(VTK_TRIANGLE); aFilter->RegisterCellsWithType(VTK_POLYGON); aFilter->RegisterCellsWithType(VTK_QUAD); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); } if(myEntityMode & eVolumes){ @@ -1031,6 +1042,8 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){ aFilter->RegisterCellsWithType(VTK_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_WEDGE); aFilter->RegisterCellsWithType(VTK_PYRAMID); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); } aFilter->Update(); @@ -1135,6 +1148,8 @@ void SMESH_ActorDef::SetRepresentation(int theMode){ void SMESH_ActorDef::SetPointRepresentation(bool theIsPointsVisible){ + if ( myIsPointsVisible == theIsPointsVisible ) + return; myIsPointsVisible = theIsPointsVisible; SetRepresentation(GetRepresentation()); } @@ -1175,12 +1190,16 @@ void SMESH_ActorDef::UpdateHighlight(){ void SMESH_ActorDef::highlight(bool theHighlight){ + if ( myIsHighlighted == theHighlight ) + return; myIsHighlighted = theHighlight; UpdateHighlight(); } void SMESH_ActorDef::SetPreSelected(bool thePreselect){ + if ( myIsPreselected == thePreselect ) + return; myIsPreselected = thePreselect; UpdateHighlight(); } diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx index 3548aaefe..28670e6be 100644 --- a/src/OBJECT/SMESH_DeviceActor.cxx +++ b/src/OBJECT/SMESH_DeviceActor.cxx @@ -547,14 +547,22 @@ void SMESH_DeviceActor::SetRepresentation(EReperesent theMode){ switch(theMode){ case ePoint: myGeomFilter->SetInside(true); + myGeomFilter->SetWireframeMode(false); GetProperty()->SetRepresentation(0); break; + case eWireframe: + myGeomFilter->SetInside(false); + myGeomFilter->SetWireframeMode(true); + GetProperty()->SetRepresentation(theMode); + break; case eInsideframe: myGeomFilter->SetInside(true); + myGeomFilter->SetWireframeMode(true); GetProperty()->SetRepresentation(1); break; - default : + case eSurface: myGeomFilter->SetInside(false); + myGeomFilter->SetWireframeMode(false); GetProperty()->SetRepresentation(theMode); } myRepresentation = theMode; @@ -646,6 +654,8 @@ void SMESH_DeviceActor::SetShrinkFactor(float theValue){ void SMESH_DeviceActor::SetHighlited(bool theIsHighlited){ + if ( myIsHighlited == theIsHighlited ) + return; myIsHighlited = theIsHighlited; Modified(); } diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index 885ee3de3..33aa1b0b6 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -31,8 +31,10 @@ #include "SMDS_Mesh.hxx" #include "SMESH_Actor.h" #include "SMESH_ControlsDef.hxx" -#include +#include "SalomeApp_Application.h" +#include "VTKViewer_ExtractUnstructuredGrid.h" +#include CORBA_SERVER_HEADER(SMESH_Gen) #include CORBA_SERVER_HEADER(SALOME_Exception) #include @@ -69,271 +71,6 @@ static int MYDEBUGWITHFILES = 0; #endif -namespace{ - - inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){ - if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem; - EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<FindElement(theId)) return anElem; - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<AddNodeWithID(aCoords[aCoordId], - aCoords[aCoordId+1], - aCoords[aCoordId+2], - anIndexes[anElemId]); - if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<AddEdgeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId]); - if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId]); - if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId]); - if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "< nodes_ids (aNbNodes); - for (int i = 0; i < aNbNodes; i++) { - nodes_ids[i] = anIndexes[anIndexId++]; - } - - SMDS_MeshElement* anElem = theMesh->AddPolygonalFaceWithID(nodes_ids, aFaceId); - if (!anElem) - EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolygonalFaceWithID for ID = " - << anElemId); - } - } - - - inline void AddTetrasWithID(SMDS_Mesh* theMesh, - SMESH::log_array_var& theSeq, - CORBA::Long theId) - { - const SMESH::long_array& anIndexes = theSeq[theId].indexes; - CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number; - if(5*aNbElems != anIndexes.length()) - EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()"); - for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){ - SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId]); - if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId]); - if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId]); - if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId+7], - anIndexes[anIndexId+8], - anIndexes[anIndexId]); - if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "< nodes_ids (aNbNodes); - for (int i = 0; i < aNbNodes; i++) { - nodes_ids[i] = anIndexes[anIndexId++]; - } - - int aNbFaces = anIndexes[anIndexId++]; - std::vector quantities (aNbFaces); - for (int i = 0; i < aNbFaces; i++) { - quantities[i] = anIndexes[anIndexId++]; - } - - SMDS_MeshElement* anElem = - theMesh->AddPolyhedralVolumeWithID(nodes_ids, quantities, aFaceId); - if (!anElem) - EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = " - << anElemId); - } - } - - - inline void ChangePolyhedronNodes (SMDS_Mesh* theMesh, - SMESH::log_array_var& theSeq, - CORBA::Long theId) - { - const SMESH::long_array& anIndexes = theSeq[theId].indexes; - CORBA::Long iind = 0, aNbElems = theSeq[theId].number; - - for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) - { - // find element - const SMDS_MeshElement* elem = FindElement(theMesh, anIndexes[iind++]); - // nb nodes - int nbNodes = anIndexes[iind++]; - // nodes - std::vector aNodes (nbNodes); - for (int iNode = 0; iNode < nbNodes; iNode++) { - aNodes[iNode] = FindNode(theMesh, anIndexes[iind++]); - } - // nb faces - int nbFaces = anIndexes[iind++]; - // quantities - std::vector quantities (nbFaces); - for (int iFace = 0; iFace < nbFaces; iFace++) { - quantities[iFace] = anIndexes[iind++]; - } - // change - theMesh->ChangePolyhedronNodes(elem, aNodes, quantities); - } - } - - -} /* Class : SMESH_VisualObjDef Description : Base class for all mesh objects to be visuilised @@ -350,12 +87,16 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType, switch( theType ) { case SMDSAbs_Edge: - return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL; + if( theNbNodes == 2 ) return VTK_LINE; + else if ( theNbNodes == 3 ) return VTK_QUADRATIC_EDGE; + else return VTK_EMPTY_CELL; case SMDSAbs_Face : if (thePoly && theNbNodes>2 ) return VTK_POLYGON; else if ( theNbNodes == 3 ) return VTK_TRIANGLE; else if ( theNbNodes == 4 ) return VTK_QUAD; + else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE; + else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD; else return VTK_EMPTY_CELL; case SMDSAbs_Volume: @@ -364,6 +105,15 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType, else if ( theNbNodes == 5 ) return VTK_PYRAMID; else if ( theNbNodes == 6 ) return VTK_WEDGE; else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON; + else if ( theNbNodes == 10 ) { + return VTK_QUADRATIC_TETRA; + } + else if ( theNbNodes == 20 ) { + return VTK_QUADRATIC_HEXAHEDRON; + } + else if ( theNbNodes==13 || theNbNodes==15 ) { + return VTK_CONVEX_POINT_SET; + } else return VTK_EMPTY_CELL; default: return VTK_EMPTY_CELL; @@ -485,42 +235,6 @@ void SMESH_VisualObjDef::buildNodePrs() aPoints->Delete(); myGrid->SetCells( 0, 0, 0 ); - - // Create cells - /* - int nbPoints = aPoints->GetNumberOfPoints(); - vtkIdList *anIdList = vtkIdList::New(); - anIdList->SetNumberOfIds( 1 ); - - vtkCellArray *aCells = vtkCellArray::New(); - aCells->Allocate( 2 * nbPoints, 0 ); - - vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New(); - aCellTypesArray->SetNumberOfComponents( 1 ); - aCellTypesArray->Allocate( nbPoints ); - - for( vtkIdType aCellId = 0; aCellId < nbPoints; aCellId++ ) - { - anIdList->SetId( 0, aCellId ); - aCells->InsertNextCell( anIdList ); - aCellTypesArray->InsertNextValue( VTK_VERTEX ); - } - - vtkIntArray* aCellLocationsArray = vtkIntArray::New(); - aCellLocationsArray->SetNumberOfComponents( 1 ); - aCellLocationsArray->SetNumberOfTuples( nbPoints ); - - aCells->InitTraversal(); - for( vtkIdType i = 0, *pts, npts; aCells->GetNextCell( npts, pts ); i++ ) - aCellLocationsArray->SetValue( i, aCells->GetTraversalLocation( npts ) ); - - myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells ); - - aCellLocationsArray->Delete(); - aCellTypesArray->Delete(); - aCells->Delete(); - anIdList->Delete(); - */ } //================================================================================= @@ -651,11 +365,34 @@ void SMESH_VisualObjDef::buildElemPrs() static int anIds[] = {0,1,2,3,4,5}; for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); - } else if (aNbNodes == 8) { + } + else if (aNbNodes == 8) { static int anIds[] = {0,3,2,1,4,7,6,5}; for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); - } else { + } + else if (aNbNodes == 10) { + static int anIds[] = {0,2,1,3,6,5,4,7,9,8}; + for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); + } + else if (aNbNodes == 13) { + static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; + for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); + } + else if (aNbNodes == 15) { + static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13}; + for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]); + //for (int k = 0; k < aNbNodes; k++) { + // int nn = aConnectivities[k]; + // const SMDS_MeshNode* N = static_cast (aConnect[nn]); + // cout<<"k="<X()<<","<Y()<<","<Z()<<")"< 0) { @@ -748,14 +485,11 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId, // function : SMESH_MeshObj // purpose : Constructor //================================================================================= -SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh) +SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh): + myClient(SalomeApp_Application::orb(),theMesh) { if ( MYDEBUG ) - MESSAGE("SMESH_MeshObj - theMesh->_is_nil() = "<_is_nil()); - - myMeshServer = SMESH::SMESH_Mesh::_duplicate( theMesh ); - myMeshServer->Register(); - myMesh = new SMDS_Mesh(); + MESSAGE("SMESH_MeshObj - this = "<_is_nil() = "<_is_nil()); } //================================================================================= @@ -764,8 +498,8 @@ SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh) //================================================================================= SMESH_MeshObj::~SMESH_MeshObj() { - myMeshServer->Destroy(); - delete myMesh; + if ( MYDEBUG ) + MESSAGE("SMESH_MeshObj - this = "<GetLog( theIsClear ); - CORBA::Long aLength = aSeq->length(); - - if( MYDEBUG ) MESSAGE( "Update: length of the script is "<RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) ); - break; - - case SMESH::REMOVE_ELEMENT: - for( ; anElemId < aNbElems; anElemId++ ) - myMesh->RemoveElement( FindElement( myMesh, anIndexes[anElemId] ) ); - break; - - case SMESH::MOVE_NODE: - for(CORBA::Long aCoordId=0; anElemId < aNbElems; anElemId++, aCoordId+=3) - { - SMDS_MeshNode* node = - const_cast( FindNode( myMesh, anIndexes[anElemId] )); - node->setXYZ( aCoords[aCoordId], aCoords[aCoordId+1], aCoords[aCoordId+2] ); - } - break; - - case SMESH::CHANGE_ELEMENT_NODES: - for ( CORBA::Long i = 0; anElemId < aNbElems; anElemId++ ) - { - // find element - const SMDS_MeshElement* elem = FindElement( myMesh, anIndexes[i++] ); - // nb nodes - int nbNodes = anIndexes[i++]; - // nodes - //ASSERT( nbNodes < 9 ); - const SMDS_MeshNode* aNodes[ nbNodes ]; - for ( int iNode = 0; iNode < nbNodes; iNode++ ) - aNodes[ iNode ] = FindNode( myMesh, anIndexes[i++] ); - // change - myMesh->ChangeElementNodes( elem, aNodes, nbNodes ); - } - break; - - case SMESH::CHANGE_POLYHEDRON_NODES: - ChangePolyhedronNodes(myMesh, aSeq, anId); - break; - case SMESH::RENUMBER: - for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3) - { - myMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] ); - } - break; - - default:; - } - } - } - catch ( SALOME::SALOME_Exception& exc ) - { - INFOS("Following exception was cought:\n\t"<NbNodes() = "<NbNodes()); - MESSAGE("Update - myMesh->NbEdges() = "<NbEdges()); - MESSAGE("Update - myMesh->NbFaces() = "<NbFaces()); - MESSAGE("Update - myMesh->NbVolumes() = "<NbVolumes()); - } - - // Fill unstructured grid - buildPrs(); + if ( myClient.Update(theIsClear) ) + buildPrs(); // Fill unstructured grid } //================================================================================= @@ -887,7 +519,7 @@ void SMESH_MeshObj::Update( int theIsClear ) //================================================================================= int SMESH_MeshObj::GetElemDimension( const int theObjId ) { - const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId ); + const SMDS_MeshElement* anElem = myClient->FindElement( theObjId ); if ( anElem == 0 ) return 0; @@ -911,22 +543,22 @@ int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const { case SMDSAbs_Node: { - return myMesh->NbNodes(); + return myClient->NbNodes(); } break; case SMDSAbs_Edge: { - return myMesh->NbEdges(); + return myClient->NbEdges(); } break; case SMDSAbs_Face: { - return myMesh->NbFaces(); + return myClient->NbFaces(); } break; case SMDSAbs_Volume: { - return myMesh->NbVolumes(); + return myClient->NbVolumes(); } break; default: @@ -943,25 +575,25 @@ int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& { case SMDSAbs_Node: { - SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator(); + SMDS_NodeIteratorPtr anIter = myClient->nodesIterator(); while ( anIter->more() ) theObjs.push_back( anIter->next() ); } break; case SMDSAbs_Edge: { - SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator(); + SMDS_EdgeIteratorPtr anIter = myClient->edgesIterator(); while ( anIter->more() ) theObjs.push_back( anIter->next() ); } break; case SMDSAbs_Face: { - SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); + SMDS_FaceIteratorPtr anIter = myClient->facesIterator(); while ( anIter->more() ) theObjs.push_back( anIter->next() ); } break; case SMDSAbs_Volume: { - SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator(); + SMDS_VolumeIteratorPtr anIter = myClient->volumesIterator(); while ( anIter->more() ) theObjs.push_back( anIter->next() ); } break; @@ -987,7 +619,7 @@ void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor //================================================================================= bool SMESH_MeshObj::IsNodePrs() const { - return myMesh->NbEdges() == 0 &&myMesh->NbFaces() == 0 &&myMesh->NbVolumes() == 0 ; + return myClient->NbEdges() == 0 &&myClient->NbFaces() == 0 && myClient->NbVolumes() == 0 ; } @@ -1256,15 +888,3 @@ bool SMESH_subMeshObj::IsNodePrs() const { return mySubMeshServer->GetNumberOfElements() == 0; } - - - - - - - - - - - - diff --git a/src/OBJECT/SMESH_ObjectDef.h b/src/OBJECT/SMESH_ObjectDef.h index 134b47b10..f45f14a63 100644 --- a/src/OBJECT/SMESH_ObjectDef.h +++ b/src/OBJECT/SMESH_ObjectDef.h @@ -29,6 +29,10 @@ #ifndef SMESH_OBJECTDEF_H #define SMESH_OBJECTDEF_H +#include "SMESH_Controls.hxx" +#include "SMESH_Object.h" +#include "SMESH_Client.hxx" + // IDL Headers #include #include CORBA_SERVER_HEADER(SMESH_Mesh) @@ -37,9 +41,6 @@ #include #include -#include "SMESH_Controls.hxx" -#include "SMESH_Object.h" - class vtkPoints; class SALOME_ExtractUnstructuredGrid; @@ -121,13 +122,11 @@ public: virtual void UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor ); - SMESH::SMESH_Mesh_ptr GetMeshServer() { return myMeshServer.in(); } - SMDS_Mesh* GetMesh() const { return myMesh; } + SMESH::SMESH_Mesh_ptr GetMeshServer() { return myClient.GetMeshServer(); } + SMDS_Mesh* GetMesh() const { return myClient.GetMesh(); } protected: - - SMESH::SMESH_Mesh_var myMeshServer; - SMDS_Mesh* myMesh; + SMESH_Client myClient; }; diff --git a/src/SMDS/Makefile.in b/src/SMDS/Makefile.in index e066e25e0..7ecaf313a 100644 --- a/src/SMDS/Makefile.in +++ b/src/SMDS/Makefile.in @@ -59,21 +59,10 @@ LIB_SRC = \ SMDS_FaceOfEdges.cxx \ SMDS_FaceOfNodes.cxx \ SMDS_PolygonalFaceOfNodes.cxx \ - SMDS_VolumeTool.cxx -# SMDS_Tria3OfNodes.cxx \ -# SMDS_HexahedronOfNodes.cxx - -#SMDSControl_BoundaryEdges.cxx \ -#SMDSControl_BoundaryFaces.cxx \ -#SMDSControl.cxx \ -#SMDSControl_MeshBoundary.cxx \ -#SMDSEdit_Transform.cxx \ -#SMDS_MeshNodeIDFactory.cxx \ -#SMDS_MeshPrism.cxx \ -#SMDS_MeshPyramid.cxx \ -#SMDS_MeshQuadrangle.cxx \ -#SMDS_MeshTetrahedron.cxx \ -#SMDS_MeshTriangle.cxx \ + SMDS_VolumeTool.cxx \ + SMDS_QuadraticEdge.cxx \ + SMDS_QuadraticFaceOfNodes.cxx \ + SMDS_QuadraticVolumeOfNodes.cxx LIB_CLIENT_IDL = @@ -113,21 +102,11 @@ EXPORT_HEADERS= \ SMDS_FaceOfEdges.hxx \ SMDS_FaceOfNodes.hxx \ SMDS_PolygonalFaceOfNodes.hxx \ - SMDS_VolumeTool.hxx -# SMDS_Tria3OfNodes.hxx \ -# SMDS_HexahedronOfNodes.hxx - -#SMDSControl_BoundaryEdges.hxx \ -#SMDSControl_BoundaryFaces.hxx \ -#SMDSControl.hxx \ -#SMDSControl_MeshBoundary.hxx \ -#SMDSEdit_Transform.hxx \ -#SMDS_MeshPrism.hxx \ -#SMDS_MeshPyramid.hxx \ -#SMDS_MeshQuadrangle.hxx \ -#SMDS_MeshTetrahedron.hxx \ -#SMDS_MeshTriangle.hxx \ -#SMDS_MeshNodeIDFactory.hxx + SMDS_VolumeTool.hxx \ + SMDS_QuadraticEdge.hxx \ + SMDS_QuadraticFaceOfNodes.hxx \ + SMDS_QuadraticVolumeOfNodes.hxx \ + SMDS_SetIterator.hxx # additionnal information to compil and link file CPPFLAGS += -I${KERNEL_ROOT_DIR}/include/salome $(OCC_INCLUDES) $(BOOST_CPPFLAGS) diff --git a/src/SMDS/SMDS_ElemIterator.hxx b/src/SMDS/SMDS_ElemIterator.hxx index c8432afdd..6ff098644 100755 --- a/src/SMDS/SMDS_ElemIterator.hxx +++ b/src/SMDS/SMDS_ElemIterator.hxx @@ -33,8 +33,24 @@ #include class SMDS_MeshElement; +class SMDS_MeshNode; +class SMDS_MeshEdge; +class SMDS_MeshFace; +class SMDS_MeshVolume; typedef SMDS_Iterator SMDS_ElemIterator; typedef boost::shared_ptr > SMDS_ElemIteratorPtr; +typedef SMDS_Iterator SMDS_NodeIterator; +typedef boost::shared_ptr > SMDS_NodeIteratorPtr; + +typedef SMDS_Iterator SMDS_EdgeIterator; +typedef boost::shared_ptr > SMDS_EdgeIteratorPtr; + +typedef SMDS_Iterator SMDS_FaceIterator; +typedef boost::shared_ptr > SMDS_FaceIteratorPtr; + +typedef SMDS_Iterator SMDS_VolumeIterator; +typedef boost::shared_ptr > SMDS_VolumeIteratorPtr; + #endif diff --git a/src/SMDS/SMDS_FaceOfEdges.cxx b/src/SMDS/SMDS_FaceOfEdges.cxx index 640c55d30..7a014afb8 100644 --- a/src/SMDS/SMDS_FaceOfEdges.cxx +++ b/src/SMDS/SMDS_FaceOfEdges.cxx @@ -155,3 +155,29 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, }*/ + +int SMDS_FaceOfEdges::NbNodes() const +{ + return myEdges[0]->NbNodes() + myEdges[1]->NbNodes() + myEdges[2]->NbNodes() + + ( myNbEdges == 4 ? myEdges[3]->NbNodes() : 0 ) - myNbEdges; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ +const SMDS_MeshNode* SMDS_FaceOfEdges::GetNode(const int ind) const +{ + int index = WrappedIndex( ind ); + for ( int i = 0; i < myNbEdges; ++i ) { + if ( index >= myEdges[ i ]->NbNodes() ) + index -= myEdges[ i ]->NbNodes(); + else + return myEdges[ i ]->GetNode( index ); + } + return 0; +} + diff --git a/src/SMDS/SMDS_FaceOfEdges.hxx b/src/SMDS/SMDS_FaceOfEdges.hxx index cd8e5dd8f..54a9a688f 100644 --- a/src/SMDS/SMDS_FaceOfEdges.hxx +++ b/src/SMDS/SMDS_FaceOfEdges.hxx @@ -42,10 +42,21 @@ class SMDS_FaceOfEdges:public SMDS_MeshFace const SMDS_MeshEdge* edge4); SMDSAbs_ElementType GetType() const; + int NbNodes() const; int NbEdges() const; int NbFaces() const; // friend bool operator<(const SMDS_FaceOfEdges& e1, const SMDS_FaceOfEdges& e2); + + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + protected: SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; diff --git a/src/SMDS/SMDS_FaceOfNodes.cxx b/src/SMDS/SMDS_FaceOfNodes.cxx index aa6870824..018bd88a0 100644 --- a/src/SMDS/SMDS_FaceOfNodes.cxx +++ b/src/SMDS/SMDS_FaceOfNodes.cxx @@ -23,6 +23,7 @@ #pragma warning(disable:4786) #endif +#include "SMDS_SetIterator.hxx" #include "SMDS_FaceOfNodes.hxx" #include "SMDS_IteratorOfElements.hxx" #include "SMDS_MeshNode.hxx" @@ -68,25 +69,11 @@ void SMDS_FaceOfNodes::Print(ostream & OS) const //purpose : //======================================================================= -class SMDS_FaceOfNodes_MyIterator:public SMDS_ElemIterator +class SMDS_FaceOfNodes_MyIterator:public SMDS_NodeArrayElemIterator { - const SMDS_MeshNode* const *mySet; - int myLength; - int index; public: SMDS_FaceOfNodes_MyIterator(const SMDS_MeshNode* const *s, int l): - mySet(s),myLength(l),index(0) {} - - bool more() - { - return index set1,set2; diff --git a/src/SMDS/SMDS_FaceOfNodes.hxx b/src/SMDS/SMDS_FaceOfNodes.hxx index 290195107..8cbdf6f33 100644 --- a/src/SMDS/SMDS_FaceOfNodes.hxx +++ b/src/SMDS/SMDS_FaceOfNodes.hxx @@ -44,6 +44,16 @@ class SMDS_FaceOfNodes:public SMDS_MeshFace int NbEdges() const; int NbFaces() const; int NbNodes() const; + + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + protected: SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 6381e547e..5df2090e9 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -31,6 +31,9 @@ #include "SMDS_FaceOfEdges.hxx" #include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_PolygonalFaceOfNodes.hxx" +#include "SMDS_QuadraticEdge.hxx" +#include "SMDS_QuadraticFaceOfNodes.hxx" +#include "SMDS_QuadraticVolumeOfNodes.hxx" #include #include @@ -1084,19 +1087,32 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, if ( edge ) Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1] ); } + else if ( nbnodes == 3 ) { + const SMDS_QuadraticEdge* edge = dynamic_cast( elem ); + if ( edge ) + Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] ); + } break; } case SMDSAbs_Face: { const SMDS_FaceOfNodes* face = dynamic_cast( elem ); if ( face ) { Ok = const_cast( face )->ChangeNodes( nodes, nbnodes ); - } else { - /// ??? begin - const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); - if (face) { - Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); + } + else { + const SMDS_QuadraticFaceOfNodes* QF = + dynamic_cast( elem ); + if ( QF ) { + Ok = const_cast( QF )->ChangeNodes( nodes, nbnodes ); + } + else { + /// ??? begin + const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); + if (face) { + Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); + } + /// ??? end } - /// ??? end } break; } @@ -1109,8 +1125,15 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, //} case SMDSAbs_Volume: { const SMDS_VolumeOfNodes* vol = dynamic_cast( elem ); - if ( vol ) + if ( vol ) { Ok = const_cast( vol )->ChangeNodes( nodes, nbnodes ); + } + else { + const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast( elem ); + if ( QV ) { + Ok = const_cast( QV )->ChangeNodes( nodes, nbnodes ); + } + } break; } default: @@ -1200,6 +1223,7 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, return Ok; } + //======================================================================= //function : FindEdge //purpose : @@ -1207,54 +1231,95 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const { - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - if((node1==NULL)||(node2==NULL)) return NULL; - return FindEdge(node1,node2); + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + if((node1==NULL)||(node2==NULL)) return NULL; + return FindEdge(node1,node2); } //#include "Profiler.h" const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) { - const SMDS_MeshEdge * toReturn=NULL; - //PROFILER_Init(); - //PROFILER_Set(); - SMDS_ElemIteratorPtr it1=node1->edgesIterator(); - //PROFILER_Get(0); - //PROFILER_Set(); - while(it1->more()) - { - const SMDS_MeshEdge * e=static_cast - (it1->next()); - SMDS_ElemIteratorPtr it2=e->nodesIterator(); - while(it2->more()) - { - if(it2->next()->GetID()==node2->GetID()) - { - toReturn=e; - break; - } - } - } - //PROFILER_Get(1); - return toReturn; + const SMDS_MeshEdge * toReturn=NULL; + //PROFILER_Init(); + //PROFILER_Set(); + SMDS_ElemIteratorPtr it1=node1->edgesIterator(); + //PROFILER_Get(0); + //PROFILER_Set(); + while(it1->more()) { + const SMDS_MeshEdge * e=static_cast (it1->next()); + SMDS_ElemIteratorPtr it2=e->nodesIterator(); + while(it2->more()) { + if(it2->next()->GetID()==node2->GetID()) { + toReturn = e; + break; + } + } + } + //PROFILER_Get(1); + return toReturn; } +//======================================================================= +//function : FindEdgeOrCreate +//purpose : +//======================================================================= + SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) + const SMDS_MeshNode * node2) { - SMDS_MeshEdge * toReturn=NULL; - toReturn=const_cast(FindEdge(node1,node2)); - if(toReturn==NULL) - { - toReturn=new SMDS_MeshEdge(node1,node2); - myEdges.Add(toReturn); - } - return toReturn; + SMDS_MeshEdge * toReturn=NULL; + toReturn=const_cast(FindEdge(node1,node2)); + if(toReturn==NULL) { + toReturn=new SMDS_MeshEdge(node1,node2); + myEdges.Add(toReturn); + } + return toReturn; +} + + +//======================================================================= +//function : FindEdge +//purpose : +//======================================================================= + +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2, + int idnode3) const +{ + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) ) return NULL; + return FindEdge(node1,node2,node3); +} + +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3) +{ + const SMDS_MeshEdge * toReturn = NULL; + SMDS_ElemIteratorPtr it1 = node1->edgesIterator(); + while(it1->more()) { + const SMDS_MeshEdge * e = static_cast (it1->next()); + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + int tmp = 0; + while(it2->more()) { + int nID = it2->next()->GetID(); + if( nID==node2->GetID() || nID==node3->GetID() ) { + tmp++; + if(tmp==2) { + toReturn = e; + break; + } + } + } + } + return toReturn; } + //======================================================================= //function : FindFace //purpose : @@ -1263,118 +1328,219 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3) const { - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - const SMDS_MeshNode * node3=FindNode(idnode3); - if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL; - return FindFace(node1, node2, node3); + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) ) return NULL; + return FindFace(node1, node2, node3); } -const SMDS_MeshFace* SMDS_Mesh::FindFace( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3) +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - bool node2found, node3found; - - SMDS_ElemIteratorPtr it1=node1->facesIterator(); - while(it1->more()) - { - face=static_cast(it1->next()); - if(face->NbNodes()!=3) continue; - SMDS_ElemIteratorPtr it2=face->nodesIterator(); - node2found=false; - node3found=false; - while(it2->more()) - { - node=it2->next(); - if(node->GetID()==node2->GetID()) node2found=true; - if(node->GetID()==node3->GetID()) node3found=true; - } - if(node2found&&node3found) - return face; - } - return NULL; + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + bool node2found, node3found; + + SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + while(it1->more()) { + face = static_cast(it1->next()); + if(face->NbNodes()!=3) continue; + SMDS_ElemIteratorPtr it2 = face->nodesIterator(); + node2found = false; + node3found = false; + while(it2->more()) { + node = it2->next(); + if(node->GetID()==node2->GetID()) node2found = true; + if(node->GetID()==node3->GetID()) node3found = true; + } + if( node2found && node3found ) + return face; + } + return NULL; } -SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3) +SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) { - SMDS_MeshFace * toReturn=NULL; - toReturn=const_cast(FindFace(node1,node2,node3)); - if(toReturn==NULL) - { - toReturn=createTriangle(node1,node2,node3); - } - return toReturn; + SMDS_MeshFace * toReturn=NULL; + toReturn = const_cast(FindFace(node1,node2,node3)); + if(toReturn==NULL) { + toReturn = createTriangle(node1,node2,node3); + } + return toReturn; } + //======================================================================= //function : FindFace //purpose : //======================================================================= -const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3, - int idnode4) const +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3, int idnode4) const { - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - const SMDS_MeshNode * node3=FindNode(idnode3); - const SMDS_MeshNode * node4=FindNode(idnode4); - if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL; - return FindFace(node1, node2, node3, node4); + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + const SMDS_MeshNode * node4=FindNode(idnode4); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) ) + return NULL; + return FindFace(node1, node2, node3, node4); } -const SMDS_MeshFace* SMDS_Mesh::FindFace( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3, - const SMDS_MeshNode *node4) +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - bool node2found, node3found, node4found; - SMDS_ElemIteratorPtr it1=node1->facesIterator(); - while(it1->more()) - { - face=static_cast(it1->next()); - if(face->NbNodes()!=4) continue; - SMDS_ElemIteratorPtr it2=face->nodesIterator(); - node2found=false; - node3found=false; - node4found=false; - while(it2->more()) - { - node=it2->next(); - if(node->GetID()==node2->GetID()) node2found=true; - if(node->GetID()==node3->GetID()) node3found=true; - if(node->GetID()==node4->GetID()) node4found=true; - } - if(node2found&&node3found&&node4found) - return face; - } - return NULL; + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + bool node2found, node3found, node4found; + SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + while(it1->more()) { + face = static_cast(it1->next()); + if(face->NbNodes()!=4) continue; + SMDS_ElemIteratorPtr it2 = face->nodesIterator(); + node2found = false; + node3found = false; + node4found = false; + while(it2->more()) { + node=it2->next(); + if(node->GetID()==node2->GetID()) node2found = true; + if(node->GetID()==node3->GetID()) node3found = true; + if(node->GetID()==node4->GetID()) node4found = true; + } + if( node2found && node3found && node4found ) + return face; + } + return NULL; } -SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3, - const SMDS_MeshNode *node4) +SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4) { - SMDS_MeshFace * toReturn=NULL; - toReturn=const_cast(FindFace(node1,node2,node3,node4)); - if(toReturn==NULL) - { - toReturn=createQuadrangle(node1,node2,node3,node4); - } - return toReturn; + SMDS_MeshFace * toReturn=NULL; + toReturn=const_cast(FindFace(node1,node2,node3,node4)); + if(toReturn==NULL) { + toReturn=createQuadrangle(node1,node2,node3,node4); + } + return toReturn; +} + + +//======================================================================= +//function : FindFace +//purpose :quadratic triangle +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3, int idnode4, + int idnode5, int idnode6) const +{ + const SMDS_MeshNode * node1 = FindNode(idnode1); + const SMDS_MeshNode * node2 = FindNode(idnode2); + const SMDS_MeshNode * node3 = FindNode(idnode3); + const SMDS_MeshNode * node4 = FindNode(idnode4); + const SMDS_MeshNode * node5 = FindNode(idnode5); + const SMDS_MeshNode * node6 = FindNode(idnode6); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) || + (node4==NULL) || (node5==NULL) || (node6==NULL) ) return NULL; + return FindFace(node1, node2, node3, node4, node5, node6); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4, + const SMDS_MeshNode *node5, + const SMDS_MeshNode *node6) +{ + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + while(it1->more()) { + face = static_cast(it1->next()); + if(face->NbNodes()!=6) continue; + SMDS_ElemIteratorPtr it2 = face->nodesIterator(); + int tmp = 0; + while(it2->more()) { + node = it2->next(); + if(node->GetID()==node2->GetID()) tmp++; + if(node->GetID()==node3->GetID()) tmp++; + if(node->GetID()==node4->GetID()) tmp++; + if(node->GetID()==node5->GetID()) tmp++; + if(node->GetID()==node6->GetID()) tmp++; + } + if( tmp==5 ) + return static_cast(face); + } + return NULL; +} + + +//======================================================================= +//function : FindFace +//purpose : quadratic quadrangle +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3, int idnode4, + int idnode5, int idnode6, + int idnode7, int idnode8) const +{ + const SMDS_MeshNode * node1 = FindNode(idnode1); + const SMDS_MeshNode * node2 = FindNode(idnode2); + const SMDS_MeshNode * node3 = FindNode(idnode3); + const SMDS_MeshNode * node4 = FindNode(idnode4); + const SMDS_MeshNode * node5 = FindNode(idnode5); + const SMDS_MeshNode * node6 = FindNode(idnode6); + const SMDS_MeshNode * node7 = FindNode(idnode7); + const SMDS_MeshNode * node8 = FindNode(idnode8); + if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) || + (node5==NULL) || (node6==NULL) || (node7==NULL) || (node8==NULL) ) + return NULL; + return FindFace(node1, node2, node3, node4, node5, node6, node7, node8); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4, + const SMDS_MeshNode *node5, + const SMDS_MeshNode *node6, + const SMDS_MeshNode *node7, + const SMDS_MeshNode *node8) +{ + const SMDS_MeshFace * face; + const SMDS_MeshElement * node; + SMDS_ElemIteratorPtr it1 = node1->facesIterator(); + while(it1->more()) { + face = static_cast(it1->next()); + if(face->NbNodes()!=8) continue; + SMDS_ElemIteratorPtr it2 = face->nodesIterator(); + int tmp = 0; + while(it2->more()) { + node = it2->next(); + if(node->GetID()==node2->GetID()) tmp++; + if(node->GetID()==node3->GetID()) tmp++; + if(node->GetID()==node4->GetID()) tmp++; + if(node->GetID()==node5->GetID()) tmp++; + if(node->GetID()==node6->GetID()) tmp++; + if(node->GetID()==node7->GetID()) tmp++; + if(node->GetID()==node8->GetID()) tmp++; + } + if( tmp==7 ) + return face; + } + return NULL; } + //======================================================================= //function : FindElement //purpose : @@ -1382,7 +1548,7 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const { - return myElementIDFactory->MeshElement(IDelem); + return myElementIDFactory->MeshElement(IDelem); } //======================================================================= @@ -2075,6 +2241,57 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, delete s1; } + +/////////////////////////////////////////////////////////////////////////////// +///@param elem The element to delete +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) +{ + SMDSAbs_ElementType aType = elem->GetType(); + if (aType == SMDSAbs_Node) { + // only free node can be removed by this method + const SMDS_MeshNode* n = static_cast(elem); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + if (!itFe->more()) { // free node + myNodes.Remove(const_cast(n)); + myNodeIDFactory->ReleaseID(elem->GetID()); + delete elem; + } + } else { + if (hasConstructionEdges() || hasConstructionFaces()) + // this methods is only for meshes without descendants + return; + + // Remove element from of its nodes + SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + while (itn->more()) { + SMDS_MeshNode * n = static_cast + (const_cast(itn->next())); + n->RemoveInverseElement(elem); + } + + // in meshes without descendants elements are always free + switch (aType) { + case SMDSAbs_Edge: + myEdges.Remove(static_cast + (const_cast(elem))); + break; + case SMDSAbs_Face: + myFaces.Remove(static_cast + (const_cast(elem))); + break; + case SMDSAbs_Volume: + myVolumes.Remove(static_cast + (const_cast(elem))); + break; + default: + break; + } + myElementIDFactory->ReleaseID(elem->GetID()); + delete elem; + } +} + /*! * Checks if the element is present in mesh. * Useful to determine dead pointers. @@ -2200,4 +2417,589 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) } else return elem->GetType(); -} \ No newline at end of file +} + + + +//******************************************************************** +//******************************************************************** +//******** ********* +//***** Methods for addition of quadratic elements ****** +//******** ********* +//******************************************************************** +//******************************************************************** + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) +{ + SMDS_MeshNode* node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + SMDS_MeshNode* node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + SMDS_MeshNode* node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + if(!node1 || !node2 || !node12) return NULL; + return SMDS_Mesh::AddEdgeWithID(node1, node2, node12, ID); +} + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) +{ + return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID) +{ + SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12); + if(myElementIDFactory->BindID(ID, edge)) { + SMDS_MeshNode *node1,*node2, *node12; + node1 = const_cast(n1); + node2 = const_cast(n2); + node12 = const_cast(n12); + node1->AddInverseElement(edge); + node2->AddInverseElement(edge); + node12->AddInverseElement(edge); + myEdges.Add(edge); + return edge; + } + else { + delete edge; + return NULL; + } +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31, + myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID) +{ + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2); + SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3); + SMDS_MeshNode * node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12); + SMDS_MeshNode * node23 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23); + SMDS_MeshNode * node31 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31); + if(!node1 || !node2 || !node3 || !node12 || !node23 || !node31) return NULL; + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, + node12, node23, node31, ID); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID) +{ + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + } + SMDS_QuadraticFaceOfNodes* face = + new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31); + myFaces.Add(face); + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41, + myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID) +{ + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2); + SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3); + SMDS_MeshNode * node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4); + SMDS_MeshNode * node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12); + SMDS_MeshNode * node23 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23); + SMDS_MeshNode * node34 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34); + SMDS_MeshNode * node41 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41); + if(!node1 || !node2 || !node3 || !node4 || + !node12 || !node23 || !node34 || !node41) return NULL; + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, + node12, node23, node34, node41, ID); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + int ID) +{ + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + } + SMDS_QuadraticFaceOfNodes* face = + new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41); + myFaces.Add(face); + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23, + n31, n14, n24, n34, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node12, *node23; + SMDS_MeshNode *node31, *node14, *node24, *node34; + node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); + node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); + node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); + node31 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31); + node14 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14); + node24 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24); + node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34); + if( !node1 || !node2 || !node3 || !node4 || !node12 || !node23 || + !node31 || !node14 || !node24 || !node34 ) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node12, node23, + node31, node14, node24, node34, ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order tetrahedron of 10 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + int ID) +{ + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41, + n15, n25, n35, n45, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; + SMDS_MeshNode *node12, *node23, *node34, *node41; + SMDS_MeshNode *node15, *node25, *node35, *node45; + node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); + node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); + node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5); + node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); + node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34); + node41 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41); + node15 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15); + node25 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25); + node35 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35); + node45 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45); + if( !node1 || !node2 || !node3 || !node4 || !node5 || + !node12 || !node23 || !node34 || !node41 || + !node15 || !node25 || !node35 || !node45 ) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, + node12, node23, node34, node41, + node15, node25, node35, node45, ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order pyramid of 13 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + int ID) +{ + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23, + n34,n41,n15,n25,n35,n45); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +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) +{ + 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, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +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 ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; + SMDS_MeshNode *node12, *node23, *node31; + SMDS_MeshNode *node45, *node56, *node64; + SMDS_MeshNode *node14, *node25, *node36; + node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); + node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); + node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5); + node6 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6); + node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); + node31 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31); + node45 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45); + node56 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56); + node64 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64); + node14 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14); + node25 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25); + node36 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36); + if( !node1 || !node2 || !node3 || !node4 || !node5 || !node6 || + !node12 || !node23 || !node31 || !node45 || !node56 || + !node64 || !node14 || !node25 || !node36 ) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, + node12, node23, node31, node45, node56, + node64, node14, node25, node36, ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron with 15 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, + int ID) +{ + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, + n56, n67, n78, n85, n15, n26, n37, n48, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(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 n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4; + SMDS_MeshNode *node5, *node6, *node7, *node8; + SMDS_MeshNode *node12, *node23, *node34, *node41; + SMDS_MeshNode *node56, *node67, *node78, *node85; + SMDS_MeshNode *node15, *node26, *node37, *node48; + node1 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1); + node2 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2); + node3 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3); + node4 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4); + node5 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5); + node6 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6); + node7 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7); + node8 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8); + node12 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12); + node23 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23); + node34 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34); + node41 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41); + node56 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56); + node67 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67); + node78 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78); + node85 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85); + node15 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15); + node26 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26); + node37 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37); + node48 = (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48); + if( !node1 || !node2 || !node3 || !node4 || + !node5 || !node6 || !node7 || !node8 || + !node12 || !node23 || !node34 || !node41 || + !node56 || !node67 || !node78 || !node85 || + !node15 || !node26 || !node37 || !node48 ) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, + node5, node6, node7, node8, + node12, node23, node34, node41, + node56, node67, node78, node85, + node15, node26, node37, node48, ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Hexahedrons with 20 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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + int ID) +{ + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41, + n56,n67,n78,n85,n15,n26,n37,n48); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index 612082ce4..00db00fa1 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -50,15 +50,6 @@ #include #include -typedef SMDS_Iterator SMDS_NodeIterator; -typedef boost::shared_ptr > SMDS_NodeIteratorPtr; -typedef SMDS_Iterator SMDS_EdgeIterator; -typedef boost::shared_ptr > SMDS_EdgeIteratorPtr; -typedef SMDS_Iterator SMDS_FaceIterator; -typedef boost::shared_ptr > SMDS_FaceIteratorPtr; -typedef SMDS_Iterator SMDS_VolumeIterator; -typedef boost::shared_ptr > SMDS_VolumeIteratorPtr; - class SMDS_WNT_EXPORT SMDS_Mesh:public SMDS_MeshObject{ public: @@ -84,6 +75,16 @@ public: virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2); + // 2d order edge with 3 nodes: n12 - node between n1 and n2 + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID); + virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID); + virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12); + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -120,6 +121,44 @@ public: const SMDS_MeshEdge * e3, const SMDS_MeshEdge * e4); + // 2d order triangle of 6 nodes + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31); + + // 2d order quadrangle + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41); + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -214,6 +253,153 @@ public: const SMDS_MeshFace * f5, const SMDS_MeshFace * f6); + // 2d order tetrahedron of 10 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34); + + // 2d order pyramid of 13 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, + 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45); + + // 2d order Pentahedron with 15 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 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, + 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); + + // 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, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + 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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + 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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48); + virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes_ids, const int ID); @@ -245,6 +431,12 @@ public: virtual void RemoveEdge(const SMDS_MeshEdge * edge); virtual void RemoveFace(const SMDS_MeshFace * face); virtual void RemoveVolume(const SMDS_MeshVolume * volume); + + /*! Remove only the given element and only if it is free. + * Method does not work for meshes with descendants. + * Implemented for fast cleaning of meshes. + */ + virtual void RemoveFreeElement(const SMDS_MeshElement * elem); virtual bool RemoveFromParent(); virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh); @@ -261,11 +453,19 @@ public: const SMDS_MeshNode *FindNode(int idnode) const; const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const; + const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2, int idnode3) const; const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const; const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5, int idnode6) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4, + int idnode5, int idnode6, int idnode7, int idnode8) const; const SMDS_MeshElement *FindElement(int IDelem) const; static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2); + static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3); static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1, const SMDS_MeshNode *n2, const SMDS_MeshNode *n3); @@ -273,6 +473,20 @@ public: const SMDS_MeshNode *n2, const SMDS_MeshNode *n3, const SMDS_MeshNode *n4); + static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3, + const SMDS_MeshNode *n4, + const SMDS_MeshNode *n5, + const SMDS_MeshNode *n6); + static const SMDS_MeshFace* FindFace(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 *n7, + const SMDS_MeshNode *n8); const SMDS_MeshFace *FindFace(std::vector nodes_ids) const; static const SMDS_MeshFace* FindFace(std::vector nodes); diff --git a/src/SMDS/SMDS_MeshEdge.cxx b/src/SMDS/SMDS_MeshEdge.cxx index 66c8ae3d5..dc1dab968 100644 --- a/src/SMDS/SMDS_MeshEdge.cxx +++ b/src/SMDS/SMDS_MeshEdge.cxx @@ -135,6 +135,18 @@ bool operator<(const SMDS_MeshEdge & e1, const SMDS_MeshEdge & e2) else return false; } +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ +const SMDS_MeshNode* SMDS_MeshEdge::GetNode(const int ind) const +{ + return myNodes[ WrappedIndex( ind )]; +} + //======================================================================= //function : ChangeNodes //purpose : diff --git a/src/SMDS/SMDS_MeshEdge.hxx b/src/SMDS/SMDS_MeshEdge.hxx index 290210ca3..c99b08198 100644 --- a/src/SMDS/SMDS_MeshEdge.hxx +++ b/src/SMDS/SMDS_MeshEdge.hxx @@ -44,12 +44,22 @@ class SMDS_MeshEdge:public SMDS_MeshElement int NbNodes() const; int NbEdges() const; friend bool operator<(const SMDS_MeshEdge& e1, const SMDS_MeshEdge& e2); + + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + protected: SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; - private: - const SMDS_MeshNode* myNodes[2]; + protected: + const SMDS_MeshNode* myNodes[3]; }; #endif diff --git a/src/SMDS/SMDS_MeshElement.cxx b/src/SMDS/SMDS_MeshElement.cxx index 8d4d9b75d..83f073fdb 100644 --- a/src/SMDS/SMDS_MeshElement.cxx +++ b/src/SMDS/SMDS_MeshElement.cxx @@ -192,3 +192,29 @@ bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2) } return false; } + +bool SMDS_MeshElement::IsValidIndex(const int ind) const +{ + return ( ind>-1 && indnext(); + if ( it->more() ) + return static_cast (it->next()); + return 0; +} + +bool SMDS_MeshElement::IsQuadratic() const +{ + return false; +} + +bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const +{ + return false; +} diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx index 73870b707..67ac8f247 100644 --- a/src/SMDS/SMDS_MeshElement.hxx +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -56,32 +56,64 @@ class SMDS_MeshFace; /////////////////////////////////////////////////////////////////////////////// class SMDS_WNT_EXPORT SMDS_MeshElement:public SMDS_MeshObject { +public: - public: - SMDS_ElemIteratorPtr nodesIterator() const; - SMDS_ElemIteratorPtr edgesIterator() const; - SMDS_ElemIteratorPtr facesIterator() const; - virtual SMDS_ElemIteratorPtr - elementsIterator(SMDSAbs_ElementType type) const; + SMDS_ElemIteratorPtr nodesIterator() const; + SMDS_ElemIteratorPtr edgesIterator() const; + SMDS_ElemIteratorPtr facesIterator() const; + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; - virtual int NbNodes() const; - virtual int NbEdges() const; - virtual int NbFaces() const; - int GetID() const; + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + int GetID() const; - ///Return the type of the current element - virtual SMDSAbs_ElementType GetType() const = 0; - virtual bool IsPoly() const { return false; }; + ///Return the type of the current element + virtual SMDSAbs_ElementType GetType() const = 0; + virtual bool IsPoly() const { return false; }; + virtual bool IsQuadratic() const; - friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *); - friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem); + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; - protected: - SMDS_MeshElement(int ID=-1); - virtual void Print(std::ostream & OS) const; - - private: - int myID; + friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *); + friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem); + + // =========================== + // Access to nodes by index + // =========================== + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + + /*! + * \brief Return true if index of node is valid (0 <= ind < NbNodes()) + * \param ind - node index + * \retval bool - index check result + */ + virtual bool IsValidIndex(const int ind) const; + + /*! + * \brief Return a valid node index, fixing the given one if necessary + * \param ind - node index + * \retval int - valid node index + */ + int WrappedIndex(const int ind) const { + if ( ind < 0 ) return -( ind % NbNodes()); + if ( ind >= NbNodes() ) return ind % NbNodes(); + return ind; + } + +protected: + SMDS_MeshElement(int ID=-1); + virtual void Print(std::ostream & OS) const; + +private: + int myID; }; #endif diff --git a/src/SMDS/SMDS_MeshNode.hxx b/src/SMDS/SMDS_MeshNode.hxx index 042a1734a..fad622534 100644 --- a/src/SMDS/SMDS_MeshNode.hxx +++ b/src/SMDS/SMDS_MeshNode.hxx @@ -64,6 +64,15 @@ class SMDS_WNT_EXPORT SMDS_MeshNode:public SMDS_MeshElement void setXYZ(double x, double y, double z); friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2); + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ + virtual const SMDS_MeshNode* GetNode(const int) const { return this; } + protected: SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx index 38abf18c2..568bd34d0 100644 --- a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx +++ b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx @@ -26,7 +26,7 @@ #include "SMDS_PolygonalFaceOfNodes.hxx" #include "SMDS_IteratorOfElements.hxx" -//#include "SMDS_MeshNode.hxx" +#include "SMDS_SetIterator.hxx" #include "utilities.h" using namespace std; @@ -128,28 +128,11 @@ void SMDS_PolygonalFaceOfNodes::Print(ostream & OS) const //function : elementsIterator //purpose : //======================================================================= -class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_ElemIterator +class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_NodeVectorElemIterator { - //const SMDS_MeshNode* const *mySet; - const std::vector mySet; - //int myLength; - int index; public: - //SMDS_PolygonalFaceOfNodes_MyIterator(const SMDS_MeshNode* const *s, int l): - // mySet(s),myLength(l),index(0) {} - SMDS_PolygonalFaceOfNodes_MyIterator(const std::vector s): - mySet(s),index(0) {} - - bool more() - { - return index < mySet.size(); - } - - const SMDS_MeshElement* next() - { - index++; - return mySet[index-1]; - } + SMDS_PolygonalFaceOfNodes_MyIterator(const vector& s): + SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {} }; SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator @@ -172,3 +155,16 @@ SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator } return SMDS_ElemIteratorPtr(); } + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ +const SMDS_MeshNode* SMDS_PolygonalFaceOfNodes::GetNode(const int ind) const +{ + return myNodes[ WrappedIndex( ind )]; +} + diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx index 567746259..c8884b319 100644 --- a/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx +++ b/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx @@ -50,6 +50,15 @@ class SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace virtual void Print (std::ostream & OS) const; + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + protected: virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; diff --git a/src/SMDS/SMDS_QuadraticEdge.cxx b/src/SMDS/SMDS_QuadraticEdge.cxx new file mode 100644 index 000000000..ca12343ff --- /dev/null +++ b/src/SMDS/SMDS_QuadraticEdge.cxx @@ -0,0 +1,187 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File: SMDS_QuadraticEdge.cxx +// Created: 16.01.06 16:25:42 +// Author: Sergey KUUL + + +#include "SMDS_QuadraticEdge.hxx" + +#include "SMDS_SetIterator.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" + +using namespace std; + +//======================================================================= +//function : SMDS_QuadraticEdge +//purpose : +//======================================================================= + +SMDS_QuadraticEdge::SMDS_QuadraticEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node12) + :SMDS_MeshEdge(node1,node2) +{ + myNodes[2]=node12; +} + + +//======================================================================= +//function : Print +//purpose : +//======================================================================= + +void SMDS_QuadraticEdge::Print(ostream & OS) const +{ + OS << "quadratic edge <" << GetID() << "> : ( first-" << myNodes[0] + << " , last-" << myNodes[1] << " , medium-" << myNodes[2] << ") " << endl; +} + + +//======================================================================= +//function : NbNodes +//purpose : +//======================================================================= + +int SMDS_QuadraticEdge::NbNodes() const +{ + return 3; +} + +//======================================================================= +//function : ChangeNodes +//purpose : +//======================================================================= + +bool SMDS_QuadraticEdge::ChangeNodes(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node12) +{ + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node12; + return true; +} + +//======================================================================= +//function : IsMediumNode +//purpose : +//======================================================================= + +bool SMDS_QuadraticEdge::IsMediumNode(const SMDS_MeshNode * node) const +{ + return (myNodes[2]==node); +} + +namespace +{ + //======================================================================= + //class : _MyInterlacedNodeIterator + //purpose : + //======================================================================= + + class _MyInterlacedNodeIterator: public SMDS_NodeArrayIterator + { + const SMDS_MeshNode * myNodes[3]; + public: + _MyInterlacedNodeIterator(const SMDS_MeshNode * const * nodes): + SMDS_NodeArrayIterator( myNodes, & myNodes[3] ) + { + myNodes[0] = nodes[0]; + myNodes[1] = nodes[2]; + myNodes[2] = nodes[1]; + } + }; + + //======================================================================= + //class : _MyInterlacedNodeElemIterator + //purpose : + //======================================================================= + + class _MyInterlacedNodeElemIterator : public SMDS_ElemIterator + { + SMDS_NodeIteratorPtr myItr; + public: + _MyInterlacedNodeElemIterator(SMDS_NodeIteratorPtr interlacedNodeItr): + myItr( interlacedNodeItr ) {} + bool more() { return myItr->more(); } + const SMDS_MeshElement* next() { return myItr->next(); } + }; + + //======================================================================= + //class : _MyNodeIterator + //purpose : + //======================================================================= + + class _MyNodeIterator:public SMDS_NodeArrayElemIterator + { + public: + _MyNodeIterator(const SMDS_MeshNode * const * nodes): + SMDS_NodeArrayElemIterator( nodes, & nodes[3] ) {} + }; +} + +//======================================================================= +//function : interlacedNodesIterator +//purpose : +//======================================================================= + +SMDS_NodeIteratorPtr SMDS_QuadraticEdge::interlacedNodesIterator() const +{ + return SMDS_NodeIteratorPtr (new _MyInterlacedNodeIterator (myNodes)); +} + + +//======================================================================= +//function : interlacedNodesElemIterator +//purpose : +//======================================================================= + +SMDS_ElemIteratorPtr SMDS_QuadraticEdge::interlacedNodesElemIterator() const +{ + return SMDS_ElemIteratorPtr + (new _MyInterlacedNodeElemIterator ( interlacedNodesIterator() )); +} + +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= + +SMDS_ElemIteratorPtr SMDS_QuadraticEdge::elementsIterator(SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_Edge: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes)); + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type, SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes)))); + } +} + diff --git a/src/SMDS/SMDS_QuadraticEdge.hxx b/src/SMDS/SMDS_QuadraticEdge.hxx new file mode 100644 index 000000000..dacdef01c --- /dev/null +++ b/src/SMDS/SMDS_QuadraticEdge.hxx @@ -0,0 +1,62 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_QuadraticEdge.hxx +// Module : SMESH + +#ifndef _SMDS_QuadraticEdge_HeaderFile +#define _SMDS_QuadraticEdge_HeaderFile + +#include "SMDS_MeshEdge.hxx" +#include + +class SMDS_WNT_EXPORT SMDS_QuadraticEdge: public SMDS_MeshEdge +{ + +public: + SMDS_QuadraticEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node12); + + bool ChangeNodes(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node12); + + void Print(std::ostream & OS) const; + + int NbNodes() const; + + virtual bool IsQuadratic() const { return true; } + + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + SMDS_NodeIteratorPtr interlacedNodesIterator() const; + + SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; + +protected: + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + +}; +#endif diff --git a/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx b/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx new file mode 100644 index 000000000..ecd69cc70 --- /dev/null +++ b/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx @@ -0,0 +1,281 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File: SMDS_QuadraticFaceOfNodes.cxx +// Created: 16.01.06 17:12:58 +// Author: Sergey KUUL + +#include "SMDS_QuadraticFaceOfNodes.hxx" + +#include "SMDS_SetIterator.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" + +#include "utilities.h" + +using namespace std; + + +//======================================================================= +//function : SMDS_QuadraticFaceOfNodes() +//purpose : Constructor +//======================================================================= + +SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31) +{ + myNodes.resize( 6 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n12; + myNodes[ 4 ] = n23; + myNodes[ 5 ] = n31; +} + + +//======================================================================= +//function : SMDS_QuadraticFaceOfNodes() +//purpose : Constructor +//======================================================================= + +SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41) +{ + myNodes.resize( 8 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n12; + myNodes[ 5 ] = n23; + myNodes[ 6 ] = n34; + myNodes[ 7 ] = n41; +} + + +//======================================================================= +//function : IsMediumNode +//purpose : +//======================================================================= + +bool SMDS_QuadraticFaceOfNodes::IsMediumNode(const SMDS_MeshNode * node) const +{ + int i=NbNodes()/2; + for(; i : "; + int i, nbNodes = myNodes.size(); + for (i = 0; i < nbNodes - 1; i++) + OS << myNodes[i] << ","; + OS << myNodes[i] << ") " << endl; +} + +namespace { + + //======================================================================= + //class : _MyInterlacedNodeIterator + //purpose : + //======================================================================= + + class _MyInterlacedNodeIterator:public SMDS_NodeIterator + { + const vector& mySet; + int myIndex; + const int * myInterlace; + public: + _MyInterlacedNodeIterator(const vector& s, + const int * interlace): + mySet(s),myIndex(0),myInterlace(interlace) {} + + bool more() + { + return myIndex < mySet.size(); + } + + const SMDS_MeshNode* next() + { + return mySet[ myInterlace[ myIndex++ ]]; + } + }; + + //======================================================================= + //class : _MyInterlacedNodeElemIterator + //purpose : + //======================================================================= + + class _MyInterlacedNodeElemIterator : public SMDS_ElemIterator + { + SMDS_NodeIteratorPtr myItr; + public: + _MyInterlacedNodeElemIterator(SMDS_NodeIteratorPtr interlacedNodeItr): + myItr( interlacedNodeItr ) {} + bool more() { return myItr->more(); } + const SMDS_MeshElement* next() { return myItr->next(); } + }; + + //======================================================================= + //class : _MyNodeIterator + //purpose : + //======================================================================= + + class _MyNodeIterator : public SMDS_NodeVectorElemIterator + { + public: + _MyNodeIterator(const vector& s): + SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {} + }; + +} + +//======================================================================= +//function : interlacedNodesIterator +//purpose : +//======================================================================= + +SMDS_NodeIteratorPtr SMDS_QuadraticFaceOfNodes::interlacedNodesIterator() const +{ + static int triaInterlace [] = { 0, 3, 1, 4, 2, 5 }; + static int quadInterlace [] = { 0, 4, 1, 5, 2, 6, 3, 7 }; + return SMDS_NodeIteratorPtr + (new _MyInterlacedNodeIterator (myNodes, myNodes.size()==6 ? triaInterlace : quadInterlace)); +} + +//======================================================================= +//function : interlacedNodesElemIterator +//purpose : +//======================================================================= + +SMDS_ElemIteratorPtr SMDS_QuadraticFaceOfNodes::interlacedNodesElemIterator() const +{ + return SMDS_ElemIteratorPtr + (new _MyInterlacedNodeElemIterator ( interlacedNodesIterator() )); +} + +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= + +SMDS_ElemIteratorPtr SMDS_QuadraticFaceOfNodes::elementsIterator + (SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_Face: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Face); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes)); + case SMDSAbs_Edge: + MESSAGE("Error : edge iterator for SMDS_QuadraticFaceOfNodes not implemented"); + break; + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type,SMDS_ElemIteratorPtr (new _MyNodeIterator(myNodes)))); + } + return SMDS_ElemIteratorPtr(); +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ +const SMDS_MeshNode* SMDS_QuadraticFaceOfNodes::GetNode(const int ind) const +{ + return myNodes[ WrappedIndex( ind )]; +} + diff --git a/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx b/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx new file mode 100644 index 000000000..77cda784a --- /dev/null +++ b/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx @@ -0,0 +1,84 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_QuadraticVolumeOfNodes.hxx +// Module : SMESH + +#ifndef _SMDS_QuadraticFaceOfNodes_HeaderFile +#define _SMDS_QuadraticFaceOfNodes_HeaderFile + +#include "SMDS_MeshFace.hxx" + +class SMDS_WNT_EXPORT SMDS_QuadraticFaceOfNodes:public SMDS_MeshFace +{ +public: + SMDS_QuadraticFaceOfNodes (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31); + + SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41); + + virtual bool IsQuadratic() const { return true; } + + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes); + + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + + virtual void Print (std::ostream & OS) const; + + SMDS_NodeIteratorPtr interlacedNodesIterator() const; + + SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; + + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + +protected: + virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; + + private: + std::vector myNodes; +}; + +#endif diff --git a/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx new file mode 100644 index 000000000..b7f7e7821 --- /dev/null +++ b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx @@ -0,0 +1,347 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File: SMDS_QuadraticVolumeOfNodes.cxx +// Created: 17.01.06 09:46:11 +// Author: Sergey KUUL + +#include "SMDS_QuadraticVolumeOfNodes.hxx" + +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_SetIterator.hxx" + +#include "utilities.h" + +using namespace std; + + +//======================================================================= +//function : SMDS_QuadraticVolumeOfNodes() +//purpose : Constructor tetrahedron of 10 nodes +//======================================================================= + +SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes + (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34) +{ + myNodes.resize( 10 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n12; + myNodes[ 5 ] = n23; + myNodes[ 6 ] = n31; + myNodes[ 7 ] = n14; + myNodes[ 8 ] = n24; + myNodes[ 9 ] = n34; +} + + +//======================================================================= +//function : SMDS_QuadraticVolumeOfNodes() +//purpose : Constructor pyramid of 13 nodes +//======================================================================= + +SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes + (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45) +{ + myNodes.resize( 13 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n5; + myNodes[ 5 ] = n12; + myNodes[ 6 ] = n23; + myNodes[ 7 ] = n34; + myNodes[ 8 ] = n41; + myNodes[ 9 ] = n15; + myNodes[ 10 ] = n25; + myNodes[ 11 ] = n35; + myNodes[ 12 ] = n45; +} + + +//======================================================================= +//function : SMDS_QuadraticVolumeOfNodes() +//purpose : Constructor Pentahedron with 15 nodes +//======================================================================= + +SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes + (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) +{ + myNodes.resize( 15 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n5; + myNodes[ 5 ] = n6; + myNodes[ 6 ] = n12; + myNodes[ 7 ] = n23; + myNodes[ 8 ] = n31; + myNodes[ 9 ] = n45; + myNodes[ 10 ] = n56; + myNodes[ 11 ] = n64; + myNodes[ 12 ] = n14; + myNodes[ 13 ] = n25; + myNodes[ 14 ] = n36; +} + + +//======================================================================= +//function : SMDS_QuadraticVolumeOfNodes() +//purpose : Constructor Hexahedrons with 20 nodes +//======================================================================= + +SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes + (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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48) +{ + myNodes.resize( 20 ); + myNodes[ 0 ] = n1; + myNodes[ 1 ] = n2; + myNodes[ 2 ] = n3; + myNodes[ 3 ] = n4; + myNodes[ 4 ] = n5; + myNodes[ 5 ] = n6; + myNodes[ 6 ] = n7; + myNodes[ 7 ] = n8; + myNodes[ 8 ] = n12; + myNodes[ 9 ] = n23; + myNodes[ 10 ] = n34; + myNodes[ 11 ] = n41; + myNodes[ 12 ] = n56; + myNodes[ 13 ] = n67; + myNodes[ 14 ] = n78; + myNodes[ 15 ] = n85; + myNodes[ 16 ] = n15; + myNodes[ 17 ] = n26; + myNodes[ 18 ] = n37; + myNodes[ 19 ] = n48; +} + + +//======================================================================= +//function : IsMediumNode +//purpose : +//======================================================================= + +bool SMDS_QuadraticVolumeOfNodes::IsMediumNode(const SMDS_MeshNode* node) const +{ + int nbCorners = 0; + switch (myNodes.size()) { + case 10: nbCorners = 4; break; + case 13: nbCorners = 5; break; + case 15: nbCorners = 6; break; + default: nbCorners = 8; + } + for ( int i = nbCorners; i : "; + int i, nbNodes = myNodes.size(); + for (i = 0; i < nbNodes - 1; i++) + OS << myNodes[i] << ","; + OS << myNodes[i] << ") " << endl; +} + + +//======================================================================= +//private class : SMDS_QuadraticVolumeOfNodes_MyIterator +//purpose : +//======================================================================= + +class SMDS_QuadraticVolumeOfNodes_MyIterator : public SMDS_NodeVectorElemIterator +{ +public: + SMDS_QuadraticVolumeOfNodes_MyIterator(const vector& s): + SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {} +}; + +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= + +SMDS_ElemIteratorPtr SMDS_QuadraticVolumeOfNodes::elementsIterator + (SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_Volume: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_QuadraticVolumeOfNodes_MyIterator(myNodes)); + case SMDSAbs_Edge: + MESSAGE("Error : edge iterator for SMDS_QuadraticVolumeOfNodes not implemented"); + break; + case SMDSAbs_Face: + MESSAGE("Error : face iterator for SMDS_QuadraticVolumeOfNodes not implemented"); + break; + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type,SMDS_ElemIteratorPtr + (new SMDS_QuadraticVolumeOfNodes_MyIterator(myNodes)))); + } + return SMDS_ElemIteratorPtr(); +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ +const SMDS_MeshNode* SMDS_QuadraticVolumeOfNodes::GetNode(const int ind) const +{ + return myNodes[ WrappedIndex( ind )]; +} + diff --git a/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx b/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx new file mode 100644 index 000000000..6fa60b0b6 --- /dev/null +++ b/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx @@ -0,0 +1,130 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_QuadraticVolumeOfNodes.hxx +// Module : SMESH + +#ifndef _SMDS_QuadraticVolumeOfNodes_HeaderFile +#define _SMDS_QuadraticVolumeOfNodes_HeaderFile + +#include "SMDS_MeshVolume.hxx" + +class SMDS_WNT_EXPORT SMDS_QuadraticVolumeOfNodes: public SMDS_MeshVolume +{ +public: + // tetrahedron of 10 nodes + SMDS_QuadraticVolumeOfNodes (const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34); + + // pyramid of 13 nodes + SMDS_QuadraticVolumeOfNodes(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45); + + // Pentahedron with 15 nodes + SMDS_QuadraticVolumeOfNodes(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); + + // Hexahedrons with 20 nodes + SMDS_QuadraticVolumeOfNodes(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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48); + + virtual bool IsQuadratic() const { return true; } + + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes); + + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + + virtual void Print (std::ostream & OS) const; + + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + * + * Index is wrapped if it is out of a valid range + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + + protected: + virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; + + private: + std::vector myNodes; +}; + +#endif diff --git a/src/SMDS/SMDS_SetIterator.hxx b/src/SMDS/SMDS_SetIterator.hxx new file mode 100644 index 000000000..8c08a737b --- /dev/null +++ b/src/SMDS/SMDS_SetIterator.hxx @@ -0,0 +1,101 @@ +// SMESH SMDS : implementaion of Salome mesh data structure +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMDS_SetIterator.hxx +// Created : Mon Feb 27 16:57:43 2006 +// Author : Edward AGAPOV (eap) + + +#ifndef SMDS_SetIterator_HeaderFile +#define SMDS_SetIterator_HeaderFile + +#include "SMDS_Iterator.hxx" + +/////////////////////////////////////////////////////////////////////////////// +/// specific SMDS_Iterator iterating over abstract set of values like STL containers +/// +/// BE CAREFUL: iterator pointed value is static_cast'ed to VALUE +/// +/////////////////////////////////////////////////////////////////////////////// + +template +class SMDS_SetIterator : public SMDS_Iterator +{ +protected: + VALUE_SET_ITERATOR _beg, _end; +public: + SMDS_SetIterator(const VALUE_SET_ITERATOR & begin, + const VALUE_SET_ITERATOR & end) + { init ( begin, end ); } + + /// Initialization + virtual void init(const VALUE_SET_ITERATOR & begin, + const VALUE_SET_ITERATOR & end) + { _beg = begin; _end = end; } + + /// Return true if and only if there are other object in this iterator + virtual bool more() { return _beg != _end; } + + /// Return the current object and step to the next one + virtual VALUE next() { return static_cast( *_beg++ ); } + +}; + +// useful specifications + +#include + +class SMDS_MeshElement; +class SMDS_MeshNode; + +typedef const SMDS_MeshElement* SMDS_pElement; +typedef const SMDS_MeshNode* SMDS_pNode; + +// element iterators + +typedef SMDS_SetIterator< SMDS_pElement, std::vector< SMDS_pElement >::const_iterator> +SMDS_ElementVectorIterator; + + +typedef SMDS_SetIterator< SMDS_pElement, SMDS_pElement const *> +SMDS_ElementArrayIterator; + + +typedef SMDS_SetIterator< SMDS_pElement, std::vector< SMDS_pNode >::const_iterator> +SMDS_NodeVectorElemIterator; + + +typedef SMDS_SetIterator< SMDS_pElement, SMDS_pNode const * > +SMDS_NodeArrayElemIterator; + +// node iterators + +typedef SMDS_SetIterator< SMDS_pNode, std::vector< SMDS_pNode >::const_iterator > +SMDS_NodeVectorIterator; + + +typedef SMDS_SetIterator< SMDS_pNode, SMDS_pNode const * > +SMDS_NodeArrayIterator; + + +#endif diff --git a/src/SMDS/SMDS_VolumeOfNodes.cxx b/src/SMDS/SMDS_VolumeOfNodes.cxx index cd893f484..941f538c3 100644 --- a/src/SMDS/SMDS_VolumeOfNodes.cxx +++ b/src/SMDS/SMDS_VolumeOfNodes.cxx @@ -25,6 +25,7 @@ #include "SMDS_VolumeOfNodes.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_SetIterator.hxx" #include "utilities.h" using namespace std; @@ -170,29 +171,14 @@ int SMDS_VolumeOfNodes::NbEdges() const return 0; } -class SMDS_VolumeOfNodes_MyIterator:public SMDS_ElemIterator +class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator { - const SMDS_MeshNode* const* mySet; - int myLength; - int index; public: SMDS_VolumeOfNodes_MyIterator(const SMDS_MeshNode* const* s, int l): - mySet(s),myLength(l),index(0) {} - - bool more() - { - return index EXTERNAL { 1, 2, 6, 5, 1 }}; static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 }; + +/* +// N3 +// + +// /|\ +// 7/ | \8 +// / |4 \ QUADRATIC +// N0 +---|---+ N1 TETRAHEDRON +// \ +9 / +// \ | / +// 6\ | /5 +// \|/ +// + +// N2 +*/ +static int QuadTetra_F [4][7] = { // FORWARD == EXTERNAL + { 0, 4, 1, 5, 2, 6, 0 }, // All faces have external normals + { 0, 7, 3, 8, 1, 4, 0 }, + { 1, 8, 3, 9, 2, 5, 1 }, + { 0, 6, 2, 9, 3, 7, 0 }}; +static int QuadTetra_R [4][7] = { // REVERSED + { 0, 4, 1, 5, 2, 6, 0 }, // All faces but a bottom have external normals + { 0, 4, 1, 8, 3, 7, 0 }, + { 1, 5, 2, 9, 3, 8, 1 }, + { 0, 7, 3, 9, 2, 6, 0 }}; +static int QuadTetra_RE [4][7] = { // REVERSED -> FORWARD (EXTERNAL) + { 0, 6, 2, 5, 1, 4, 0 }, // All faces have external normals + { 0, 4, 1, 8, 3, 7, 0 }, + { 1, 5, 2, 9, 3, 8, 1 }, + { 0, 7, 3, 9, 2, 6, 0 }}; +static int QuadTetra_nbN [] = { 6, 6, 6, 6 }; + +// +// QUADRATIC +// PYRAMID +// +// +4 +// +// +// 10+-----+11 +// | | 9 - middle point for (0,4) etc. +// | | +// 9+-----+12 +// +// 6 +// 1+----+----+2 +// | | +// | | +// 5+ +7 +// | | +// | | +// 0+----+----+3 +// 8 +static int QuadPyram_F [5][9] = { // FORWARD == EXTERNAL + { 0, 5, 1, 6, 2, 7, 3, 8, 0 }, // All faces have external normals + { 0, 9, 4, 10,1, 5, 0, 4, 4 }, + { 1, 10,4, 11,2, 6, 1, 4, 4 }, + { 2, 11,4, 12,3, 7, 2, 4, 4 }, + { 3, 12,4, 9, 0, 8, 3, 4, 4 }}; +static int QuadPyram_R [5][9] = { // REVERSED + { 0, 5, 1, 6, 2, 7, 3, 8, 0 }, // All faces but a bottom have external normals + { 0, 5, 1, 10,4, 9, 0, 4, 4 }, + { 1, 6, 2, 11,4, 10,1, 4, 4 }, + { 2, 7, 3, 12,4, 11,2, 4, 4 }, + { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; +static int QuadPyram_RE [5][9] = { // REVERSED -> FORWARD (EXTERNAL) + { 0, 8, 3, 7, 2, 6, 1, 5, 0 }, // All faces but a bottom have external normals + { 0, 5, 1, 10,4, 9, 0, 4, 4 }, + { 1, 6, 2, 11,4, 10,1, 4, 4 }, + { 2, 7, 3, 12,4, 11,2, 4, 4 }, + { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; +static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 }; + +/* +// + N4 +// /|\ +// 9/ | \10 +// / | \ +// / | \ +// N3 +----+----+ N5 +// | |11 | +// | | | +// | +13 | QUADRATIC +// | | | PENTAHEDRON +// | | | +// | | | +// | | | +// 12+ | +14 +// | | | +// | | | +// | + N1 | +// | / \ | +// | 6/ \7 | +// | / \ | +// |/ \| +// N0 +---------+ N2 +// 8 +*/ +static int QuadPenta_F [5][9] = { // FORWARD + { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, // Top face has an internal normal, other - external + { 3, 9, 4, 10,5, 11,3, 3, 3 }, // 0 is bottom, 1 is top face + { 0, 8, 2, 14,5, 11,3, 12,0 }, + { 1, 13,4, 10,5, 14,2, 7, 1 }, + { 0, 12,3, 9, 4, 13,1, 6, 0 }}; +static int QuadPenta_R [5][9] = { // REVERSED + { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, // Bottom face has an internal normal, other - external + { 3, 9, 4, 10,5, 11,3, 3, 3 }, // 0 is bottom, 1 is top face + { 0, 12,3, 11,5, 14,2, 8, 0 }, + { 1, 7, 2, 14,5, 10,4, 13,1 }, + { 0, 6, 1, 13,4, 9, 3, 12,0 }}; +static int QuadPenta_FE [5][9] = { // FORWARD -> EXTERNAL + { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, + { 3,11, 5, 10,4, 9, 3, 3, 3 }, + { 0, 8, 2, 14,5, 11,3, 12,0 }, + { 1, 13,4, 10,5, 14,2, 7, 1 }, + { 0, 12,3, 9, 4, 13,1, 6, 0 }}; +static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL + { 0, 8, 2, 7, 1, 6, 0, 0, 0 }, + { 3, 9, 4, 10,5, 11,3, 3, 3 }, + { 0, 12,3, 11,5, 14,2, 8, 0 }, + { 1, 7, 2, 14,5, 10,4, 13,1 }, + { 0, 6, 1, 13,4, 9, 3, 12,0 }}; +static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 }; + +/* +// 13 +// N5+-----+-----+N6 +// /| /| +// 12+ | 14+ | +// / | / | +// N4+-----+-----+N7 | QUADRATIC +// | | 15 | | HEXAHEDRON +// | | | | +// | 17+ | +18 +// | | | | +// | | | | +// | | | | +// 16+ | +19 | +// | | | | +// | | 9 | | +// | N1+-----+-|---+N2 +// | / | / +// | +8 | +10 +// |/ |/ +// N0+-----+-----+N3 +// 11 +*/ +static int QuadHexa_F [6][9] = { // FORWARD + { 0, 8, 1, 9, 2, 10,3, 11,0 }, // opposite faces are neighbouring, + { 4, 12,5, 13,6, 14,7, 15,4 }, // odd face(1,3,5) normal is internal, even(0,2,4) - external + { 1, 8, 0, 16,4, 12,5, 17,1 }, // same index nodes of opposite faces are linked + { 2, 10,3, 19,7, 14,6, 18,2 }, + { 0, 11,3, 19,7, 15,4, 16,0 }, + { 1, 9, 2, 18,6, 13,5, 17,1 }}; +// static int Hexa_R [6][5] = { // REVERSED +// { 0, 3, 2, 1, 0 }, // opposite faces are neighbouring, +// { 4, 7, 6, 5, 4 }, // odd face(1,3,5) normal is external, even(0,2,4) - internal +// { 1, 5, 4, 0, 1 }, // same index nodes of opposite faces are linked +// { 2, 6, 7, 3, 2 }, +// { 0, 4, 7, 3, 0 }, +// { 1, 5, 6, 2, 1 }}; +static int QuadHexa_FE [6][9] = { // FORWARD -> EXTERNAL + { 0, 8, 1, 9, 2, 10,3, 11,0 }, // opposite faces are neighbouring, + { 4, 15,7, 14,6, 13,5, 12,4 }, // all face normals are external, + { 0, 16,4, 12,5, 17,1, 8, 0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 3, 10,2, 18,6, 14,7, 19,3 }, + { 0, 11,3, 19,7, 15,4, 16,0 }, + { 1, 17,5, 13,6, 18,2, 9, 1 }}; +static int QuadHexa_RE [6][9] = { // REVERSED -> EXTERNAL + { 0, 11,3, 10,2, 9, 1, 8, 0 }, // opposite faces are neighbouring, + { 4, 12,5, 13,6, 14,7, 15,4 }, // all face normals are external, + { 0, 8, 1, 17,5, 12,4, 16,0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 3, 19,7, 14,6, 18,2, 10,3 }, + { 0, 16,4, 15,7, 19,3, 11,0 }, + { 1, 9, 2, 18,6, 13,5, 17,1 }}; +static int QuadHexa_nbN [] = { 8, 8, 8, 8, 8, 8 }; + + // ======================================================== // to perform some calculations without linkage to CASCADE // ======================================================== @@ -323,12 +501,17 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume) MESSAGE("Warning: bad volumic element"); return false; } - } else { + } + else { switch ( myVolumeNbNodes ) { case 4: case 5: case 6: - case 8: { + case 8: + case 10: + case 13: + case 15: + case 20: { // define volume orientation XYZ botNormal; GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z ); @@ -387,6 +570,34 @@ void SMDS_VolumeTool::Inverse () SWAP_NODES( myVolumeNodes, 1, 3 ); SWAP_NODES( myVolumeNodes, 5, 7 ); break; + + case 10: + SWAP_NODES( myVolumeNodes, 1, 2 ); + SWAP_NODES( myVolumeNodes, 4, 6 ); + SWAP_NODES( myVolumeNodes, 8, 9 ); + break; + case 13: + SWAP_NODES( myVolumeNodes, 1, 3 ); + SWAP_NODES( myVolumeNodes, 5, 8 ); + SWAP_NODES( myVolumeNodes, 6, 7 ); + SWAP_NODES( myVolumeNodes, 10, 12 ); + break; + case 15: + SWAP_NODES( myVolumeNodes, 1, 2 ); + SWAP_NODES( myVolumeNodes, 4, 5 ); + SWAP_NODES( myVolumeNodes, 6, 8 ); + SWAP_NODES( myVolumeNodes, 9, 11 ); + SWAP_NODES( myVolumeNodes, 13, 14 ); + break; + case 20: + SWAP_NODES( myVolumeNodes, 1, 3 ); + SWAP_NODES( myVolumeNodes, 5, 7 ); + SWAP_NODES( myVolumeNodes, 8, 11 ); + SWAP_NODES( myVolumeNodes, 9, 10 ); + SWAP_NODES( myVolumeNodes, 12, 15 ); + SWAP_NODES( myVolumeNodes, 13, 14 ); + SWAP_NODES( myVolumeNodes, 17, 19 ); + break; default:; } } @@ -402,14 +613,25 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const return POLYHEDA; if ( myVolume ) { - static const VolumeType types[] = { - TETRA, // myVolumeNbNodes = 4 - PYRAM, // myVolumeNbNodes = 5 - PENTA, // myVolumeNbNodes = 6 - UNKNOWN, // myVolumeNbNodes = 7 - HEXA // myVolumeNbNodes = 8 - }; - return types[ myVolumeNbNodes - 4 ]; +// static const VolumeType types[] = { +// TETRA, // myVolumeNbNodes = 4 +// PYRAM, // myVolumeNbNodes = 5 +// PENTA, // myVolumeNbNodes = 6 +// UNKNOWN, // myVolumeNbNodes = 7 +// HEXA // myVolumeNbNodes = 8 +// }; +// return types[ myVolumeNbNodes - 4 ]; + switch(myVolumeNbNodes) { + case 4: return TETRA; break; + case 5: return PYRAM; break; + case 6: return PENTA; break; + case 8: return HEXA; break; + case 10: return QUAD_TETRA; break; + case 13: return QUAD_PYRAM; break; + case 15: return QUAD_PENTA; break; + case 20: return QUAD_HEXA; break; + default: break; + } } return UNKNOWN; @@ -491,7 +713,7 @@ double SMDS_VolumeTool::GetSize() const else { const static int ind[] = { - 0, 1, 3, 6, 11 }; + 0, 1, 3, 6, 11, 19, 32, 46, 66}; const static int vtab[][4] = { // tetrahedron { 0, 1, 2, 3 }, @@ -507,15 +729,80 @@ double SMDS_VolumeTool::GetSize() const { 4, 1, 6, 5 }, { 1, 3, 6, 2 }, { 4, 6, 3, 7 }, - { 1, 4, 6, 3 } + { 1, 4, 6, 3 }, + + // quadratic tetrahedron + { 0, 4, 6, 7 }, + { 1, 5, 4, 8 }, + { 2, 6, 5, 9 }, + { 7, 8, 9, 3 }, + { 4, 6, 7, 9 }, + { 4, 5, 6, 9 }, + { 4, 7, 8, 9 }, + { 4, 5, 9, 8 }, + + // quadratic pyramid + { 0, 5, 8, 9 }, + { 1, 5,10, 6 }, + { 2, 6,11, 7 }, + { 3, 7,12, 8 }, + { 4, 9,11,10 }, + { 4, 9,12,11 }, + { 10, 5, 9, 8 }, + { 10, 8, 9,12 }, + { 10, 8,12, 7 }, + { 10, 7,12,11 }, + { 10, 7,11, 6 }, + { 10, 5, 8, 6 }, + { 10, 6, 8, 7 }, + + // quadratic pentahedron + { 12, 0, 8, 6 }, + { 12, 8, 7, 6 }, + { 12, 8, 2, 7 }, + { 12, 6, 7, 1 }, + { 12, 1, 7,13 }, + { 12, 7, 2,13 }, + { 12, 2,14,13 }, + + { 12, 3, 9,11 }, + { 12,11, 9,10 }, + { 12,11,10, 5 }, + { 12, 9, 4,10 }, + { 12,14, 5,10 }, + { 12,14,10, 4 }, + { 12,14, 4,13 }, + + // quadratic hexahedron + { 16, 0,11, 8 }, + { 16,11, 9, 8 }, + { 16, 8, 9, 1 }, + { 16,11, 3,10 }, + { 16,11,10, 9 }, + { 16,10, 2, 9 }, + { 16, 3,19, 2 }, + { 16, 2,19,18 }, + { 16, 2,18,17 }, + { 16, 2,17, 1 }, + + { 16, 4,12,15 }, + { 16,12, 5,13 }, + { 16,12,13,15 }, + { 16,13, 6,14 }, + { 16,13,14,15 }, + { 16,14, 7,15 }, + { 16, 6, 5,17 }, + { 16,18, 6,17 }, + { 16,18, 7, 6 }, + { 16,18,19, 7 }, + }; int type = GetVolumeType(); int n1 = ind[type]; int n2 = ind[type+1]; - for (int i = n1; i < n2; i++) - { + for (int i = n1; i < n2; i++) { V -= getTetraVolume( myVolumeNodes[ vtab[i][0] ], myVolumeNodes[ vtab[i][1] ], myVolumeNodes[ vtab[i][2] ], @@ -647,12 +934,16 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) switch ( myVolumeNbNodes ) { case 4: case 5: + case 10: + case 13: // only the bottom of a reversed tetrahedron can be internal return ( myVolForward || faceIndex != 0 ); case 6: + case 15: // in a forward pentahedron, the top is internal, in a reversed one - bottom return ( myVolForward ? faceIndex != 1 : faceIndex != 0 ); - case 8: { + case 8: + case 20: { // in a forward hexahedron, even face normal is external, odd - internal bool odd = faceIndex % 2; return ( myVolForward ? !odd : odd ); @@ -679,7 +970,8 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub XYZ aVec13( p3 - p1 ); XYZ cross = aVec12.Crossed( aVec13 ); - if ( myFaceNbNodes == 4 ) { + //if ( myFaceNbNodes == 4 ) { + if ( myFaceNbNodes >3 ) { XYZ p4 ( myFaceNodes[3] ); XYZ aVec14( p4 - p1 ); XYZ cross2 = aVec13.Crossed( aVec14 ); @@ -815,7 +1107,7 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, bool SMDS_VolumeTool::IsLinked (const int theNode1Index, const int theNode2Index) const { - if (myVolume->IsPoly()) { + if ( myVolume->IsPoly() ) { return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]); } @@ -853,6 +1145,57 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, default:; } break; + case 10: + { + switch ( minInd ) { + case 0: if( maxInd==4 || maxInd==6 || maxInd==7 ) return true; + case 1: if( maxInd==4 || maxInd==5 || maxInd==8 ) return true; + case 2: if( maxInd==5 || maxInd==6 || maxInd==9 ) return true; + case 3: if( maxInd==7 || maxInd==8 || maxInd==9 ) return true; + default:; + } + break; + } + case 13: + { + switch ( minInd ) { + case 0: if( maxInd==5 || maxInd==8 || maxInd==9 ) return true; + case 1: if( maxInd==5 || maxInd==6 || maxInd==10 ) return true; + case 2: if( maxInd==6 || maxInd==7 || maxInd==11 ) return true; + case 3: if( maxInd==7 || maxInd==8 || maxInd==12 ) return true; + case 4: if( maxInd==9 || maxInd==10 || maxInd==11 || maxInd==12 ) return true; + default:; + } + break; + } + case 15: + { + switch ( minInd ) { + case 0: if( maxInd==6 || maxInd==8 || maxInd==12 ) return true; + case 1: if( maxInd==6 || maxInd==7 || maxInd==13 ) return true; + case 2: if( maxInd==7 || maxInd==8 || maxInd==14 ) return true; + case 3: if( maxInd==9 || maxInd==11 || maxInd==12 ) return true; + case 4: if( maxInd==9 || maxInd==10 || maxInd==13 ) return true; + case 5: if( maxInd==10 || maxInd==11 || maxInd==14 ) return true; + default:; + } + break; + } + case 20: + { + switch ( minInd ) { + case 0: if( maxInd==8 || maxInd==11 || maxInd==16 ) return true; + case 1: if( maxInd==8 || maxInd==9 || maxInd==17 ) return true; + case 2: if( maxInd==9 || maxInd==10 || maxInd==18 ) return true; + case 3: if( maxInd==10 || maxInd==11 || maxInd==19 ) return true; + case 4: if( maxInd==12 || maxInd==15 || maxInd==16 ) return true; + case 5: if( maxInd==12 || maxInd==13 || maxInd==17 ) return true; + case 6: if( maxInd==13 || maxInd==14 || maxInd==18 ) return true; + case 7: if( maxInd==14 || maxInd==15 || maxInd==19 ) return true; + default:; + } + break; + } default:; } return false; @@ -894,8 +1237,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) typedef map< const SMDS_MeshElement*, int > TElemIntMap; TElemIntMap volNbShared; TElemIntMap::iterator vNbIt; - for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) - { + for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) { const SMDS_MeshNode* n = nodes[ iNode ]; SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(); while ( eIt->more() ) { @@ -903,10 +1245,12 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) if ( elem != myVolume && elem->GetType() == SMDSAbs_Volume ) { int nbShared = 1; vNbIt = volNbShared.find( elem ); - if ( vNbIt == volNbShared.end() ) + if ( vNbIt == volNbShared.end() ) { volNbShared.insert ( TElemIntMap::value_type( elem, nbShared )); - else + } + else { nbShared = ++(*vNbIt).second; + } if ( nbShared > maxNbShared ) maxNbShared = nbShared; } @@ -922,8 +1266,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) if ( IsFaceExternal( faceIndex )) intNormal = XYZ( -intNormal.x, -intNormal.y, -intNormal.z ); XYZ p0 ( nodes[0] ), baryCenter; - for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) - { + for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) { int nbShared = (*vNbIt).second; if ( nbShared >= 3 ) { SMDS_VolumeTool volume( (*vNbIt).first ); @@ -935,20 +1278,20 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) // remove a volume from volNbShared map volNbShared.erase( vNbIt ); } + // here volNbShared contains only volumes laying on the // opposite side of the face - if ( volNbShared.empty() ) + if ( volNbShared.empty() ) { return free; // is free + } // check if the whole area of a face is shared bool isShared[] = { false, false, false, false }; // 4 triangle parts of a quadrangle - for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) - { + for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) { SMDS_VolumeTool volume( (*vNbIt).first ); bool prevLinkShared = false; int nbSharedLinks = 0; - for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) - { + for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) { bool linkShared = volume.IsLinked( nodes[ iNode ], nodes[ iNode + 1] ); if ( linkShared ) nbSharedLinks++; @@ -1059,7 +1402,8 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) } myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ]; // last = first - } else { + } + else { // choose face node indices switch ( myVolumeNbNodes ) { case 4: @@ -1090,6 +1434,34 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) else myFaceNodeIndices = Hexa_F[ faceIndex ]; break; + case 10: + myFaceNbNodes = QuadTetra_nbN[ faceIndex ]; + if ( myExternalFaces ) + myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_RE[ faceIndex ]; + else + myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_R[ faceIndex ]; + break; + case 13: + myFaceNbNodes = QuadPyram_nbN[ faceIndex ]; + if ( myExternalFaces ) + myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_RE[ faceIndex ]; + else + myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_R[ faceIndex ]; + break; + case 15: + myFaceNbNodes = QuadPenta_nbN[ faceIndex ]; + if ( myExternalFaces ) + myFaceNodeIndices = myVolForward ? QuadPenta_FE[ faceIndex ] : QuadPenta_RE[ faceIndex ]; + else + myFaceNodeIndices = myVolForward ? QuadPenta_F[ faceIndex ] : QuadPenta_R[ faceIndex ]; + break; + case 20: + myFaceNbNodes = QuadHexa_nbN[ faceIndex ]; + if ( myExternalFaces ) + myFaceNodeIndices = myVolForward ? QuadHexa_FE[ faceIndex ] : QuadHexa_RE[ faceIndex ]; + else + myFaceNodeIndices = QuadHexa_F[ faceIndex ]; + break; default: return false; } @@ -1118,6 +1490,10 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes) case 5: return PYRAM; case 6: return PENTA; case 8: return HEXA; + case 10: return QUAD_TETRA; + case 13: return QUAD_PYRAM; + case 15: return QUAD_PENTA; + case 20: return QUAD_HEXA; default:return UNKNOWN; } } @@ -1130,10 +1506,14 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes) int SMDS_VolumeTool::NbFaces( VolumeType type ) { switch ( type ) { - case TETRA: return 4; - case PYRAM: return 5; - case PENTA: return 5; - case HEXA : return 6; + case TETRA : + case QUAD_TETRA: return 4; + case PYRAM : + case QUAD_PYRAM: return 5; + case PENTA : + case QUAD_PENTA: return 5; + case HEXA : + case QUAD_HEXA : return 6; default: return 0; } } @@ -1155,6 +1535,10 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices(VolumeType type, case PYRAM: return Pyramid_F[ faceIndex ]; case PENTA: return external ? Penta_FE[ faceIndex ] : Penta_F[ faceIndex ]; case HEXA: return external ? Hexa_FE[ faceIndex ] : Hexa_F[ faceIndex ]; + case QUAD_TETRA: return QuadTetra_F[ faceIndex ]; + case QUAD_PYRAM: return QuadPyram_F[ faceIndex ]; + case QUAD_PENTA: return external ? QuadPenta_FE[ faceIndex ] : QuadPenta_F[ faceIndex ]; + case QUAD_HEXA: return external ? QuadHexa_FE[ faceIndex ] : QuadHexa_F[ faceIndex ]; default:; } return 0; @@ -1173,6 +1557,10 @@ int SMDS_VolumeTool::NbFaceNodes(VolumeType type, case PYRAM: return Pyramid_nbN[ faceIndex ]; case PENTA: return Penta_nbN[ faceIndex ]; case HEXA: return Hexa_nbN[ faceIndex ]; + case QUAD_TETRA: return QuadTetra_nbN[ faceIndex ]; + case QUAD_PYRAM: return QuadPyram_nbN[ faceIndex ]; + case QUAD_PENTA: return QuadPenta_nbN[ faceIndex ]; + case QUAD_HEXA: return QuadHexa_nbN[ faceIndex ]; default:; } return 0; diff --git a/src/SMDS/SMDS_VolumeTool.hxx b/src/SMDS/SMDS_VolumeTool.hxx index beec061b7..b5528c10e 100644 --- a/src/SMDS/SMDS_VolumeTool.hxx +++ b/src/SMDS/SMDS_VolumeTool.hxx @@ -61,7 +61,8 @@ class SMDS_WNT_EXPORT SMDS_VolumeTool { public: - enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA, POLYHEDA }; + enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA, QUAD_TETRA, + QUAD_PYRAM, QUAD_PENTA, QUAD_HEXA, POLYHEDA }; SMDS_VolumeTool (); ~SMDS_VolumeTool (); diff --git a/src/SMESH/Makefile.in b/src/SMESH/Makefile.in index a311488eb..12c077a7d 100644 --- a/src/SMESH/Makefile.in +++ b/src/SMESH/Makefile.in @@ -39,6 +39,7 @@ EXPORT_HEADERS= \ SMESH_Mesh.hxx \ SMESH_subMesh.hxx \ SMESH_Hypothesis.hxx \ + SMESH_HypoFilter.hxx \ SMESH_Algo.hxx \ SMESH_1D_Algo.hxx \ SMESH_2D_Algo.hxx \ diff --git a/src/SMESH/SMESH_2D_Algo.cxx b/src/SMESH/SMESH_2D_Algo.cxx index d1084f7d4..1c9af478a 100644 --- a/src/SMESH/SMESH_2D_Algo.cxx +++ b/src/SMESH/SMESH_2D_Algo.cxx @@ -29,7 +29,7 @@ using namespace std; #include "SMESH_2D_Algo.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_subMesh.hxx" +#include #include "utilities.h" @@ -80,13 +80,14 @@ int SMESH_2D_Algo::NumberOfWires(const TopoDS_Shape& S) int SMESH_2D_Algo::NumberOfPoints(SMESH_Mesh& aMesh, const TopoDS_Wire& W) { int nbPoints = 0; - for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next()) - { - const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); - int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - //SCRUTE(nb); - nbPoints += nb +1; // internal points plus 1 vertex of 2 (last point ?) - } - //SCRUTE(nbPoints); + for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); + int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + if(_quadraticMesh) + nb = nb/2; + nbPoints += nb + 1; // internal points plus 1 vertex of 2 (last point ?) + } return nbPoints; } + + diff --git a/src/SMESH/SMESH_2D_Algo.hxx b/src/SMESH/SMESH_2D_Algo.hxx index 5c904e22e..259a51157 100644 --- a/src/SMESH/SMESH_2D_Algo.hxx +++ b/src/SMESH/SMESH_2D_Algo.hxx @@ -30,7 +30,8 @@ #define _SMESH_2D_ALGO_HXX_ #include "SMESH_Algo.hxx" -#include +#include "SMESH_subMesh.hxx" +#include "TopoDS_Wire.hxx" class SMESH_2D_Algo: public SMESH_Algo @@ -41,6 +42,7 @@ public: int NumberOfWires(const TopoDS_Shape& S); int NumberOfPoints(SMESH_Mesh& aMesh,const TopoDS_Wire& W); + }; #endif diff --git a/src/SMESH/SMESH_3D_Algo.cxx b/src/SMESH/SMESH_3D_Algo.cxx index d42680f62..6a05c16af 100644 --- a/src/SMESH/SMESH_3D_Algo.cxx +++ b/src/SMESH/SMESH_3D_Algo.cxx @@ -29,7 +29,6 @@ using namespace std; #include "SMESH_3D_Algo.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_subMesh.hxx" #include "utilities.h" @@ -56,3 +55,5 @@ SMESH_3D_Algo::SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen) SMESH_3D_Algo::~SMESH_3D_Algo() { } + + diff --git a/src/SMESH/SMESH_3D_Algo.hxx b/src/SMESH/SMESH_3D_Algo.hxx index 62621ce3c..21c53ca0f 100644 --- a/src/SMESH/SMESH_3D_Algo.hxx +++ b/src/SMESH/SMESH_3D_Algo.hxx @@ -37,6 +37,7 @@ class SMESH_3D_Algo: public: SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen); virtual ~SMESH_3D_Algo(); + }; #endif diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 3cddc41e7..94803ac7c 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -69,6 +69,7 @@ SMESH_Algo::SMESH_Algo(int hypId, int studyId, gen->_mapAlgo[hypId] = this; _onlyUnaryInput = _requireDescretBoundary = true; + _quadraticMesh = false; } //============================================================================= @@ -102,18 +103,17 @@ const vector < string > &SMESH_Algo::GetCompatibleHypothesis() */ //============================================================================= -const list & SMESH_Algo::GetUsedHypothesis( - SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +const list & +SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary) { _usedHypList.clear(); - if ( !_compatibleHypothesis.empty() ) + SMESH_HypoFilter filter; + if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary )) { - SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( _compatibleHypothesis[0] )); - for ( int i = 1; i < _compatibleHypothesis.size(); ++i ) - filter.Or( filter.HasName( _compatibleHypothesis[ i ] )); - aMesh.GetHypotheses( aShape, filter, _usedHypList, true ); - if ( _usedHypList.size() > 1 ) + if ( ignoreAuxiliary && _usedHypList.size() > 1 ) _usedHypList.clear(); //only one compatible hypothesis allowed } return _usedHypList; @@ -127,18 +127,16 @@ const list & SMESH_Algo::GetUsedHypothesis( */ //============================================================================= -const list & SMESH_Algo::GetAppliedHypothesis( - SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +const list & +SMESH_Algo::GetAppliedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary) { _appliedHypList.clear(); - if ( !_compatibleHypothesis.empty() ) - { - SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( _compatibleHypothesis[0] )); - for ( int i = 1; i < _compatibleHypothesis.size(); ++i ) - filter.Or( filter.HasName( _compatibleHypothesis[ i ] )); - + SMESH_HypoFilter filter; + if ( InitCompatibleHypoFilter( filter, ignoreAuxiliary )) aMesh.GetHypotheses( aShape, filter, _appliedHypList, false ); - } + return _appliedHypList; } @@ -344,3 +342,28 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh, return theParams.size() > 1; } + +//================================================================================ +/*! + * \brief Make filter recognize only compatible hypotheses + * \param theFilter - the filter to initialize + * \param ignoreAuxiliary - make filter ignore compatible auxiliary hypotheses + */ +//================================================================================ + +bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter, + const bool ignoreAuxiliary) const +{ + if ( !_compatibleHypothesis.empty() ) + { + theFilter.Init( theFilter.HasName( _compatibleHypothesis[0] )); + for ( int i = 1; i < _compatibleHypothesis.size(); ++i ) + theFilter.Or( theFilter.HasName( _compatibleHypothesis[ i ] )); + + if ( ignoreAuxiliary ) + theFilter.AndNot( theFilter.IsAuxiliary() ); + + return true; + } + return false; +} diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx index c92b5893f..57bc4245a 100644 --- a/src/SMESH/SMESH_Algo.hxx +++ b/src/SMESH/SMESH_Algo.hxx @@ -33,16 +33,20 @@ #include #include +#include #include #include #include +#include class SMESH_Gen; class SMESH_Mesh; +class SMESH_HypoFilter; class TopoDS_Face; class TopoDS_Shape; class SMESHDS_Mesh; +class SMDS_MeshNode; class SMESH_Algo:public SMESH_Hypothesis { @@ -58,13 +62,27 @@ class SMESH_Algo:public SMESH_Hypothesis virtual bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) = 0; virtual const std::list & - GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + GetUsedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary=true); const list & - GetAppliedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + GetAppliedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary=true); static double EdgeLength(const TopoDS_Edge & E); + + /*! + * \brief Make filter recognize only compatible hypotheses + * \param theFilter - the filter to initialize + * \param ignoreAuxiliary - make filter ignore compatible auxiliary hypotheses + * \retval bool - true if the algo has compatible hypotheses + */ + bool InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter, + const bool ignoreAuxiliary) const; + /*! * \brief Fill vector of node parameters on geometrical edge, including vertex nodes * \param theMesh - The mesh containing nodes @@ -121,6 +139,9 @@ class SMESH_Algo:public SMESH_Hypothesis std::vector _compatibleHypothesis; std::list _appliedHypList; std::list _usedHypList; + + // quadratic mesh creation required + bool _quadraticMesh; }; #endif diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index c5a611a29..b7e50f209 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -102,33 +102,24 @@ SMESH_Gen::~SMESH_Gen() */ //============================================================================= -SMESH_Mesh* SMESH_Gen::CreateMesh(int studyId) -throw(SALOME_Exception) +SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode) + throw(SALOME_Exception) { - Unexpect aCatch(SalomeException); - MESSAGE("SMESH_Gen::CreateMesh"); -// if (aShape.ShapeType() == TopAbs_COMPOUND) -// { -// INFOS("Mesh Compound not yet implemented!"); -// throw(SALOME_Exception(LOCALIZED("Mesh Compound not yet implemented!"))); -// } + Unexpect aCatch(SalomeException); + MESSAGE("SMESH_Gen::CreateMesh"); - // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document - - StudyContextStruct *myStudyContext = GetStudyContext(studyId); - - // create a new SMESH_mesh object - - SMESH_Mesh *mesh = new SMESH_Mesh(_localId++, - studyId, - this, - myStudyContext->myDocument); - myStudyContext->mapMesh[_localId] = mesh; + // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document + StudyContextStruct *aStudyContext = GetStudyContext(theStudyId); - // associate a TopoDS_Shape to the mesh + // create a new SMESH_mesh object + SMESH_Mesh *aMesh = new SMESH_Mesh(_localId++, + theStudyId, + this, + theIsEmbeddedMode, + aStudyContext->myDocument); + aStudyContext->mapMesh[_localId] = aMesh; -//mesh->ShapeToMesh(aShape); - return mesh; + return aMesh; } //============================================================================= @@ -633,13 +624,14 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) if ( algoList.empty() ) return NULL; - if (algoList.size() > 1 ) { // check if there is one algo several times - list ::iterator algo = algoList.begin(); - for ( ; algo != algoList.end(); ++algo ) - if ( (*algo) != algoList.front() && - (*algo)->GetName() != algoList.front()->GetName() ) - return NULL; - } + // Now it is checked in SMESH_Mesh::GetHypotheses() +// if (algoList.size() > 1 ) { // check if there is one algo several times +// list ::iterator algo = algoList.begin(); +// for ( ; algo != algoList.end(); ++algo ) +// if ( (*algo) != algoList.front() && +// (*algo)->GetName() != algoList.front()->GetName() ) +// return NULL; +// } return const_cast ( static_cast( algoList.front() )); } @@ -702,37 +694,20 @@ void SMESH_Gen::Close(int studyId) int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType) { - int shapeDim = -1; // Shape dimension: 0D, 1D, 2D, 3D - int type = aShapeType;//.ShapeType(); - switch (type) - { - case TopAbs_COMPOUND: - case TopAbs_COMPSOLID: - case TopAbs_SOLID: - case TopAbs_SHELL: - { - shapeDim = 3; - break; - } - // case TopAbs_SHELL: - case TopAbs_FACE: - { - shapeDim = 2; - break; - } - case TopAbs_WIRE: - case TopAbs_EDGE: - { - shapeDim = 1; - break; - } - case TopAbs_VERTEX: - { - shapeDim = 0; - break; - } - } - return shapeDim; + static vector dim; + if ( dim.empty() ) + { + dim.resize( TopAbs_SHAPE, -1 ); + dim[ TopAbs_COMPOUND ] = 3; + dim[ TopAbs_COMPSOLID ] = 3; + dim[ TopAbs_SOLID ] = 3; + dim[ TopAbs_SHELL ] = 3; + dim[ TopAbs_FACE ] = 2; + dim[ TopAbs_WIRE ] = 1; + dim[ TopAbs_EDGE ] = 1; + dim[ TopAbs_VERTEX ] = 0; + } + return dim[ aShapeType ]; } //============================================================================= diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index 5364065ef..ab780a070 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -60,7 +60,7 @@ class SMESH_Gen // SMESH_Hypothesis *CreateHypothesis(const char *anHyp, int studyId) // throw(SALOME_Exception); - SMESH_Mesh* CreateMesh(int studyId) + SMESH_Mesh* CreateMesh(int theStudyId, bool theIsEmbeddedMode) throw(SALOME_Exception); bool Compute(::SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); diff --git a/src/SMESH/SMESH_Group.hxx b/src/SMESH/SMESH_Group.hxx index 26493e4e0..3819cd4aa 100644 --- a/src/SMESH/SMESH_Group.hxx +++ b/src/SMESH/SMESH_Group.hxx @@ -53,6 +53,9 @@ class SMESH_Group SMESHDS_GroupBase * GetGroupDS () { return myGroupDS; } + void SetColorNumber (int theColorNumber) { myColorNumber = theColorNumber; } + int GetColorNumber() const { return myColorNumber; } + private: SMESH_Group (const SMESH_Group& theOther); // prohibited copy constructor @@ -61,7 +64,7 @@ class SMESH_Group SMESHDS_GroupBase * myGroupDS; std::string myName; - + int myColorNumber; }; #endif diff --git a/src/SMESH/SMESH_HypoFilter.cxx b/src/SMESH/SMESH_HypoFilter.cxx index ff14016d8..2e4469fb4 100644 --- a/src/SMESH/SMESH_HypoFilter.cxx +++ b/src/SMESH/SMESH_HypoFilter.cxx @@ -75,6 +75,17 @@ bool SMESH_HypoFilter::ApplicablePredicate::IsOk(const SMESH_Hypothesis* aHyp, return SMESH_subMesh::IsApplicableHypotesis( aHyp, (TopAbs_ShapeEnum)_shapeType ); }; +//======================================================================= +//function : IsAuxiliaryPredicate::IsOk +//purpose : +//======================================================================= + +bool SMESH_HypoFilter::IsAuxiliaryPredicate::IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& /*aShape*/) const +{ + return aHyp->IsAuxiliary(); +}; + //======================================================================= //function : ApplicablePredicate::ApplicablePredicate //purpose : @@ -190,6 +201,17 @@ SMESH_HypoPredicate* SMESH_HypoFilter::IsAlgo() return new TypePredicate( MORE, SMESHDS_Hypothesis::PARAM_ALGO ); } +//======================================================================= +//function : IsAuxiliary +//purpose : +//======================================================================= + +SMESH_HypoPredicate* SMESH_HypoFilter::IsAuxiliary() +{ + return new IsAuxiliaryPredicate(); +} + + //======================================================================= //function : IsGlobal //purpose : @@ -287,6 +309,7 @@ SMESH_HypoFilter & SMESH_HypoFilter::Init ( SMESH_HypoPredicate* aPredicate, bo list::const_iterator pred = myPredicates.begin(); for ( ; pred != myPredicates.end(); ++pred ) delete *pred; + myPredicates.clear(); add( notNagate ? AND : AND_NOT, aPredicate ); return *this; diff --git a/src/SMESH/SMESH_HypoFilter.hxx b/src/SMESH/SMESH_HypoFilter.hxx index 6bc34bf53..9638495d1 100644 --- a/src/SMESH/SMESH_HypoFilter.hxx +++ b/src/SMESH/SMESH_HypoFilter.hxx @@ -67,6 +67,7 @@ class SMESH_HypoFilter: public SMESH_HypoPredicate // Create predicates static SMESH_HypoPredicate* IsAlgo(); + static SMESH_HypoPredicate* IsAuxiliary(); static SMESH_HypoPredicate* IsApplicableTo(const TopoDS_Shape& theShape); static SMESH_HypoPredicate* IsAssignedTo(const TopoDS_Shape& theShape); static SMESH_HypoPredicate* Is(const SMESH_Hypothesis* theHypo); @@ -158,6 +159,11 @@ class SMESH_HypoFilter: public SMESH_HypoPredicate const TopoDS_Shape& aShape) const; }; + struct IsAuxiliaryPredicate : public SMESH_HypoPredicate { + bool IsOk(const SMESH_Hypothesis* aHyp, + const TopoDS_Shape& aShape) const; + }; + }; diff --git a/src/SMESH/SMESH_Hypothesis.cxx b/src/SMESH/SMESH_Hypothesis.cxx index 0107c3e36..268581791 100644 --- a/src/SMESH/SMESH_Hypothesis.cxx +++ b/src/SMESH/SMESH_Hypothesis.cxx @@ -72,13 +72,14 @@ SMESH_Hypothesis::~SMESH_Hypothesis() int SMESH_Hypothesis::GetDim() const { - int dim = -1; + int dim = 0; switch (_type) { case ALGO_1D: dim = 1; break; case ALGO_2D: dim = 2; break; case ALGO_3D: dim = 3; break; - case PARAM_ALGO: dim = _param_algo_dim; break; + case PARAM_ALGO: + dim = ( _param_algo_dim < 0 ) ? -_param_algo_dim : _param_algo_dim; break; } return dim; } @@ -124,14 +125,15 @@ void SMESH_Hypothesis::NotifySubMeshesHypothesisModification() itm++) { SMESH_Mesh* mesh = (*itm).second; - const list& subMeshes = - mesh->GetSubMeshUsingHypothesis(this); + mesh->NotifySubMeshesHypothesisModification( this ); +// const list& subMeshes = +// mesh->GetSubMeshUsingHypothesis(this); - //for all subMeshes using hypothesis +// //for all subMeshes using hypothesis - list::const_iterator its; - for (its = subMeshes.begin(); its != subMeshes.end(); its++) - (*its)->ComputeStateEngine(SMESH_subMesh::MODIF_HYP); +// list::const_iterator its; +// for (its = subMeshes.begin(); its != subMeshes.end(); its++) +// (*its)->ComputeStateEngine(SMESH_subMesh::MODIF_HYP); } } diff --git a/src/SMESH/SMESH_Hypothesis.hxx b/src/SMESH/SMESH_Hypothesis.hxx index 2edcd141a..d7a12f9a0 100644 --- a/src/SMESH/SMESH_Hypothesis.hxx +++ b/src/SMESH/SMESH_Hypothesis.hxx @@ -49,18 +49,19 @@ public: HYP_INCOMPATIBLE, // hypothesis does not fit algo HYP_NOTCONFORM, // not conform mesh is produced appling a hypothesis HYP_ALREADY_EXIST,// such hypothesis already exist - HYP_BAD_DIM // bad dimension + HYP_BAD_DIM, // bad dimension + HYP_BAD_SUBSHAPE // shape is neither the main one, nor its subshape, nor a group }; static bool IsStatusFatal(Hypothesis_Status theStatus) { return theStatus >= HYP_UNKNOWN_FATAL; } SMESH_Hypothesis(int hypId, int studyId, SMESH_Gen* gen); virtual ~SMESH_Hypothesis(); - int GetDim() const; + virtual int GetDim() const; int GetStudyId() const; - void NotifySubMeshesHypothesisModification(); - int GetShapeType() const; - const char* GetLibName() const; + virtual void NotifySubMeshesHypothesisModification(); + virtual int GetShapeType() const; + virtual const char* GetLibName() const; void SetLibName(const char* theLibName); /*! @@ -71,6 +72,17 @@ public: */ virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape)=0; + /*! + * \brief Return true if me is an auxiliary hypothesis + * \retval bool - auxiliary or not + * + * An auxiliary hypothesis is optional, i.e. an algorithm + * can work without it and another hypothesis of the same + * dimention can be assigned to the shape + */ + virtual bool IsAuxiliary() const + { return GetType() == PARAM_ALGO && _param_algo_dim <= 0; } + protected: SMESH_Gen* _gen; int _studyId; diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index a4b5f80af..23c5041c7 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -63,6 +63,9 @@ #include "Utils_ExceptHandlers.hxx" +// maximum stored group name length in MED file +#define MAX_MED_GROUP_NAME_LENGTH 80 + #ifdef _DEBUG_ static int MYDEBUG = 0; #else @@ -76,17 +79,21 @@ static int MYDEBUG = 0; */ //============================================================================= -SMESH_Mesh::SMESH_Mesh(int localId, int studyId, SMESH_Gen * gen, SMESHDS_Document * myDocument) -: _groupId( 0 ) +SMESH_Mesh::SMESH_Mesh(int theLocalId, + int theStudyId, + SMESH_Gen* theGen, + bool theIsEmbeddedMode, + SMESHDS_Document* theDocument): + _groupId( 0 ) { INFOS("SMESH_Mesh::SMESH_Mesh(int localId)"); - _id = localId; - _studyId = studyId; - _gen = gen; - _myDocument = myDocument; - _idDoc = _myDocument->NewMesh(); - _myMeshDS = _myDocument->GetMesh(_idDoc); - _isShapeToMesh = false; + _id = theLocalId; + _studyId = theStudyId; + _gen = theGen; + _myDocument = theDocument; + _idDoc = theDocument->NewMesh(theIsEmbeddedMode); + _myMeshDS = theDocument->GetMesh(_idDoc); + _isShapeToMesh = false; } //============================================================================= @@ -149,7 +156,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) // fill _mapAncestors _mapAncestors.Clear(); int desType, ancType; - for ( desType = TopAbs_EDGE; desType > TopAbs_COMPOUND; desType-- ) + for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- ) for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- ) TopExp::MapShapesAndAncestors ( aShape, (TopAbs_ShapeEnum) desType, @@ -267,6 +274,9 @@ SMESH_Hypothesis::Hypothesis_Status if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis"); SMESH_subMesh *subMesh = GetSubMesh(aSubShape); + if ( !subMesh || !subMesh->GetId()) + return SMESH_Hypothesis::HYP_BAD_SUBSHAPE; + SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS(); if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) // group of sub-shapes and maybe of not sub- { @@ -520,45 +530,62 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubS //purpose : //======================================================================= -bool SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, - const SMESH_HypoFilter& aFilter, - list & aHypList, - const bool andAncestors) const +//================================================================================ +/*! + * \brief Return hypothesis assigned to the shape + * \param aSubShape - the shape to check + * \param aFilter - the hypothesis filter + * \param aHypList - the list of the found hypotheses + * \param andAncestors - flag to check hypos assigned to ancestors of the shape + * \retval int - number of unique hypos in aHypList + */ +//================================================================================ + +int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, + const SMESH_HypoFilter& aFilter, + list & aHypList, + const bool andAncestors) const { - int nbHyp = 0; + set hypTypes; // to exclude same type hypos from the result list + int nbHyps = 0; + + // fill in hypTypes + list::const_iterator hyp; + for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) + if ( hypTypes.insert( (*hyp)->GetName() ).second ) + nbHyps++; + + // get hypos from aSubShape { const list& hypList = _myMeshDS->GetHypothesis(aSubShape); - list::const_iterator hyp = hypList.begin(); - for ( ; hyp != hypList.end(); hyp++ ) - if ( aFilter.IsOk (static_cast( *hyp ), aSubShape)) { + for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) + if ( aFilter.IsOk (static_cast( *hyp ), aSubShape) && + hypTypes.insert( (*hyp)->GetName() ).second ) + { aHypList.push_back( *hyp ); - nbHyp++; + nbHyps++; } } - // get hypos from shape of one type only: if any hypo is found on edge, do - // not look up on faces - if ( !nbHyp && andAncestors ) + + // get hypos from ancestors of aSubShape + if ( andAncestors ) { TopTools_MapOfShape map; TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); - int shapeType = it.More() ? it.Value().ShapeType() : TopAbs_SHAPE; for (; it.More(); it.Next() ) { - if ( nbHyp && shapeType != it.Value().ShapeType() ) - break; - shapeType = it.Value().ShapeType(); - if ( !map.Add( it.Value() )) + if ( !map.Add( it.Value() )) continue; const list& hypList = _myMeshDS->GetHypothesis(it.Value()); - list::const_iterator hyp = hypList.begin(); - for ( ; hyp != hypList.end(); hyp++ ) - if (aFilter.IsOk( static_cast( *hyp ), it.Value() )) { - aHypList.push_back( *hyp ); - nbHyp++; - } + for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) + if (aFilter.IsOk( static_cast( *hyp ), it.Value() ) && + hypTypes.insert( (*hyp)->GetName() ).second ) { + aHypList.push_back( *hyp ); + nbHyps++; + } } } - return nbHyp; + return nbHyps; } //============================================================================= @@ -616,28 +643,31 @@ SMESH_Gen *SMESH_Mesh::GetGen() //============================================================================= SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) -throw(SALOME_Exception) + throw(SALOME_Exception) { Unexpect aCatch(SalomeException); SMESH_subMesh *aSubMesh; int index = _myMeshDS->ShapeToIndex(aSubShape); - + // for submeshes on GEOM Group if ( !index && aSubShape.ShapeType() == TopAbs_COMPOUND ) { TopoDS_Iterator it( aSubShape ); if ( it.More() ) index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() ); } +// if ( !index ) +// return NULL; // neither sub-shape nor a group - if (_mapSubMesh.find(index) != _mapSubMesh.end()) - { - aSubMesh = _mapSubMesh[index]; - } + map ::iterator i_sm = _mapSubMesh.find(index); + if ( i_sm != _mapSubMesh.end()) + { + aSubMesh = i_sm->second; + } else - { - aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape); - _mapSubMesh[index] = aSubMesh; - } + { + aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape); + _mapSubMesh[index] = aSubMesh; + } return aSubMesh; } @@ -649,20 +679,17 @@ throw(SALOME_Exception) //============================================================================= SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) -throw(SALOME_Exception) + throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - bool isFound = false; SMESH_subMesh *aSubMesh = NULL; int index = _myMeshDS->ShapeToIndex(aSubShape); - if (_mapSubMesh.find(index) != _mapSubMesh.end()) - { - aSubMesh = _mapSubMesh[index]; - isFound = true; - } - if (!isFound) - aSubMesh = NULL; + + map ::iterator i_sm = _mapSubMesh.find(index); + if ( i_sm != _mapSubMesh.end()) + aSubMesh = i_sm->second; + return aSubMesh; } @@ -690,15 +717,17 @@ throw(SALOME_Exception) //======================================================================= bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, - const TopoDS_Shape & aSubShape) + const SMESH_subMesh* aSubMesh) { SMESH_Hypothesis* hyp = static_cast(anHyp); - // check if anHyp is applicable to aSubShape - SMESH_subMesh * subMesh = GetSubMeshContaining( aSubShape ); - if ( !subMesh || !subMesh->IsApplicableHypotesis( hyp )) + + // check if anHyp can be used to mesh aSubMesh + if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp )) return false; - SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape); + const TopoDS_Shape & aSubShape = const_cast( aSubMesh )->GetSubShape(); + + SMESH_Algo *algo = _gen->GetAlgo(*this, aSubShape ); // algorithm if (anHyp->GetType() > SMESHDS_Hypothesis::PARAM_ALGO) @@ -708,17 +737,19 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, if (algo) { // look trough hypotheses used by algo - const list &usedHyps = - algo->GetUsedHypothesis(*this, aSubShape); - return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() ); + SMESH_HypoFilter hypoKind; + if ( algo->InitCompatibleHypoFilter( hypoKind, !hyp->IsAuxiliary() )) { + list usedHyps; + if ( GetHypotheses( aSubShape, hypoKind, usedHyps, true )) + return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() ); + } } // look through all assigned hypotheses - SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp )); - return GetHypothesis( aSubShape, filter, true ); + //SMESH_HypoFilter filter( SMESH_HypoFilter::Is( hyp )); + return false; //GetHypothesis( aSubShape, filter, true ); } - //============================================================================= /*! * @@ -726,28 +757,100 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, //============================================================================= const list < SMESH_subMesh * >& - SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) -throw(SALOME_Exception) +SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) + throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis"); + map < int, SMESH_subMesh * >::iterator itsm; + _subMeshesUsingHypothesisList.clear(); + for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++) + { + SMESH_subMesh *aSubMesh = (*itsm).second; + if ( IsUsedHypothesis ( anHyp, aSubMesh )) + _subMeshesUsingHypothesisList.push_back(aSubMesh); + } + return _subMeshesUsingHypothesisList; +} + +//======================================================================= +//function : NotifySubMeshesHypothesisModification +//purpose : Say all submeshes using theChangedHyp that it has been modified +//======================================================================= + +void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp) { Unexpect aCatch(SalomeException); - if(MYDEBUG) MESSAGE("SMESH_Mesh::GetSubMeshUsingHypothesis"); - map < int, SMESH_subMesh * >::iterator itsm; - _subMeshesUsingHypothesisList.clear(); - for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++) - { - SMESH_subMesh *aSubMesh = (*itsm).second; - if ( IsUsedHypothesis ( anHyp, aSubMesh->GetSubShape() )) - _subMeshesUsingHypothesisList.push_back(aSubMesh); - } - return _subMeshesUsingHypothesisList; + + const SMESH_Hypothesis* hyp = static_cast(theChangedHyp); + + const SMESH_Algo *foundAlgo = 0; + SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() ); + SMESH_HypoFilter compatibleHypoKind; + list usedHyps; + + + map < int, SMESH_subMesh * >::iterator itsm; + for (itsm = _mapSubMesh.begin(); itsm != _mapSubMesh.end(); itsm++) + { + SMESH_subMesh *aSubMesh = (*itsm).second; + if ( aSubMesh->IsApplicableHypotesis( hyp )) + { + const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); + + if ( !foundAlgo ) // init filter for algo search + algoKind.And( algoKind.IsApplicableTo( aSubShape )); + + const SMESH_Algo *algo = static_cast + ( GetHypothesis( aSubShape, algoKind, true )); + + if ( algo ) + { + bool sameAlgo = ( algo == foundAlgo ); + if ( !sameAlgo && foundAlgo ) + sameAlgo = ( strcmp( algo->GetName(), foundAlgo->GetName() ) == 0); + + if ( !sameAlgo ) { // init filter for used hypos search + if ( !algo->InitCompatibleHypoFilter( compatibleHypoKind, !hyp->IsAuxiliary() )) + continue; // algo does not use any hypothesis + foundAlgo = algo; + } + + // check if hyp is used by algo + usedHyps.clear(); + if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) && + find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() ) + { + aSubMesh->ComputeStateEngine(SMESH_subMesh::MODIF_HYP); + + if ( algo->GetDim() == 1 && IsPropagationHypothesis( aSubShape )) + CleanMeshOnPropagationChain( aSubShape ); + } + } + } + } } //============================================================================= -/*! - * +/*! Export* methods. + * To store mesh contents on disk in different formats. */ //============================================================================= +bool SMESH_Mesh::HasDuplicatedGroupNamesMED() +{ + set aGroupNames; + for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + SMESH_Group* aGroup = it->second; + string aGroupName = aGroup->GetName(); + aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); + if (!aGroupNames.insert(aGroupName).second) + return true; + } + + return false; +} + void SMESH_Mesh::ExportMED(const char *file, const char* theMeshName, bool theAutoGroups, @@ -755,6 +858,7 @@ void SMESH_Mesh::ExportMED(const char *file, throw(SALOME_Exception) { Unexpect aCatch(SalomeException); + DriverMED_W_SMESHDS_Mesh myWriter; myWriter.SetFile ( file, MED::EVersion(theVersion) ); myWriter.SetMesh ( _myMeshDS ); @@ -772,15 +876,28 @@ void SMESH_Mesh::ExportMED(const char *file, myWriter.AddGroupOfVolumes(); } + // Pass groups to writer. Provide unique group names. + set aGroupNames; + char aString [256]; + int maxNbIter = 10000; // to guarantee cycle finish for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { SMESH_Group* aGroup = it->second; SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS(); if ( aGroupDS ) { - aGroupDS->SetStoreName( aGroup->GetName() ); + string aGroupName0 = aGroup->GetName(); + aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH); + string aGroupName = aGroupName0; + for (int i = 1; !aGroupNames.insert(aGroupName).second && i < maxNbIter; i++) { + sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str()); + aGroupName = aString; + aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); + } + aGroupDS->SetStoreName( aGroupName.c_str() ); myWriter.AddGroup( aGroupDS ); } } + // Perform export myWriter.Perform(); } @@ -861,7 +978,8 @@ int SMESH_Mesh::NbTriangles() throw(SALOME_Exception) const SMDS_MeshFace * curFace; while (itFaces->more()) { curFace = itFaces->next(); - if (!curFace->IsPoly() && curFace->NbNodes() == 3) Nb++; + if ( !curFace->IsPoly() && + ( curFace->NbNodes()==3 || curFace->NbNodes()==6 ) ) Nb++; } return Nb; } @@ -879,7 +997,8 @@ int SMESH_Mesh::NbQuadrangles() throw(SALOME_Exception) const SMDS_MeshFace * curFace; while (itFaces->more()) { curFace = itFaces->next(); - if (!curFace->IsPoly() && curFace->NbNodes() == 4) Nb++; + if ( !curFace->IsPoly() && + ( curFace->NbNodes() == 4 || curFace->NbNodes()==8 ) ) Nb++; } return Nb; } @@ -917,7 +1036,8 @@ int SMESH_Mesh::NbTetras() throw(SALOME_Exception) const SMDS_MeshVolume * curVolume; while (itVolumes->more()) { curVolume = itVolumes->next(); - if (!curVolume->IsPoly() && curVolume->NbNodes() == 4) Nb++; + if ( !curVolume->IsPoly() && + ( curVolume->NbNodes() == 4 || curVolume->NbNodes()==10 ) ) Nb++; } return Nb; } @@ -931,7 +1051,8 @@ int SMESH_Mesh::NbHexas() throw(SALOME_Exception) const SMDS_MeshVolume * curVolume; while (itVolumes->more()) { curVolume = itVolumes->next(); - if (!curVolume->IsPoly() && curVolume->NbNodes() == 8) Nb++; + if ( !curVolume->IsPoly() && + ( curVolume->NbNodes() == 8 || curVolume->NbNodes()==20 ) ) Nb++; } return Nb; } @@ -945,7 +1066,8 @@ int SMESH_Mesh::NbPyramids() throw(SALOME_Exception) const SMDS_MeshVolume * curVolume; while (itVolumes->more()) { curVolume = itVolumes->next(); - if (!curVolume->IsPoly() && curVolume->NbNodes() == 5) Nb++; + if ( !curVolume->IsPoly() && + ( curVolume->NbNodes() == 5 || curVolume->NbNodes()==13 ) ) Nb++; } return Nb; } @@ -959,7 +1081,8 @@ int SMESH_Mesh::NbPrisms() throw(SALOME_Exception) const SMDS_MeshVolume * curVolume; while (itVolumes->more()) { curVolume = itVolumes->next(); - if (!curVolume->IsPoly() && curVolume->NbNodes() == 6) Nb++; + if ( !curVolume->IsPoly() && + ( curVolume->NbNodes() == 6 || curVolume->NbNodes()==15 ) ) Nb++; } return Nb; } @@ -1152,7 +1275,7 @@ void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge) SMESH_subMesh *subMesh = GetSubMesh(anEdge); SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS(); if (subMeshDS && subMeshDS->NbElements() > 0) { - subMesh->ComputeStateEngine(SMESH_subMesh::CLEANDEP); + subMesh->ComputeStateEngine(SMESH_subMesh::CLEAN); } } } diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 5054e0038..93802346d 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -79,8 +79,11 @@ class SMESH_Mesh SMESH_Mesh(); SMESH_Mesh(const SMESH_Mesh&); public: - SMESH_Mesh(int localId, int studyId, SMESH_Gen * gen, - SMESHDS_Document * myDocument); + SMESH_Mesh(int theLocalId, + int theStudyId, + SMESH_Gen* theGen, + bool theIsEmbeddedMode, + SMESHDS_Document* theDocument); virtual ~SMESH_Mesh(); @@ -110,10 +113,10 @@ public: const SMESH_HypoFilter& aFilter, const bool andAncestors) const; - bool GetHypotheses(const TopoDS_Shape & aSubShape, - const SMESH_HypoFilter& aFilter, - list & aHypList, - const bool andAncestors) const; + int GetHypotheses(const TopoDS_Shape & aSubShape, + const SMESH_HypoFilter& aFilter, + list & aHypList, + const bool andAncestors) const; const list & GetLog() throw(SALOME_Exception); @@ -134,12 +137,15 @@ public: SMESH_subMesh *GetSubMeshContaining(const int aShapeID) throw(SALOME_Exception); + void NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp); + // Say all submeshes that theChangedHyp has been modified + const list < SMESH_subMesh * >& GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) throw(SALOME_Exception); - bool IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, - const TopoDS_Shape & aSubShape); + bool IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, + const SMESH_subMesh * aSubMesh); // Return True if anHyp is used to mesh aSubShape bool IsNotConformAllowed() const; @@ -150,7 +156,12 @@ public: const TopTools_ListOfShape& GetAncestors(const TopoDS_Shape& theSubShape) const; // return list of ancestors of theSubShape in the order // that lower dimention shapes come first. - + + /*! Check group names for duplications. + * Consider maximum group name length stored in MED file. + */ + bool HasDuplicatedGroupNamesMED(); + void ExportMED(const char *file, const char* theMeshName = NULL, bool theAutoGroups = true, diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index d75adf3e7..992916482 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -34,6 +34,7 @@ #include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_SpacePosition.hxx" +#include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Mesh.hxx" @@ -75,8 +76,12 @@ typedef map > TElemOfNode typedef map > TElemOfElemListMap; typedef map > TNodeOfNodeListMap; typedef TNodeOfNodeListMap::iterator TNodeOfNodeListMapItr; +//typedef map > TNodeOfNodeVecMap; +//typedef TNodeOfNodeVecMap::iterator TNodeOfNodeVecMapItr; typedef map > TElemOfVecOfNnlmiMap; +//typedef map > TElemOfVecOfMapNodesMap; +typedef pair NLink; //======================================================================= //function : SMESH_MeshEditor @@ -102,8 +107,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, set< SMESH_subMesh *> smmap; list::const_iterator it = theIDs.begin(); - for ( ; it != theIDs.end(); it++ ) - { + for ( ; it != theIDs.end(); it++ ) { const SMDS_MeshElement * elem; if ( isNodes ) elem = aMesh->FindNode( *it ); @@ -114,8 +118,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, // Find sub-meshes to notify about modification SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); - while ( nodeIt->more() ) - { + while ( nodeIt->more() ) { const SMDS_MeshNode* node = static_cast( nodeIt->next() ); const SMDS_PositionPtr& aPosition = node->GetPosition(); if ( aPosition.get() ) { @@ -142,6 +145,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, for ( smIt = smmap.begin(); smIt != smmap.end(); smIt++ ) (*smIt)->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED ); } + return true; } @@ -157,8 +161,7 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem) if ( aMesh->ShapeToMesh().IsNull() ) return 0; - if ( theElem->GetType() == SMDSAbs_Node ) - { + if ( theElem->GetType() == SMDSAbs_Node ) { const SMDS_PositionPtr& aPosition = static_cast( theElem )->GetPosition(); if ( aPosition.get() ) @@ -169,25 +172,22 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem) TopoDS_Shape aShape; // the shape a node is on SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); - while ( nodeIt->more() ) - { + while ( nodeIt->more() ) { const SMDS_MeshNode* node = static_cast( nodeIt->next() ); const SMDS_PositionPtr& aPosition = node->GetPosition(); if ( aPosition.get() ) { - int aShapeID = aPosition->GetShapeId(); - SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID ); - if ( sm ) - { - if ( sm->Contains( theElem )) - return aShapeID; - if ( aShape.IsNull() ) - aShape = aMesh->IndexToShape( aShapeID ); - } - else - { - //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID ); - } + int aShapeID = aPosition->GetShapeId(); + SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID ); + if ( sm ) { + if ( sm->Contains( theElem )) + return aShapeID; + if ( aShape.IsNull() ) + aShape = aMesh->IndexToShape( aShapeID ); } + else { + //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID ); + } + } } // None of nodes is on a proper shape, @@ -197,17 +197,108 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem) return 0; } TopTools_ListIteratorOfListOfShape ancIt( GetMesh()->GetAncestors( aShape )); - for ( ; ancIt.More(); ancIt.Next() ) - { - SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() ); - if ( sm && sm->Contains( theElem )) - return aMesh->ShapeToIndex( ancIt.Value() ); + for ( ; ancIt.More(); ancIt.Next() ) { + SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() ); + if ( sm && sm->Contains( theElem )) + return aMesh->ShapeToIndex( ancIt.Value() ); } //MESSAGE ("::FindShape() - SHAPE NOT FOUND") return 0; } +//======================================================================= +//function : IsMedium +//purpose : +//======================================================================= + +bool SMESH_MeshEditor::IsMedium(const SMDS_MeshNode* node, + const SMDSAbs_ElementType typeToCheck) +{ + bool isMedium = false; + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); + while (it->more()) { + const SMDS_MeshElement* elem = it->next(); + isMedium = elem->IsMediumNode(node); + if ( typeToCheck == SMDSAbs_All || elem->GetType() == typeToCheck ) + break; + } + return isMedium; +} + +//======================================================================= +//function : ShiftNodesQuadTria +//purpose : auxilary +// Shift nodes in the array corresponded to quadratic triangle +// example: (0,1,2,3,4,5) -> (1,2,0,4,5,3) +//======================================================================= +static void ShiftNodesQuadTria(const SMDS_MeshNode* aNodes[]) +{ + const SMDS_MeshNode* nd1 = aNodes[0]; + aNodes[0] = aNodes[1]; + aNodes[1] = aNodes[2]; + aNodes[2] = nd1; + const SMDS_MeshNode* nd2 = aNodes[3]; + aNodes[3] = aNodes[4]; + aNodes[4] = aNodes[5]; + aNodes[5] = nd2; +} + +//======================================================================= +//function : GetNodesFromTwoTria +//purpose : auxilary +// Shift nodes in the array corresponded to quadratic triangle +// example: (0,1,2,3,4,5) -> (1,2,0,4,5,3) +//======================================================================= +static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1, + const SMDS_MeshElement * theTria2, + const SMDS_MeshNode* N1[], + const SMDS_MeshNode* N2[]) +{ + SMDS_ElemIteratorPtr it = theTria1->nodesIterator(); + int i=0; + while(i<6) { + N1[i] = static_cast( it->next() ); + i++; + } + if(it->more()) return false; + it = theTria2->nodesIterator(); + i=0; + while(i<6) { + N2[i] = static_cast( it->next() ); + i++; + } + if(it->more()) return false; + + int sames[3] = {-1,-1,-1}; + int nbsames = 0; + int j; + for(i=0; i<3; i++) { + for(j=0; j<3; j++) { + if(N1[i]==N2[j]) { + sames[i] = j; + nbsames++; + break; + } + } + } + if(nbsames!=2) return false; + if(sames[0]>-1) { + ShiftNodesQuadTria(N1); + if(sames[1]>-1) { + ShiftNodesQuadTria(N1); + } + } + i = sames[0] + sames[1] + sames[2]; + for(; i<2; i++) { + ShiftNodesQuadTria(N2); + } + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + return true; +} + //======================================================================= //function : InverseDiag //purpose : Replace two neighbour triangles with ones built on the same 4 nodes @@ -220,71 +311,116 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, { if (!theTria1 || !theTria2) return false; + const SMDS_FaceOfNodes* F1 = dynamic_cast( theTria1 ); - if (!F1) return false; const SMDS_FaceOfNodes* F2 = dynamic_cast( theTria2 ); - if (!F2) return false; + if (F1 && F2) { - // 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A - // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | - // |/ | | \| - // B +--+ 2 B +--+ 2 + // 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A + // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | + // |/ | | \| + // B +--+ 2 B +--+ 2 - // put nodes in array and find out indices of the same ones - const SMDS_MeshNode* aNodes [6]; - int sameInd [] = { 0, 0, 0, 0, 0, 0 }; - int i = 0; - SMDS_ElemIteratorPtr it = theTria1->nodesIterator(); - while ( it->more() ) - { - aNodes[ i ] = static_cast( it->next() ); - - if ( i > 2 ) // theTria2 - // find same node of theTria1 - for ( int j = 0; j < 3; j++ ) - if ( aNodes[ i ] == aNodes[ j ]) { - sameInd[ j ] = i; - sameInd[ i ] = j; - break; - } - // next - i++; - if ( i == 3 ) { - if ( it->more() ) - return false; // theTria1 is not a triangle - it = theTria2->nodesIterator(); + // put nodes in array and find out indices of the same ones + const SMDS_MeshNode* aNodes [6]; + int sameInd [] = { 0, 0, 0, 0, 0, 0 }; + int i = 0; + SMDS_ElemIteratorPtr it = theTria1->nodesIterator(); + while ( it->more() ) { + aNodes[ i ] = static_cast( it->next() ); + + if ( i > 2 ) // theTria2 + // find same node of theTria1 + for ( int j = 0; j < 3; j++ ) + if ( aNodes[ i ] == aNodes[ j ]) { + sameInd[ j ] = i; + sameInd[ i ] = j; + break; + } + // next + i++; + if ( i == 3 ) { + if ( it->more() ) + return false; // theTria1 is not a triangle + it = theTria2->nodesIterator(); + } + if ( i == 6 && it->more() ) + return false; // theTria2 is not a triangle } - if ( i == 6 && it->more() ) - return false; // theTria2 is not a triangle - } + + // find indices of 1,2 and of A,B in theTria1 + int iA = 0, iB = 0, i1 = 0, i2 = 0; + for ( i = 0; i < 6; i++ ) { + if ( sameInd [ i ] == 0 ) + if ( i < 3 ) i1 = i; + else i2 = i; + else if (i < 3) + if ( iA ) iB = i; + else iA = i; + } + // nodes 1 and 2 should not be the same + if ( aNodes[ i1 ] == aNodes[ i2 ] ) + return false; + + // theTria1: A->2 + aNodes[ iA ] = aNodes[ i2 ]; + // theTria2: B->1 + aNodes[ sameInd[ iB ]] = aNodes[ i1 ]; + + //MESSAGE( theTria1 << theTria2 ); + + GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 ); + GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 ); + + //MESSAGE( theTria1 << theTria2 ); - // find indices of 1,2 and of A,B in theTria1 - int iA = 0, iB = 0, i1 = 0, i2 = 0; - for ( i = 0; i < 6; i++ ) - { - if ( sameInd [ i ] == 0 ) - if ( i < 3 ) i1 = i; - else i2 = i; - else if (i < 3) - if ( iA ) iB = i; - else iA = i; - } - // nodes 1 and 2 should not be the same - if ( aNodes[ i1 ] == aNodes[ i2 ] ) + return true; + + } // end if(F1 && F2) + + // check case of quadratic faces + const SMDS_QuadraticFaceOfNodes* QF1 = + dynamic_cast (theTria1); + if(!QF1) return false; + const SMDS_QuadraticFaceOfNodes* QF2 = + dynamic_cast (theTria2); + if(!QF2) return false; + + // 5 + // 1 +--+--+ 2 theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9) + // | /| theTria2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8) + // | / | + // 7 + + + 6 + // | /9 | + // |/ | + // 4 +--+--+ 3 + // 8 + + const SMDS_MeshNode* N1 [6]; + const SMDS_MeshNode* N2 [6]; + if(!GetNodesFromTwoTria(theTria1,theTria2,N1,N2)) return false; - - - // theTria1: A->2 - aNodes[ iA ] = aNodes[ i2 ]; - // theTria2: B->1 - aNodes[ sameInd[ iB ]] = aNodes[ i1 ]; - - //MESSAGE( theTria1 << theTria2 ); - - GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 ); - GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 ); - - //MESSAGE( theTria1 << theTria2 ); + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + + const SMDS_MeshNode* N1new [6]; + const SMDS_MeshNode* N2new [6]; + N1new[0] = N1[0]; + N1new[1] = N2[0]; + N1new[2] = N2[1]; + N1new[3] = N1[4]; + N1new[4] = N2[3]; + N1new[5] = N1[5]; + N2new[0] = N1[0]; + N2new[1] = N1[1]; + N2new[2] = N2[0]; + N2new[3] = N1[3]; + N2new[4] = N2[5]; + N2new[5] = N1[4]; + // replaces nodes in faces + GetMeshDS()->ChangeElementNodes( theTria1, N1new, 6 ); + GetMeshDS()->ChangeElementNodes( theTria2, N2new, 6 ); return true; } @@ -318,7 +454,8 @@ static bool findTriangles(const SMDS_MeshNode * theNode1, if ( theTria1 ) { theTria2 = elem; break; - } else { + } + else { theTria1 = elem; } } @@ -342,55 +479,65 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1, return false; const SMDS_FaceOfNodes* F1 = dynamic_cast( tr1 ); - if (!F1) return false; + //if (!F1) return false; const SMDS_FaceOfNodes* F2 = dynamic_cast( tr2 ); - if (!F2) return false; - - // 1 +--+ A tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A - // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | - // |/ | | \| - // B +--+ 2 B +--+ 2 - - // put nodes in array - // and find indices of 1,2 and of A in tr1 and of B in tr2 - int i, iA1 = 0, i1 = 0; - const SMDS_MeshNode* aNodes1 [3]; - SMDS_ElemIteratorPtr it; - for (i = 0, it = tr1->nodesIterator(); it->more(); i++ ) { - aNodes1[ i ] = static_cast( it->next() ); - if ( aNodes1[ i ] == theNode1 ) - iA1 = i; // node A in tr1 - else if ( aNodes1[ i ] != theNode2 ) - i1 = i; // node 1 - } - int iB2 = 0, i2 = 0; - const SMDS_MeshNode* aNodes2 [3]; - for (i = 0, it = tr2->nodesIterator(); it->more(); i++ ) { - aNodes2[ i ] = static_cast( it->next() ); - if ( aNodes2[ i ] == theNode2 ) - iB2 = i; // node B in tr2 - else if ( aNodes2[ i ] != theNode1 ) - i2 = i; // node 2 - } - - // nodes 1 and 2 should not be the same - if ( aNodes1[ i1 ] == aNodes2[ i2 ] ) - return false; - - // tr1: A->2 - aNodes1[ iA1 ] = aNodes2[ i2 ]; - // tr2: B->1 - aNodes2[ iB2 ] = aNodes1[ i1 ]; + //if (!F2) return false; + if (F1 && F2) { + + // 1 +--+ A tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A + // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | + // |/ | | \| + // B +--+ 2 B +--+ 2 + + // put nodes in array + // and find indices of 1,2 and of A in tr1 and of B in tr2 + int i, iA1 = 0, i1 = 0; + const SMDS_MeshNode* aNodes1 [3]; + SMDS_ElemIteratorPtr it; + for (i = 0, it = tr1->nodesIterator(); it->more(); i++ ) { + aNodes1[ i ] = static_cast( it->next() ); + if ( aNodes1[ i ] == theNode1 ) + iA1 = i; // node A in tr1 + else if ( aNodes1[ i ] != theNode2 ) + i1 = i; // node 1 + } + int iB2 = 0, i2 = 0; + const SMDS_MeshNode* aNodes2 [3]; + for (i = 0, it = tr2->nodesIterator(); it->more(); i++ ) { + aNodes2[ i ] = static_cast( it->next() ); + if ( aNodes2[ i ] == theNode2 ) + iB2 = i; // node B in tr2 + else if ( aNodes2[ i ] != theNode1 ) + i2 = i; // node 2 + } + + // nodes 1 and 2 should not be the same + if ( aNodes1[ i1 ] == aNodes2[ i2 ] ) + return false; - //MESSAGE( tr1 << tr2 ); + // tr1: A->2 + aNodes1[ iA1 ] = aNodes2[ i2 ]; + // tr2: B->1 + aNodes2[ iB2 ] = aNodes1[ i1 ]; - GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 ); - GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 ); + //MESSAGE( tr1 << tr2 ); - //MESSAGE( tr1 << tr2 ); + GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 ); + GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 ); - return true; + //MESSAGE( tr1 << tr2 ); + + return true; + } + // check case of quadratic faces + const SMDS_QuadraticFaceOfNodes* QF1 = + dynamic_cast (tr1); + if(!QF1) return false; + const SMDS_QuadraticFaceOfNodes* QF2 = + dynamic_cast (tr2); + if(!QF2) return false; + return InverseDiag(tr1,tr2); } //======================================================================= @@ -406,12 +553,16 @@ bool getQuadrangleNodes(const SMDS_MeshNode * theQuadNodes [], const SMDS_MeshElement * tr1, const SMDS_MeshElement * tr2 ) { + if( tr1->NbNodes() != tr2->NbNodes() ) + return false; // find the 4-th node to insert into tr1 const SMDS_MeshNode* n4 = 0; SMDS_ElemIteratorPtr it = tr2->nodesIterator(); - while ( !n4 && it->more() ) - { + int i=0; + //while ( !n4 && it->more() ) { + while ( !n4 && i<3 ) { const SMDS_MeshNode * n = static_cast( it->next() ); + i++; bool isDiag = ( n == theNode1 || n == theNode2 ); if ( !isDiag ) n4 = n; @@ -419,19 +570,19 @@ bool getQuadrangleNodes(const SMDS_MeshNode * theQuadNodes [], // Make an array of nodes to be in a quadrangle int iNode = 0, iFirstDiag = -1; it = tr1->nodesIterator(); - while ( it->more() ) - { + i=0; + //while ( it->more() ) { + while ( i<3 ) { const SMDS_MeshNode * n = static_cast( it->next() ); + i++; bool isDiag = ( n == theNode1 || n == theNode2 ); - if ( isDiag ) - { + if ( isDiag ) { if ( iFirstDiag < 0 ) iFirstDiag = iNode; else if ( iNode - iFirstDiag == 1 ) theQuadNodes[ iNode++ ] = n4; // insert the 4-th node between diagonal nodes } - else if ( n == n4 ) - { + else if ( n == n4 ) { return false; // tr1 and tr2 should not have all the same nodes } theQuadNodes[ iNode++ ] = n; @@ -459,20 +610,66 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, return false; const SMDS_FaceOfNodes* F1 = dynamic_cast( tr1 ); - if (!F1) return false; + //if (!F1) return false; const SMDS_FaceOfNodes* F2 = dynamic_cast( tr2 ); - if (!F2) return false; + //if (!F2) return false; + if (F1 && F2) { - const SMDS_MeshNode* aNodes [ 4 ]; - if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 )) - return false; + const SMDS_MeshNode* aNodes [ 4 ]; + if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 )) + return false; - //MESSAGE( endl << tr1 << tr2 ); + //MESSAGE( endl << tr1 << tr2 ); - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 ); + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 ); + GetMeshDS()->RemoveElement( tr2 ); + + //MESSAGE( endl << tr1 ); + + return true; + } + + // check case of quadratic faces + const SMDS_QuadraticFaceOfNodes* QF1 = + dynamic_cast (tr1); + if(!QF1) return false; + const SMDS_QuadraticFaceOfNodes* QF2 = + dynamic_cast (tr2); + if(!QF2) return false; + + // 5 + // 1 +--+--+ 2 tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9) + // | /| tr2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8) + // | / | + // 7 + + + 6 + // | /9 | + // |/ | + // 4 +--+--+ 3 + // 8 + + const SMDS_MeshNode* N1 [6]; + const SMDS_MeshNode* N2 [6]; + if(!GetNodesFromTwoTria(tr1,tr2,N1,N2)) + return false; + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + + const SMDS_MeshNode* aNodes[8]; + aNodes[0] = N1[0]; + aNodes[1] = N1[1]; + aNodes[2] = N2[0]; + aNodes[3] = N2[1]; + aNodes[4] = N1[3]; + aNodes[5] = N2[5]; + aNodes[6] = N2[3]; + aNodes[7] = N1[5]; + + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); GetMeshDS()->RemoveElement( tr2 ); - //MESSAGE( endl << tr1 ); + // remove middle node (9) + GetMeshDS()->RemoveNode( N1[4] ); return true; } @@ -493,16 +690,39 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) switch ( theElem->GetType() ) { case SMDSAbs_Edge: - case SMDSAbs_Face: - { - int i = theElem->NbNodes(); - vector aNodes( i ); - while ( it->more() ) - aNodes[ --i ]= static_cast( it->next() ); - return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], theElem->NbNodes() ); + case SMDSAbs_Face: { + if(!theElem->IsQuadratic()) { + int i = theElem->NbNodes(); + vector aNodes( i ); + while ( it->more() ) + aNodes[ --i ]= static_cast( it->next() ); + return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], theElem->NbNodes() ); + } + else { + // quadratic elements + if(theElem->GetType()==SMDSAbs_Edge) { + vector aNodes(3); + aNodes[1]= static_cast( it->next() ); + aNodes[0]= static_cast( it->next() ); + aNodes[2]= static_cast( it->next() ); + return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], 3 ); + } + else { + int nbn = theElem->NbNodes(); + vector aNodes(nbn); + aNodes[0]= static_cast( it->next() ); + int i=1; + for(; i( it->next() ); + } + for(i=0; i( it->next() ); + } + return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], nbn ); + } + } } - case SMDSAbs_Volume: - { + case SMDSAbs_Volume: { if (theElem->IsPoly()) { const SMDS_PolyhedralVolumeOfNodes* aPolyedre = static_cast( theElem ); @@ -519,16 +739,17 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) for (int iface = 1; iface <= nbFaces; iface++) { int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface); quantities[iface - 1] = nbFaceNodes; - + for (inode = nbFaceNodes; inode >= 1; inode--) { const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode); poly_nodes.push_back(curNode); } } - + return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities ); - } else { + } + else { SMDS_VolumeTool vTool; if ( !vTool.Set( theElem )) return false; @@ -574,54 +795,119 @@ bool SMESH_MeshEditor::QuadToTri (set & theElems, SMESHDS_Mesh * aMesh = GetMeshDS(); set< const SMDS_MeshElement * >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); - if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() != 4 ) + if ( !elem || elem->GetType() != SMDSAbs_Face ) continue; - // retrieve element nodes - const SMDS_MeshNode* aNodes [4]; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - int i = 0; - while ( itN->more() ) - aNodes[ i++ ] = static_cast( itN->next() ); + if(elem->NbNodes()==4) { - // compare two sets of possible triangles - double aBadRate1, aBadRate2; // to what extent a set is bad - SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); - SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); - aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); - - SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); - SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); - aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); + // retrieve element nodes + const SMDS_MeshNode* aNodes [4]; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int i = 0; + while ( itN->more() ) + aNodes[ i++ ] = static_cast( itN->next() ); + + // compare two sets of possible triangles + double aBadRate1, aBadRate2; // to what extent a set is bad + SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); + SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); + aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); + + SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); + SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); + aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); - int aShapeId = FindShape( elem ); - //MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2 + int aShapeId = FindShape( elem ); + //MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2 // << " ShapeID = " << aShapeId << endl << elem ); - if ( aBadRate1 <= aBadRate2 ) { - // tr1 + tr2 is better - aMesh->ChangeElementNodes( elem, aNodes, 3 ); + if ( aBadRate1 <= aBadRate2 ) { + // tr1 + tr2 is better + aMesh->ChangeElementNodes( elem, aNodes, 3 ); + //MESSAGE( endl << elem ); + + elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + } + else { + // tr3 + tr4 is better + aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); + //MESSAGE( endl << elem ); + + elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + } //MESSAGE( endl << elem ); - elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + // put a new triangle on the same shape + if ( aShapeId ) + aMesh->SetMeshElementOnShape( elem, aShapeId ); } - else { - // tr3 + tr4 is better - aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); - //MESSAGE( endl << elem ); - elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + if( elem->NbNodes()==8 && elem->IsQuadratic() ) { + const SMDS_MeshNode* aNodes [8]; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int i = 0; + while ( itN->more() ) { + aNodes[ i++ ] = static_cast( itN->next() ); + } + + // compare two sets of possible triangles + // use for comparing simple triangles (not quadratic) + double aBadRate1, aBadRate2; // to what extent a set is bad + SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); + SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); + aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); + + SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); + SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); + aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); + + int aShapeId = FindShape( elem ); + + // find middle point for (0,1,2,3) + // and create node in this point; + double x=0., y=0., z=0.; + for(i=0; i<4; i++) { + x += aNodes[i]->X(); + y += aNodes[i]->Y(); + z += aNodes[i]->Z(); + } + const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4); + + if ( aBadRate1 <= aBadRate2 ) { + // tr1 + tr2 is better + const SMDS_MeshNode* N[6]; + N[0] = aNodes[0]; + N[1] = aNodes[1]; + N[2] = aNodes[2]; + N[3] = aNodes[4]; + N[4] = aNodes[5]; + N[5] = newN; + aMesh->ChangeElementNodes( elem, N, 6 ); + elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], + aNodes[6], aNodes[7], newN ); + } + else { + // tr3 + tr4 is better + const SMDS_MeshNode* N[6]; + N[0] = aNodes[1]; + N[1] = aNodes[2]; + N[2] = aNodes[3]; + N[3] = aNodes[5]; + N[4] = aNodes[6]; + N[5] = newN; + aMesh->ChangeElementNodes( elem, N, 6 ); + elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], + aNodes[7], aNodes[4], newN ); + } + // put a new triangle on the same shape + if ( aShapeId ) { + aMesh->SetMeshElementOnShape( elem, aShapeId ); + } } - //MESSAGE( endl << elem ); - // put a new triangle on the same shape - if ( aShapeId ) - aMesh->SetMeshElementOnShape( elem, aShapeId ); } - return true; } @@ -635,30 +921,36 @@ int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad, if (!theCrit.get()) return -1; - if (!theQuad || theQuad->GetType() != SMDSAbs_Face || theQuad->NbNodes() != 4) + if (!theQuad || theQuad->GetType() != SMDSAbs_Face ) return -1; - // retrieve element nodes - const SMDS_MeshNode* aNodes [4]; - SMDS_ElemIteratorPtr itN = theQuad->nodesIterator(); - int i = 0; - while (itN->more()) - aNodes[ i++ ] = static_cast( itN->next() ); + if( theQuad->NbNodes()==4 || + (theQuad->NbNodes()==8 && theQuad->IsQuadratic()) ) { - // compare two sets of possible triangles - double aBadRate1, aBadRate2; // to what extent a set is bad - SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); - SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); - aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); + // retrieve element nodes + const SMDS_MeshNode* aNodes [4]; + SMDS_ElemIteratorPtr itN = theQuad->nodesIterator(); + int i = 0; + //while (itN->more()) + while (i<4) { + aNodes[ i++ ] = static_cast( itN->next() ); + } + // compare two sets of possible triangles + double aBadRate1, aBadRate2; // to what extent a set is bad + SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] ); + SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] ); + aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit ); - SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); - SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); - aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); + SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] ); + SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] ); + aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); - if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better - return 1; // diagonal 1-3 + if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better + return 1; // diagonal 1-3 - return 2; // diagonal 2-4 + return 2; // diagonal 2-4 + } + return -1; } //======================================================================= @@ -693,38 +985,86 @@ bool SMESH_MeshEditor::QuadToTri (std::set & theElems, SMESHDS_Mesh * aMesh = GetMeshDS(); set< const SMDS_MeshElement * >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); - if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() != 4 ) + if ( !elem || elem->GetType() != SMDSAbs_Face ) continue; + bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8; + if(!isquad) continue; - // retrieve element nodes - const SMDS_MeshNode* aNodes [4]; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - int i = 0; - while ( itN->more() ) - aNodes[ i++ ] = static_cast( itN->next() ); + if(elem->NbNodes()==4) { + // retrieve element nodes + const SMDS_MeshNode* aNodes [4]; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int i = 0; + while ( itN->more() ) + aNodes[ i++ ] = static_cast( itN->next() ); - int aShapeId = FindShape( elem ); - const SMDS_MeshElement* newElem = 0; - if ( the13Diag ) - { - aMesh->ChangeElementNodes( elem, aNodes, 3 ); - newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); - } - else - { - aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); - newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + int aShapeId = FindShape( elem ); + const SMDS_MeshElement* newElem = 0; + if ( the13Diag ) { + aMesh->ChangeElementNodes( elem, aNodes, 3 ); + newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + } + else { + aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); + newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + } + // put a new triangle on the same shape and add to the same groups + if ( aShapeId ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + AddToSameGroups( newElem, elem, aMesh ); } - // put a new triangle on the same shape and add to the same groups + if( elem->NbNodes()==8 && elem->IsQuadratic() ) { + const SMDS_MeshNode* aNodes [8]; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + int i = 0; + while ( itN->more() ) { + aNodes[ i++ ] = static_cast( itN->next() ); + } - if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); + // find middle point for (0,1,2,3) + // and create node in this point; + double x=0., y=0., z=0.; + for(i=0; i<4; i++) { + x += aNodes[i]->X(); + y += aNodes[i]->Y(); + z += aNodes[i]->Z(); + } + const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4); - AddToSameGroups( newElem, elem, aMesh ); + int aShapeId = FindShape( elem ); + const SMDS_MeshElement* newElem = 0; + if ( the13Diag ) { + const SMDS_MeshNode* N[6]; + N[0] = aNodes[0]; + N[1] = aNodes[1]; + N[2] = aNodes[2]; + N[3] = aNodes[4]; + N[4] = aNodes[5]; + N[5] = newN; + aMesh->ChangeElementNodes( elem, N, 6 ); + elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], + aNodes[6], aNodes[7], newN ); + } + else { + const SMDS_MeshNode* N[6]; + N[0] = aNodes[1]; + N[1] = aNodes[2]; + N[2] = aNodes[3]; + N[3] = aNodes[5]; + N[4] = aNodes[6]; + N[5] = newN; + aMesh->ChangeElementNodes( elem, N, 6 ); + elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], + aNodes[7], aNodes[4], newN ); + } + // put a new triangle on the same shape and add to the same groups + if ( aShapeId ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + AddToSameGroups( newElem, elem, aMesh ); + } } return true; @@ -747,18 +1087,24 @@ double getAngle(const SMDS_MeshElement * tr1, if ( !SMESH::Controls::NumericalFunctor::GetPoints( tr1, P1 ) || !SMESH::Controls::NumericalFunctor::GetPoints( tr2, P2 )) return angle; - gp_Vec N1 = gp_Vec( P1(2) - P1(1) ) ^ gp_Vec( P1(3) - P1(1) ); + gp_Vec N1,N2; + if(!tr1->IsQuadratic()) + N1 = gp_Vec( P1(2) - P1(1) ) ^ gp_Vec( P1(3) - P1(1) ); + else + N1 = gp_Vec( P1(3) - P1(1) ) ^ gp_Vec( P1(5) - P1(1) ); if ( N1.SquareMagnitude() <= gp::Resolution() ) return angle; - gp_Vec N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) ); + if(!tr2->IsQuadratic()) + N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) ); + else + N2 = gp_Vec( P2(3) - P2(1) ) ^ gp_Vec( P2(5) - P2(1) ); if ( N2.SquareMagnitude() <= gp::Resolution() ) return angle; // find the first diagonal node n1 in the triangles: // take in account a diagonal link orientation const SMDS_MeshElement *nFirst[2], *tr[] = { tr1, tr2 }; - for ( int t = 0; t < 2; t++ ) - { + for ( int t = 0; t < 2; t++ ) { SMDS_ElemIteratorPtr it = tr[ t ]->nodesIterator(); int i = 0, iDiag = -1; while ( it->more()) { @@ -788,7 +1134,6 @@ double getAngle(const SMDS_MeshElement * tr1, // class generating a unique ID for a pair of nodes // and able to return nodes by that ID // ================================================= - class LinkID_Gen { public: @@ -819,6 +1164,7 @@ class LinkID_Gen { long myMaxID; }; + //======================================================================= //function : TriToQuad //purpose : Fuse neighbour triangles into quadrangles. @@ -837,65 +1183,76 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, return false; SMESHDS_Mesh * aMesh = GetMeshDS(); - LinkID_Gen aLinkID_Gen( aMesh ); - + //LinkID_Gen aLinkID_Gen( aMesh ); // Prepare data for algo: build // 1. map of elements with their linkIDs // 2. map of linkIDs with their elements - map< long, list< const SMDS_MeshElement* > > mapLi_listEl; - map< long, list< const SMDS_MeshElement* > >::iterator itLE; - map< const SMDS_MeshElement*, set< long > > mapEl_setLi; - map< const SMDS_MeshElement*, set< long > >::iterator itEL; + //map< long, list< const SMDS_MeshElement* > > mapLi_listEl; + //map< long, list< const SMDS_MeshElement* > >::iterator itLE; + //map< const SMDS_MeshElement*, set< long > > mapEl_setLi; + //map< const SMDS_MeshElement*, set< long > >::iterator itEL; + + map< NLink, list< const SMDS_MeshElement* > > mapLi_listEl; + map< NLink, list< const SMDS_MeshElement* > >::iterator itLE; + map< const SMDS_MeshElement*, set< NLink > > mapEl_setLi; + map< const SMDS_MeshElement*, set< NLink > >::iterator itEL; set::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); - if ( !elem || elem->NbNodes() != 3 ) - continue; + //if ( !elem || elem->NbNodes() != 3 ) + // continue; + if(!elem || elem->GetType() != SMDSAbs_Face ) continue; + bool IsTria = elem->NbNodes()==3 || (elem->NbNodes()==6 && elem->IsQuadratic()); + if(!IsTria) continue; // retrieve element nodes const SMDS_MeshNode* aNodes [4]; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); int i = 0; - while ( itN->more() ) + //while ( itN->more() ) + while ( i<3 ) aNodes[ i++ ] = static_cast( itN->next() ); ASSERT( i == 3 ); aNodes[ 3 ] = aNodes[ 0 ]; // fill maps - for ( i = 0; i < 3; i++ ) - { - long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] ); + for ( i = 0; i < 3; i++ ) { + //long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] ); + NLink link(( aNodes[i] < aNodes[i+1] ? aNodes[i] : aNodes[i+1] ), + ( aNodes[i] < aNodes[i+1] ? aNodes[i+1] : aNodes[i] )); // check if elements sharing a link can be fused - itLE = mapLi_listEl.find( linkID ); - if ( itLE != mapLi_listEl.end() ) - { + //itLE = mapLi_listEl.find( linkID ); + itLE = mapLi_listEl.find( link ); + if ( itLE != mapLi_listEl.end() ) { if ((*itLE).second.size() > 1 ) // consider only 2 elems adjacent by a link continue; const SMDS_MeshElement* elem2 = (*itLE).second.front(); -// if ( FindShape( elem ) != FindShape( elem2 )) -// continue; // do not fuse triangles laying on different shapes + //if ( FindShape( elem ) != FindShape( elem2 )) + // continue; // do not fuse triangles laying on different shapes if ( getAngle( elem, elem2, aNodes[i], aNodes[i+1] ) > theMaxAngle ) continue; // avoid making badly shaped quads (*itLE).second.push_back( elem ); } - else - mapLi_listEl[ linkID ].push_back( elem ); - mapEl_setLi [ elem ].insert( linkID ); + else { + //mapLi_listEl[ linkID ].push_back( elem ); + mapLi_listEl[ link ].push_back( elem ); + } + //mapEl_setLi [ elem ].insert( linkID ); + mapEl_setLi [ elem ].insert( link ); } } // Clean the maps from the links shared by a sole element, ie // links to which only one element is bound in mapLi_listEl - for ( itLE = mapLi_listEl.begin(); itLE != mapLi_listEl.end(); itLE++ ) - { + for ( itLE = mapLi_listEl.begin(); itLE != mapLi_listEl.end(); itLE++ ) { int nbElems = (*itLE).second.size(); if ( nbElems < 2 ) { const SMDS_MeshElement* elem = (*itLE).second.front(); - long link = (*itLE).first; + //long link = (*itLE).first; + NLink link = (*itLE).first; mapEl_setLi[ elem ].erase( link ); if ( mapEl_setLi[ elem ].empty() ) mapEl_setLi.erase( elem ); @@ -904,18 +1261,15 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, // Algo: fuse triangles into quadrangles - while ( ! mapEl_setLi.empty() ) - { + while ( ! mapEl_setLi.empty() ) { // Look for the start element: // the element having the least nb of shared links const SMDS_MeshElement* startElem = 0; int minNbLinks = 4; - for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ ) - { + for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ ) { int nbLinks = (*itEL).second.size(); - if ( nbLinks < minNbLinks ) - { + if ( nbLinks < minNbLinks ) { startElem = (*itEL).first; minNbLinks = nbLinks; if ( minNbLinks == 1 ) @@ -925,17 +1279,16 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, // search elements to fuse starting from startElem or links of elements // fused earlyer - startLinks - list< long > startLinks; - while ( startElem || !startLinks.empty() ) - { - while ( !startElem && !startLinks.empty() ) - { + //list< long > startLinks; + list< NLink > startLinks; + while ( startElem || !startLinks.empty() ) { + while ( !startElem && !startLinks.empty() ) { // Get an element to start, by a link - long linkId = startLinks.front(); + //long linkId = startLinks.front(); + NLink linkId = startLinks.front(); startLinks.pop_front(); itLE = mapLi_listEl.find( linkId ); - if ( itLE != mapLi_listEl.end() ) - { + if ( itLE != mapLi_listEl.end() ) { list< const SMDS_MeshElement* > & listElem = (*itLE).second; list< const SMDS_MeshElement* >::iterator itE = listElem.begin(); for ( ; itE != listElem.end() ; itE++ ) @@ -945,69 +1298,83 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, } } - if ( startElem ) - { + if ( startElem ) { // Get candidates to be fused - const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0; - long link12, link13; + //long link12, link13; + NLink link12, link13; startElem = 0; ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() ); - set< long >& setLi = mapEl_setLi[ tr1 ]; + //set< long >& setLi = mapEl_setLi[ tr1 ]; + set< NLink >& setLi = mapEl_setLi[ tr1 ]; ASSERT( !setLi.empty() ); - set< long >::iterator itLi; - for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) - { - long linkID = (*itLi); + //set< long >::iterator itLi; + set< NLink >::iterator itLi; + for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) { + //long linkID = (*itLi); + NLink linkID = (*itLi); itLE = mapLi_listEl.find( linkID ); if ( itLE == mapLi_listEl.end() ) continue; + const SMDS_MeshElement* elem = (*itLE).second.front(); if ( elem == tr1 ) elem = (*itLE).second.back(); mapLi_listEl.erase( itLE ); if ( mapEl_setLi.find( elem ) == mapEl_setLi.end()) continue; - if ( tr2 ) - { + if ( tr2 ) { tr3 = elem; link13 = linkID; } - else - { + else { tr2 = elem; link12 = linkID; } // add other links of elem to list of links to re-start from - set< long >& links = mapEl_setLi[ elem ]; - set< long >::iterator it; - for ( it = links.begin(); it != links.end(); it++ ) - { - long linkID2 = (*it); + //set< long >& links = mapEl_setLi[ elem ]; + //set< long >::iterator it; + set< NLink >& links = mapEl_setLi[ elem ]; + set< NLink >::iterator it; + for ( it = links.begin(); it != links.end(); it++ ) { + //long linkID2 = (*it); + NLink linkID2 = (*it); if ( linkID2 != linkID ) startLinks.push_back( linkID2 ); } } // Get nodes of possible quadrangles - const SMDS_MeshNode *n12 [4], *n13 [4]; bool Ok12 = false, Ok13 = false; + //const SMDS_MeshNode *linkNode1, *linkNode2; const SMDS_MeshNode *linkNode1, *linkNode2; - if ( tr2 && - aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) && - getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 )) - Ok12 = true; - if ( tr3 && - aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) && - getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 )) - Ok13 = true; + if(tr2) { + //const SMDS_MeshNode *linkNode1 = link12.first; + //const SMDS_MeshNode *linkNode2 = link12.second; + linkNode1 = link12.first; + linkNode2 = link12.second; + //if ( tr2 && + // aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) && + // getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 )) + // Ok12 = true; + if ( tr2 && getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 )) + Ok12 = true; + } + if(tr3) { + linkNode1 = link13.first; + linkNode2 = link13.second; + //if ( tr3 && + // aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) && + // getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 )) + // Ok13 = true; + if ( tr3 && getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 )) + Ok13 = true; + } // Choose a pair to fuse - - if ( Ok12 && Ok13 ) - { + if ( Ok12 && Ok13 ) { SMDS_FaceOfNodes quad12 ( n12[ 0 ], n12[ 1 ], n12[ 2 ], n12[ 3 ] ); SMDS_FaceOfNodes quad13 ( n13[ 0 ], n13[ 1 ], n13[ 2 ], n13[ 3 ] ); double aBadRate12 = getBadRate( &quad12, theCrit ); @@ -1018,24 +1385,66 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, Ok13 = false; } - // Make quadrangles // and remove fused elems and removed links from the maps - mapEl_setLi.erase( tr1 ); - if ( Ok12 ) - { + if ( Ok12 ) { mapEl_setLi.erase( tr2 ); mapLi_listEl.erase( link12 ); - aMesh->ChangeElementNodes( tr1, n12, 4 ); - aMesh->RemoveElement( tr2 ); + if(tr1->NbNodes()==3) { + aMesh->ChangeElementNodes( tr1, n12, 4 ); + aMesh->RemoveElement( tr2 ); + } + else { + const SMDS_MeshNode* N1 [6]; + const SMDS_MeshNode* N2 [6]; + GetNodesFromTwoTria(tr1,tr2,N1,N2); + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + const SMDS_MeshNode* aNodes[8]; + aNodes[0] = N1[0]; + aNodes[1] = N1[1]; + aNodes[2] = N2[0]; + aNodes[3] = N2[1]; + aNodes[4] = N1[3]; + aNodes[5] = N2[5]; + aNodes[6] = N2[3]; + aNodes[7] = N1[5]; + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); + GetMeshDS()->RemoveElement( tr2 ); + // remove middle node (9) + GetMeshDS()->RemoveNode( N1[4] ); + } } - else if ( Ok13 ) - { + else if ( Ok13 ) { mapEl_setLi.erase( tr3 ); mapLi_listEl.erase( link13 ); - aMesh->ChangeElementNodes( tr1, n13, 4 ); - aMesh->RemoveElement( tr3 ); + if(tr1->NbNodes()==3) { + aMesh->ChangeElementNodes( tr1, n13, 4 ); + aMesh->RemoveElement( tr3 ); + } + else { + const SMDS_MeshNode* N1 [6]; + const SMDS_MeshNode* N2 [6]; + GetNodesFromTwoTria(tr1,tr3,N1,N2); + // now we receive following N1 and N2 (using numeration as above image) + // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6) + // i.e. first nodes from both arrays determ new diagonal + const SMDS_MeshNode* aNodes[8]; + aNodes[0] = N1[0]; + aNodes[1] = N1[1]; + aNodes[2] = N2[0]; + aNodes[3] = N2[1]; + aNodes[4] = N1[3]; + aNodes[5] = N2[5]; + aNodes[6] = N2[3]; + aNodes[7] = N1[5]; + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); + GetMeshDS()->RemoveElement( tr3 ); + // remove middle node (9) + GetMeshDS()->RemoveNode( N1[4] ); + } } // Next element to fuse: the rejected one @@ -1349,22 +1758,23 @@ void laplacianSmooth(const SMDS_MeshNode* theNode, if ( elem->GetType() != SMDSAbs_Face ) continue; - // put all nodes in array - int nbNodes = 0, iNode = 0; - vector< const SMDS_MeshNode*> aNodes( elem->NbNodes() ); - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { - aNodes[ nbNodes ] = static_cast( itN->next() ); - if ( aNodes[ nbNodes ] == theNode ) - iNode = nbNodes; // index of theNode within aNodes - nbNodes++; + for ( int i = 0; i < elem->NbNodes(); ++i ) { + if ( elem->GetNode( i ) == theNode ) { + // add linked nodes + int iBefore = i - 1; + int iAfter = i + 1; + if ( elem->IsQuadratic() ) { + int nbCorners = elem->NbNodes() / 2; + if ( iAfter >= nbCorners ) + iAfter = 0; // elem->GetNode() wraps index + if ( iBefore == -1 ) + iBefore = nbCorners - 1; + } + nodeSet.insert( elem->GetNode( iAfter )); + nodeSet.insert( elem->GetNode( iBefore )); + break; + } } - // add linked nodes - int iAfter = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1; - nodeSet.insert( aNodes[ iAfter ]); - int iBefore = ( iNode == 0 ) ? nbNodes - 1 : iNode - 1; - nodeSet.insert( aNodes[ iBefore ]); } // compute new coodrs @@ -1435,9 +1845,13 @@ void centroidalSmooth(const SMDS_MeshNode* theNode, gp_XYZ elemCenter(0.,0.,0.); SMESH::Controls::TSequenceOfXYZ aNodePoints; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { + int nn = elem->NbNodes(); + if(elem->IsQuadratic()) nn = nn/2; + int i=0; + //while ( itN->more() ) { + while ( i( itN->next() ); + i++; gp_XYZ aP( aNode->X(), aNode->Y(), aNode->Z() ); aNodePoints.push_back( aP ); if ( !theSurface.IsNull() ) { // smooth in 2D @@ -1449,12 +1863,11 @@ void centroidalSmooth(const SMDS_MeshNode* theNode, } double elemArea = anAreaFunc.GetValue( aNodePoints ); totalArea += elemArea; - elemCenter /= elem->NbNodes(); + elemCenter /= nn; aNewXYZ += elemCenter * elemArea; } aNewXYZ /= totalArea; if ( !theSurface.IsNull() ) { - ASSERT( theUVMap.find( theNode ) != theUVMap.end() ); theUVMap[ theNode ]->SetCoord( aNewXYZ.X(), aNewXYZ.Y() ); aNewXYZ = theSurface->Value( aNewXYZ.X(), aNewXYZ.Y() ).XYZ(); } @@ -1509,6 +1922,8 @@ void SMESH_MeshEditor::Smooth (set & theElems, if ( theTgtAspectRatio < 1.0 ) theTgtAspectRatio = 1.0; + const double disttol = 1.e-16; + SMESH::Controls::AspectRatio aQualityFunc; SMESHDS_Mesh* aMesh = GetMeshDS(); @@ -1541,8 +1956,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, // =============================================== set< int >::reverse_iterator fId = faceIdSet.rbegin(); // treate 0 fId at the end - for ( ; fId != faceIdSet.rend(); ++fId ) - { + for ( ; fId != faceIdSet.rend(); ++fId ) { // get face surface and submesh Handle(Geom_Surface) surface; SMESHDS_SubMesh* faceSubMesh = 0; @@ -1569,6 +1983,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, // compute UV for them // --------------------------------------------------------- bool checkBoundaryNodes = false; + bool isQuadratic = false; set setMovableNodes; map< const SMDS_MeshNode*, gp_XY* > uvMap, uvMap2; list< gp_XY > listUV; // uvs the 2 uvMaps refer to @@ -1583,8 +1998,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, int nbElemOnFace = 0; itElem = theElems.begin(); // loop on not yet smoothed elements: look for elems on a face - while ( itElem != theElems.end() ) - { + while ( itElem != theElems.end() ) { if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() ) break; // all elements found @@ -1598,11 +2012,17 @@ void SMESH_MeshEditor::Smooth (set & theElems, theElems.erase( itElem++ ); nbElemOnFace++; + if ( !isQuadratic ) + isQuadratic = elem->IsQuadratic(); + // get movable nodes of elem const SMDS_MeshNode* node; SMDS_TypeOfPosition posType; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) { + int nn = 0, nbn = elem->NbNodes(); + if(elem->IsQuadratic()) + nbn = nbn/2; + while ( nn++ < nbn ) { node = static_cast( itN->next() ); const SMDS_PositionPtr& pos = node->GetPosition(); posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; @@ -1636,7 +2056,10 @@ void SMESH_MeshEditor::Smooth (set & theElems, // get nodes to check UV list< const SMDS_MeshNode* > uvCheckNodes; itN = elem->nodesIterator(); - while ( itN->more() ) { + nn = 0; nbn = elem->NbNodes(); + if(elem->IsQuadratic()) + nbn = nbn/2; + while ( nn++ < nbn ) { node = static_cast( itN->next() ); if ( uvMap.find( node ) == uvMap.end() ) uvCheckNodes.push_back( node ); @@ -1657,8 +2080,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, } // check UV on face list< const SMDS_MeshNode* >::iterator n = uvCheckNodes.begin(); - for ( ; n != uvCheckNodes.end(); ++n ) - { + for ( ; n != uvCheckNodes.end(); ++n ) { node = *n; gp_XY uv( 0, 0 ); const SMDS_PositionPtr& pos = node->GetPosition(); @@ -1725,29 +2147,25 @@ void SMESH_MeshEditor::Smooth (set & theElems, // fix nodes on mesh boundary - if ( checkBoundaryNodes ) - { + if ( checkBoundaryNodes ) { typedef pair TLink; map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace map< TLink, int >::iterator link_nb; // put all elements links to linkNbMap list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); - for ( ; elemIt != elemsOnFace.end(); ++elemIt ) - { - // put elem nodes in array - vector< const SMDS_MeshNode* > nodes; - nodes.reserve( (*elemIt)->NbNodes() + 1 ); - SMDS_ElemIteratorPtr itN = (*elemIt)->nodesIterator(); - while ( itN->more() ) - nodes.push_back( static_cast( itN->next() )); - nodes.push_back( nodes.front() ); + for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { + const SMDS_MeshElement* elem = (*elemIt); + int nbn = elem->NbNodes(); + if(elem->IsQuadratic()) + nbn = nbn/2; // loop on elem links: insert them in linkNbMap - for ( int iN = 1; iN < nodes.size(); ++iN ) { + const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn ); + for ( int iN = 0; iN < nbn; ++iN ) { + curNode = elem->GetNode( iN ); TLink link; - if ( nodes[ iN-1 ]->GetID() < nodes[ iN ]->GetID() ) - link = make_pair( nodes[ iN-1 ], nodes[ iN ] ); - else - link = make_pair( nodes[ iN ], nodes[ iN-1 ] ); + if ( curNode < prevNode ) link = make_pair( curNode , prevNode ); + else link = make_pair( prevNode , curNode ); + prevNode = curNode; link_nb = linkNbMap.find( link ); if ( link_nb == linkNbMap.end() ) linkNbMap.insert( make_pair ( link, 1 )); @@ -1771,11 +2189,9 @@ void SMESH_MeshEditor::Smooth (set & theElems, // ----------------------------------------------------- set nodesNearSeam; // to smooth using uvMap2 - if ( !surface.IsNull() ) - { + if ( !surface.IsNull() ) { TopExp_Explorer eExp( face, TopAbs_EDGE ); - for ( ; eExp.More(); eExp.Next() ) - { + for ( ; eExp.More(); eExp.Next() ) { TopoDS_Edge edge = TopoDS::Edge( eExp.Current() ); if ( !BRep_Tool::IsClosed( edge, face )) continue; @@ -1799,8 +2215,11 @@ void SMESH_MeshEditor::Smooth (set & theElems, // get nodes on seam and its vertices list< const SMDS_MeshNode* > seamNodes; SMDS_NodeIteratorPtr nSeamIt = sm->GetNodes(); - while ( nSeamIt->more() ) - seamNodes.push_back( nSeamIt->next() ); + while ( nSeamIt->more() ) { + const SMDS_MeshNode* node = nSeamIt->next(); + if ( !isQuadratic || !IsMedium( node )) + seamNodes.push_back( node ); + } TopExp_Explorer vExp( edge, TopAbs_VERTEX ); for ( ; vExp.More(); vExp.Next() ) { sm = aMesh->MeshElements( vExp.Current() ); @@ -1812,8 +2231,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, } // loop on nodes on seam list< const SMDS_MeshNode* >::iterator noSeIt = seamNodes.begin(); - for ( ; noSeIt != seamNodes.end(); ++noSeIt ) - { + for ( ; noSeIt != seamNodes.end(); ++noSeIt ) { const SMDS_MeshNode* nSeam = *noSeIt; map< const SMDS_MeshNode*, gp_XY* >::iterator n_uv = uvMap.find( nSeam ); if ( n_uv == uvMap.end() ) @@ -1829,14 +2247,15 @@ void SMESH_MeshEditor::Smooth (set & theElems, // collect movable nodes linked to ones on seam in nodesNearSeam SMDS_ElemIteratorPtr eIt = nSeam->GetInverseElementIterator(); - while ( eIt->more() ) - { + while ( eIt->more() ) { const SMDS_MeshElement* e = eIt->next(); if ( e->GetType() != SMDSAbs_Face ) continue; int nbUseMap1 = 0, nbUseMap2 = 0; SMDS_ElemIteratorPtr nIt = e->nodesIterator(); - while ( nIt->more() ) + int nn = 0, nbn = e->NbNodes(); + if(e->IsQuadratic()) nbn = nbn/2; + while ( nn++ < nbn ) { const SMDS_MeshNode* n = static_cast( nIt->next() ); @@ -1858,10 +2277,10 @@ void SMESH_MeshEditor::Smooth (set & theElems, } // for centroidalSmooth all element nodes must // be on one side of a seam - if ( theSmoothMethod == CENTROIDAL && nbUseMap1 && nbUseMap2 ) - { + if ( theSmoothMethod == CENTROIDAL && nbUseMap1 && nbUseMap2 ) { SMDS_ElemIteratorPtr nIt = e->nodesIterator(); - while ( nIt->more() ) { + nn = 0; + while ( nn++ < nbn ) { const SMDS_MeshNode* n = static_cast( nIt->next() ); setMovableNodes.erase( n ); @@ -1884,12 +2303,10 @@ void SMESH_MeshEditor::Smooth (set & theElems, int it = -1; double maxRatio = -1., maxDisplacement = -1.; set::iterator nodeToMove; - for ( it = 0; it < theNbIterations; it++ ) - { + for ( it = 0; it < theNbIterations; it++ ) { maxDisplacement = 0.; nodeToMove = setMovableNodes.begin(); - for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) - { + for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) { const SMDS_MeshNode* node = (*nodeToMove); gp_XYZ aPrevPos ( node->X(), node->Y(), node->Z() ); @@ -1907,7 +2324,8 @@ void SMESH_MeshEditor::Smooth (set & theElems, maxDisplacement = aDispl; } // no node movement => exit - if ( maxDisplacement < 1.e-16 ) { + //if ( maxDisplacement < 1.e-16 ) { + if ( maxDisplacement < disttol ) { MESSAGE("-- no node movement --"); break; } @@ -1915,8 +2333,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, // check elements quality maxRatio = 0; list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); - for ( ; elemIt != elemsOnFace.end(); ++elemIt ) - { + for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { const SMDS_MeshElement* elem = (*elemIt); if ( !elem || elem->GetType() != SMDSAbs_Face ) continue; @@ -1945,10 +2362,8 @@ void SMESH_MeshEditor::Smooth (set & theElems, // new nodes positions are computed, // record movement in DS and set new UV // --------------------------------------- - nodeToMove = setMovableNodes.begin(); - for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) - { + for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) { SMDS_MeshNode* node = const_cast< SMDS_MeshNode* > (*nodeToMove); aMesh->MoveNode( node, node->X(), node->Y(), node->Z() ); map< const SMDS_MeshNode*, gp_XY* >::iterator node_uv = uvMap.find( node ); @@ -1959,7 +2374,37 @@ void SMESH_MeshEditor::Smooth (set & theElems, } } + // move medium nodes of quadratic elements + if ( isQuadratic ) + { + list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); + for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { + const SMDS_QuadraticFaceOfNodes* QF = + dynamic_cast (*elemIt); + if(QF) { + vector Ns; + Ns.reserve(QF->NbNodes()+1); + SMDS_NodeIteratorPtr anIter = QF->interlacedNodesIterator(); + while ( anIter->more() ) + Ns.push_back( anIter->next() ); + Ns.push_back( Ns[0] ); + for(int i=0; iNbNodes(); i=i+2) { + double x = (Ns[i]->X() + Ns[i+2]->X())/2; + double y = (Ns[i]->Y() + Ns[i+2]->Y())/2; + double z = (Ns[i]->Z() + Ns[i+2]->Z())/2; + if( fabs( Ns[i+1]->X() - x ) > disttol || + fabs( Ns[i+1]->Y() - y ) > disttol || + fabs( Ns[i+1]->Z() - z ) > disttol ) { + // we have to move i+1 node + aMesh->MoveNode( Ns[i+1], x, y, z ); + } + } + } + } + } + } // loop on face ids + } //======================================================================= @@ -2000,38 +2445,57 @@ static bool isReverse(const SMDS_MeshNode* prevNodes[], static void sweepElement(SMESHDS_Mesh* aMesh, const SMDS_MeshElement* elem, const vector & newNodesItVec, - list& newElems) + list& newElems, + const int nbSteps) { // Loop on elem nodes: // find new nodes and detect same nodes indices int nbNodes = elem->NbNodes(); list::const_iterator itNN[ nbNodes ]; - const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ]; + const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ], *midlNod[ nbNodes ]; int iNode, nbSame = 0, iNotSameNode = 0, iSameNode = 0; + vector sames(nbNodes); - for ( iNode = 0; iNode < nbNodes; iNode++ ) - { + bool issimple[nbNodes]; + + for ( iNode = 0; iNode < nbNodes; iNode++ ) { TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ]; const SMDS_MeshNode* node = nnIt->first; const list< const SMDS_MeshNode* > & listNewNodes = nnIt->second; if ( listNewNodes.empty() ) return; + if(listNewNodes.size()==nbSteps) { + issimple[iNode] = true; + } + else { + issimple[iNode] = false; + } + itNN[ iNode ] = listNewNodes.begin(); prevNod[ iNode ] = node; nextNod[ iNode ] = listNewNodes.front(); +//cout<<"iNode="<GetID() ); return; } +// if( elem->IsQuadratic() && nbSame>0 ) { +// MESSAGE( "Can not rotate quadratic element " << elem->GetID() ); +// return; +// } + int iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0; if ( nbSame > 0 ) { iBeforeSame = ( iSameNode == 0 ? nbNodes - 1 : iSameNode - 1 ); @@ -2039,6 +2503,12 @@ static void sweepElement(SMESHDS_Mesh* aMesh, iOpposSame = ( iSameNode - 2 < 0 ? iSameNode + 2 : iSameNode - 2 ); } +//if(nbNodes==8) +//cout<<" prevNod[0]="<< prevNod[0]<<" prevNod[1]="<< prevNod[1] +// <<" prevNod[2]="<< prevNod[2]<<" prevNod[3]="<< prevNod[4] +// <<" prevNod[4]="<< prevNod[4]<<" prevNod[5]="<< prevNod[5] +// <<" prevNod[6]="<< prevNod[6]<<" prevNod[7]="<< prevNod[7]< 2 && !isReverse( prevNod, nextNod, nbNodes, iNotSameNode )) { @@ -2053,82 +2523,195 @@ static void sweepElement(SMESHDS_Mesh* aMesh, } // make new elements - int iStep, nbSteps = newNodesItVec[ 0 ]->second.size(); - for (iStep = 0; iStep < nbSteps; iStep++ ) - { + int iStep;//, nbSteps = newNodesItVec[ 0 ]->second.size(); + for (iStep = 0; iStep < nbSteps; iStep++ ) { // get next nodes for ( iNode = 0; iNode < nbNodes; iNode++ ) { - nextNod[ iNode ] = *itNN[ iNode ]; - itNN[ iNode ]++; + if(issimple[iNode]) { + nextNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + } + else { + if( elem->GetType()==SMDSAbs_Node ) { + // we have to use two nodes + midlNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + nextNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + } + else if(!elem->IsQuadratic() || + elem->IsQuadratic() && elem->IsMediumNode(prevNod[iNode]) ) { + // we have to use each second node + itNN[ iNode ]++; + nextNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + } + else { + // we have to use two nodes + midlNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + nextNod[ iNode ] = *itNN[ iNode ]; + itNN[ iNode ]++; + } + } } SMDS_MeshElement* aNewElem = 0; - switch ( nbNodes ) - { - case 0: - return; - case 1: { // NODE - if ( nbSame == 0 ) - aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] ); - break; - } - case 2: { // EDGE - - if ( nbSame == 0 ) - aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], - nextNod[ 1 ], nextNod[ 0 ] ); - else - aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], - nextNod[ iNotSameNode ] ); - break; - } - case 3: { // TRIANGLE - - if ( nbSame == 0 ) // --- pentahedron - aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], - nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] ); + if(!elem->IsPoly()) { + switch ( nbNodes ) { + case 0: + return; + case 1: { // NODE + if ( nbSame == 0 ) { + if(issimple[0]) + aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] ); + else + aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ], midlNod[ 0 ] ); + } + break; + } + case 2: { // EDGE + if ( nbSame == 0 ) + aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], + nextNod[ 1 ], nextNod[ 0 ] ); + else + aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], + nextNod[ iNotSameNode ] ); + break; + } - else if ( nbSame == 1 ) // --- pyramid - aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], - nextNod[ iAfterSame ], nextNod[ iBeforeSame ], - nextNod[ iSameNode ]); + case 3: { // TRIANGLE or quadratic edge + if(elem->GetType() == SMDSAbs_Face) { // TRIANGLE - else // 2 same nodes: --- tetrahedron - aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], - nextNod[ iNotSameNode ]); - break; - } - case 4: { // QUADRANGLE + if ( nbSame == 0 ) // --- pentahedron + aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], + nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] ); - if ( nbSame == 0 ) // --- hexahedron - aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ], - nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]); + else if ( nbSame == 1 ) // --- pyramid + aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], + nextNod[ iAfterSame ], nextNod[ iBeforeSame ], + nextNod[ iSameNode ]); - else if ( nbSame == 1 ) // --- pyramid + pentahedron - { - aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], - nextNod[ iAfterSame ], nextNod[ iBeforeSame ], - nextNod[ iSameNode ]); - newElems.push_back( aNewElem ); - aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ], - prevNod[ iBeforeSame ], nextNod[ iAfterSame ], - nextNod[ iOpposSame ], nextNod[ iBeforeSame ] ); - } - else if ( nbSame == 2 ) // pentahedron - { - if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] ) - // iBeforeSame is same too - aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ], - nextNod[ iOpposSame ], prevNod[ iSameNode ], - prevNod[ iAfterSame ], nextNod[ iAfterSame ]); - else - // iAfterSame is same too - aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ], - nextNod[ iBeforeSame ], prevNod[ iAfterSame ], - prevNod[ iOpposSame ], nextNod[ iOpposSame ]); + else // 2 same nodes: --- tetrahedron + aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], + nextNod[ iNotSameNode ]); + } + else { // quadratic edge + if(nbSame==0) { // quadratic quadrangle + aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], nextNod[1], prevNod[1], + midlNod[0], nextNod[2], midlNod[1], prevNod[2]); + } + else if(nbSame==1) { // quadratic triangle + if(sames[0]==2) + return; // medium node on axis + else if(sames[0]==0) { + aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1], + nextNod[2], midlNod[1], prevNod[2]); + } + else { // sames[0]==1 + aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1], + midlNod[0], nextNod[2], prevNod[2]); + } + } + else + return; + } + break; + } + case 4: { // QUADRANGLE + + if ( nbSame == 0 ) // --- hexahedron + aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ], + nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]); + + else if ( nbSame == 1 ) { // --- pyramid + pentahedron + aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], + nextNod[ iAfterSame ], nextNod[ iBeforeSame ], + nextNod[ iSameNode ]); + newElems.push_back( aNewElem ); + aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ], + prevNod[ iBeforeSame ], nextNod[ iAfterSame ], + nextNod[ iOpposSame ], nextNod[ iBeforeSame ] ); + } + else if ( nbSame == 2 ) { // pentahedron + if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] ) + // iBeforeSame is same too + aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ], + nextNod[ iOpposSame ], prevNod[ iSameNode ], + prevNod[ iAfterSame ], nextNod[ iAfterSame ]); + else + // iAfterSame is same too + aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ], + nextNod[ iBeforeSame ], prevNod[ iAfterSame ], + prevNod[ iOpposSame ], nextNod[ iOpposSame ]); + } + break; + } + case 6: { // quadratic triangle + // create pentahedron with 15 nodes + if(i0>0) { // reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1], + nextNod[0], nextNod[2], nextNod[1], + prevNod[5], prevNod[4], prevNod[3], + nextNod[5], nextNod[4], nextNod[3], + midlNod[0], midlNod[2], midlNod[1]); + } + else { // not reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], + nextNod[0], nextNod[1], nextNod[2], + prevNod[3], prevNod[4], prevNod[5], + nextNod[3], nextNod[4], nextNod[5], + midlNod[0], midlNod[1], midlNod[2]); + } + break; + } + case 8: { // quadratic quadrangle + // create hexahedron with 20 nodes + if(i0>0) { // reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1], + nextNod[0], nextNod[3], nextNod[2], nextNod[1], + prevNod[7], prevNod[6], prevNod[5], prevNod[4], + nextNod[7], nextNod[6], nextNod[5], nextNod[4], + midlNod[0], midlNod[3], midlNod[2], midlNod[1]); + } + else { // not reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3], + nextNod[0], nextNod[1], nextNod[2], nextNod[3], + prevNod[4], prevNod[5], prevNod[6], prevNod[7], + nextNod[4], nextNod[5], nextNod[6], nextNod[7], + midlNod[0], midlNod[1], midlNod[2], midlNod[3]); + } + break; + } + default: { + // realized for extrusion only + //vector polyedre_nodes (nbNodes*2 + 4*nbNodes); + //vector quantities (nbNodes + 2); + + //quantities[0] = nbNodes; // bottom of prism + //for (int inode = 0; inode < nbNodes; inode++) { + // polyedre_nodes[inode] = prevNod[inode]; + //} + + //quantities[1] = nbNodes; // top of prism + //for (int inode = 0; inode < nbNodes; inode++) { + // polyedre_nodes[nbNodes + inode] = nextNod[inode]; + //} + + //for (int iface = 0; iface < nbNodes; iface++) { + // quantities[iface + 2] = 4; + // int inextface = (iface == nbNodes - 1) ? 0 : iface + 1; + // polyedre_nodes[2*nbNodes + 4*iface + 0] = prevNod[iface]; + // polyedre_nodes[2*nbNodes + 4*iface + 1] = prevNod[inextface]; + // polyedre_nodes[2*nbNodes + 4*iface + 2] = nextNod[inextface]; + // polyedre_nodes[2*nbNodes + 4*iface + 3] = nextNod[iface]; + //} + //aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities); + break; + } } - break; } - default: { + + if(!aNewElem) { // realized for extrusion only vector polyedre_nodes (nbNodes*2 + 4*nbNodes); vector quantities (nbNodes + 2); @@ -2153,9 +2736,10 @@ static void sweepElement(SMESHDS_Mesh* aMesh, } aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities); } - } - if ( aNewElem ) + + if ( aNewElem ) { newElems.push_back( aNewElem ); + } // set new prev nodes for ( iNode = 0; iNode < nbNodes; iNode++ ) @@ -2173,26 +2757,33 @@ static void makeWalls (SMESHDS_Mesh* aMesh, TNodeOfNodeListMap & mapNewNodes, TElemOfElemListMap & newElemsMap, TElemOfVecOfNnlmiMap & elemNewNodesMap, - set& elemSet) + set& elemSet, + const int nbSteps) { ASSERT( newElemsMap.size() == elemNewNodesMap.size() ); // Find nodes belonging to only one initial element - sweep them to get edges. TNodeOfNodeListMapItr nList = mapNewNodes.begin(); - for ( ; nList != mapNewNodes.end(); nList++ ) - { + for ( ; nList != mapNewNodes.end(); nList++ ) { const SMDS_MeshNode* node = static_cast( nList->first ); SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(); int nbInitElems = 0; - while ( eIt->more() && nbInitElems < 2 ) - if ( elemSet.find( eIt->next() ) != elemSet.end() ) + const SMDS_MeshElement* el; + while ( eIt->more() && nbInitElems < 2 ) { + el = eIt->next(); + //if ( elemSet.find( eIt->next() ) != elemSet.end() ) + if ( elemSet.find(el) != elemSet.end() ) nbInitElems++; + } if ( nbInitElems < 2 ) { - vector newNodesItVec( 1, nList ); - list newEdges; - sweepElement( aMesh, node, newNodesItVec, newEdges ); + bool NotCreateEdge = el->IsQuadratic() && el->IsMediumNode(node); + if(!NotCreateEdge) { + vector newNodesItVec( 1, nList ); + list newEdges; + sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps ); + } } } @@ -2201,16 +2792,22 @@ static void makeWalls (SMESHDS_Mesh* aMesh, TElemOfElemListMap::iterator itElem = newElemsMap.begin(); TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin(); - for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ ) - { + for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ ) { const SMDS_MeshElement* elem = itElem->first; vector& vecNewNodes = itElemNodes->second; - if ( elem->GetType() == SMDSAbs_Edge ) - { - // create a ceiling edge - aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), - vecNewNodes[ 1 ]->second.back() ); + if ( elem->GetType() == SMDSAbs_Edge ) { + if(!elem->IsQuadratic()) { + // create a ceiling edge + aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), + vecNewNodes[ 1 ]->second.back() ); + } + else { + // create a ceiling edge + aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), + vecNewNodes[ 1 ]->second.back(), + vecNewNodes[ 2 ]->second.back()); + } } if ( elem->GetType() != SMDSAbs_Face ) continue; @@ -2220,43 +2817,72 @@ static void makeWalls (SMESHDS_Mesh* aMesh, set avoidSet; avoidSet.insert( elem ); - // loop on a face nodes set aFaceLastNodes; int iNode, nbNodes = vecNewNodes.size(); - for ( iNode = 0; iNode < nbNodes; iNode++ ) - { - aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); - // look for free links of a face - int iNext = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1; - const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first; - const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first; - // check if a link is free - if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) - { - hasFreeLinks = true; - // make an edge and a ceiling for a new edge - if ( !aMesh->FindEdge( n1, n2 )) - aMesh->AddEdge( n1, n2 ); - n1 = vecNewNodes[ iNode ]->second.back(); - n2 = vecNewNodes[ iNext ]->second.back(); - if ( !aMesh->FindEdge( n1, n2 )) - aMesh->AddEdge( n1, n2 ); + if(!elem->IsQuadratic()) { + // loop on a face nodes + for ( iNode = 0; iNode < nbNodes; iNode++ ) { + aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); + // look for free links of a face + int iNext = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1; + const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first; + const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first; + // check if a link is free + if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) { + hasFreeLinks = true; + // make an edge and a ceiling for a new edge + if ( !aMesh->FindEdge( n1, n2 )) { + aMesh->AddEdge( n1, n2 ); + } + n1 = vecNewNodes[ iNode ]->second.back(); + n2 = vecNewNodes[ iNext ]->second.back(); + if ( !aMesh->FindEdge( n1, n2 )) { + aMesh->AddEdge( n1, n2 ); + } + } } } + else { // elem is quadratic face + int nbn = nbNodes/2; + for ( iNode = 0; iNode < nbn; iNode++ ) { + aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); + int iNext = ( iNode + 1 == nbn ) ? 0 : iNode + 1; + const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first; + const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first; + // check if a link is free + if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) { + hasFreeLinks = true; + // make an edge and a ceiling for a new edge + // find medium node + const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first; + if ( !aMesh->FindEdge( n1, n2, n3 )) { + aMesh->AddEdge( n1, n2, n3 ); + } + n1 = vecNewNodes[ iNode ]->second.back(); + n2 = vecNewNodes[ iNext ]->second.back(); + n3 = vecNewNodes[ iNode+nbn ]->second.back(); + if ( !aMesh->FindEdge( n1, n2, n3 )) { + aMesh->AddEdge( n1, n2, n3 ); + } + } + } + for ( iNode = nbn; iNode < 2*nbn; iNode++ ) { + aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); + } + } + // sweep free links into faces - if ( hasFreeLinks ) - { + if ( hasFreeLinks ) { list & newVolumes = itElem->second; - int iStep, nbSteps = vecNewNodes[0]->second.size(); + int iStep; //, nbSteps = vecNewNodes[0]->second.size(); int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps; set initNodeSet, faceNodeSet; for ( iNode = 0; iNode < nbNodes; iNode++ ) initNodeSet.insert( vecNewNodes[ iNode ]->first ); - for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) - { + for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) { list::iterator v = newVolumes.begin(); iVol = 0; while ( iVol++ < volNb ) v++; @@ -2264,36 +2890,50 @@ static void makeWalls (SMESHDS_Mesh* aMesh, list< int > fInd; SMDS_VolumeTool vTool( *v ); int iF, nbF = vTool.NbFaces(); - for ( iF = 0; iF < nbF; iF ++ ) + for ( iF = 0; iF < nbF; iF ++ ) { if (vTool.IsFreeFace( iF ) && vTool.GetFaceNodes( iF, faceNodeSet ) && initNodeSet != faceNodeSet) // except an initial face fInd.push_back( iF ); + } if ( fInd.empty() ) continue; // create faces for all steps - for ( iStep = 0; iStep < nbSteps; iStep++ ) - { + for ( iStep = 0; iStep < nbSteps; iStep++ ) { vTool.Set( *v ); vTool.SetExternalNormal(); list< int >::iterator ind = fInd.begin(); - for ( ; ind != fInd.end(); ind++ ) - { + for ( ; ind != fInd.end(); ind++ ) { const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind ); - switch ( vTool.NbFaceNodes( *ind ) ) { + int nbn = vTool.NbFaceNodes( *ind ); + //switch ( vTool.NbFaceNodes( *ind ) ) { + switch ( nbn ) { case 3: aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break; case 4: aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); break; default: { - int nbPolygonNodes = vTool.NbFaceNodes( *ind ); - vector polygon_nodes (nbPolygonNodes); - for (int inode = 0; inode < nbPolygonNodes; inode++) { - polygon_nodes[inode] = nodes[inode]; + if( (*v)->IsQuadratic() ) { + if(nbn==6) { + aMesh->AddFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5]); break; + } + else { + aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7]); + break; + } + } + else { + int nbPolygonNodes = vTool.NbFaceNodes( *ind ); + vector polygon_nodes (nbPolygonNodes); + for (int inode = 0; inode < nbPolygonNodes; inode++) { + polygon_nodes[inode] = nodes[inode]; + } + aMesh->AddPolygonalFace(polygon_nodes); } - aMesh->AddPolygonalFace(polygon_nodes); break; } } @@ -2308,12 +2948,13 @@ static void makeWalls (SMESHDS_Mesh* aMesh, // make a ceiling face with a normal external to a volume SMDS_VolumeTool lastVol( itElem->second.back() ); + int iF = lastVol.GetFaceIndex( aFaceLastNodes ); - if ( iF >= 0 ) - { + if ( iF >= 0 ) { lastVol.SetExternalNormal(); const SMDS_MeshNode** nodes = lastVol.GetFaceNodes( iF ); - switch ( lastVol.NbFaceNodes( iF ) ) { + int nbn = lastVol.NbFaceNodes( iF ); + switch ( nbn ) { case 3: if (!hasFreeLinks || !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ])) @@ -2326,18 +2967,36 @@ static void makeWalls (SMESHDS_Mesh* aMesh, break; default: { - int nbPolygonNodes = lastVol.NbFaceNodes( iF ); - vector polygon_nodes (nbPolygonNodes); - for (int inode = 0; inode < nbPolygonNodes; inode++) { - polygon_nodes[inode] = nodes[inode]; + if(itElem->second.back()->IsQuadratic()) { + if(nbn==6) { + if (!hasFreeLinks || + !aMesh->FindFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5]) ) { + aMesh->AddFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5]); break; + } + } + else { // nbn==8 + if (!hasFreeLinks || + !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7]) ) + aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7]); + } + } + else { + int nbPolygonNodes = lastVol.NbFaceNodes( iF ); + vector polygon_nodes (nbPolygonNodes); + for (int inode = 0; inode < nbPolygonNodes; inode++) { + polygon_nodes[inode] = nodes[inode]; + } + if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes)) + aMesh->AddPolygonalFace(polygon_nodes); } - if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes)) - aMesh->AddPolygonalFace(polygon_nodes); } break; } } - } // loop on swept elements } @@ -2355,6 +3014,8 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, MESSAGE( "RotationSweep()"); gp_Trsf aTrsf; aTrsf.SetRotation( theAxis, theAngle ); + gp_Trsf aTrsf2; + aTrsf2.SetRotation( theAxis, theAngle/2. ); gp_Lin aLine( theAxis ); double aSqTol = theTol * theTol; @@ -2367,8 +3028,7 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, // loop on theElems set< const SMDS_MeshElement* >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); if ( !elem ) continue; @@ -2383,8 +3043,7 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, const SMDS_MeshNode* node = static_cast( itN->next() ); TNodeOfNodeListMapItr nIt = mapNewNodes.find( node ); - if ( nIt == mapNewNodes.end() ) - { + if ( nIt == mapNewNodes.end() ) { nIt = mapNewNodes.insert( make_pair( node, list() )).first; list& listNewNodes = nIt->second; @@ -2396,19 +3055,53 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, const SMDS_MeshNode * newNode = node; for ( int i = 0; i < theNbSteps; i++ ) { if ( !isOnAxis ) { - aTrsf.Transforms( coord[0], coord[1], coord[2] ); + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + // create two nodes + aTrsf2.Transforms( coord[0], coord[1], coord[2] ); + //aTrsf.Transforms( coord[0], coord[1], coord[2] ); + newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + listNewNodes.push_back( newNode ); + aTrsf2.Transforms( coord[0], coord[1], coord[2] ); + //aTrsf.Transforms( coord[0], coord[1], coord[2] ); + } + else { + aTrsf.Transforms( coord[0], coord[1], coord[2] ); + } newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); } - listNewNodes.push_back( newNode ); + listNewNodes.push_back( newNode ); + } + } + else { + // if current elem is quadratic and current node is not medium + // we have to check - may be it is needed to insert additional nodes + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + list< const SMDS_MeshNode* > & listNewNodes = nIt->second; + if(listNewNodes.size()==theNbSteps) { + listNewNodes.clear(); + // make new nodes + gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); + double coord[3]; + aXYZ.Coord( coord[0], coord[1], coord[2] ); + const SMDS_MeshNode * newNode = node; + for(int i = 0; iAddNode( coord[0], coord[1], coord[2] ); + listNewNodes.push_back( newNode ); + aTrsf2.Transforms( coord[0], coord[1], coord[2] ); + newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + listNewNodes.push_back( newNode ); + } + } } } newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] ); + sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps ); } - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems ); + makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps ); } @@ -2493,19 +3186,23 @@ void SMESH_MeshEditor::ExtrusionSweep { SMESHDS_Mesh* aMesh = GetMeshDS(); + int nbsteps = theParams.mySteps->Length(); + TNodeOfNodeListMap mapNewNodes; + //TNodeOfNodeVecMap mapNewNodes; TElemOfVecOfNnlmiMap mapElemNewNodes; + //TElemOfVecOfMapNodesMap mapElemNewNodes; // loop on theElems set< const SMDS_MeshElement* >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { // check element type const SMDS_MeshElement* elem = (*itElem); if ( !elem ) continue; vector & newNodesItVec = mapElemNewNodes[ elem ]; + //vector & newNodesItVec = mapElemNewNodes[ elem ]; newNodesItVec.reserve( elem->NbNodes() ); // loop on elem nodes @@ -2516,15 +3213,33 @@ void SMESH_MeshEditor::ExtrusionSweep const SMDS_MeshNode* node = static_cast( itN->next() ); TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node ); - if ( nIt == mapNewNodes.end() ) - { + //TNodeOfNodeVecMap::iterator nIt = mapNewNodes.find( node ); + if ( nIt == mapNewNodes.end() ) { nIt = mapNewNodes.insert( make_pair( node, list() )).first; + //nIt = mapNewNodes.insert( make_pair( node, vector() )).first; list& listNewNodes = nIt->second; + //vector& vecNewNodes = nIt->second; + //vecNewNodes.reserve(nbsteps); // make new nodes double coord[] = { node->X(), node->Y(), node->Z() }; - int nbsteps = theParams.mySteps->Length(); + //int nbsteps = theParams.mySteps->Length(); for ( int i = 0; i < nbsteps; i++ ) { + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + // create additional node + double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1)/2.; + double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1)/2.; + double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1)/2.; + if( theFlags & EXTRUSION_FLAG_SEW ) { + const SMDS_MeshNode * newNode = CreateNode(x, y, z, + theTolerance, theParams.myNodes); + listNewNodes.push_back( newNode ); + } + else { + const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z); + listNewNodes.push_back( newNode ); + } + } //aTrsf.Transforms( coord[0], coord[1], coord[2] ); coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1); @@ -2533,20 +3248,59 @@ void SMESH_MeshEditor::ExtrusionSweep const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2], theTolerance, theParams.myNodes); listNewNodes.push_back( newNode ); + //vecNewNodes[i]=newNode; } else { const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); listNewNodes.push_back( newNode ); + //vecNewNodes[i]=newNode; + } + } + } + else { + // if current elem is quadratic and current node is not medium + // we have to check - may be it is needed to insert additional nodes + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + list< const SMDS_MeshNode* > & listNewNodes = nIt->second; + if(listNewNodes.size()==nbsteps) { + listNewNodes.clear(); + double coord[] = { node->X(), node->Y(), node->Z() }; + for ( int i = 0; i < nbsteps; i++ ) { + double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); + double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1); + double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1); + if( theFlags & EXTRUSION_FLAG_SEW ) { + const SMDS_MeshNode * newNode = CreateNode(x, y, z, + theTolerance, theParams.myNodes); + listNewNodes.push_back( newNode ); + } + else { + const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z); + listNewNodes.push_back( newNode ); + } + coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); + coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1); + coord[2] = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1); + if( theFlags & EXTRUSION_FLAG_SEW ) { + const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2], + theTolerance, theParams.myNodes); + listNewNodes.push_back( newNode ); + } + else { + const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + listNewNodes.push_back( newNode ); + } + } } } } newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] ); + sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps ); } if( theFlags & EXTRUSION_FLAG_BOUNDARY ) { - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems ); + makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps ); } } @@ -2855,6 +3609,14 @@ SMESH_MeshEditor::Extrusion_Error } // make new node + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + // create additional node + double x = ( aPN1.X() + aPN0.X() )/2.; + double y = ( aPN1.Y() + aPN0.Y() )/2.; + double z = ( aPN1.Z() + aPN0.Z() )/2.; + const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z); + listNewNodes.push_back( newNode ); + } aX = aPN1.X(); aY = aPN1.Y(); aZ = aPN1.Z(); @@ -2867,13 +3629,44 @@ SMESH_MeshEditor::Extrusion_Error aDT0x = aDT1x; } } + + else { + // if current elem is quadratic and current node is not medium + // we have to check - may be it is needed to insert additional nodes + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + list< const SMDS_MeshNode* > & listNewNodes = nIt->second; + if(listNewNodes.size()==aNbTP-1) { + vector aNodes(2*(aNbTP-1)); + gp_XYZ P(node->X(), node->Y(), node->Z()); + list< const SMDS_MeshNode* >::iterator it = listNewNodes.begin(); + int i; + for(i=0; iX() + P.X() )/2.; + double y = ( N->Y() + P.Y() )/2.; + double z = ( N->Z() + P.Z() )/2.; + const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z); + aNodes[2*i] = newN; + aNodes[2*i+1] = N; + P = gp_XYZ(N->X(),N->Y(),N->Z()); + } + listNewNodes.clear(); + for(i=0; i<2*(aNbTP-1); i++) { + listNewNodes.push_back(aNodes[i]); + } + } + } + } + newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] ); + sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], + newNodesItVec[0]->second.size() ); } - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements ); + makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements, + aNbTP-1 ); return EXTR_OK; } @@ -2908,8 +3701,7 @@ void SMESH_MeshEditor::Transform (set & theElems, // loop on theElems set< const SMDS_MeshElement* >::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); if ( !elem ) continue; @@ -2979,8 +3771,7 @@ void SMESH_MeshEditor::Transform (set & theElems, { 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD }; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = (*itElem); if ( !elem || elem->GetType() == SMDSAbs_Node ) continue; @@ -3071,12 +3862,46 @@ void SMESH_MeshEditor::Transform (set & theElems, else i = index[ nbNodes - 4 ]; + if(elem->IsQuadratic()) { + static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + i = anIds; + if(needReverse) { + if(nbNodes==3) { // quadratic edge + static int anIds[] = {1,0,2}; + i = anIds; + } + else if(nbNodes==6) { // quadratic triangle + static int anIds[] = {0,2,1,5,4,3}; + i = anIds; + } + else if(nbNodes==8) { // quadratic quadrangle + static int anIds[] = {0,3,2,1,7,6,5,4}; + i = anIds; + } + else if(nbNodes==10) { // quadratic tetrahedron of 10 nodes + static int anIds[] = {0,2,1,3,6,5,4,7,9,8}; + i = anIds; + } + else if(nbNodes==13) { // quadratic pyramid of 13 nodes + static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; + i = anIds; + } + else if(nbNodes==15) { // quadratic pentahedron with 15 nodes + static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13}; + i = anIds; + } + else { // nbNodes==20 - quadratic hexahedron with 20 nodes + static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17}; + i = anIds; + } + } + } + // find transformed nodes const SMDS_MeshNode* nodes[8]; int iNode = 0; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { + while ( itN->more() ) { const SMDS_MeshNode* node = static_cast( itN->next() ); TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node ); @@ -3087,18 +3912,26 @@ void SMESH_MeshEditor::Transform (set & theElems, if ( iNode != nbNodes ) continue; // not all nodes transformed - if ( theCopy ) - { + if ( theCopy ) { // add a new element switch ( elemType ) { case SMDSAbs_Edge: - aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] ); + if ( nbNodes == 2 ) + aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] ); + else + aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break; case SMDSAbs_Face: if ( nbNodes == 3 ) aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); - else + else if(nbNodes==4) aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]); + else if(nbNodes==6) + aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5]); + else // nbNodes==8 + aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7]); break; case SMDSAbs_Volume: if ( nbNodes == 4 ) @@ -3112,6 +3945,22 @@ void SMESH_MeshEditor::Transform (set & theElems, else if ( nbNodes == 5 ) aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ], nodes[ 4 ]); + else if(nbNodes==10) + aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]); + else if(nbNodes==13) + aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], + nodes[10], nodes[11], nodes[12]); + else if(nbNodes==15) + aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], + nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]); + else // nbNodes==20 + aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], + nodes[10], nodes[11], nodes[12], nodes[13], nodes[14], + nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]); break; default:; } @@ -3275,13 +4124,11 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // Fill nodeNodeMap and elems TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin(); - for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) - { + for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) { list& nodes = *grIt; list::iterator nIt = nodes.begin(); const SMDS_MeshNode* nToKeep = *nIt; - for ( ; nIt != nodes.end(); nIt++ ) - { + for ( ; nIt != nodes.end(); nIt++ ) { const SMDS_MeshNode* nToRemove = *nIt; nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep )); if ( nToRemove != nToKeep ) { @@ -3290,15 +4137,16 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); - while ( invElemIt->more() ) - elems.insert( invElemIt->next() ); + while ( invElemIt->more() ) { + const SMDS_MeshElement* elem = invElemIt->next(); + elems.insert(elem); + } } } // Change element nodes or remove an element set::iterator eIt = elems.begin(); - for ( ; eIt != elems.end(); eIt++ ) - { + for ( ; eIt != elems.end(); eIt++ ) { const SMDS_MeshElement* elem = *eIt; int nbNodes = elem->NbNodes(); int aShapeId = FindShape( elem ); @@ -3309,8 +4157,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // get new seq of nodes SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { + while ( itN->more() ) { const SMDS_MeshNode* n = static_cast( itN->next() ); @@ -3330,8 +4177,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) bool isOk = true; int nbUniqueNodes = nodeSet.size(); - if ( nbNodes != nbUniqueNodes ) // some nodes stick - { + if ( nbNodes != nbUniqueNodes ) { // some nodes stick // Polygons and Polyhedral volumes if (elem->IsPoly()) { @@ -3360,15 +4206,18 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) aMesh->SetMeshElementOnShape(newElem, aShapeId); } aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]); - } else { + } + else { rmElemIds.push_back(elem->GetID()); } - } else if (elem->GetType() == SMDSAbs_Volume) { + } + else if (elem->GetType() == SMDSAbs_Volume) { // Polyhedral volume if (nbUniqueNodes < 4) { rmElemIds.push_back(elem->GetID()); - } else { + } + else { // each face has to be analized in order to check volume validity const SMDS_PolyhedralVolumeOfNodes* aPolyedre = static_cast( elem ); @@ -3403,11 +4252,13 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) else rmElemIds.push_back(elem->GetID()); - } else { + } + else { rmElemIds.push_back(elem->GetID()); } } - } else { + } + else { } continue; @@ -3478,7 +4329,96 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) else isOk = false; break; - case 8: { //////////////////////////////////// HEXAHEDRON + case 8: { + if(elem->IsQuadratic()) { // Quadratic quadrangle + // 1 5 2 + // +---+---+ + // | | + // | | + // 4+ +6 + // | | + // | | + // +---+---+ + // 0 7 3 + isOk = false; + if(nbRepl==3) { + nbUniqueNodes = 6; + if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[2]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[5]; + uniqueNodes[4] = curNodes[6]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==0 && iRepl[1]==3 && iRepl[2]==7 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[2]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[5]; + uniqueNodes[5] = curNodes[6]; + isOk = true; + } + if( iRepl[0]==0 && iRepl[1]==4 && iRepl[2]==7 ) { + uniqueNodes[0] = curNodes[1]; + uniqueNodes[1] = curNodes[2]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[5]; + uniqueNodes[4] = curNodes[6]; + uniqueNodes[5] = curNodes[0]; + isOk = true; + } + if( iRepl[0]==1 && iRepl[1]==2 && iRepl[2]==5 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[6]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==1 && iRepl[1]==4 && iRepl[2]==5 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[2]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[1]; + uniqueNodes[4] = curNodes[6]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==2 && iRepl[1]==3 && iRepl[2]==6 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[2]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[5]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==2 && iRepl[1]==5 && iRepl[2]==6 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[3]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[2]; + uniqueNodes[5] = curNodes[7]; + isOk = true; + } + if( iRepl[0]==3 && iRepl[1]==6 && iRepl[2]==7 ) { + uniqueNodes[0] = curNodes[0]; + uniqueNodes[1] = curNodes[1]; + uniqueNodes[2] = curNodes[2]; + uniqueNodes[3] = curNodes[4]; + uniqueNodes[4] = curNodes[5]; + uniqueNodes[5] = curNodes[3]; + isOk = true; + } + } + break; + } + //////////////////////////////////// HEXAHEDRON isOk = false; SMDS_VolumeTool hexa (elem); hexa.SetExternalNormal(); @@ -3682,11 +4622,13 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities ); } - } else { + } + else { // Change regular element or polygon aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes ); } - } else { + } + else { // Remove invalid regular element or invalid polygon rmElemIds.push_back( elem->GetID() ); } @@ -3779,14 +4721,52 @@ const SMDS_MeshElement* i1 = iNode - 1; } // find a n2 linked to n1 - for ( iNode = 0; iNode < 2; iNode++ ) { - if ( iNode ) // node before n1 - n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ]; - else // node after n1 - n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ]; - if ( n == n2 ) - return elem; + if(!elem->IsQuadratic()) { + for ( iNode = 0; iNode < 2; iNode++ ) { + if ( iNode ) // node before n1 + n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ]; + else // node after n1 + n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ]; + if ( n == n2 ) + return elem; + } } + else { // analysis for quadratic elements + bool IsFind = false; + // check using only corner nodes + for ( iNode = 0; iNode < 2; iNode++ ) { + if ( iNode ) // node before n1 + n = faceNodes[ i1 == 0 ? nbN/2 - 1 : i1 - 1 ]; + else // node after n1 + n = faceNodes[ i1 + 1 == nbN/2 ? 0 : i1 + 1 ]; + if ( n == n2 ) + IsFind = true; + } + if(IsFind) { + return elem; + } + else { + // check using all nodes + const SMDS_QuadraticFaceOfNodes* F = + static_cast(elem); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while ( anIter->more() ) { + faceNodes[iNode] = static_cast(anIter->next()); + if ( faceNodes[ iNode++ ] == n1 ) + i1 = iNode - 1; + } + for ( iNode = 0; iNode < 2; iNode++ ) { + if ( iNode ) // node before n1 + n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ]; + else // node after n1 + n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ]; + if ( n == n2 ) { + return elem; + } + } + } + } // end analysis for quadratic elements } return 0; } @@ -3830,12 +4810,12 @@ static bool findFreeBorder (const SMDS_MeshNode* theFirstNode, theNodes.push_back( theFirstNode ); theNodes.push_back( theSecondNode ); - const SMDS_MeshNode* nodes [5], *nIgnore = theFirstNode, * nStart = theSecondNode; + //vector nodes; + const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode; set < const SMDS_MeshElement* > foundElems; bool needTheLast = ( theLastNode != 0 ); - while ( nStart != theLastNode ) - { + while ( nStart != theLastNode ) { if ( nStart == theFirstNode ) return !needTheLast; @@ -3846,13 +4826,24 @@ static bool findFreeBorder (const SMDS_MeshNode* theFirstNode, SMDS_ElemIteratorPtr invElemIt = nStart->facesIterator(); while ( invElemIt->more() ) { const SMDS_MeshElement* e = invElemIt->next(); - if ( e == curElem || foundElems.insert( e ).second ) - { + if ( e == curElem || foundElems.insert( e ).second ) { // get nodes - SMDS_ElemIteratorPtr nIt = e->nodesIterator(); int iNode = 0, nbNodes = e->NbNodes(); - while ( nIt->more() ) - nodes[ iNode++ ] = static_cast( nIt->next() ); + const SMDS_MeshNode* nodes[nbNodes+1]; + if(e->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(e); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() ) { + nodes[ iNode++ ] = anIter->next(); + } + } + else { + SMDS_ElemIteratorPtr nIt = e->nodesIterator(); + while ( nIt->more() ) + nodes[ iNode++ ] = static_cast( nIt->next() ); + } nodes[ iNode ] = nodes[ 0 ]; // check 2 links for ( iNode = 0; iNode < nbNodes; iNode++ ) @@ -3987,8 +4978,7 @@ SMESH_MeshEditor::Sew_Error MESSAGE(" Free Border 1 not found " ); aResult = SEW_BORDER1_NOT_FOUND; } - if (theSideIsFreeBorder) - { + if (theSideIsFreeBorder) { // Free border 2 // -------------- if (!findFreeBorder(theSideFirstNode, theSideSecondNode, theSideThirdNode, @@ -4000,8 +4990,7 @@ SMESH_MeshEditor::Sew_Error if ( aResult != SEW_OK ) return aResult; - if (!theSideIsFreeBorder) - { + if (!theSideIsFreeBorder) { // Side 2 // -------------- @@ -4027,8 +5016,7 @@ SMESH_MeshEditor::Sew_Error gp_XYZ Ps2( theSideSecondNode->X(), theSideSecondNode->Y(), theSideSecondNode->Z() ); double tol2 = 1.e-8; gp_Vec Vbs1( Pb1 - Ps1 ),Vbs2( Pb2 - Ps2 ); - if ( Vbs1.SquareMagnitude() > tol2 || Vbs2.SquareMagnitude() > tol2 ) - { + if ( Vbs1.SquareMagnitude() > tol2 || Vbs2.SquareMagnitude() > tol2 ) { // Need node movement. // find X and Z axes to create trsf @@ -4057,8 +5045,7 @@ SMESH_MeshEditor::Sew_Error nBordXYZ.insert( TNodeXYZMap::value_type( n, xyz )); } } - else - { + else { // just insert nodes XYZ in the nBordXYZ map for ( nBordIt = bordNodes.begin(); nBordIt != bordNodes.end(); nBordIt++ ) { const SMDS_MeshNode* n = *nBordIt; @@ -4110,13 +5097,27 @@ SMESH_MeshEditor::Sew_Error const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : faceNodes; if ( isVolume ) // --volume hasVolumes = true; - else if ( nbNodes > 2 ) { // --face + //else if ( nbNodes > 2 ) { // --face + else if ( elem->GetType()==SMDSAbs_Face ) { // --face // retrieve all face nodes and find iPrevNode - an index of the prevSideNode - SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); - while ( nIt->more() ) { - nodes[ iNode ] = static_cast( nIt->next() ); - if ( nodes[ iNode++ ] == prevSideNode ) - iPrevNode = iNode - 1; + if(elem->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(elem); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() ) { + nodes[ iNode ] = anIter->next(); + if ( nodes[ iNode++ ] == prevSideNode ) + iPrevNode = iNode - 1; + } + } + else { + SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); + while ( nIt->more() ) { + nodes[ iNode ] = static_cast( nIt->next() ); + if ( nodes[ iNode++ ] == prevSideNode ) + iPrevNode = iNode - 1; + } } // there are 2 links to check nbNodes = 2; @@ -4129,7 +5130,8 @@ SMESH_MeshEditor::Sew_Error if ( isVolume ) { if ( !volume.IsLinked( n, prevSideNode )) continue; - } else { + } + else { if ( iNode ) // a node before prevSideNode n = nodes[ iPrevNode == 0 ? elem->NbNodes() - 1 : iPrevNode - 1 ]; else // a node after prevSideNode @@ -4408,18 +5410,39 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, int iNode = 0, il1, il2, i3, i4; il1 = il2 = i3 = i4 = -1; const SMDS_MeshNode* nodes[ theFace->NbNodes() ]; - SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* n = static_cast( nodeIt->next() ); - if ( n == theBetweenNode1 ) - il1 = iNode; - else if ( n == theBetweenNode2 ) - il2 = iNode; - else if ( i3 < 0 ) - i3 = iNode; - else - i4 = iNode; - nodes[ iNode++ ] = n; + + if(theFace->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(theFace); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() ) { + const SMDS_MeshNode* n = anIter->next(); + if ( n == theBetweenNode1 ) + il1 = iNode; + else if ( n == theBetweenNode2 ) + il2 = iNode; + else if ( i3 < 0 ) + i3 = iNode; + else + i4 = iNode; + nodes[ iNode++ ] = n; + } + } + else { + SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator(); + while ( nodeIt->more() ) { + const SMDS_MeshNode* n = static_cast( nodeIt->next() ); + if ( n == theBetweenNode1 ) + il1 = iNode; + else if ( n == theBetweenNode2 ) + il2 = iNode; + else if ( i3 < 0 ) + i3 = iNode; + else + i4 = iNode; + nodes[ iNode++ ] = n; + } } if ( il1 < 0 || il2 < 0 || i3 < 0 ) return ; @@ -4448,25 +5471,48 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, // add nodes of face up to first node of link bool isFLN = false; - nodeIt = theFace->nodesIterator(); - while ( nodeIt->more() && !isFLN ) { - const SMDS_MeshNode* n = static_cast( nodeIt->next() ); - poly_nodes[iNode++] = n; - if (n == nodes[il1]) { - isFLN = true; - } - } - // add nodes to insert - list::iterator nIt = aNodesToInsert.begin(); - for (; nIt != aNodesToInsert.end(); nIt++) { - poly_nodes[iNode++] = *nIt; + if(theFace->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(theFace); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() && !isFLN ) { + const SMDS_MeshNode* n = anIter->next(); + poly_nodes[iNode++] = n; + if (n == nodes[il1]) { + isFLN = true; + } + } + // add nodes to insert + list::iterator nIt = aNodesToInsert.begin(); + for (; nIt != aNodesToInsert.end(); nIt++) { + poly_nodes[iNode++] = *nIt; + } + // add nodes of face starting from last node of link + while ( anIter->more() ) { + poly_nodes[iNode++] = anIter->next(); + } } - - // add nodes of face starting from last node of link - while ( nodeIt->more() ) { - const SMDS_MeshNode* n = static_cast( nodeIt->next() ); - poly_nodes[iNode++] = n; + else { + SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator(); + while ( nodeIt->more() && !isFLN ) { + const SMDS_MeshNode* n = static_cast( nodeIt->next() ); + poly_nodes[iNode++] = n; + if (n == nodes[il1]) { + isFLN = true; + } + } + // add nodes to insert + list::iterator nIt = aNodesToInsert.begin(); + for (; nIt != aNodesToInsert.end(); nIt++) { + poly_nodes[iNode++] = *nIt; + } + // add nodes of face starting from last node of link + while ( nodeIt->more() ) { + const SMDS_MeshNode* n = static_cast( nodeIt->next() ); + poly_nodes[iNode++] = n; + } } // edit or replace the face @@ -4474,8 +5520,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, if (theFace->IsPoly()) { aMesh->ChangePolygonNodes(theFace, poly_nodes); - - } else { + } + else { int aShapeId = FindShape( theFace ); SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes); @@ -4487,81 +5533,184 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, return; } - // put aNodesToInsert between theBetweenNode1 and theBetweenNode2 - int nbLinkNodes = 2 + aNodesToInsert.size(); - const SMDS_MeshNode* linkNodes[ nbLinkNodes ]; - linkNodes[ 0 ] = nodes[ il1 ]; - linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ]; - list::iterator nIt = aNodesToInsert.begin(); - for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) { - linkNodes[ iNode++ ] = *nIt; - } - // decide how to split a quadrangle: compare possible variants - // and choose which of splits to be a quadrangle - int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad; - if ( nbFaceNodes == 3 ) - { - iBestQuad = nbSplits; - i4 = i3; - } - else if ( nbFaceNodes == 4 ) - { - SMESH::Controls::NumericalFunctorPtr aCrit( new SMESH::Controls::AspectRatio); - double aBestRate = DBL_MAX; - for ( int iQuad = 0; iQuad < nbSplits; iQuad++ ) { - i1 = 0; i2 = 1; - double aBadRate = 0; - // evaluate elements quality - for ( iSplit = 0; iSplit < nbSplits; iSplit++ ) { - if ( iSplit == iQuad ) { - SMDS_FaceOfNodes quad (linkNodes[ i1++ ], - linkNodes[ i2++ ], - nodes[ i3 ], - nodes[ i4 ]); - aBadRate += getBadRate( &quad, aCrit ); + if( !theFace->IsQuadratic() ) { + + // put aNodesToInsert between theBetweenNode1 and theBetweenNode2 + int nbLinkNodes = 2 + aNodesToInsert.size(); + const SMDS_MeshNode* linkNodes[ nbLinkNodes ]; + linkNodes[ 0 ] = nodes[ il1 ]; + linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ]; + list::iterator nIt = aNodesToInsert.begin(); + for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) { + linkNodes[ iNode++ ] = *nIt; + } + // decide how to split a quadrangle: compare possible variants + // and choose which of splits to be a quadrangle + int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad; + if ( nbFaceNodes == 3 ) { + iBestQuad = nbSplits; + i4 = i3; + } + else if ( nbFaceNodes == 4 ) { + SMESH::Controls::NumericalFunctorPtr aCrit( new SMESH::Controls::AspectRatio); + double aBestRate = DBL_MAX; + for ( int iQuad = 0; iQuad < nbSplits; iQuad++ ) { + i1 = 0; i2 = 1; + double aBadRate = 0; + // evaluate elements quality + for ( iSplit = 0; iSplit < nbSplits; iSplit++ ) { + if ( iSplit == iQuad ) { + SMDS_FaceOfNodes quad (linkNodes[ i1++ ], + linkNodes[ i2++ ], + nodes[ i3 ], + nodes[ i4 ]); + aBadRate += getBadRate( &quad, aCrit ); + } + else { + SMDS_FaceOfNodes tria (linkNodes[ i1++ ], + linkNodes[ i2++ ], + nodes[ iSplit < iQuad ? i4 : i3 ]); + aBadRate += getBadRate( &tria, aCrit ); + } } - else { - SMDS_FaceOfNodes tria (linkNodes[ i1++ ], - linkNodes[ i2++ ], - nodes[ iSplit < iQuad ? i4 : i3 ]); - aBadRate += getBadRate( &tria, aCrit ); + // choice + if ( aBadRate < aBestRate ) { + iBestQuad = iQuad; + aBestRate = aBadRate; } } - // choice - if ( aBadRate < aBestRate ) { - iBestQuad = iQuad; - aBestRate = aBadRate; + } + + // create new elements + SMESHDS_Mesh *aMesh = GetMeshDS(); + int aShapeId = FindShape( theFace ); + + i1 = 0; i2 = 1; + for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) { + SMDS_MeshElement* newElem = 0; + if ( iSplit == iBestQuad ) + newElem = aMesh->AddFace (linkNodes[ i1++ ], + linkNodes[ i2++ ], + nodes[ i3 ], + nodes[ i4 ]); + else + newElem = aMesh->AddFace (linkNodes[ i1++ ], + linkNodes[ i2++ ], + nodes[ iSplit < iBestQuad ? i4 : i3 ]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + + // change nodes of theFace + const SMDS_MeshNode* newNodes[ 4 ]; + newNodes[ 0 ] = linkNodes[ i1 ]; + newNodes[ 1 ] = linkNodes[ i2 ]; + newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ]; + newNodes[ 3 ] = nodes[ i4 ]; + aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 ); + } // end if(!theFace->IsQuadratic()) + else { // theFace is quadratic + // we have to split theFace on simple triangles and one simple quadrangle + int tmp = il1/2; + int nbshift = tmp*2; + // shift nodes in nodes[] by nbshift + int i,j; + for(i=0; iAddFace (linkNodes[ i1++ ], - linkNodes[ i2++ ], - nodes[ i3 ], - nodes[ i4 ]); - else - newElem = aMesh->AddFace (linkNodes[ i1++ ], - linkNodes[ i2++ ], - nodes[ iSplit < iBestQuad ? i4 : i3 ]); - if ( aShapeId && newElem ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); + int n1,n2,n3; + if(nbFaceNodes==6) { // quadratic triangle + SMDS_MeshElement* newElem = + aMesh->AddFace(nodes[3],nodes[4],nodes[5]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + if(theFace->IsMediumNode(nodes[il1])) { + // create quadrangle + newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[5]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + n1 = 1; + n2 = 2; + n3 = 3; + } + else { + // create quadrangle + newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[5]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + n1 = 0; + n2 = 1; + n3 = 5; + } + } + else { // nbFaceNodes==8 - quadratic quadrangle + SMDS_MeshElement* newElem = + aMesh->AddFace(nodes[3],nodes[4],nodes[5]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + newElem = aMesh->AddFace(nodes[5],nodes[6],nodes[7]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + newElem = aMesh->AddFace(nodes[5],nodes[7],nodes[3]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + if(theFace->IsMediumNode(nodes[il1])) { + // create quadrangle + newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[7]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + n1 = 1; + n2 = 2; + n3 = 3; + } + else { + // create quadrangle + newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[7]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + n1 = 0; + n2 = 1; + n3 = 7; + } + } + // create needed triangles using n1,n2,n3 and inserted nodes + int nbn = 2 + aNodesToInsert.size(); + const SMDS_MeshNode* aNodes[nbn]; + aNodes[0] = nodes[n1]; + aNodes[nbn-1] = nodes[n2]; + list::iterator nIt = aNodesToInsert.begin(); + for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) { + aNodes[iNode++] = *nIt; + } + for(i=1; iAddFace(aNodes[i-1],aNodes[i],nodes[n3]); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + // remove old quadratic face + aMesh->RemoveElement(theFace); } - - // change nodes of theFace - const SMDS_MeshNode* newNodes[ 4 ]; - newNodes[ 0 ] = linkNodes[ i1 ]; - newNodes[ 1 ] = linkNodes[ i2 ]; - newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ]; - newNodes[ 3 ] = nodes[ i4 ]; - aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 ); } //======================================================================= @@ -4607,7 +5756,8 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode poly_nodes.push_back(*nIt); } } - } else if (faceNodes[inode] == theBetweenNode2) { + } + else if (faceNodes[inode] == theBetweenNode2) { if (faceNodes[inode + 1] == theBetweenNode1) { nbInserted = theNodesToInsert.size(); @@ -4619,7 +5769,8 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode } poly_nodes.push_back(*nIt); } - } else { + } + else { } } } @@ -4632,7 +5783,8 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode if (elem->IsPoly()) { aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); - } else { + } + else { int aShapeId = FindShape( elem ); SMDS_MeshElement* newElem = @@ -4709,11 +5861,24 @@ SMESH_MeshEditor::Sew_Error if ( elem->GetType() == SMDSAbs_Face ) { faceSet->insert( elem ); set faceNodeSet; - SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* n = static_cast( nodeIt->next() ); - nodeSet->insert( n ); - faceNodeSet.insert( n ); + if(elem->IsQuadratic()) { + const SMDS_QuadraticFaceOfNodes* F = + static_cast(elem); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while( anIter->more() ) { + const SMDS_MeshNode* n = anIter->next(); + nodeSet->insert( n ); + faceNodeSet.insert( n ); + } + } + else { + SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); + while ( nodeIt->more() ) { + const SMDS_MeshNode* n = static_cast( nodeIt->next() ); + nodeSet->insert( n ); + faceNodeSet.insert( n ); + } } setOfFaceNodeSet.insert( faceNodeSet ); } @@ -4754,8 +5919,7 @@ SMESH_MeshEditor::Sew_Error // face does not exist // ------------------------------------------------------------------------- - if ( !volSet->empty() ) - { + if ( !volSet->empty() ) { //int nodeSetSize = nodeSet->size(); // loop on given volumes @@ -4778,9 +5942,11 @@ SMESH_MeshEditor::Sew_Error // no such a face is given but it still can exist, check it if ( nbNodes == 3 ) { aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2] ); - } else if ( nbNodes == 4 ) { + } + else if ( nbNodes == 4 ) { aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); - } else { + } + else { vector poly_nodes (nbNodes); for (int inode = 0; inode < nbNodes; inode++) { poly_nodes[inode] = fNodes[inode]; @@ -4792,9 +5958,11 @@ SMESH_MeshEditor::Sew_Error // create a temporary face if ( nbNodes == 3 ) { aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] ); - } else if ( nbNodes == 4 ) { + } + else if ( nbNodes == 4 ) { aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); - } else { + } + else { vector poly_nodes (nbNodes); for (int inode = 0; inode < nbNodes; inode++) { poly_nodes[inode] = fNodes[inode]; @@ -4946,8 +6114,7 @@ SMESH_MeshEditor::Sew_Error // loop on links in linkList; find faces by links and append links // of the found faces to linkList list< TPairOfNodes >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ; - for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) - { + for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) { TPairOfNodes link[] = { *linkIt[0], *linkIt[1] }; long linkID = aLinkID_Gen.GetLinkID( link[0].first, link[0].second ); if ( linkIdSet.find( linkID ) == linkIdSet.end() ) @@ -4959,8 +6126,12 @@ SMESH_MeshEditor::Sew_Error // --------------------------------------------------------------- const SMDS_MeshElement* face[] = { 0, 0 }; - const SMDS_MeshNode* faceNodes[ 2 ][ 5 ]; - const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ; + //const SMDS_MeshNode* faceNodes[ 2 ][ 5 ]; + vector fnodes1(9); + vector fnodes2(9); + //const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ; + vector notLinkNodes1(6); + vector notLinkNodes2(6); int iLinkNode[2][2]; for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides const SMDS_MeshNode* n1 = link[iSide].first; @@ -4984,40 +6155,109 @@ SMESH_MeshEditor::Sew_Error faceSet->erase( f ); // get face nodes and find ones of a link iNode = 0; - SMDS_ElemIteratorPtr nIt = f->nodesIterator(); - while ( nIt->more() ) { - const SMDS_MeshNode* n = - static_cast( nIt->next() ); - if ( n == n1 ) - iLinkNode[ iSide ][ 0 ] = iNode; - else if ( n == n2 ) - iLinkNode[ iSide ][ 1 ] = iNode; - else if ( notLinkNodes[ iSide ][ 0 ] ) - notLinkNodes[ iSide ][ 1 ] = n; - else - notLinkNodes[ iSide ][ 0 ] = n; - faceNodes[ iSide ][ iNode++ ] = n; + int nbl = -1; + if(f->IsPoly()) { + if(iSide==0) { + fnodes1.resize(f->NbNodes()+1); + notLinkNodes1.resize(f->NbNodes()-2); + } + else { + fnodes2.resize(f->NbNodes()+1); + notLinkNodes2.resize(f->NbNodes()-2); + } + } + if(!f->IsQuadratic()) { + SMDS_ElemIteratorPtr nIt = f->nodesIterator(); + while ( nIt->more() ) { + const SMDS_MeshNode* n = + static_cast( nIt->next() ); + if ( n == n1 ) { + iLinkNode[ iSide ][ 0 ] = iNode; + } + else if ( n == n2 ) { + iLinkNode[ iSide ][ 1 ] = iNode; + } + //else if ( notLinkNodes[ iSide ][ 0 ] ) + // notLinkNodes[ iSide ][ 1 ] = n; + //else + // notLinkNodes[ iSide ][ 0 ] = n; + else { + nbl++; + if(iSide==0) + notLinkNodes1[nbl] = n; + //notLinkNodes1.push_back(n); + else + notLinkNodes2[nbl] = n; + //notLinkNodes2.push_back(n); + } + //faceNodes[ iSide ][ iNode++ ] = n; + if(iSide==0) { + fnodes1[iNode++] = n; + } + else { + fnodes2[iNode++] = n; + } + } + } + else { // f->IsQuadratic() + const SMDS_QuadraticFaceOfNodes* F = + static_cast(f); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + while ( anIter->more() ) { + const SMDS_MeshNode* n = + static_cast( anIter->next() ); + if ( n == n1 ) { + iLinkNode[ iSide ][ 0 ] = iNode; + } + else if ( n == n2 ) { + iLinkNode[ iSide ][ 1 ] = iNode; + } + else { + nbl++; + if(iSide==0) { + notLinkNodes1[nbl] = n; + } + else { + notLinkNodes2[nbl] = n; + } + } + if(iSide==0) { + fnodes1[iNode++] = n; + } + else { + fnodes2[iNode++] = n; + } + } + } + //faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ]; + if(iSide==0) { + fnodes1[iNode] = fnodes1[0]; + } + else { + fnodes2[iNode] = fnodes1[0]; } - faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ]; } } } } + // check similarity of elements of the sides if (aResult == SEW_OK && ( face[0] && !face[1] ) || ( !face[0] && face[1] )) { MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 )); - if ( nReplaceMap.size() == 2 ) // faces on input nodes not found + if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found aResult = ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES ); - else + } + else { aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS; + } break; // do not return because it s necessary to remove tmp faces } // set nodes to merge // ------------------- - if ( face[0] && face[1] ) - { + if ( face[0] && face[1] ) { int nbNodes = face[0]->NbNodes(); if ( nbNodes != face[1]->NbNodes() ) { MESSAGE("Diff nb of face nodes"); @@ -5025,9 +6265,12 @@ SMESH_MeshEditor::Sew_Error break; // do not return because it s necessary to remove tmp faces } bool reverse[] = { false, false }; // order of notLinkNodes of quadrangle - if ( nbNodes == 3 ) + if ( nbNodes == 3 ) { + //nReplaceMap.insert( TNodeNodeMap::value_type + // ( notLinkNodes[0][0], notLinkNodes[1][0] )); nReplaceMap.insert( TNodeNodeMap::value_type - ( notLinkNodes[0][0], notLinkNodes[1][0] )); + ( notLinkNodes1[0], notLinkNodes2[0] )); + } else { for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides // analyse link orientation in faces @@ -5041,34 +6284,44 @@ SMESH_MeshEditor::Sew_Error reverse[ iSide ] = !reverse[ iSide ]; } if ( reverse[0] == reverse[1] ) { - nReplaceMap.insert( TNodeNodeMap::value_type - ( notLinkNodes[0][0], notLinkNodes[1][0] )); - nReplaceMap.insert( TNodeNodeMap::value_type - ( notLinkNodes[0][1], notLinkNodes[1][1] )); + //nReplaceMap.insert( TNodeNodeMap::value_type + // ( notLinkNodes[0][0], notLinkNodes[1][0] )); + //nReplaceMap.insert( TNodeNodeMap::value_type + // ( notLinkNodes[0][1], notLinkNodes[1][1] )); + for(int nn=0; nn::iterator, bool > iter_isnew = linkIdSet.insert( linkID ); if ( !iter_isnew.second ) { // already in a set: no need to process linkIdSet.erase( iter_isnew.first ); } else // new in set == encountered for the first time: add { - const SMDS_MeshNode* n1 = nodes[ iNode ]; - const SMDS_MeshNode* n2 = nodes[ iNode + 1]; + //const SMDS_MeshNode* n1 = nodes[ iNode ]; + //const SMDS_MeshNode* n2 = nodes[ iNode + 1]; + const SMDS_MeshNode* n1 = fnodes1[ iNode ]; + const SMDS_MeshNode* n2 = fnodes1[ iNode + 1]; linkList[0].push_back ( TPairOfNodes( n1, n2 )); linkList[1].push_back ( TPairOfNodes( nReplaceMap[n1], nReplaceMap[n2] )); } @@ -5100,8 +6353,7 @@ SMESH_MeshEditor::Sew_Error // loop on nodes replacement map TNodeNodeMap::iterator nReplaceMapIt = nReplaceMap.begin(), nnIt; for ( ; nReplaceMapIt != nReplaceMap.end(); nReplaceMapIt++ ) - if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) - { + if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) { const SMDS_MeshNode* nToRemove = (*nReplaceMapIt).first; nodeIDsToRemove.push_back( nToRemove->GetID() ); // loop on elements sharing nToRemove @@ -5128,7 +6380,7 @@ SMESH_MeshEditor::Sew_Error if ( nbReplaced ) aMesh->ChangeElementNodes( e, nodes, nbNodes ); } - } + } Remove( nodeIDsToRemove, true ); diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index 78457ef15..3805bfd84 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -364,6 +364,15 @@ class SMESH_MeshEditor { // - not in avoidSet, // - in elemSet provided that !elemSet.empty() + /*! + * \brief Returns true if given node is medium + * \param n - node to check + * \param typeToCheck - type of elements containing the node to ask about node status + * \retval bool - check result + */ + static bool IsMedium(const SMDS_MeshNode* node, + const SMDSAbs_ElementType typeToCheck = SMDSAbs_All); + int FindShape (const SMDS_MeshElement * theElem); // Return an index of the shape theElem is on // or zero if a shape not found diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index 493799d35..f6090b1a8 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -3505,7 +3505,7 @@ void SMESH_Pattern::clearMesh(SMESH_Mesh* theMesh) const { if ( SMESH_subMesh * aSubMesh = theMesh->GetSubMesh/*Containing*/( myShape )) { - aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEANDEP ); + aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN ); } else { SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS(); diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 250040453..a2c73ac6d 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -53,6 +53,9 @@ using namespace std; #include #endif +#include +#include + //============================================================================= /*! * default constructor: @@ -76,8 +79,8 @@ SMESH_subMesh::SMESH_subMesh(int Id, SMESH_Mesh * father, SMESHDS_Mesh * meshDS, } else { - _algoState = NO_ALGO; - _computeState = NOT_READY; + _algoState = NO_ALGO; + _computeState = NOT_READY; } } @@ -89,8 +92,8 @@ SMESH_subMesh::SMESH_subMesh(int Id, SMESH_Mesh * father, SMESHDS_Mesh * meshDS, SMESH_subMesh::~SMESH_subMesh() { - MESSAGE("SMESH_subMesh::~SMESH_subMesh"); - // **** + MESSAGE("SMESH_subMesh::~SMESH_subMesh"); + // **** } //============================================================================= @@ -101,8 +104,8 @@ SMESH_subMesh::~SMESH_subMesh() int SMESH_subMesh::GetId() const { - //MESSAGE("SMESH_subMesh::GetId"); - return _Id; + //MESSAGE("SMESH_subMesh::GetId"); + return _Id; } //============================================================================= @@ -113,19 +116,16 @@ int SMESH_subMesh::GetId() const SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS() { - //MESSAGE("SMESH_subMesh::GetSubMeshDS"); - if (_subMeshDS==NULL) - { - //MESSAGE("subMesh pointer still null, trying to get it..."); - _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ... - if (_subMeshDS==NULL) - { - MESSAGE("problem... subMesh still empty"); - //NRI ASSERT(0); - //NRI throw SALOME_Exception(LOCALIZED(subMesh still empty)); - } - } - return _subMeshDS; + // submesh appears in DS only when a mesher set nodes and elements on it + if (_subMeshDS==NULL) + { + _subMeshDS = _meshDS->MeshElements(_subShape); // may be null ... +// if (_subMeshDS==NULL) +// { +// MESSAGE("problem... subMesh still empty"); +// } + } + return _subMeshDS; } //============================================================================= @@ -150,7 +150,6 @@ SMESHDS_SubMesh* SMESH_subMesh::CreateSubMeshDS() SMESH_subMesh *SMESH_subMesh::GetFirstToCompute() { - //MESSAGE("SMESH_subMesh::GetFirstToCompute"); const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); SMESH_subMesh *firstToCompute = 0; @@ -158,13 +157,10 @@ SMESH_subMesh *SMESH_subMesh::GetFirstToCompute() for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) { SMESH_subMesh *sm = (*itsub).second; - // SCRUTE(sm->GetId()); - // SCRUTE(sm->GetComputeState()); bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE); if (readyToCompute) { firstToCompute = sm; - //SCRUTE(sm->GetId()); break; } } @@ -423,20 +419,12 @@ void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape) int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid int cle = aSubMesh->GetId(); cle += 10000000 * ordType; // sort map by ordType then index - if (_mapDepend.find(cle) == _mapDepend.end()) + if ( _mapDepend.find( cle ) == _mapDepend.end()) { _mapDepend[cle] = aSubMesh; - const map < int, SMESH_subMesh * >&subMap = aSubMesh->DependsOn(); - map < int, SMESH_subMesh * >::const_iterator im; - for (im = subMap.begin(); im != subMap.end(); im++) - { - int clesub = (*im).first; - SMESH_subMesh *sm = (*im).second; - if (_mapDepend.find(clesub) == _mapDepend.end()) - _mapDepend[clesub] = sm; - } + const map < int, SMESH_subMesh * > & subMap = aSubMesh->DependsOn(); + _mapDepend.insert( subMap.begin(), subMap.end() ); } - } //============================================================================= @@ -445,7 +433,7 @@ void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape) */ //============================================================================= -const TopoDS_Shape & SMESH_subMesh::GetSubShape() +const TopoDS_Shape & SMESH_subMesh::GetSubShape() const { //MESSAGE("SMESH_subMesh::GetSubShape"); return _subShape; @@ -483,20 +471,18 @@ bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis, return ( theHypothesis->GetShapeType() & (1<< theShapeType)); // hypothesis - int aShapeDim = 100; switch ( theShapeType ) { - case TopAbs_EDGE: aShapeDim = 1; break; - case TopAbs_FACE: aShapeDim = 2; break; - case TopAbs_SHELL:aShapeDim = 3; break; - case TopAbs_SOLID:aShapeDim = 3; break; -// case TopAbs_VERTEX: + case TopAbs_EDGE: + case TopAbs_FACE: + case TopAbs_SHELL: + case TopAbs_SOLID: + return SMESH_Gen::GetShapeDim( theShapeType ) == theHypothesis->GetDim(); // case TopAbs_WIRE: // case TopAbs_COMPSOLID: // case TopAbs_COMPOUND: - default: return false; + default:; } - - return ( theHypothesis->GetDim() == aShapeDim ); + return false; } //============================================================================= @@ -554,7 +540,7 @@ SMESH_Hypothesis::Hypothesis_Status if ( ! CanAddHypothesis( anHyp )) return SMESH_Hypothesis::HYP_BAD_DIM; - if ( GetSimilarAttached( _subShape, anHyp ) ) + if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) ) return SMESH_Hypothesis::HYP_ALREADY_EXIST; if ( !_meshDS->AddHypothesis(_subShape, anHyp)) @@ -563,9 +549,9 @@ SMESH_Hypothesis::Hypothesis_Status // Serve Propagation of 1D hypothesis if (event == ADD_HYP) { bool isPropagationOk = true; - string hypName = anHyp->GetName(); + bool isPropagationHyp = ( strcmp( "Propagation", anHyp->GetName() ) == 0 ); - if (hypName == "Propagation") { + if ( isPropagationHyp ) { TopExp_Explorer exp (_subShape, TopAbs_EDGE); TopTools_MapOfShape aMap; for (; exp.More(); exp.Next()) { @@ -593,7 +579,11 @@ SMESH_Hypothesis::Hypothesis_Status } else { } - if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) { + if ( isPropagationOk ) { + if ( isPropagationHyp ) + return ret; // nothing more to do for "Propagation" hypothesis + } + else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) { ret = SMESH_Hypothesis::HYP_CONCURENT; } } // Serve Propagation of 1D hypothesis @@ -612,7 +602,9 @@ SMESH_Hypothesis::Hypothesis_Status { bool isPropagationOk = true; SMESH_HypoFilter propagFilter( SMESH_HypoFilter::HasName( "Propagation" )); - if ( propagFilter.IsOk( anHyp, _subShape )) + bool isPropagationHyp = propagFilter.IsOk( anHyp, _subShape ); + + if ( isPropagationHyp ) { TopExp_Explorer exp (_subShape, TopAbs_EDGE); TopTools_MapOfShape aMap; @@ -634,7 +626,11 @@ SMESH_Hypothesis::Hypothesis_Status isPropagationOk = _father->RebuildPropagationChains(); } - if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) { + if ( isPropagationOk ) { + if ( isPropagationHyp ) + return ret; // nothing more to do for "Propagation" hypothesis + } + else if ( ret < SMESH_Hypothesis::HYP_CONCURENT) { ret = SMESH_Hypothesis::HYP_CONCURENT; } } // Serve Propagation of 1D hypothesis @@ -712,7 +708,7 @@ SMESH_Hypothesis::Hypothesis_Status SetAlgoState(HYP_OK); if (SMESH_Hypothesis::IsStatusFatal( ret )) _meshDS->RemoveHypothesis(_subShape, anHyp); - else if (!_father->IsUsedHypothesis( anHyp, _subShape )) + else if (!_father->IsUsedHypothesis( anHyp, this )) { _meshDS->RemoveHypothesis(_subShape, anHyp); ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; @@ -802,7 +798,7 @@ SMESH_Hypothesis::Hypothesis_Status // ret should be fatal: anHyp was not added ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; } - else if (!_father->IsUsedHypothesis( anHyp, _subShape )) + else if (!_father->IsUsedHypothesis( anHyp, this )) ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; if (SMESH_Hypothesis::IsStatusFatal( ret )) @@ -866,7 +862,7 @@ SMESH_Hypothesis::Hypothesis_Status ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { - if (_father->IsUsedHypothesis( anHyp, _subShape )) // new Hyp + if (_father->IsUsedHypothesis( anHyp, this )) // new Hyp modifiedHyp = true; } else @@ -1000,9 +996,7 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo) void SMESH_subMesh::SetAlgoState(int state) { -// if (state != _oldAlgoState) -// int retc = ComputeStateEngine(MODIF_ALGO_STATE); - _algoState = state; + _algoState = state; } //============================================================================= @@ -1018,7 +1012,7 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK; //EAP: a wire (dim==1) should notify edges (dim==1) //EAP: int dim = SMESH_Gen::GetShapeDim(_subShape); - if (/*EAP:dim > 1*/ _subShape.ShapeType() < TopAbs_EDGE ) + if (_subShape.ShapeType() < TopAbs_EDGE ) // wire,face etc { const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); @@ -1043,18 +1037,18 @@ SMESH_Hypothesis::Hypothesis_Status void SMESH_subMesh::CleanDependsOn() { - MESSAGE("SMESH_subMesh::CleanDependsOn"); - // **** parcourir les ancetres dans l'ordre de dépendance + //MESSAGE("SMESH_subMesh::CleanDependsOn"); + // **** parcourir les ancetres dans l'ordre de dépendance - ComputeStateEngine(CLEAN); + ComputeStateEngine(CLEAN); - const map < int, SMESH_subMesh * >&dependson = DependsOn(); - map < int, SMESH_subMesh * >::const_iterator its; - for (its = dependson.begin(); its != dependson.end(); its++) - { - SMESH_subMesh *sm = (*its).second; - sm->ComputeStateEngine(CLEAN); - } + const map < int, SMESH_subMesh * >&dependson = DependsOn(); + map < int, SMESH_subMesh * >::const_iterator its; + for (its = dependson.begin(); its != dependson.end(); its++) + { + SMESH_subMesh *sm = (*its).second; + sm->ComputeStateEngine(CLEAN); + } } //============================================================================= @@ -1109,31 +1103,33 @@ void SMESH_subMesh::DumpAlgoState(bool isMain) } } -//============================================================================= +//================================================================================ /*! - * + * \brief Remove nodes and elements bound to submesh + * \param subMesh - submesh containing nodes and elements */ -//============================================================================= +//================================================================================ -static void removeSubMesh( SMESHDS_Mesh * meshDS, const TopoDS_Shape& subShape) +static void cleanSubMesh( SMESH_subMesh * subMesh ) { - SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(subShape); - if (subMeshDS!=NULL) - { - SMDS_ElemIteratorPtr ite=subMeshDS->GetElements(); - while(ite->more()) - { - const SMDS_MeshElement * elt = ite->next(); - //MESSAGE( " RM elt: "<GetID()<<" ( "<NbNodes()<<" )" ); - meshDS->RemoveElement(elt); - } + if (subMesh) { + if (SMESHDS_SubMesh * subMeshDS = subMesh->GetSubMeshDS()) { + SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS(); + SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); + while (ite->more()) { + const SMDS_MeshElement * elt = ite->next(); + //MESSAGE( " RM elt: "<GetID()<<" ( "<NbNodes()<<" )" ); + //meshDS->RemoveElement(elt); + meshDS->RemoveFreeElement(elt, subMeshDS); + } - SMDS_NodeIteratorPtr itn=subMeshDS->GetNodes(); - while(itn->more()) - { - const SMDS_MeshNode * node = itn->next(); - //MESSAGE( " RM node: "<GetID()); - meshDS->RemoveNode(node); + SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes(); + while (itn->more()) { + const SMDS_MeshNode * node = itn->next(); + //MESSAGE( " RM node: "<GetID()); + //meshDS->RemoveNode(node); + meshDS->RemoveFreeNode(node, subMeshDS); + } } } } @@ -1181,13 +1177,11 @@ bool SMESH_subMesh::ComputeStateEngine(int event) _computeState = READY_TO_COMPUTE; } break; - case COMPUTE: // nothing to do + case COMPUTE: // nothing to do break; case CLEAN: - RemoveSubMeshElementsAndNodes(); - break; - case CLEANDEP: CleanDependants(); + RemoveSubMeshElementsAndNodes(); break; case SUBMESH_COMPUTED: // nothing to do break; @@ -1245,13 +1239,17 @@ bool SMESH_subMesh::ComputeStateEngine(int event) } // compute CleanDependants(); - //RemoveSubMeshElementsAndNodes(); - //removeSubMesh( _meshDS, _subShape ); - if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput()) - ret = ApplyToCollection( algo, GetCollection( gen, algo ) ); - else - ret = algo->Compute((*_father), _subShape); - + RemoveSubMeshElementsAndNodes(); + try { + if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput()) + ret = ApplyToCollection( algo, GetCollection( gen, algo ) ); + else + ret = algo->Compute((*_father), _subShape); + } + catch (Standard_Failure) { + MESSAGE( "Exception in algo->Compute() "); + ret = false; + } if (!ret) { MESSAGE("problem in algo execution: failed to compute"); @@ -1280,6 +1278,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) } break; case CLEAN: + CleanDependants(); RemoveSubMeshElementsAndNodes(); _computeState = NOT_READY; algo = gen->GetAlgo((*_father), _subShape); @@ -1290,9 +1289,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event) _computeState = READY_TO_COMPUTE; } break; - case CLEANDEP: - CleanDependants(); - break; case SUBMESH_COMPUTED: // nothing to do break; case SUBMESH_RESTORED: @@ -1319,20 +1315,16 @@ bool SMESH_subMesh::ComputeStateEngine(int event) switch (event) { case MODIF_HYP: - CleanDependants(); // recursive recall with event CLEANDEP - algo = gen->GetAlgo((*_father), _subShape); - if (algo && !algo->NeedDescretBoundary()) - CleanDependsOn(); // remove sub-mesh with event CLEANDEP - break; case MODIF_ALGO_STATE: - CleanDependants(); // recursive recall with event CLEANDEP + ComputeStateEngine( CLEAN ); algo = gen->GetAlgo((*_father), _subShape); if (algo && !algo->NeedDescretBoundary()) - CleanDependsOn(); // remove sub-mesh with event CLEANDEP + CleanDependsOn(); // clean sub-meshes with event CLEAN break; - case COMPUTE: // nothing to do + case COMPUTE: // nothing to do break; case CLEAN: + CleanDependants(); // clean sub-meshes, dependant on this one, with event CLEAN RemoveSubMeshElementsAndNodes(); _computeState = NOT_READY; algo = gen->GetAlgo((*_father), _subShape); @@ -1343,9 +1335,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event) _computeState = READY_TO_COMPUTE; } break; - case CLEANDEP: - CleanDependants(); // recursive recall with event CLEANDEP - break; case SUBMESH_COMPUTED: // nothing to do break; case SUBMESH_RESTORED: @@ -1390,15 +1379,13 @@ bool SMESH_subMesh::ComputeStateEngine(int event) case COMPUTE: // nothing to do break; case CLEAN: + CleanDependants(); // submeshes dependent on me should be cleaned as well RemoveSubMeshElementsAndNodes(); if (_algoState == HYP_OK) _computeState = READY_TO_COMPUTE; else _computeState = NOT_READY; break; - case CLEANDEP: - CleanDependants(); - break; case SUBMESH_COMPUTED: // allow retry compute if (_algoState == HYP_OK) _computeState = READY_TO_COMPUTE; @@ -1534,19 +1521,22 @@ void SMESH_subMesh::UpdateDependantsState(const compute_event theEvent) void SMESH_subMesh::CleanDependants() { + int dimToClean = SMESH_Gen::GetShapeDim( _subShape ) + 1; + TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape )); for (; it.More(); it.Next()) { const TopoDS_Shape& ancestor = it.Value(); - // PAL8021. do not go upper than SOLID, else ComputeStateEngine(CLEANDEP) - // will erase mesh on other shapes in a compound - if ( ancestor.ShapeType() >= TopAbs_SOLID ) { - SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor); - if (aSubMesh) - aSubMesh->ComputeStateEngine(CLEANDEP); + if ( SMESH_Gen::GetShapeDim( ancestor ) == dimToClean ) { + // PAL8021. do not go upper than SOLID, else ComputeStateEngine(CLEAN) + // will erase mesh on other shapes in a compound + if ( ancestor.ShapeType() >= TopAbs_SOLID ) { + SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor); + if (aSubMesh) + aSubMesh->ComputeStateEngine(CLEAN); + } } } - ComputeStateEngine(CLEAN); } //============================================================================= @@ -1559,22 +1549,23 @@ void SMESH_subMesh::RemoveSubMeshElementsAndNodes() { //SCRUTE(_subShape.ShapeType()); - removeSubMesh( _meshDS, _subShape ); + cleanSubMesh( this ); // algo may bind a submesh not to _subShape, eg 3D algo // sets nodes on SHELL while _subShape may be SOLID int dim = SMESH_Gen::GetShapeDim( _subShape ); int type = _subShape.ShapeType() + 1; - for ( ; type <= TopAbs_EDGE; type++) + for ( ; type <= TopAbs_EDGE; type++) { if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type )) { TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type ); for ( ; exp.More(); exp.Next() ) - removeSubMesh( _meshDS, exp.Current() ); + cleanSubMesh( _father->GetSubMeshContaining( exp.Current() )); } else break; + } } //======================================================================= @@ -1626,8 +1617,9 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg if ( mainShape.IsSame( _subShape )) return _subShape; + const bool ignoreAuxiliaryHyps = false; list aUsedHyp = - theAlgo->GetUsedHypothesis( *_father, _subShape ); // copy + theAlgo->GetUsedHypothesis( *_father, _subShape, ignoreAuxiliaryHyps ); // copy // put in a compound all shapes with the same hypothesis assigned // and a good ComputState @@ -1645,7 +1637,7 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg if (subMesh->GetComputeState() == READY_TO_COMPUTE && anAlgo == theAlgo && - anAlgo->GetUsedHypothesis( *_father, S ) == aUsedHyp) + anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) { aBuilder.Add( aCompound, S ); } @@ -1656,26 +1648,31 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg //======================================================================= //function : GetSimilarAttached -//purpose : return nb of hypotheses attached to theShape. +//purpose : return a hypothesis attached to theShape. // If theHyp is provided, similar but not same hypotheses -// are countered; else only applicable ones having theHypType -// are countered +// is returned; else only applicable ones having theHypType +// is returned //======================================================================= const SMESH_Hypothesis* SMESH_subMesh::GetSimilarAttached(const TopoDS_Shape& theShape, const SMESH_Hypothesis * theHyp, const int theHypType) { - SMESH_HypoFilter filter; - filter.Init( SMESH_HypoFilter::HasType( theHyp ? theHyp->GetType() : theHypType )); + SMESH_HypoFilter hypoKind; + hypoKind.Init( hypoKind.HasType( theHyp ? theHyp->GetType() : theHypType )); if ( theHyp ) { - filter.And( SMESH_HypoFilter::HasDim( theHyp->GetDim() )); - filter.AndNot( SMESH_HypoFilter::Is( theHyp )); + hypoKind.And ( hypoKind.HasDim( theHyp->GetDim() )); + hypoKind.AndNot( hypoKind.Is( theHyp )); + if ( theHyp->IsAuxiliary() ) + hypoKind.And( hypoKind.HasName( theHyp->GetName() )); + else + hypoKind.AndNot( hypoKind.IsAuxiliary()); + } + else { + hypoKind.And( hypoKind.IsApplicableTo( theShape )); } - else - filter.And( SMESH_HypoFilter::IsApplicableTo( theShape )); - return _father->GetHypothesis( theShape, filter, false ); + return _father->GetHypothesis( theShape, hypoKind, false ); } //======================================================================= diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index 8251c6b94..5c5b92ec6 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -70,7 +70,7 @@ class SMESH_subMesh const map < int, SMESH_subMesh * >&DependsOn(); //const map < int, SMESH_subMesh * >&Dependants(); - const TopoDS_Shape & GetSubShape(); + const TopoDS_Shape & GetSubShape() const; // bool _vertexSet; // only for vertex subMesh, set to false for dim > 0 @@ -93,7 +93,7 @@ class SMESH_subMesh enum compute_event { MODIF_HYP, MODIF_ALGO_STATE, COMPUTE, - CLEAN, CLEANDEP, SUBMESH_COMPUTED, SUBMESH_RESTORED, + CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED, MESH_ENTITY_REMOVED, CHECK_COMPUTE_STATE }; @@ -103,17 +103,13 @@ class SMESH_subMesh SMESH_Hypothesis::Hypothesis_Status SubMeshesAlgoStateEngine(int event, SMESH_Hypothesis * anHyp); - int GetAlgoState() { return _algoState; } + int GetAlgoState() const { return _algoState; } + int GetComputeState() const { return _computeState; }; void DumpAlgoState(bool isMain); bool ComputeStateEngine(int event); - int GetComputeState() - { - return _computeState; - }; - bool IsConform(const SMESH_Algo* theAlgo); // check if a conform mesh will be produced by the Algo diff --git a/src/SMESHClient/Makefile.in b/src/SMESHClient/Makefile.in new file mode 100644 index 000000000..39b084a65 --- /dev/null +++ b/src/SMESHClient/Makefile.in @@ -0,0 +1,97 @@ +# GEOM GEOMClient : tool to transfer BREP files from GEOM server to GEOM client +# +# Copyright (C) 2003 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. +# +# 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Pavel TELKOV (OCC) +# Module : SHESM + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +# header files +EXPORT_HEADERS = \ + SMESH_Client.hxx + +# Libraries targets + +LIB = libSMESHClient.la +LIB_SRC = SMESH_Client.cxx + +LIB_CLIENT_IDL = SALOME_Comm.idl \ + SALOME_Component.idl \ + SALOMEDS.idl \ + SALOMEDS_Attributes.idl \ + SALOME_Exception.idl \ + SALOME_GenericObj.idl \ + SMESH_Mesh.idl \ + SMESH_Gen.idl \ + SMESH_Group.idl \ + SMESH_Hypothesis.idl \ + SMESH_Pattern.idl \ + SMESH_Filter.idl \ + GEOM_Gen.idl \ + MED.idl + +# Executables targets +BIN = SMESHClientBin +BIN_SRC = +BIN_CLIENT_IDL = +BIN_SERVER_IDL = + +# additionnal information to compil and link file +CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) +CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome +LDFLAGS += $(OCC_KERNEL_LIBS) \ + -L${KERNEL_ROOT_DIR}/lib/salome \ + -L${GEOM_ROOT_DIR}/lib/salome \ + -L${MED_ROOT_DIR}/lib/salome \ + -lSMDS \ + -lSMESHimpl \ + -lSMESHDS \ + -lSMESHControls \ + -lNMTTools \ + -lNMTDS \ + -lmed_V2_1 \ + -lMEDWrapper \ + -lMEDWrapperBase \ + -lMEDWrapper_V2_1 \ + -lMEDWrapper_V2_2 \ + -lSalomeResourcesManager \ + -lSalomeLifeCycleCORBA \ + -lSalomeNotification \ + -lSalomeContainer \ + -lRegistry \ + -lSalomeNS \ + -lSALOMELocalTrace \ + -lSALOMEBasics \ + -lOpUtil + +LDFLAGSFORBIN += $(LDFLAGS) + +@CONCLUDE@ + diff --git a/src/SMESHClient/SMESHClientBin.cxx b/src/SMESHClient/SMESHClientBin.cxx new file mode 100644 index 000000000..0ac9bf899 --- /dev/null +++ b/src/SMESHClient/SMESHClientBin.cxx @@ -0,0 +1,30 @@ +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// File : +// Author : +// Module : +// $Header: + +#include "SMESH_Client.hxx" + +int main( int, char** ) +{ + return 0; +} diff --git a/src/SMESHClient/SMESH_Client.cxx b/src/SMESHClient/SMESH_Client.cxx new file mode 100644 index 000000000..f6667a1b2 --- /dev/null +++ b/src/SMESHClient/SMESH_Client.cxx @@ -0,0 +1,542 @@ +// SMESH SMESHClient : tool to update client mesh structure by mesh from server +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Client.cxx +// Author : Pavel TELKOV +// Module : SMESH + +#include "SMESH_Client.hxx" +#include "SMESH_Mesh.hxx" + +#include "SALOME_NamingService.hxx" +#include "SALOME_LifeCycleCORBA.hxx" + +#include +#include CORBA_SERVER_HEADER(SALOME_Component) +#include CORBA_SERVER_HEADER(SALOME_Exception) + +#include "OpUtil.hxx" +#include "utilities.h" + +#ifdef WNT +#include +#else +#include +#endif + +#include + +#ifndef EXCEPTION +#define EXCEPTION(TYPE, MSG) {\ + std::ostringstream aStream;\ + aStream<<__FILE__<<"["<<__LINE__<<"]::"<FindNode(theId)) return anElem; + EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<FindElement(theId)) return anElem; + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<AddNodeWithID(aCoords[aCoordId], + aCoords[aCoordId+1], + aCoords[aCoordId+2], + anIndexes[anElemId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<AddEdgeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "< nodes_ids (aNbNodes); + for (int i = 0; i < aNbNodes; i++) { + nodes_ids[i] = anIndexes[anIndexId++]; + } + + SMDS_MeshElement* anElem = theMesh->AddPolygonalFaceWithID(nodes_ids, aFaceId); + if (!anElem) + EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolygonalFaceWithID for ID = " + << anElemId); + } + } + + + inline void AddTetrasWithID(SMDS_Mesh* theMesh, + SMESH::log_array_var& theSeq, + CORBA::Long theId) + { + const SMESH::long_array& anIndexes = theSeq[theId].indexes; + CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number; + if(5*aNbElems != anIndexes.length()) + EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()"); + for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){ + SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "< nodes_ids (aNbNodes); + for (int i = 0; i < aNbNodes; i++) { + nodes_ids[i] = anIndexes[anIndexId++]; + } + + int aNbFaces = anIndexes[anIndexId++]; + std::vector quantities (aNbFaces); + for (int i = 0; i < aNbFaces; i++) { + quantities[i] = anIndexes[anIndexId++]; + } + + SMDS_MeshElement* anElem = + theMesh->AddPolyhedralVolumeWithID(nodes_ids, quantities, aFaceId); + if (!anElem) + EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = " + << anElemId); + } + } + + + inline void ChangePolyhedronNodes (SMDS_Mesh* theMesh, + SMESH::log_array_var& theSeq, + CORBA::Long theId) + { + const SMESH::long_array& anIndexes = theSeq[theId].indexes; + CORBA::Long iind = 0, aNbElems = theSeq[theId].number; + + for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) + { + // find element + const SMDS_MeshElement* elem = FindElement(theMesh, anIndexes[iind++]); + // nb nodes + int nbNodes = anIndexes[iind++]; + // nodes + std::vector aNodes (nbNodes); + for (int iNode = 0; iNode < nbNodes; iNode++) { + aNodes[iNode] = FindNode(theMesh, anIndexes[iind++]); + } + // nb faces + int nbFaces = anIndexes[iind++]; + // quantities + std::vector quantities (nbFaces); + for (int iFace = 0; iFace < nbFaces; iFace++) { + quantities[iFace] = anIndexes[iind++]; + } + // change + theMesh->ChangePolyhedronNodes(elem, aNodes, quantities); + } + } +} + +//======================================================================= +SMESH::SMESH_Gen_var +SMESH_Client::GetSMESHGen(CORBA::ORB_ptr theORB, + CORBA::Boolean& theIsEmbeddedMode) +{ + static SMESH::SMESH_Gen_var aMeshGen; + + if(CORBA::is_nil(aMeshGen.in())){ +#ifdef WNT + long aClientPID = (long)_getpid(); +#else + long aClientPID = (long)getpid(); +#endif + + SALOME_NamingService aNamingService(theORB); + SALOME_LifeCycleCORBA aLifeCycleCORBA(&aNamingService); + Engines::Component_var aComponent = aLifeCycleCORBA.FindOrLoad_Component("FactoryServer","SMESH"); + aMeshGen = SMESH::SMESH_Gen::_narrow(aComponent); + + std::string aClientHostName = GetHostname(); + Engines::Container_var aServerContainer = aMeshGen->GetContainerRef(); + CORBA::String_var aServerHostName = aServerContainer->getHostName(); + CORBA::Long aServerPID = aServerContainer->getPID(); + aMeshGen->SetEmbeddedMode((aClientPID == aServerPID) && (aClientHostName == aServerHostName.in())); + } + theIsEmbeddedMode = aMeshGen->IsEmbeddedMode(); + + return aMeshGen; +} + + +//======================================================================= +// function : Create() +// purpose : +//======================================================================= +SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB, + SMESH::SMESH_Mesh_ptr theMesh): + myMeshServer(SMESH::SMESH_Mesh::_duplicate(theMesh)), + mySMESHDSMesh(NULL), + mySMDSMesh(NULL) +{ + myMeshServer->Register(); + + CORBA::Boolean anIsEmbeddedMode; + GetSMESHGen(theORB,anIsEmbeddedMode); + if(anIsEmbeddedMode){ + if ( MYDEBUG ) + MESSAGE("Info: The same process, update mesh by pointer "); + // just set client mesh pointer to server mesh pointer + SMESH_Mesh* aMesh = reinterpret_cast(theMesh->GetMeshPtr()); + if(aMesh->GetMeshDS()->IsEmbeddedMode()){ + mySMESHDSMesh = aMesh->GetMeshDS(); + mySMDSMesh = mySMESHDSMesh; + } + } + if(!mySMDSMesh) + mySMDSMesh = new SMDS_Mesh(); +} + + +//================================================================================= +// function : ~SMESH_Client +// purpose : Destructor +//================================================================================= +SMESH_Client::~SMESH_Client() +{ + myMeshServer->Destroy(); + if(!mySMESHDSMesh) + delete mySMDSMesh; +} + + +//================================================================================= +SMDS_Mesh* +SMESH_Client::GetMesh() const +{ + return mySMDSMesh; +} + + +//================================================================================= +SMDS_Mesh* +SMESH_Client::operator->() const +{ + return GetMesh(); +} + + +//================================================================================= +SMESH::SMESH_Mesh_ptr +SMESH_Client::GetMeshServer() +{ + return myMeshServer.in(); +} + + +//================================================================================= +// function : SMESH_Client +// purpose : Update mesh +//================================================================================= +bool +SMESH_Client::Update(bool theIsClear) +{ + bool anIsModified = true; + if(mySMESHDSMesh){ + SMESHDS_Script* aScript = mySMESHDSMesh->GetScript(); + anIsModified = aScript->IsModified(); + aScript->SetModified(false); + }else{ + SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear ); + CORBA::Long aLength = aSeq->length(); + anIsModified = aLength > 0; + if( MYDEBUG ) + MESSAGE( "Update: length of the script is "<RemoveNode( FindNode( mySMDSMesh, anIndexes[anElemId] ) ); + break; + + case SMESH::REMOVE_ELEMENT: + for( ; anElemId < aNbElems; anElemId++ ) + mySMDSMesh->RemoveElement( FindElement( mySMDSMesh, anIndexes[anElemId] ) ); + break; + + case SMESH::MOVE_NODE: + for(CORBA::Long aCoordId=0; anElemId < aNbElems; anElemId++, aCoordId+=3) + { + SMDS_MeshNode* node = + const_cast( FindNode( mySMDSMesh, anIndexes[anElemId] )); + node->setXYZ( aCoords[aCoordId], aCoords[aCoordId+1], aCoords[aCoordId+2] ); + } + break; + + case SMESH::CHANGE_ELEMENT_NODES: + for ( CORBA::Long i = 0; anElemId < aNbElems; anElemId++ ) + { + // find element + const SMDS_MeshElement* elem = FindElement( mySMDSMesh, anIndexes[i++] ); + // nb nodes + int nbNodes = anIndexes[i++]; + // nodes + //ASSERT( nbNodes < 9 ); + const SMDS_MeshNode* aNodes[ nbNodes ]; + for ( int iNode = 0; iNode < nbNodes; iNode++ ) + aNodes[ iNode ] = FindNode( mySMDSMesh, anIndexes[i++] ); + // change + mySMDSMesh->ChangeElementNodes( elem, aNodes, nbNodes ); + } + break; + + case SMESH::CHANGE_POLYHEDRON_NODES: + ChangePolyhedronNodes(mySMDSMesh, aSeq, anId); + break; + case SMESH::RENUMBER: + for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3) + { + mySMDSMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] ); + } + break; + + default:; + } + } + } + catch ( SALOME::SALOME_Exception& exc ) + { + INFOS("Following exception was cought:\n\t"<NbNodes() = "<NbNodes()); + MESSAGE("Update - mySMDSMesh->NbEdges() = "<NbEdges()); + MESSAGE("Update - mySMDSMesh->NbFaces() = "<NbFaces()); + MESSAGE("Update - mySMDSMesh->NbVolumes() = "<NbVolumes()); + } + } // end of update mesh by log script + + return anIsModified; +} diff --git a/src/SMESHClient/SMESH_Client.hxx b/src/SMESHClient/SMESH_Client.hxx new file mode 100644 index 000000000..646811051 --- /dev/null +++ b/src/SMESHClient/SMESH_Client.hxx @@ -0,0 +1,79 @@ +// SMESH SMESHClient : tool to update client mesh structure by mesh from server +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Client.hxx +// Author : Pavel TELKOV +// Module : SMESH + +#ifndef _SMESH_Client_HeaderFile +#define _SMESH_Client_HeaderFile + +#include +#include CORBA_SERVER_HEADER(SMESH_Gen) +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +#if defined WNT && defined WIN32 && defined SALOME_WNT_EXPORTS +#define SMESHCLIENT_WNT_EXPORT __declspec( dllexport ) +#else +#define SMESHCLIENT_WNT_EXPORT +#endif + +class SMESHDS_Mesh; +class SMDS_Mesh; + + +//===================================================================== +// SMESH_Client : class definition +//===================================================================== +class SMESHCLIENT_WNT_EXPORT SMESH_Client +{ +public: + static + SMESH::SMESH_Gen_var + GetSMESHGen(CORBA::ORB_ptr theORB, + CORBA::Boolean& theIsEmbeddedMode); + + SMESH_Client(CORBA::ORB_ptr theORB, + SMESH::SMESH_Mesh_ptr theMesh); + ~SMESH_Client(); + + bool + Update(bool theIsClear); + + SMDS_Mesh* + GetMesh() const; + + SMDS_Mesh* + operator->() const; + + SMESH::SMESH_Mesh_ptr + GetMeshServer(); + +protected: + SMESH::SMESH_Mesh_var myMeshServer; + SMESHDS_Mesh* mySMESHDSMesh; + SMDS_Mesh* mySMDSMesh; +}; + + +#endif diff --git a/src/SMESHDS/SMESHDS_Command.cxx b/src/SMESHDS/SMESHDS_Command.cxx index b55b5af1c..7de0dc637 100644 --- a/src/SMESHDS/SMESHDS_Command.cxx +++ b/src/SMESHDS/SMESHDS_Command.cxx @@ -33,7 +33,7 @@ using namespace std; //======================================================================= -//function : +//function : Constructor //purpose : //======================================================================= SMESHDS_Command::SMESHDS_Command(const SMESHDS_CommandType aType):myType(aType), @@ -41,6 +41,14 @@ myNumber(0) { } +//======================================================================= +//function : Destructor +//purpose : +//======================================================================= +SMESHDS_Command::~SMESHDS_Command() +{ +} + //======================================================================= //function : //purpose : @@ -408,3 +416,199 @@ const list < double >&SMESHDS_Command::GetCoords() { return myReals; } + + +//******************************************************************** +//***** Methods for quadratic elements ****** +//******************************************************************** + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +void SMESHDS_Command::AddEdge(int NewEdgeID, int n1, int n2, int n12) +{ + if (!myType == SMESHDS_AddQuadEdge) { + MESSAGE("SMESHDS_Command::AddEdge : Bad Type"); + return; + } + myIntegers.push_back(NewEdgeID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n12); + myNumber++; +} + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Command::AddFace(int NewFaceID, + int n1, int n2, int n3, + int n12, int n23, int n31) +{ + if (!myType == SMESHDS_AddQuadTriangle) { + MESSAGE("SMESHDS_Command::AddFace : Bad Type"); + return; + } + myIntegers.push_back(NewFaceID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n31); + myNumber++; +} + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Command::AddFace(int NewFaceID, + int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41) +{ + if (!myType == SMESHDS_AddQuadQuadrangle) { + MESSAGE("SMESHDS_Command::AddFace : Bad Type"); + return; + } + myIntegers.push_back(NewFaceID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n4); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n34); + myIntegers.push_back(n41); + myNumber++; +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, + int n14, int n24, int n34) +{ + if (!myType == SMESHDS_AddQuadTetrahedron) { + 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(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n31); + myIntegers.push_back(n14); + myIntegers.push_back(n24); + myIntegers.push_back(n34); + myNumber++; +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, + int n3, int n4, int n5, + int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45) +{ + if (!myType == SMESHDS_AddQuadPyramid) { + 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(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n34); + myIntegers.push_back(n41); + myIntegers.push_back(n15); + myIntegers.push_back(n25); + myIntegers.push_back(n35); + myIntegers.push_back(n45); + 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) +{ + if (!myType == SMESHDS_AddQuadPentahedron) { + 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); + myNumber++; +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Command::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 n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48) +{ + if (!myType == SMESHDS_AddQuadHexahedron) { + 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(n7); + myIntegers.push_back(n8); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n34); + myIntegers.push_back(n41); + myIntegers.push_back(n56); + myIntegers.push_back(n67); + myIntegers.push_back(n78); + myIntegers.push_back(n85); + myIntegers.push_back(n15); + myIntegers.push_back(n26); + myIntegers.push_back(n37); + myIntegers.push_back(n48); + myNumber++; +} + diff --git a/src/SMESHDS/SMESHDS_Command.hxx b/src/SMESHDS/SMESHDS_Command.hxx index 3ecd762f3..7f1e3dbd3 100644 --- a/src/SMESHDS/SMESHDS_Command.hxx +++ b/src/SMESHDS/SMESHDS_Command.hxx @@ -54,6 +54,28 @@ class SMESHDS_Command void AddPolyhedralVolume (const int ElementID, std::vector nodes_ids, std::vector quantities); + // special methods for quadratic elements + void AddEdge(int NewEdgeID, int n1, int n2, int n12); + void AddFace(int NewFaceID, int n1, int n2, int n3, + int n12, int n23, int n31); + void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, int n14, int n24, int n34); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, + int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45); + 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); + 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, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48); + void MoveNode(int NewNodeID, double x, double y, double z); void RemoveNode(int NodeID); void RemoveElement(int ElementID); diff --git a/src/SMESHDS/SMESHDS_CommandType.hxx b/src/SMESHDS/SMESHDS_CommandType.hxx index f2c505b1f..2f7455a58 100644 --- a/src/SMESHDS/SMESHDS_CommandType.hxx +++ b/src/SMESHDS/SMESHDS_CommandType.hxx @@ -30,22 +30,30 @@ //#include enum SMESHDS_CommandType { - SMESHDS_AddNode, - SMESHDS_AddEdge, - SMESHDS_AddTriangle, - SMESHDS_AddQuadrangle, - SMESHDS_AddPolygon, - SMESHDS_AddTetrahedron, - SMESHDS_AddPyramid, - SMESHDS_AddPrism, - SMESHDS_AddHexahedron, - SMESHDS_AddPolyhedron, - SMESHDS_RemoveNode, - SMESHDS_RemoveElement, - SMESHDS_MoveNode, - SMESHDS_ChangeElementNodes, - SMESHDS_ChangePolyhedronNodes, - SMESHDS_Renumber + SMESHDS_AddNode, + SMESHDS_AddEdge, + SMESHDS_AddTriangle, + SMESHDS_AddQuadrangle, + SMESHDS_AddPolygon, + SMESHDS_AddTetrahedron, + SMESHDS_AddPyramid, + SMESHDS_AddPrism, + SMESHDS_AddHexahedron, + SMESHDS_AddPolyhedron, + SMESHDS_RemoveNode, + SMESHDS_RemoveElement, + SMESHDS_MoveNode, + SMESHDS_ChangeElementNodes, + SMESHDS_ChangePolyhedronNodes, + SMESHDS_Renumber, + // special types for quadratic elements + SMESHDS_AddQuadEdge, + SMESHDS_AddQuadTriangle, + SMESHDS_AddQuadQuadrangle, + SMESHDS_AddQuadTetrahedron, + SMESHDS_AddQuadPyramid, + SMESHDS_AddQuadPentahedron, + SMESHDS_AddQuadHexahedron }; diff --git a/src/SMESHDS/SMESHDS_Document.cxx b/src/SMESHDS/SMESHDS_Document.cxx index f533a72a7..8529c2b24 100644 --- a/src/SMESHDS/SMESHDS_Document.cxx +++ b/src/SMESHDS/SMESHDS_Document.cxx @@ -43,13 +43,13 @@ SMESHDS_Document::SMESHDS_Document(int UserID):myUserID(UserID) //function : NewMesh //purpose : //======================================================================= -int SMESHDS_Document::NewMesh() +int SMESHDS_Document::NewMesh(bool theIsEmbeddedMode) { - static int NewMeshID = 0; - NewMeshID++; - SMESHDS_Mesh *aNewMesh = new SMESHDS_Mesh(NewMeshID); - myMeshes[NewMeshID] = aNewMesh; - return NewMeshID; + static int aNewMeshID = 0; + aNewMeshID++; + SMESHDS_Mesh *aNewMesh = new SMESHDS_Mesh(aNewMeshID,theIsEmbeddedMode); + myMeshes[aNewMeshID] = aNewMesh; + return aNewMeshID; } //======================================================================= diff --git a/src/SMESHDS/SMESHDS_Document.hxx b/src/SMESHDS/SMESHDS_Document.hxx index e95269f11..7378573ec 100644 --- a/src/SMESHDS/SMESHDS_Document.hxx +++ b/src/SMESHDS/SMESHDS_Document.hxx @@ -36,7 +36,7 @@ class SMESHDS_Document { public: SMESHDS_Document(int UserID); - int NewMesh(); + int NewMesh(bool theIsEmbeddedMode); void RemoveMesh(int MeshID); SMESHDS_Mesh * GetMesh(int MeshID); void AddHypothesis(SMESHDS_Hypothesis * H); diff --git a/src/SMESHDS/SMESHDS_GroupBase.hxx b/src/SMESHDS/SMESHDS_GroupBase.hxx index a7aa87ced..1902f8e9d 100644 --- a/src/SMESHDS/SMESHDS_GroupBase.hxx +++ b/src/SMESHDS/SMESHDS_GroupBase.hxx @@ -66,6 +66,12 @@ class SMESHDS_GroupBase virtual ~SMESHDS_GroupBase() {} + void SetColorGroup (int theColorGroup) + { myColorGroup = theColorGroup;} + + int GetColorGroup() const + { return myColorGroup;} + protected: const SMDS_MeshElement* findInMesh (const int theID) const; void resetIterator(); @@ -84,7 +90,7 @@ class SMESHDS_GroupBase int myCurIndex; int myCurID; SMDS_ElemIteratorPtr myIterator; - + int myColorGroup; }; #endif diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 5f92232dd..c1d3cc45c 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -45,9 +45,17 @@ using namespace std; //function : Create //purpose : //======================================================================= -SMESHDS_Mesh::SMESHDS_Mesh(int MeshID):myMeshID(MeshID) +SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode): + myIsEmbeddedMode(theIsEmbeddedMode), + myMeshID(theMeshID) { - myScript = new SMESHDS_Script(); + myScript = new SMESHDS_Script(theIsEmbeddedMode); +} + +//======================================================================= +bool SMESHDS_Mesh::IsEmbeddedMode() +{ + return myIsEmbeddedMode; } //======================================================================= @@ -607,10 +615,10 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume //purpose : //======================================================================= -static void removeFromContainers (map & theSubMeshes, - set& theGroups, - list & theElems, - const bool isNode) +static void removeFromContainers (map& theSubMeshes, + set& theGroups, + list& theElems, + const bool isNode) { if ( theElems.empty() ) return; @@ -682,6 +690,32 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true ); } +//======================================================================= +//function : RemoveFreeNode +//purpose : +//======================================================================= +void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, SMESHDS_SubMesh * subMesh) +{ + myScript->RemoveNode(n->GetID()); + + // Rm from group + // Node can belong to several groups + if (!myGroups.empty()) { + set::iterator GrIt = myGroups.begin(); + for (; GrIt != myGroups.end(); GrIt++) { + SMESHDS_Group* group = dynamic_cast(*GrIt); + if (!group || group->IsEmpty()) continue; + group->SMDSGroup().Remove(n); + } + } + + // Rm from sub-mesh + // Node should belong to only one sub-mesh + subMesh->RemoveNode(n); + + SMDS_Mesh::RemoveFreeElement(n); +} + //======================================================================= //function : RemoveElement //purpose : @@ -704,6 +738,107 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false ); } +//======================================================================= +//function : RemoveFreeElement +//purpose : +//======================================================================== +void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, SMESHDS_SubMesh * subMesh) +{ + if (elt->GetType() == SMDSAbs_Node) { + RemoveFreeNode( static_cast(elt), subMesh); + return; + } + + if (hasConstructionEdges() || hasConstructionFaces()) + // this methods is only for meshes without descendants + return; + + myScript->RemoveElement(elt->GetID()); + + // Rm from group + // Node can belong to several groups + if (!myGroups.empty()) { + set::iterator GrIt = myGroups.begin(); + for (; GrIt != myGroups.end(); GrIt++) { + SMESHDS_Group* group = dynamic_cast(*GrIt); + if (!group || group->IsEmpty()) continue; + group->SMDSGroup().Remove(elt); + } + } + + // Rm from sub-mesh + // Element should belong to only one sub-mesh + subMesh->RemoveElement(elt); + + SMDS_Mesh::RemoveFreeElement(elt); +} + +//================================================================================ +/*! + * \brief return submesh by shape + * \param shape - the subshape + * \retval SMESHDS_SubMesh* - the found submesh + * + * search of submeshes is optimized + */ +//================================================================================ + +SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape ) +{ + if ( shape.IsNull() ) + return 0; + + if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape )) + return myCurSubMesh; + + getSubmesh( ShapeToIndex( shape )); + myCurSubShape = shape; + return myCurSubMesh; +} + +//================================================================================ +/*! + * \brief return submesh by subshape index + * \param Index - the subshape index + * \retval SMESHDS_SubMesh* - the found submesh + * search of submeshes is optimized + */ +//================================================================================ + +SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index ) +{ + //Update or build submesh + if ( Index != myCurSubID ) { + map::iterator it = myShapeIndexToSubMesh.find( Index ); + if ( it == myShapeIndexToSubMesh.end() ) + it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first; + myCurSubMesh = it->second; + myCurSubID = Index; + myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh + } + return myCurSubMesh; +} + +//================================================================================ +/*! + * \brief Add element or node to submesh + * \param elem - element to add + * \param subMesh - submesh to be filled in + */ +//================================================================================ + +bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh ) +{ + if ( elem && subMesh ) { + if ( elem->GetType() == SMDSAbs_Node ) + subMesh->AddNode( static_cast( elem )); + else + subMesh->AddElement( elem ); + return true; + } + return false; +} + //======================================================================= //function : SetNodeOnVolume //purpose : @@ -711,7 +846,7 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S) { - SetNodeInVolume( aNode, myIndexToShape.FindIndex(S) ); + add( aNode, getSubmesh(S) ); } //======================================================================= //function : SetNodeOnVolume @@ -720,7 +855,7 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode, void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Solid & S) { - SetNodeInVolume( aNode, myIndexToShape.FindIndex(S) ); + add( aNode, getSubmesh(S) ); } //======================================================================= @@ -732,7 +867,8 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode, double u, double v) { - SetNodeOnFace( aNode, myIndexToShape.FindIndex(S), u, v ); + if ( add( aNode, getSubmesh(S) )) + aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v))); } //======================================================================= @@ -743,7 +879,8 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode, const TopoDS_Edge & S, double u) { - SetNodeOnEdge( aNode, myIndexToShape.FindIndex(S), u ); + if ( add( aNode, getSubmesh(S) )) + aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u))); } //======================================================================= @@ -753,7 +890,8 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode, void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode, const TopoDS_Vertex & S) { - SetNodeOnVertex( aNode, myIndexToShape.FindIndex(S)); + if ( add( aNode, getSubmesh(S) )) + aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID))); } //======================================================================= @@ -762,7 +900,12 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode, //======================================================================= void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode) { - MESSAGE("not implemented"); + if ( aNode && aNode->GetPosition() ) { + map::iterator it = + myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() ); + if ( it != myShapeIndexToSubMesh.end() ) + it->second->RemoveNode( aNode ); + } } //======================================================================= @@ -770,32 +913,26 @@ void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode) //purpose : //======================================================================= void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement, - const TopoDS_Shape & S) + const TopoDS_Shape & S) { - if (myShape.IsNull()) MESSAGE("myShape is NULL"); - - int Index = myIndexToShape.FindIndex(S); - - if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end()) - myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh(); - - myShapeIndexToSubMesh[Index]->AddElement(anElement); + add( anElement, getSubmesh(S) ); } //======================================================================= //function : UnSetMeshElementOnShape //purpose : //======================================================================= -void SMESHDS_Mesh:: -UnSetMeshElementOnShape(const SMDS_MeshElement * anElement, - const TopoDS_Shape & S) +void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem, + const TopoDS_Shape & S) { - if (myShape.IsNull()) MESSAGE("myShape is NULL"); - - int Index = myIndexToShape.FindIndex(S); + int Index = myIndexToShape.FindIndex(S); - if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end()) - myShapeIndexToSubMesh[Index]->RemoveElement(anElement); + map::iterator it = myShapeIndexToSubMesh.find( Index ); + if ( it != myShapeIndexToSubMesh.end() ) + if ( elem->GetType() == SMDSAbs_Node ) + it->second->RemoveNode( static_cast( elem )); + else + it->second->RemoveElement( elem ); } //======================================================================= @@ -833,8 +970,6 @@ bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const /////////////////////////////////////////////////////////////////////////////// SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const { - if (myShape.IsNull()) MESSAGE("myShape is NULL"); - int Index = ShapeToIndex(S); TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index); if (anIter != myShapeIndexToSubMesh.end()) @@ -848,10 +983,9 @@ SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const /////////////////////////////////////////////////////////////////////////////// SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) { - if (myShape.IsNull()) MESSAGE("myShape is NULL"); - - if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end()) - return myShapeIndexToSubMesh[Index]; + TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index); + if (anIter != myShapeIndexToSubMesh.end()) + return anIter->second; else return NULL; } @@ -981,7 +1115,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, //function : IndexToShape //purpose : //======================================================================= -TopoDS_Shape SMESHDS_Mesh::IndexToShape(int ShapeIndex) +const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const { return myIndexToShape.FindKey(ShapeIndex); } @@ -1006,7 +1140,7 @@ int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const //======================================================================= void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index) { - addNodeToSubmesh( aNode, Index ); + add( aNode, getSubmesh( Index )); } //======================================================================= @@ -1016,9 +1150,8 @@ void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index) void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v) { //Set Position on Node - aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v))); - - addNodeToSubmesh( aNode, Index ); + if ( add( aNode, getSubmesh( Index ))) + aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v))); } //======================================================================= @@ -1030,9 +1163,8 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, double u) { //Set Position on Node - aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u))); - - addNodeToSubmesh( aNode, Index ); + if ( add( aNode, getSubmesh( Index ))) + aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u))); } //======================================================================= @@ -1042,9 +1174,8 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index) { //Set Position on Node - aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index))); - - addNodeToSubmesh( aNode, Index ); + if ( add( aNode, getSubmesh( Index ))) + aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index))); } //======================================================================= @@ -1052,14 +1183,469 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index) //purpose : //======================================================================= void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement, - int Index) + int Index) { - if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end()) - myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh(); - - myShapeIndexToSubMesh[Index]->AddElement(anElement); + add( anElement, getSubmesh( Index )); } SMESHDS_Mesh::~SMESHDS_Mesh() { + delete myScript; +} + + + +//******************************************************************** +//******************************************************************** +//******** ********* +//***** Methods for addition of quadratic elements ****** +//******** ********* +//******************************************************************** +//******************************************************************** + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) +{ + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID); + if(anElem) myScript->AddEdge(ID,n1,n2,n12); + return anElem; } + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) +{ + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12); + if(anElem) myScript->AddEdge(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n12->GetID()); + return anElem; +} + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID) +{ + return AddEdgeWithID(n1->GetID(), + n2->GetID(), + n12->GetID(), + ID); +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), + n12->GetID(), n23->GetID(), n31->GetID()); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID); + if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID) +{ + return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + ID); +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID()); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID); + if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + int ID) +{ + return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n14->GetID(), n24->GetID(), n34->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23, + n31,n14,n24,n34,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order tetrahedron of 10 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), + n14->GetID(), n24->GetID(), n34->GetID(), ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41, + n15,n25,n35,n45); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5, + n12,n23,n34,n41, + n15,n25,n35,n45,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41, + n15,n25,n35,n45); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order pyramid of 13 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), + n4->GetID(), n5->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(), + ID); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +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) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36); + 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()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +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 ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6, + n12,n23,n31, + n45,n56,n64, + n14,n25,n36,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron 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 : +//======================================================================= +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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8, + n12,n23,n34,n41, + n56,n67,n78,n85, + n15,n26,n37,n48); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), + n6->GetID(), n7->GetID(), n8->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(), + n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID()); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(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 n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8, + n12,n23,n34,n41, + n56,n67,n78,n85, + n15,n26,n37,n48,ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41, + n56,n67,n78,n85,n15,n26,n37,n48); + return anElem; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Hexahedrons with 20 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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(), + n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(), + ID); +} + + diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index a5a54907b..61d223ebb 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -78,7 +78,9 @@ class SMESHDS_GroupBase; class SMESHDS_WNT_EXPORT SMESHDS_Mesh:public SMDS_Mesh{ public: - SMESHDS_Mesh(int MeshID); + SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode); + bool IsEmbeddedMode(); + void ShapeToMesh(const TopoDS_Shape & S); bool AddHypothesis(const TopoDS_Shape & SS, const SMESHDS_Hypothesis * H); bool RemoveHypothesis(const TopoDS_Shape & S, const SMESHDS_Hypothesis * H); @@ -93,6 +95,16 @@ public: virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2); + // 2d order edge with 3 nodes: n12 - node between n1 and n2 + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID); + virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID); + virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12); + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -113,6 +125,44 @@ public: const SMDS_MeshNode * n3, const SMDS_MeshNode * n4); + // 2d order triangle of 6 nodes + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31); + + // 2d order quadrangle + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41); + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -171,6 +221,153 @@ public: const SMDS_MeshNode * n7, const SMDS_MeshNode * n8); + // 2d order tetrahedron of 10 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34); + + // 2d order pyramid of 13 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, + 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + 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 * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45); + + // 2d order Pentahedron with 15 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 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, + 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); + + // 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, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + 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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + 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 * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48); + virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes_ids, const int ID); @@ -196,6 +393,14 @@ public: void MoveNode(const SMDS_MeshNode *, double x, double y, double z); virtual void RemoveNode(const SMDS_MeshNode *); void RemoveElement(const SMDS_MeshElement *); + + /*! Remove only the given element/node and only if it is free. + * Methods do not work for meshes with descendants. + * Implemented for fast cleaning of meshes. + */ + void RemoveFreeNode(const SMDS_MeshNode *, SMESHDS_SubMesh *); + void RemoveFreeElement(const SMDS_MeshElement *, SMESHDS_SubMesh *); + bool ChangeElementNodes(const SMDS_MeshElement * elem, const SMDS_MeshNode * nodes[], const int nbnodes); @@ -229,7 +434,7 @@ public: SMESHDS_Script * GetScript(); void ClearScript(); int ShapeToIndex(const TopoDS_Shape & aShape) const; - TopoDS_Shape IndexToShape(int ShapeIndex); + const TopoDS_Shape& IndexToShape(int ShapeIndex) const; SMESHDS_SubMesh * NewSubMesh(int Index); int AddCompoundSubmesh(const TopoDS_Shape& S, TopAbs_ShapeEnum type = TopAbs_SHAPE); @@ -274,15 +479,6 @@ private: #endif - void addNodeToSubmesh( const SMDS_MeshNode* aNode, int Index ) - { - //Update or build submesh - map::iterator it = myShapeIndexToSubMesh.find( Index ); - if ( it == myShapeIndexToSubMesh.end() ) - it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first; - it->second->AddNode( aNode ); // add aNode to submesh - } - typedef std::list THypList; #ifndef WNT @@ -305,6 +501,16 @@ private: TGroups myGroups; SMESHDS_Script* myScript; + bool myIsEmbeddedMode; + + // optimize addition of nodes/elements to submeshes by, SetNodeInVolume() etc: + // avoid search of submeshes in maps + bool add( const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh ); + SMESHDS_SubMesh* getSubmesh( const TopoDS_Shape & shape); + SMESHDS_SubMesh* getSubmesh( const int Index ); + int myCurSubID; + TopoDS_Shape myCurSubShape; + SMESHDS_SubMesh* myCurSubMesh; }; diff --git a/src/SMESHDS/SMESHDS_Script.cxx b/src/SMESHDS/SMESHDS_Script.cxx index 369ab4697..3f2b01254 100644 --- a/src/SMESHDS/SMESHDS_Script.cxx +++ b/src/SMESHDS/SMESHDS_Script.cxx @@ -30,6 +30,35 @@ using namespace std; +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= +SMESHDS_Script::SMESHDS_Script(bool theIsEmbeddedMode): + myIsEmbeddedMode(theIsEmbeddedMode) +{} + +//======================================================================= +//function : Destructor +//purpose : +//======================================================================= +SMESHDS_Script::~SMESHDS_Script() +{ + Clear(); +} + +//======================================================================= +void SMESHDS_Script::SetModified(bool theModified) +{ + myIsModified = theModified; +} + +//======================================================================= +bool SMESHDS_Script::IsModified() +{ + return myIsModified; +} + //======================================================================= //function : getCommand //purpose : @@ -69,6 +98,10 @@ void SMESHDS_Script::AddNode(int NewNodeID, double x, double y, double z) //======================================================================= void SMESHDS_Script::AddEdge(int NewEdgeID, int idnode1, int idnode2) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_AddEdge)->AddEdge(NewEdgeID, idnode1, idnode2); } @@ -79,6 +112,10 @@ void SMESHDS_Script::AddEdge(int NewEdgeID, int idnode1, int idnode2) void SMESHDS_Script::AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_AddTriangle)->AddFace(NewFaceID, idnode1, idnode2, idnode3); } @@ -91,6 +128,10 @@ void SMESHDS_Script::AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3, int idnode4) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_AddQuadrangle)->AddFace(NewFaceID, idnode1, idnode2, idnode3, idnode4); @@ -104,6 +145,10 @@ void SMESHDS_Script::AddVolume(int NewID, int idnode1, int idnode2, int idnode3, int idnode4) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_AddTetrahedron)->AddVolume(NewID, idnode1, idnode2, idnode3, idnode4); @@ -117,6 +162,10 @@ void SMESHDS_Script::AddVolume(int NewID, int idnode1, int idnode2, int idnode3, int idnode4, int idnode5) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_AddPyramid)->AddVolume(NewID, idnode1, idnode2, idnode3, idnode4, idnode5); @@ -130,6 +179,10 @@ void SMESHDS_Script::AddVolume(int NewID, int idnode1, int idnode2, int idnode3, int idnode4, int idnode5, int idnode6) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_AddPrism)->AddVolume(NewID, idnode1, idnode2, idnode3, idnode4, idnode5, idnode6); @@ -143,6 +196,10 @@ void SMESHDS_Script::AddVolume(int NewID, int idnode1, int idnode2, int idnode3, int idnode4, int idnode5, int idnode6, int idnode7, int idnode8) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_AddHexahedron)->AddVolume(NewID, idnode1, idnode2, idnode3, idnode4, idnode5, idnode6, idnode7, idnode8); @@ -154,6 +211,10 @@ void SMESHDS_Script::AddVolume(int NewID, //======================================================================= void SMESHDS_Script::AddPolygonalFace (int NewFaceID, std::vector nodes_ids) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_AddPolygon)->AddPolygonalFace(NewFaceID, nodes_ids); } @@ -165,6 +226,10 @@ void SMESHDS_Script::AddPolyhedralVolume (int NewID, std::vector nodes_ids, std::vector quantities) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_AddPolyhedron)->AddPolyhedralVolume (NewID, nodes_ids, quantities); } @@ -175,6 +240,10 @@ void SMESHDS_Script::AddPolyhedralVolume (int NewID, //======================================================================= void SMESHDS_Script::MoveNode(int NewNodeID, double x, double y, double z) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_MoveNode)->MoveNode(NewNodeID, x, y, z); } @@ -184,6 +253,10 @@ void SMESHDS_Script::MoveNode(int NewNodeID, double x, double y, double z) //======================================================================= void SMESHDS_Script::RemoveNode(int ID) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_RemoveNode)->RemoveNode(ID); } @@ -193,6 +266,10 @@ void SMESHDS_Script::RemoveNode(int ID) //======================================================================= void SMESHDS_Script::RemoveElement(int ElementID) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_RemoveElement)->RemoveElement(ElementID); } @@ -203,6 +280,10 @@ void SMESHDS_Script::RemoveElement(int ElementID) void SMESHDS_Script::ChangeElementNodes(int ElementID, int nodes[], int nbnodes) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_ChangeElementNodes)->ChangeElementNodes( ElementID, nodes, nbnodes ); } @@ -214,6 +295,10 @@ void SMESHDS_Script::ChangePolyhedronNodes (const int ElementID, std::vector nodes_ids, std::vector quantities) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_ChangePolyhedronNodes)->ChangePolyhedronNodes (ElementID, nodes_ids, quantities); } @@ -222,9 +307,12 @@ void SMESHDS_Script::ChangePolyhedronNodes (const int ElementID, //function : Renumber //purpose : //======================================================================= - void SMESHDS_Script::Renumber (const bool isNodes, const int startID, const int deltaID) { + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } getCommand(SMESHDS_Renumber)->Renumber( isNodes, startID, deltaID ); } @@ -234,7 +322,11 @@ void SMESHDS_Script::Renumber (const bool isNodes, const int startID, const int //======================================================================= void SMESHDS_Script::Clear() { - myCommands.clear(); + list::iterator anIt = myCommands.begin(); + for (; anIt != myCommands.end(); anIt++) { + delete (*anIt); + } + myCommands.clear(); } //======================================================================= @@ -243,5 +335,128 @@ void SMESHDS_Script::Clear() //======================================================================= const list& SMESHDS_Script::GetCommands() { - return myCommands; + return myCommands; +} + + +//******************************************************************** +//***** Methods for quadratic elements ****** +//******************************************************************** + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +void SMESHDS_Script::AddEdge(int NewEdgeID, int n1, int n2, int n12) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddQuadEdge)->AddEdge(NewEdgeID, n1, n2, n12); } + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, + int n12, int n23, int n31) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddQuadTriangle)->AddFace(NewFaceID, n1, n2, n3, + n12, n23, n31); +} + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddQuadQuadrangle)->AddFace(NewFaceID, n1, n2, n3, n4, + n12, n23, n34, n41); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, + int n14, int n24, int n34) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddQuadTetrahedron)->AddVolume(NewVolID, n1, n2, n3, n4, + n12, n23, n31, + n14, n24, n34); +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5, int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddQuadPyramid)->AddVolume(NewVolID, n1, n2, n3, n4, n5, + n12, n23, n34, n41, + n15, n25, n35, n45); +} + +//======================================================================= +//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) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddQuadPentahedron)->AddVolume(NewVolID, n1,n2,n3,n4,n5,n6, + n12, n23, n31, + n45, n56, n64, + n14, n25, n36); +} + +//======================================================================= +//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 n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddQuadHexahedron)->AddVolume(NewVolID, n1, n2, n3, n4, + n5, n6, n7, n8, + n12, n23, n34, n41, + n56, n67, n78, n85, + n15, n26, n37, n48); +} + diff --git a/src/SMESHDS/SMESHDS_Script.hxx b/src/SMESHDS/SMESHDS_Script.hxx index 3874facfc..a74f10d71 100644 --- a/src/SMESHDS/SMESHDS_Script.hxx +++ b/src/SMESHDS/SMESHDS_Script.hxx @@ -36,6 +36,12 @@ class SMESHDS_Script { public: + SMESHDS_Script(bool theIsEmbeddedMode); + ~SMESHDS_Script(); + + void SetModified(bool theModified); + bool IsModified(); + void AddNode(int NewNodeID, double x, double y, double z); void AddEdge(int NewEdgeID, int idnode1, int idnode2); void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3); @@ -56,6 +62,27 @@ class SMESHDS_Script std::vector nodes_ids, std::vector quantities); + // special methods for quadratic elements + void AddEdge(int NewEdgeID, int n1, int n2, int n12); + void AddFace(int NewFaceID, int n1, int n2, int n3, + int n12, int n23, int n31); + void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n12, int n23, int n31, int n14, int n24, int n34); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, + int n12, int n23, int n34, int n41, + int n15, int n25, int n35, int n45); + 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); + 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, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48); void MoveNode(int NewNodeID, double x, double y, double z); void RemoveNode(int NodeID); void RemoveElement(int ElementID); @@ -66,12 +93,14 @@ class SMESHDS_Script void Renumber (const bool isNodes, const int startID, const int deltaID); void Clear(); const std::list & GetCommands(); - ~SMESHDS_Script(); - + private: SMESHDS_Command* getCommand(const SMESHDS_CommandType aType); std::list myCommands; + + bool myIsEmbeddedMode; + bool myIsModified; }; #endif diff --git a/src/SMESHFiltersSelection/Makefile.in b/src/SMESHFiltersSelection/Makefile.in index c438321b7..3549bc3d2 100644 --- a/src/SMESHFiltersSelection/Makefile.in +++ b/src/SMESHFiltersSelection/Makefile.in @@ -67,7 +67,7 @@ CPPFLAGS += $(OCC_INCLUDES) $(QT_INCLUDES) $(PYTHON_INCLUDES) $(VTK_INCLUDES) \ -I${GEOM_ROOT_DIR}/include/salome ${BOOST_CPPFLAGS} CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -I${GUI_ROOT_DIR}/include/salome \ -I${GEOM_ROOT_DIR}/include/salome -I${BOOSTDIR} -LDFLAGS += $(OCC_KERNEL_LIBS) -L${GUI_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lSalomeApp -lsuit +LDFLAGS += $(OCC_KERNEL_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -lSalomeDSClient -lSalomeDS -L${GUI_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lSalomeApp -lsuit # additional file to be cleaned MOSTLYCLEAN = diff --git a/src/SMESHGUI/Makefile.in b/src/SMESHGUI/Makefile.in index 55987d6c2..0ec4d1569 100644 --- a/src/SMESHGUI/Makefile.in +++ b/src/SMESHGUI/Makefile.in @@ -109,7 +109,8 @@ LIB_SRC = SMESHGUI.cxx \ SMESHGUI_MeshOp.cxx \ SMESHGUI_Displayer.cxx \ SMESHGUI_Hypotheses.cxx \ - SMESHGUI_ShapeByMeshDlg.cxx + SMESHGUI_ShapeByMeshDlg.cxx \ + SMESHGUI_AddQuadraticElementDlg.cxx LIB_MOC = \ SMESHGUI.h \ @@ -157,7 +158,8 @@ LIB_MOC = \ SMESHGUI_MeshDlg.h \ SMESHGUI_MeshOp.h \ SMESHGUI_Hypotheses.h \ - SMESHGUI_ShapeByMeshDlg.h + SMESHGUI_ShapeByMeshDlg.h \ + SMESHGUI_AddQuadraticElementDlg.h LIB_CLIENT_IDL = SALOME_Exception.idl \ @@ -191,9 +193,9 @@ CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome -I${GUI_ROOT_DIR}/include/salome LDFLAGS += -lSMESHObject -lSMESHFiltersSelection -lSMDS -lSMESHControls -lDlgRef \ $(OCC_KERNEL_LIBS) -lTKBO -lTKAdvTools -L${KERNEL_ROOT_DIR}/lib/salome -L${GUI_ROOT_DIR}/lib/salome \ - -lVTKViewer -lSalomeApp -lSalomePrs -lSalomeNS -lSalomeLifeCycleCORBA -lOpUtil -lSalomeObject \ + -lVTKViewer -lSalomeDSClient -lSalomeDS -lSalomeApp -lSalomePrs -lSalomeNS -lSalomeLifeCycleCORBA -lOpUtil -lSalomeObject \ -lEvent -lSALOMELocalTrace -lSVTK -lOCCViewer -L${GEOM_ROOT_DIR}/lib/salome -lGEOM -lGEOMClient \ - -lGEOMBase -lGEOMObject -lGEOMFiltersSelection + -lGEOMBase -lGEOMObject -lGEOMFiltersSelection -lSalomeSession LDFLAGSFORBIN += $(LDFLAGS) diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index ecc471d99..b8d0b6bd8 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -26,6 +26,7 @@ #include "SMESHGUI.h" +#include "SMESH_Client.hxx" #include "SMESHGUI_NodesDlg.h" #include "SMESHGUI_TransparencyDlg.h" #include "SMESHGUI_ClippingDlg.h" @@ -40,6 +41,7 @@ #include "SMESHGUI_Hypotheses.h" #include "SMESHGUI_MoveNodesDlg.h" #include "SMESHGUI_AddMeshElementDlg.h" +#include "SMESHGUI_AddQuadraticElementDlg.h" #include "SMESHGUI_EditHypothesesDlg.h" #include "SMESHGUI_CreateHypothesesDlg.h" #include "SMESHGUI_FilterDlg.h" @@ -83,13 +85,14 @@ #include "SalomeApp_Study.h" #include "SalomeApp_Application.h" #include "SalomeApp_CheckFileDlg.h" +#include "SalomeApp_ImportOperation.h" + #include "LightApp_DataOwner.h" #include "LightApp_Preferences.h" #include "LightApp_VTKSelector.h" #include "LightApp_Operation.h" #include "LightApp_UpdateFlags.h" - -#include "SalomeApp_ImportOperation.h" +#include "LightApp_NameDlg.h" #include #include @@ -125,7 +128,6 @@ #include #include #include -#include // BOOST Includes #include @@ -146,7 +148,7 @@ using namespace std; namespace{ - // Decalarations + // Declarations //============================================================= void ImportMeshesFromFile(SMESH::SMESH_Gen_ptr theComponentMesh, int theCommandID); @@ -260,30 +262,45 @@ namespace{ switch ( theCommandID ) { case 125: case 122: - aFilterMap.insert( QObject::tr("MED 2.1 (*.med)"), SMESH::MED_V2_1 ); - aFilterMap.insert( QObject::tr("MED 2.2 (*.med)"), SMESH::MED_V2_2 ); + { + if (aMesh->HasDuplicatedGroupNamesMED()) { + int aRet = SUIT_MessageBox::warn2 + (SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_EXPORT_MED_DUPLICATED_GRP").arg(anIObject->getName()), + QObject::tr("SMESH_BUT_YES"), QObject::tr("SMESH_BUT_NO"), + 0, 1, 0); + if (aRet) + return; + } + + aFilterMap.insert( QObject::tr("MED 2.1 (*.med)"), SMESH::MED_V2_1 ); + aFilterMap.insert( QObject::tr("MED 2.2 (*.med)"), SMESH::MED_V2_2 ); + } break; case 124: case 121: aFilter = QObject::tr("DAT files (*.dat)"); break; case 126: - case 123: { - if(aMesh->NbPyramids()){ - int aRet = SUIT_MessageBox::warn2(SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_EXPORT_UNV").arg(anIObject->getName()), - QObject::tr("SMESH_BUT_YES"), - QObject::tr("SMESH_BUT_NO"), - 0,1,0); - if(aRet) - return; - } - aFilter = QObject::tr("IDEAS files (*.unv)"); + case 123: + { + if (aMesh->NbPyramids()) { + int aRet = SUIT_MessageBox::warn2 + (SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_EXPORT_UNV").arg(anIObject->getName()), + QObject::tr("SMESH_BUT_YES"), QObject::tr("SMESH_BUT_NO"), + 0, 1, 0); + if (aRet) + return; + } + aFilter = QObject::tr("IDEAS files (*.unv)"); + } break; default: return; - }} + } QString aFilename; SMESH::MED_VERSION aFormat; @@ -295,41 +312,42 @@ namespace{ if ( theCommandID != 122 && theCommandID != 125 ) aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), "", aFilter, aTitle, false); - else - { - QStringList filters; - for ( QMap::const_iterator it = aFilterMap.begin(); it != aFilterMap.end(); ++it ) - filters.push_back( it.key() ); - - //SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true ); - SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg( SMESHGUI::desktop(), false, QObject::tr("SMESH_AUTO_GROUPS") ,true, true ); - fd->setCaption( aTitle ); - fd->setFilters( filters ); - fd->setSelectedFilter( QObject::tr("MED 2.2 (*.med)") ); - fd->SetChecked(toCreateGroups); - bool is_ok = false; - while(!is_ok){ - fd->exec(); - aFilename = fd->selectedFile(); - aFormat = aFilterMap[fd->selectedFilter()]; - is_ok = true; - if( !aFilename.isEmpty() - && (aMesh->NbPolygons()>0 or aMesh->NbPolyhedrons()>0) - && aFormat==SMESH::MED_V2_1){ - int aRet = SUIT_MessageBox::warn2(SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_EXPORT_MED_V2_1").arg(anIObject->getName()), - QObject::tr("SMESH_BUT_YES"), - QObject::tr("SMESH_BUT_NO"), - 0,1,0); - if(aRet){ - is_ok = false; - } - } - } - toCreateGroups = fd->IsChecked(); - delete fd; - } + else { + QStringList filters; + QMap::const_iterator it = aFilterMap.begin(); + for ( ; it != aFilterMap.end(); ++it ) + filters.push_back( it.key() ); + + //SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true ); + SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg + ( SMESHGUI::desktop(), false, QObject::tr("SMESH_AUTO_GROUPS") ,true, true ); + fd->setCaption( aTitle ); + fd->setFilters( filters ); + fd->setSelectedFilter( QObject::tr("MED 2.2 (*.med)") ); + fd->SetChecked(toCreateGroups); + bool is_ok = false; + while (!is_ok) { + fd->exec(); + aFilename = fd->selectedFile(); + aFormat = aFilterMap[fd->selectedFilter()]; + is_ok = true; + if ( !aFilename.isEmpty() + && (aMesh->NbPolygons()>0 or aMesh->NbPolyhedrons()>0) + && aFormat==SMESH::MED_V2_1) { + int aRet = SUIT_MessageBox::warn2(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_EXPORT_MED_V2_1").arg(anIObject->getName()), + QObject::tr("SMESH_BUT_YES"), + QObject::tr("SMESH_BUT_NO"), + 0,1,0); + if (aRet) { + is_ok = false; + } + } + } + toCreateGroups = fd->IsChecked(); + delete fd; + } if ( !aFilename.isEmpty() ) { // Check whether the file already exists and delete it if yes QFile aFile( aFilename ); @@ -808,12 +826,11 @@ SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil(); //============================================================================= SMESHGUI::SMESHGUI() : SalomeApp_Module( "SMESH" ) -{ +{ if ( CORBA::is_nil( myComponentSMESH ) ) { - SALOME_LifeCycleCORBA* ls = new SALOME_LifeCycleCORBA( getApp()->namingService() ); - Engines::Component_var comp = ls->FindOrLoad_Component( "FactoryServer", "SMESH" ); - myComponentSMESH = SMESH::SMESH_Gen::_narrow( comp ); + CORBA::Boolean anIsEmbeddedMode; + myComponentSMESH = SMESH_Client::GetSMESHGen(getApp()->orb(),anIsEmbeddedMode); } myActiveDialogBox = 0; @@ -1390,9 +1407,6 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) else aDlg = new SMESHGUI_CuttingOfQuadsDlg(this); - int x, y ; - DefineDlgPosition( aDlg, x, y ); - aDlg->move( x, y ); aDlg->show(); break; } @@ -1578,8 +1592,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) int nbSelectedGroups = 0; for ( ; It.More(); It.Next() ) { - SMESH::SMESH_Group_var aGroup = - SMESH::IObjectToInterface(It.Value()); + SMESH::SMESH_GroupBase_var aGroup = + SMESH::IObjectToInterface(It.Value()); if (!aGroup->_is_nil()) { nbSelectedGroups++; SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, "", aGroup); @@ -1588,7 +1602,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } if (nbSelectedGroups == 0) { - SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, "", SMESH::SMESH_Group::_nil()); + SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, "", SMESH::SMESH_GroupBase::_nil()); aDlg->show(); } break; @@ -1762,10 +1776,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { aName = anAttr; QString newName = QString(aName->Value().c_str()); - bool ok; - newName = QInputDialog::getText( tr( "Rename" ), tr( "Enter new name:" ), QLineEdit::Normal, - newName, &ok, desktop() ); - if ( ok && !newName.isEmpty() ) + newName = LightApp_NameDlg::getName(desktop(), newName); + if ( !newName.isEmpty() ) { //old source: aStudy->renameIObject( IObject, newName ); aName->SetValue( newName.latin1() ); @@ -1855,6 +1867,46 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } break; } + case 4034: // QUADRATIC EDGE + case 4035: // QUADRATIC TRIANGLE + case 4036: // QUADRATIC QUADRANGLE + case 4037: // QUADRATIC TETRAHEDRON + case 4038: // QUADRATIC PYRAMID + case 4039: // QUADRATIC PENTAHEDRON + case 4040: // QUADRATIC HEXAHEDRON + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + int type; + + switch (theCommandID) { + case 4034: + type = QUAD_EDGE; break; + case 4035: + type = QUAD_TRIANGLE; break; + case 4036: + type = QUAD_QUADRANGLE; break; + case 4037: + type = QUAD_TETRAHEDRON; break; + case 4038: + type = QUAD_PYRAMID; break; + case 4039: + type = QUAD_PENTAHEDRON; break; + case 4040: + type = QUAD_HEXAHEDRON; + break; + default:; + } + new SMESHGUI_AddQuadraticElementDlg( this, type ); + } + else { + SUIT_MessageBox::warn1(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } case 4041: // REMOVES NODES { if(checkLock(aStudy)) break; @@ -2309,6 +2361,13 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 301, "DISPLAY" ); createSMESHAction( 302, "DISPLAY_ONLY" ); createSMESHAction( 4033, "POLYHEDRON", "ICON_DLG_POLYHEDRON" ); + createSMESHAction( 4034, "QUADRATIC_EDGE", "ICON_DLG_QUADRATIC_EDGE" ); + createSMESHAction( 4035, "QUADRATIC_TRIANGLE", "ICON_DLG_QUADRATIC_TRIANGLE" ); + createSMESHAction( 4036, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" ); + createSMESHAction( 4037, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" ); + createSMESHAction( 4038, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" ); + createSMESHAction( 4039, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" ); + createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" ); // ----- create menu -------------- int fileId = createMenu( tr( "MEN_FILE" ), -1, 1 ), @@ -2388,6 +2447,14 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 4031, addId, -1 ); createMenu( 4032, addId, -1 ); createMenu( 4033, addId, -1 ); + createMenu( separator(), addId, -1 ); + createMenu( 4034, addId, -1 ); + createMenu( 4035, addId, -1 ); + createMenu( 4036, addId, -1 ); + createMenu( 4037, addId, -1 ); + createMenu( 4038, addId, -1 ); + createMenu( 4039, addId, -1 ); + createMenu( 4040, addId, -1 ); createMenu( 4041, removeId, -1 ); createMenu( 4042, removeId, -1 ); @@ -2464,6 +2531,14 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( 4032, addRemTb ); createTool( 4033, addRemTb ); createTool( separator(), addRemTb ); + createTool( 4034, addRemTb ); + createTool( 4035, addRemTb ); + createTool( 4036, addRemTb ); + createTool( 4037, addRemTb ); + createTool( 4038, addRemTb ); + createTool( 4039, addRemTb ); + createTool( 4040, addRemTb ); + createTool( separator(), addRemTb ); createTool( 4041, addRemTb ); createTool( 4042, addRemTb ); createTool( separator(), addRemTb ); @@ -2501,12 +2576,13 @@ void SMESHGUI::initialize( CAM_Application* app ) group = pat.arg( SMESHGUI_Selection::typeName( GROUP ) ), hypo = pat.arg( SMESHGUI_Selection::typeName( HYPOTHESIS ) ), algo = pat.arg( SMESHGUI_Selection::typeName( ALGORITHM ) ), - elems = QString( "'%1' '%2' '%3' '%4' '%5'" ). + elems = QString( "'%1' '%2' '%3' '%4' '%5' '%6'" ). arg( SMESHGUI_Selection::typeName( SUBMESH_VERTEX ) ). arg( SMESHGUI_Selection::typeName( SUBMESH_EDGE ) ). arg( SMESHGUI_Selection::typeName( SUBMESH_FACE ) ). arg( SMESHGUI_Selection::typeName( SUBMESH_SOLID ) ). - arg( SMESHGUI_Selection::typeName( SUBMESH_COMPOUND ) ), + arg( SMESHGUI_Selection::typeName( SUBMESH_COMPOUND ) ). + arg( SMESHGUI_Selection::typeName( SUBMESH ) ), subMesh = elems, mesh_group = mesh + " " + subMesh + " " + group, hyp_alg = hypo + " " + algo; @@ -3000,6 +3076,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) { if( sect=="SMESH" ){ float sbX1,sbY1,sbW,sbH; + float aTol = 1.00000009999999; std::string aWarning; SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this); if( name=="selection_object_color" || name=="selection_element_color" || @@ -3009,7 +3086,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) else if (name == QString("scalar_bar_vertical_x") || name == QString("scalar_bar_vertical_width")){ sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_x", sbX1); sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_width", sbW); - if(sbX1+sbW > 1.0){ + if(sbX1+sbW > aTol){ aWarning = "Origin and Size Vertical: X+Width > 1\n"; sbX1=0.01; sbW=0.05; @@ -3020,7 +3097,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) else if(name == QString("scalar_bar_vertical_y") || name == QString("scalar_bar_vertical_height")){ sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_y", sbY1); sbH = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_height",sbH); - if(sbY1+sbH > 1.0){ + if(sbY1+sbH > aTol){ aWarning = "Origin and Size Vertical: Y+Height > 1\n"; sbY1=0.01; sbH=0.5; @@ -3031,7 +3108,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) else if(name == QString("scalar_bar_horizontal_x") || name == QString("scalar_bar_horizontal_width")){ sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_x", sbX1); sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_width", sbW); - if(sbX1+sbW > 1.0){ + if(sbX1+sbW > aTol){ aWarning = "Origin and Size Horizontal: X+Width > 1\n"; sbX1=0.2; sbW=0.6; @@ -3042,7 +3119,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) else if(name == QString("scalar_bar_horizontal_y") || name == QString("scalar_bar_horizontal_height")){ sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_y", sbY1); sbH = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_height",sbH); - if(sbY1+sbH > 1.0){ + if(sbY1+sbH > aTol){ aWarning = "Origin and Size Horizontal: Y+Height > 1\n"; sbY1=0.01; sbH=0.12; diff --git a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx index 7a396fd41..df2bb4df1 100644 --- a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx @@ -411,10 +411,6 @@ void SMESHGUI_AddMeshElementDlg::Init() if (Reverse) connect(Reverse, SIGNAL(stateChanged(int)), SLOT(CheckBox(int))); - // Move widget on the botton right corner of main widget - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); // displays Dialog // set selection mode diff --git a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx new file mode 100644 index 000000000..7d692cfbc --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx @@ -0,0 +1,1036 @@ +#include "SMESHGUI_AddQuadraticElementDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESH_ActorUtils.h" + +#include "SMDS_Mesh.hxx" +#include "SMESH_Actor.h" + +#include "SUIT_Session.h" + +#include "SVTK_Selection.h" +#include "SVTK_Selector.h" +#include "SALOME_ListIO.hxx" +#include "SALOME_ListIteratorOfListIO.hxx" + +#include "SalomeApp_Study.h" +#include "SalomeApp_Application.h" + +#include "SVTK_ViewModel.h" +#include "SVTK_ViewWindow.h" + +#include "utilities.h" + +// OCCT Includes +#include +#include + +// VTK Includes +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +// QT Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// STL includes +#include + +using namespace std; + +namespace SMESH { + + void ReverseConnectivity( vector & ids, int type ) + { + // for reverse connectivity of other types keeping the first id, see + // void SMESH_VisualObjDef::buildElemPrs() in SMESH_Object.cxx:900 + const int* conn = 0; + + switch ( type ) { + case QUAD_TETRAHEDRON: { + static int aConn[] = {0,2,1,3,6,5,4,7,9,8}; + conn = aConn; + break; + } + case QUAD_PYRAMID: { + static int aConn[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; + conn = aConn; + break; + } + case QUAD_PENTAHEDRON: { + static int aConn[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13}; + conn = aConn; + break; + } + case QUAD_HEXAHEDRON: { + static int aConn[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17}; + conn = aConn; + break; + } + default:; + } + if ( !conn ) { + reverse( ids.begin(), ids.end() ); + } + else { + vector aRevIds( ids.size() ); + for ( int i = 0; i < ids.size(); i++) + aRevIds[ i ] = ids[ conn[ i ]]; + ids = aRevIds; + } + } + + class TElementSimulation { + SalomeApp_Application* myApplication; + SUIT_ViewWindow* myViewWindow; + SVTK_ViewWindow* myVTKViewWindow; + + SALOME_Actor* myPreviewActor; + vtkDataSetMapper* myMapper; + vtkUnstructuredGrid* myGrid; + //vtkProperty* myBackProp, *myProp; + + float anRGB[3], aBackRGB[3]; + + public: + TElementSimulation (SalomeApp_Application* theApplication) + { + myApplication = theApplication; + SUIT_ViewManager* mgr = theApplication->activeViewManager(); + if (!mgr) return; + myViewWindow = mgr->getActiveView(); + myVTKViewWindow = GetVtkViewWindow(myViewWindow); + + myGrid = vtkUnstructuredGrid::New(); + + // Create and display actor + myMapper = vtkDataSetMapper::New(); + myMapper->SetInput(myGrid); + + myPreviewActor = SALOME_Actor::New(); + myPreviewActor->PickableOff(); + myPreviewActor->VisibilityOff(); + myPreviewActor->SetMapper(myMapper); + + vtkProperty* myProp = vtkProperty::New(); + GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); + myProp->SetColor( anRGB[0], anRGB[1], anRGB[2] ); + myPreviewActor->SetProperty( myProp ); + myProp->Delete(); + + vtkProperty* myBackProp = vtkProperty::New(); + GetColor( "SMESH", "backface_color", aBackRGB[0], aBackRGB[1], aBackRGB[2], QColor( 0, 0, 255 ) ); + myBackProp->SetColor( aBackRGB[0], aBackRGB[1], aBackRGB[2] ); + myPreviewActor->SetBackfaceProperty( myBackProp ); + myBackProp->Delete(); + + myVTKViewWindow->AddActor(myPreviewActor); + } + + typedef std::vector TVTKIds; + void SetPosition (SMESH_Actor* theActor, + const int theType, + TVTKIds& theIds, + const int theMode, + const bool theReverse) + { + vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid(); + myGrid->SetPoints(aGrid->GetPoints()); + + //add points + + vtkIdType aType = 0; + + switch (theType) { + case QUAD_EDGE: + aType = VTK_QUADRATIC_EDGE; + break; + case QUAD_TRIANGLE: + aType = VTK_QUADRATIC_TRIANGLE; + break; + case QUAD_QUADRANGLE: + aType = VTK_QUADRATIC_QUAD; + break; + case QUAD_TETRAHEDRON: + aType = VTK_QUADRATIC_TETRA; + break; + case QUAD_PYRAMID: + //aType = VTK_QUADRATIC_PYRAMID; // NOT SUPPORTED IN VTK4.2 + aType = VTK_CONVEX_POINT_SET; + break; + case QUAD_PENTAHEDRON: + //aType = VTK_QUADRATIC_WEDGE; // NOT SUPPORTED IN VTK4.2 + aType = VTK_CONVEX_POINT_SET; + break; + case QUAD_HEXAHEDRON: + aType = VTK_QUADRATIC_HEXAHEDRON; + break; + } + + // take care of orientation + if ( aType == VTK_CONVEX_POINT_SET ) { + if ( theReverse && theMode == VTK_SURFACE ) { + //myPreviewActor->GetProperty()->SetColor( aBackRGB[0], aBackRGB[1], aBackRGB[2] ); + } + } + else { + // VTK cell connectivity opposites the MED one + if ( !theReverse ) { + ReverseConnectivity( theIds, theType ); + } + } + + myGrid->Reset(); + vtkIdList *anIds = vtkIdList::New(); + + for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) { + anIds->InsertId(i,theIds[i]); + //std::cout << i<< ": " << theIds[i] << std::endl; + } + + myGrid->InsertNextCell(aType,anIds); + anIds->Delete(); + + myGrid->Modified(); + + myPreviewActor->GetMapper()->Update(); + myPreviewActor->SetRepresentation( theMode ); + SetVisibility(true); + + // restore normal orientation + if ( aType == VTK_CONVEX_POINT_SET ) { + if ( theReverse && theMode == VTK_SURFACE ) { + //myPreviewActor->GetProperty()->SetColor( anRGB[0], anRGB[1], anRGB[2] ); + } + } + } + + + void SetVisibility (bool theVisibility) + { + myPreviewActor->SetVisibility(theVisibility); + RepaintCurrentView(); + } + + + ~TElementSimulation() + { + if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) { + myVTKViewWindow->RemoveActor(myPreviewActor); + } + myPreviewActor->Delete(); + + myMapper->RemoveAllInputs(); + myMapper->Delete(); + + myGrid->Delete(); + +// myProp->Delete(); +// myBackProp->Delete(); + } + }; +} + + +// Define the sequences of ids +static int FirstEdgeIds[] = {0}; +static int LastEdgeIds[] = {1}; + +static int FirstTriangleIds[] = {0,1,2}; +static int LastTriangleIds[] = {1,2,0}; + +static int FirstQuadrangleIds[] = {0,1,2,3}; +static int LastQuadrangleIds[] = {1,2,3,0}; + +static int FirstTetrahedronIds[] = {0,1,2,3,3,3}; +static int LastTetrahedronIds[] = {1,2,0,0,1,2}; + +static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4}; +static int LastPyramidIds[] = {1,2,3,0,0,1,2,3}; + +static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2}; +static int LastPentahedronIds[] = {1,2,0,4,5,3,3,4,5}; + +static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3}; +static int LastHexahedronIds[] = {1,2,3,0,5,6,7,4,4,5,6,7}; + + + +//================================================================================= +// function : SMESHGUI_AddQuadraticElementDlg() +// purpose : constructor +//================================================================================= +SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule, + const int theType, + const char* name, + bool modal, WFlags fl) + : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder | + WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myType( theType ) +{ + SalomeApp_Application* anApp = dynamic_cast + (SUIT_Session::session()->activeApplication()); + + mySimulation = new SMESH::TElementSimulation (anApp); + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + + QString anElementName; + + switch ( myType ) { + case QUAD_EDGE: + anElementName = QString("QUADRATIC_EDGE"); + break; + case QUAD_TRIANGLE: + anElementName = QString("QUADRATIC_TRIANGLE"); + break; + case QUAD_QUADRANGLE: + anElementName = QString("QUADRATIC_QUADRANGLE"); + break; + case QUAD_TETRAHEDRON: + anElementName = QString("QUADRATIC_TETRAHEDRON"); + break; + case QUAD_PYRAMID: + anElementName = QString("QUADRATIC_PYRAMID"); + break; + case QUAD_PENTAHEDRON: + anElementName = QString("QUADRATIC_PENTAHEDRON"); + break; + case QUAD_HEXAHEDRON: + anElementName = QString("QUADRATIC_HEXAHEDRON"); + break; + default: + myType = QUAD_EDGE; + anElementName = QString("QUADRATIC_EDGE"); + } + + QString iconName = tr(QString("ICON_DLG_%1").arg(anElementName)); + QString caption = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName)); + QString argumentsGrTitle = tr(QString("SMESH_ADD_%1").arg(anElementName)); + QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName)); + + QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName)); + QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT"))); + + if (!name) + setName("SMESHGUI_AddQuadraticElementDlg"); + setCaption(caption); + + setSizeGripEnabled(TRUE); + QGridLayout* aDialogLayout = new QGridLayout(this); + aDialogLayout->setSpacing(6); + aDialogLayout->setMargin(11); + + /***************************************************************/ + GroupConstructors = new QButtonGroup(this, "GroupConstructors"); + GroupConstructors->setTitle(constructorGrTitle); + + GroupConstructors->setExclusive(TRUE); + GroupConstructors->setColumnLayout(0, Qt::Vertical); + GroupConstructors->layout()->setSpacing(0); + GroupConstructors->layout()->setMargin(0); + GroupConstructors->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed)); + QGridLayout* aGroupConstructorsLayout = new QGridLayout(GroupConstructors->layout()); + aGroupConstructorsLayout->setAlignment(Qt::AlignTop); + aGroupConstructorsLayout->setSpacing(6); + aGroupConstructorsLayout->setMargin(11); + myRadioButton1 = new QRadioButton(GroupConstructors, "myRadioButton1"); + myRadioButton1->setText(tr("" )); + myRadioButton1->setPixmap(image0); + myRadioButton1->setChecked(TRUE); + myRadioButton1->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, myRadioButton1->sizePolicy().hasHeightForWidth())); + aGroupConstructorsLayout->addWidget(myRadioButton1, 0, 0); + aGroupConstructorsLayout->addItem( new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 1); + aDialogLayout->addWidget(GroupConstructors, 0, 0); + + /***************************************************************/ + GroupArguments = new QGroupBox(this, "GroupArguments"); + GroupArguments->setTitle(argumentsGrTitle); + GroupArguments->setColumnLayout(0, Qt::Vertical); + GroupArguments->layout()->setSpacing(0); + GroupArguments->layout()->setMargin(0); + GroupArguments->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding)); + QGridLayout* aGroupArgumentsLayout = new QGridLayout(GroupArguments->layout()); + aGroupArgumentsLayout->setAlignment(Qt::AlignTop); + aGroupArgumentsLayout->setSpacing(6); + aGroupArgumentsLayout->setMargin(11); + QLabel* aCornerNodesLabel = new QLabel(GroupArguments, "aCornerNodesLabel"); + aCornerNodesLabel->setText(tr("SMESH_CORNER_NODES" )); + aGroupArgumentsLayout->addWidget(aCornerNodesLabel, 0, 0); + mySelectButton = new QPushButton(GroupArguments, "mySelectButton"); + mySelectButton->setPixmap(image1); + aGroupArgumentsLayout->addWidget(mySelectButton, 0, 1); + myCornerNodes = new QLineEdit(GroupArguments, "myCornerNodes"); + aGroupArgumentsLayout->addWidget(myCornerNodes, 0, 2); + + myTable = new QTable(GroupArguments); + aGroupArgumentsLayout->addMultiCellWidget(myTable, 1, 1, 0, 2); + + myReverseCB = new QCheckBox(GroupArguments, "myReverseCB"); + myReverseCB->setText(tr("SMESH_REVERSE" )); + aGroupArgumentsLayout->addWidget(myReverseCB, 2, 0); + + aDialogLayout->addWidget(GroupArguments, 1, 0); + + + /***************************************************************/ + GroupButtons = new QGroupBox(this, "GroupButtons"); + GroupButtons->setColumnLayout(0, Qt::Vertical); + GroupButtons->layout()->setSpacing(0); + GroupButtons->layout()->setMargin(0); + GroupButtons->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + QGridLayout* aGroupButtonsLayout = new QGridLayout(GroupButtons->layout()); + aGroupButtonsLayout->setAlignment(Qt::AlignTop); + aGroupButtonsLayout->setSpacing(6); + aGroupButtonsLayout->setMargin(11); + buttonCancel = new QPushButton(GroupButtons, "buttonCancel"); + buttonCancel->setText(tr("SMESH_BUT_CLOSE" )); + buttonCancel->setAutoDefault(TRUE); + aGroupButtonsLayout->addWidget(buttonCancel, 0, 3); + buttonApply = new QPushButton(GroupButtons, "buttonApply"); + buttonApply->setText(tr("SMESH_BUT_APPLY" )); + buttonApply->setAutoDefault(TRUE); + aGroupButtonsLayout->addWidget(buttonApply, 0, 1); + aGroupButtonsLayout->addItem( new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2); + buttonOk = new QPushButton(GroupButtons, "buttonOk"); + buttonOk->setText(tr("SMESH_BUT_OK" )); + buttonOk->setAutoDefault(TRUE); + buttonOk->setDefault(TRUE); + aGroupButtonsLayout->addWidget(buttonOk, 0, 0); + + aDialogLayout->addWidget(GroupButtons, 2, 0); + + Init(); /* Initialisations */ +} + +//================================================================================= +// function : ~SMESHGUI_AddQuadraticElementDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_AddQuadraticElementDlg::~SMESHGUI_AddQuadraticElementDlg() +{ + // no need to delete child widgets, Qt does it all for us + delete mySimulation; +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::Init() +{ + GroupArguments->show(); + myRadioButton1->setChecked(TRUE); + myIsEditCorners = true; + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + myActor = 0; + + int aNumRows; + + switch (myType) { + case QUAD_EDGE: + aNumRows = 1; + myNbCorners = 2; + break; + case QUAD_TRIANGLE: + aNumRows = 3; + myNbCorners = 3; + break; + case QUAD_QUADRANGLE: + aNumRows = 4; + myNbCorners = 4; + break; + case QUAD_TETRAHEDRON: + aNumRows = 6; + myNbCorners = 4; + break; + case QUAD_PYRAMID: + aNumRows = 8; + myNbCorners = 5; + break; + case QUAD_PENTAHEDRON: + aNumRows = 9; + myNbCorners = 6; + break; + case QUAD_HEXAHEDRON: + aNumRows = 12; + myNbCorners = 8; + break; + } + + myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, "validator", myNbCorners)); + + /* initialize table */ + myTable->setNumCols(3); + myTable->setNumRows(aNumRows); + + QStringList aColLabels; + aColLabels.append(tr("SMESH_FIRST")); + aColLabels.append(tr("SMESH_MIDDLE")); + aColLabels.append(tr("SMESH_LAST")); + myTable->setColumnLabels(aColLabels); + + for ( int col = 0; col < myTable->numCols(); col++ ) + myTable->setColumnWidth(col, 80); + + myTable->setColumnReadOnly(0, true); + myTable->setColumnReadOnly(2, true); + + myTable->setEnabled( false ); + + for ( int row = 0; row < myTable->numRows(); row++ ) + { + SMESHGUI_IdEditItem* anEditItem = new SMESHGUI_IdEditItem( myTable, QTableItem::OnTyping, "" ); + anEditItem->setReplaceable(false); + myTable->setItem(row, 1, anEditItem); + } + + /* signals and slots connections */ + connect(mySelectButton, SIGNAL(clicked()), SLOT(SetEditCorners())); + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument())); + connect(myTable, SIGNAL(doubleClicked(int, int, int, const QPoint&)), SLOT(onCellDoubleClicked(int, int, int, const QPoint&))); + connect(myTable, SIGNAL(valueChanged (int, int)), SLOT(onCellTextChange(int, int))); + connect(myCornerNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); + connect(myReverseCB, SIGNAL(stateChanged(int)), SLOT(onReverse(int))); + + connect(buttonOk, SIGNAL(clicked()), SLOT(ClickOnOk())); + connect(buttonCancel, SIGNAL(clicked()), SLOT(ClickOnCancel())); + connect(buttonApply, SIGNAL(clicked()), SLOT(ClickOnApply())); + + connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog())); + connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel())); + + this->show(); // displays Dialog + + // set selection mode + SMESH::SetPointRepresentation(true); + + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( NodeSelection ); + + myBusy = false; + + SetEditCorners(); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::ClickOnApply() +{ + if (IsValid() && !mySMESHGUI->isActiveStudyLocked()) { + myBusy = true; + + vector anIds; + + switch (myType) { + case QUAD_EDGE: + anIds.push_back(myTable->text(0, 0).toInt()); + anIds.push_back(myTable->text(0, 2).toInt()); + anIds.push_back(myTable->text(0, 1).toInt()); + break; + case QUAD_TRIANGLE: + case QUAD_QUADRANGLE: + case QUAD_TETRAHEDRON: + case QUAD_PYRAMID: + case QUAD_PENTAHEDRON: + case QUAD_HEXAHEDRON: + for ( int row = 0; row < myNbCorners; row++ ) + anIds.push_back(myTable->text(row, 0).toInt()); + for ( int row = 0; row < myTable->numRows(); row++ ) + anIds.push_back(myTable->text(row, 1).toInt()); + break; + } + if ( myReverseCB->isChecked()) + SMESH::ReverseConnectivity( anIds, myType ); + + int aNumberOfIds = anIds.size(); + SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; + anArrayOfIdeces->length( aNumberOfIds ); + + for (int i = 0; i < aNumberOfIds; i++) + anArrayOfIdeces[i] = anIds[ i ]; + + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + switch (myType) { + case QUAD_EDGE: + aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break; + case QUAD_TRIANGLE: + case QUAD_QUADRANGLE: + aMeshEditor->AddFace(anArrayOfIdeces.inout()); break; + case QUAD_TETRAHEDRON: + case QUAD_PYRAMID: + case QUAD_PENTAHEDRON: + case QUAD_HEXAHEDRON: + aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break; + } + + SALOME_ListIO aList; aList.Append( myActor->getIO() ); + mySelector->ClearIndex(); + mySelectionMgr->setSelectedObjects( aList, false ); + + SMESH::UpdateView(); + mySimulation->SetVisibility(false); + + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + + UpdateTable(); + SetEditCorners(); + + myBusy = false; + } +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::ClickOnOk() +{ + ClickOnApply(); + ClickOnCancel(); + return; +} + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::ClickOnCancel() +{ + mySelectionMgr->clearSelected(); + mySimulation->SetVisibility(false); + SMESH::SetPointRepresentation(false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( ActorSelection ); + disconnect(mySelectionMgr, 0, this, 0); + mySMESHGUI->ResetState(); + reject(); + return; +} + +//================================================================================= +// function : onTextChange() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText) +{ + if (myBusy) return; + myBusy = true; + + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + + mySimulation->SetVisibility(false); + + // hilight entered nodes + SMDS_Mesh* aMesh = 0; + if (myActor) + aMesh = myActor->GetObject()->GetMesh(); + + if (aMesh) { + TColStd_MapOfInteger newIndices; + + QStringList aListId = QStringList::split(" ", theNewText, false); + bool allOk = true; + for (int i = 0; i < aListId.count(); i++) { + if( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) ) + newIndices.Add( n->GetID() ); + else + { + allOk = false; + break; + } + } + + mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( myActor->getIO(), true, true ); + + if ( sender() == myCornerNodes ) + UpdateTable( allOk ); + } + + if( IsValid() ) { + buttonOk->setEnabled(true); + buttonApply->setEnabled(true); + } + + if ( sender() == myTable ) + displaySimulation(); + + myBusy = false; +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection has changed +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument() +{ + if (myBusy) return; + + if ( myIsEditCorners ) + { + // clear + myActor = 0; + + myBusy = true; + myCornerNodes->setText(""); + myBusy = false; + + if (!GroupButtons->isEnabled()) // inactive + return; + + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + + mySimulation->SetVisibility(false); + + // get selected mesh + SALOME_ListIO aList; + mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); + + if (aList.Extent() != 1) + { + UpdateTable(); + return; + } + + Handle(SALOME_InteractiveObject) anIO = aList.First(); + myMesh = SMESH::GetMeshByIO(anIO); + if (myMesh->_is_nil()) + return; + + myActor = SMESH::FindActorByEntry(anIO->getEntry()); + + } + + if (!myActor) + return; + + // get selected nodes + QString aString = ""; + int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString); + + if ( myIsEditCorners ) + { + myBusy = true; + myCornerNodes->setText(aString); + myBusy = false; + + UpdateTable(); + } + else if ( myTable->isEnabled() && nbNodes == 1 ) + { + myBusy = true; + int theRow = myTable->currentRow(), theCol = myTable->currentColumn(); + if ( theCol == 1 ) + myTable->setText(theRow, 1, aString); + myBusy = false; + } + + if ( IsValid() ) + { + buttonOk->setEnabled( true ); + buttonApply->setEnabled( true ); + } + + displaySimulation(); +} + +//================================================================================= +// function : displaySimulation() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::displaySimulation() +{ + if (!myIsEditCorners) { + SMESH::TElementSimulation::TVTKIds anIds; + + // Collect ids from the dialog + int anID; + bool ok; + int aDisplayMode = VTK_SURFACE; + + if ( myType == QUAD_EDGE ) + { + anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->text(0, 0).toInt() ) ); + anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->text(0, 2).toInt() ) ); + anID = (myTable->text(0, 1)).toInt(&ok); + if (!ok) anID = (myTable->text(0, 0)).toInt(); + anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) ); + aDisplayMode = VTK_WIREFRAME; + } + else + { + for ( int row = 0; row < myNbCorners; row++ ) + anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->text(row, 0).toInt() ) ); + + for ( int row = 0; row < myTable->numRows(); row++ ) + { + anID = (myTable->text(row, 1)).toInt(&ok); + if (!ok) { + anID = (myTable->text(row, 0)).toInt(); + aDisplayMode = VTK_WIREFRAME; + } + anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) ); + } + } + + mySimulation->SetPosition(myActor,myType,anIds,aDisplayMode,myReverseCB->isChecked()); + SMESH::UpdateView(); + } +} + +//================================================================================= +// function : SetEditCorners() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::SetEditCorners() +{ + myCornerNodes->setFocus(); + myIsEditCorners = true; + + SelectionIntoArgument(); +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog() +{ + if (GroupConstructors->isEnabled()) { + GroupConstructors->setEnabled(false); + GroupArguments->setEnabled(false); + GroupButtons->setEnabled(false); + mySimulation->SetVisibility(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + } +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog() +{ + /* Emit a signal to deactivate the active dialog */ + mySMESHGUI->EmitSignalDeactivateDialog(); + + GroupConstructors->setEnabled(true); + GroupArguments->setEnabled(true); + GroupButtons->setEnabled(true); + + SMESH::SetPointRepresentation(true); + + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( NodeSelection ); + SelectionIntoArgument(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*) +{ + if (GroupConstructors->isEnabled()) + return; + ActivateThisDialog(); + return; +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::closeEvent (QCloseEvent*) +{ + /* same than click on cancel button */ + ClickOnCancel(); + return; +} + +//================================================================================= +// function : hideEvent() +// purpose : caused by ESC key +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::hideEvent (QHideEvent*) +{ + if (!isMinimized()) + ClickOnCancel(); +} + +//================================================================================= +// function : onReverse() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::onReverse (int state) +{ + if (!IsValid()) + return; + + if (state >= 0) { + mySimulation->SetVisibility(false); + displaySimulation(); + } +} + + +//================================================================================= +// function : IsValid() +// purpose : +//================================================================================= +bool SMESHGUI_AddQuadraticElementDlg::IsValid() +{ + SMDS_Mesh* aMesh = 0; + if (myActor) + aMesh = myActor->GetObject()->GetMesh(); + if (!aMesh) + return false; + + bool ok; + + for ( int row = 0; row < myTable->numRows(); row++ ) + { + int anID = (myTable->text(row, 1)).toInt(&ok); + if ( !ok ) + return false; + + const SMDS_MeshNode * aNode = aMesh->FindNode(anID); + if ( !aNode ) + return false; + } + + return true; +} + +//================================================================================= +// function : UpdateTable() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity ) +{ + QStringList aListCorners = QStringList::split(" ", myCornerNodes->text(), false); + + if ( aListCorners.count() == myNbCorners && theConersValidity ) + { + myTable->setEnabled( true ); + + // clear the Middle column + for ( int row = 0; row < myTable->numRows(); row++ ) + myTable->setText( row, 1, ""); + + int* aFirstColIds; + int* aLastColIds; + + switch (myType) { + case QUAD_EDGE: + aFirstColIds = FirstEdgeIds; + aLastColIds = LastEdgeIds; + break; + case QUAD_TRIANGLE: + aFirstColIds = FirstTriangleIds; + aLastColIds = LastTriangleIds; + break; + case QUAD_QUADRANGLE: + aFirstColIds = FirstQuadrangleIds; + aLastColIds = LastQuadrangleIds; + break; + case QUAD_TETRAHEDRON: + aFirstColIds = FirstTetrahedronIds; + aLastColIds = LastTetrahedronIds; + break; + case QUAD_PYRAMID: + aFirstColIds = FirstPyramidIds; + aLastColIds = LastPyramidIds; + break; + case QUAD_PENTAHEDRON: + aFirstColIds = FirstPentahedronIds; + aLastColIds = LastPentahedronIds; + break; + case QUAD_HEXAHEDRON: + aFirstColIds = FirstHexahedronIds; + aLastColIds = LastHexahedronIds; + break; + } + + // fill the First and the Last columns + for (int i = 0, iEnd = myTable->numRows(); i < iEnd; i++) + myTable->setText( i, 0, aListCorners[ aFirstColIds[i] ] ); + + for (int i = 0, iEnd = myTable->numRows(); i < iEnd; i++) + myTable->setText( i, 2, aListCorners[ aLastColIds[i] ] ); + } + else + { + // clear table + for ( int row = 0; row < myTable->numRows(); row++ ) + for ( int col = 0; col < myTable->numCols(); col++ ) + myTable->setText(row, col, ""); + + myTable->setEnabled( false ); + } +} + + +//================================================================================= +// function : onTableActivate() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol, int theButton, const QPoint& theMousePos ) +{ + if ( theButton == 1 && theCol == 1 ) + myIsEditCorners = false; + + displaySimulation(); + return; +} + + +//================================================================================= +// function : onCellTextChange() +// purpose : +//================================================================================= +void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol) +{ + onTextChange( myTable->text(theRow, theCol) ); +} + + +QWidget* SMESHGUI_IdEditItem::createEditor() const +{ + QLineEdit *aLineEdit = new QLineEdit(text(), table()->viewport()); + aLineEdit->setValidator( new SMESHGUI_IdValidator(table()->viewport(), "validator", 1) ); + return aLineEdit; +} diff --git a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.h b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.h new file mode 100644 index 000000000..2d1fa8631 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.h @@ -0,0 +1,109 @@ +#ifndef DIALOGBOX_ADD_QUADRATIC_ELEMENT_H +#define DIALOGBOX_ADD_QUADRATIC_ELEMENT_H + +#include "LightApp_SelectionMgr.h" + +// QT Includes +#include +#include + +class QButtonGroup; +class QGroupBox; +class QLineEdit; +class QPushButton; +class QRadioButton; +class QCheckBox; +class QTable; +class SMESHGUI; +class SMESH_Actor; +class SVTK_Selector; + +namespace SMESH{ + struct TElementSimulation; +} + +// IDL Headers +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +enum { QUAD_EDGE, QUAD_TRIANGLE, QUAD_QUADRANGLE, QUAD_TETRAHEDRON, QUAD_PYRAMID, QUAD_PENTAHEDRON, QUAD_HEXAHEDRON }; + +//================================================================================= +// class : SMESHGUI_AddQuadraticElementDlg +// purpose : +//================================================================================= +class SMESHGUI_AddQuadraticElementDlg : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule, + const int theType, + const char* = 0, + bool modal = FALSE, WFlags fl = 0 ); + ~SMESHGUI_AddQuadraticElementDlg(); + +private: + void Init (); + void closeEvent (QCloseEvent*); + void hideEvent (QHideEvent*); /* ESC key */ + void enterEvent (QEvent*); /* mouse enter the QWidget */ + void displaySimulation(); + void UpdateTable( bool theConersValidity = true ); + bool IsValid(); + + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ + LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ + int myNbCorners; /* The required number of corners */ + bool myBusy; + SVTK_Selector* mySelector; + + SMESH::SMESH_Mesh_var myMesh; + SMESH_Actor* myActor; + SMESH::TElementSimulation* mySimulation; + + int myType; + bool myIsEditCorners; + + QButtonGroup* GroupConstructors; + QRadioButton* myRadioButton1; + + QGroupBox* GroupArguments; + QLineEdit* myCornerNodes; + QPushButton* mySelectButton; + QTable* myTable; + QCheckBox* myReverseCB; + + QGroupBox* GroupButtons; + QPushButton* buttonOk; + QPushButton* buttonCancel; + QPushButton* buttonApply; + +private slots: + + void onTextChange(const QString&); + void onCellTextChange(int, int); + void onReverse( int ); + void onCellDoubleClicked(int, int, int, const QPoint&); + + void ClickOnOk(); + void ClickOnCancel(); + void ClickOnApply(); + void SetEditCorners() ; + void SelectionIntoArgument() ; + void DeactivateActiveDialog() ; + void ActivateThisDialog() ; +}; + +class SMESHGUI_IdEditItem: public QTableItem +{ +public: + SMESHGUI_IdEditItem(QTable* table, EditType et, const QString& text ): + QTableItem(table, et, text) {}; + ~SMESHGUI_IdEditItem() {}; + + QWidget* createEditor() const; +}; + + +#endif // DIALOGBOX_ADD_QUADRATIC_ELEMENT_H diff --git a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx index 5bac21893..7551df818 100644 --- a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx @@ -362,10 +362,6 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg (SMESHGUI* theModule, /* to close dialog if study frame change */ connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), this, SLOT(ClickOnCancel())); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); } @@ -391,6 +387,10 @@ void SMESHGUI_ClippingDlg::ClickOnApply() if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) { SUIT_OverrideCursor wc; + + QWidget *aCurrWid = this->focusWidget(); + aCurrWid->clearFocus(); + aCurrWid->setFocus(); myActor->RemoveAllClippingPlanes(); diff --git a/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx b/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx index 32e4860ac..4f97f992d 100644 --- a/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx @@ -160,9 +160,6 @@ void SMESHGUI_CreateHypothesesDlg::Init() connect(ListAlgoDefinition, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); connect(ListAlgoDefinition, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(onDoubleClicked(QListViewItem*))); - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); } diff --git a/src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx b/src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx index caa762e9e..d2f316fda 100755 --- a/src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx @@ -269,9 +269,6 @@ void SMESHGUI_CreatePatternDlg::Init( const int theType ) activateSelection(); onSelectionDone(); - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); } diff --git a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx index abced02c6..02ac5a08d 100644 --- a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx @@ -114,19 +114,17 @@ class TPolySimulation{ float anRGB[3]; vtkProperty* aProp = vtkProperty::New(); - GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); + GetColor( "SMESH", "selection_element_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); myPreviewActor->SetProperty( aProp ); + float aFactor,aUnits; + myPreviewActor->SetResolveCoincidentTopology(true); + myPreviewActor->GetPolygonOffsetParameters(aFactor,aUnits); + myPreviewActor->SetPolygonOffsetParameters(aFactor,0.2*aUnits); aProp->Delete(); - vtkProperty* aBackProp = vtkProperty::New(); - GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) ); - aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); - myPreviewActor->SetBackfaceProperty( aBackProp ); - aBackProp->Delete(); - myViewWindow->AddActor( myPreviewActor ); - + } @@ -139,7 +137,7 @@ class TPolySimulation{ vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid(); myGrid->SetPoints(aGrid->GetPoints()); - if (theReset) ResetGrid(theReset); + ResetGrid(theReset); vtkIdList *anIds = vtkIdList::New(); @@ -365,10 +363,6 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::Init() /* to close dialog if study change */ connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; - /* Move widget on the botton right corner of main widget */ - int x, y ; - mySMESHGUI->DefineDlgPosition( this, x, y ) ; - this->move( x, y ) ; this->show() ; /* displays Dialog */ ConstructorsClicked(0); @@ -458,6 +452,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnApply() { if ( myNbOkElements>0 && !mySMESHGUI->isActiveStudyLocked()) { + if(checkEditLine(false) == -1) {return;} busy = true; if (GetConstructorId() == 0) { @@ -530,7 +525,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnApply() unsigned int anEntityMode = myActor->GetEntityMode(); myActor->SetEntityMode(SMESH_Actor::eVolumes | anEntityMode); } - ConstructorsClicked( GetConstructorId() ); + //ConstructorsClicked( GetConstructorId() ); busy = false; } } @@ -541,6 +536,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnApply() //================================================================================= void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnOk() { + if(checkEditLine(false) == -1) {return;} ClickOnApply() ; ClickOnCancel() ; } @@ -572,6 +568,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnCancel() void SMESHGUI_CreatePolyhedralVolumeDlg::onTextChange(const QString& theNewText) { if ( busy ) return; + if (checkEditLine() == -1) return; busy = true; mySimulation->SetVisibility(false); @@ -706,6 +703,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::SelectionIntoArgument() } busy = true; myEditCurrentArgument->setText( aString ); + if (checkEditLine() == -1) {busy = false;return;} busy = false; break; } @@ -721,6 +719,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::SelectionIntoArgument() } busy = true; myEditCurrentArgument->setText( aString ); + if (checkEditLine() == -1) {busy = false;return;} busy = false; // OK @@ -733,6 +732,82 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::SelectionIntoArgument() displaySimulation(); } +/*\brief int SMESHGUI_CreatePolyhedralVolumeDlg::checkEditLine() + * Checking of indices in edit line. + * If incorecct indices in edit line warning message appear and myEditCurrentArgument remove last index. + * \retval 1 - if all ok(or no indices in edit line), -1 - if there are incorrect indices. + */ +int SMESHGUI_CreatePolyhedralVolumeDlg::checkEditLine(bool checkLast) +{ + QString aString = ""; + SMDS_Mesh* aMesh = 0; + + if(myMesh->_is_nil()) return 1; + if(!myActor){ + myActor = SMESH::FindActorByObject(myMesh); + if(!myActor) + return 1; + } + + aMesh = myActor->GetObject()->GetMesh(); + + // checking for nodes + if (checkLast && myEditCurrentArgument->text().right(1) != QString(" ") ) return 1; + QStringList aListId = QStringList::split( " ", myEditCurrentArgument->text() ); + for ( int i = 0; i < aListId.count(); i++ ){ + switch (GetConstructorId()){ + case 0:{ // nodes + const SMDS_MeshNode * aNode = aMesh->FindNode( aListId[ i ].toInt() ); + if( !aNode ){ + std::string aWarning; + aWarning = "The incorrect indices of nodes!"; + SUIT_MessageBox::warn1(SMESHGUI::desktop(), + QObject::tr("SMESH_POLYEDRE_CREATE_ERROR"), + QObject::tr(aWarning.c_str()), + QObject::tr("SMESH_BUT_OK")); + + myEditCurrentArgument->clear(); + myEditCurrentArgument->setText( aString ); + return -1; + } + + break; + } + case 1:{ // faces + bool aElemIsOK = true; + const SMDS_MeshElement * aElem = aMesh->FindElement( aListId[ i ].toInt() ); + if (!aElem) + { + aElemIsOK = false; + } + else + { + SMDSAbs_ElementType aType = aMesh->GetElementType( aElem->GetID(),true ); + if (aType != SMDSAbs_Face){ + aElemIsOK = false; + } + } + if (!aElemIsOK){ + std::string aWarning; + aWarning = "The incorrect indices of faces!"; + SUIT_MessageBox::warn1(SMESHGUI::desktop(), + QObject::tr("SMESH_POLYEDRE_CREATE_ERROR"), + QObject::tr(aWarning.c_str()), + QObject::tr("SMESH_BUT_OK")); + + myEditCurrentArgument->clear(); + myEditCurrentArgument->setText( aString ); + return -1; + } + break; + } + } + aString += aListId[ i ] + " "; + } + + return 1; +} + //======================================================================= //function : displaySimulation //purpose : @@ -743,7 +818,11 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::displaySimulation() { SMESH::TPolySimulation::TVTKIds aVTKIds; vtkIdType aType = VTK_CONVEX_POINT_SET ; - if (GetConstructorId() == 0){ + SMDS_Mesh* aMesh = 0; + if ( myActor ){ + aMesh = myActor->GetObject()->GetMesh(); + } + if (GetConstructorId() == 0 && aMesh){ if (!AddButton->isEnabled()){ QListBoxItem* anItem; mySimulation->ResetGrid(true); @@ -751,6 +830,8 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::displaySimulation() QStringList anIds = QStringList::split(" ", anItem->text()); SMESH::TPolySimulation::TVTKIds aVTKIds_faces; for (QStringList::iterator it = anIds.begin(); it != anIds.end(); ++it){ + const SMDS_MeshNode * aNode = aMesh->FindNode( (*it).toInt() ); + if (!aNode) continue; vtkIdType aId = myActor->GetObject()->GetNodeVTKId( (*it).toInt() ) ; aVTKIds.push_back(aId); aVTKIds_faces.push_back(aId); @@ -776,35 +857,30 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::displaySimulation() aType = VTK_POLYGON; mySimulation->SetPosition(myActor, aType, aVTKIds); } - }else if(GetConstructorId() == 1){ - SMDS_Mesh* aMesh = 0; - if ( myActor ){ - aMesh = myActor->GetObject()->GetMesh(); - } - if ( aMesh ) { - QStringList aListId = QStringList::split( " ", myEditCurrentArgument->text(), false); - for ( int i = 0; i < aListId.count(); i++ ) - { - const SMDS_MeshElement * anElem = aMesh->FindElement( aListId[ i ].toInt() ); - if ( !anElem ) - return; + }else if(GetConstructorId() == 1 && aMesh){ + QStringList aListId = QStringList::split( " ", myEditCurrentArgument->text(), false); + for ( int i = 0; i < aListId.count(); i++ ) + { + const SMDS_MeshElement * anElem = aMesh->FindElement( aListId[ i ].toInt() ); + if ( !anElem ) continue; + SMDSAbs_ElementType aFaceType = aMesh->GetElementType( anElem->GetID(),true ); + if (aFaceType != SMDSAbs_Face) continue; - SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); - SMESH::TPolySimulation::TVTKIds aVTKIds_faces; - while( anIter->more() ) + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + SMESH::TPolySimulation::TVTKIds aVTKIds_faces; + while( anIter->more() ) if ( const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next() ){ vtkIdType aId = myActor->GetObject()->GetNodeVTKId( aNode->GetID() ) ; aVTKIds.push_back(aId); aVTKIds_faces.push_back(aId); } - if(!Preview->isChecked()){ - aType = VTK_POLYGON; - mySimulation->SetPosition(myActor, aType, aVTKIds_faces); - } + if(!Preview->isChecked()){ + aType = VTK_POLYGON; + mySimulation->SetPosition(myActor, aType, aVTKIds_faces); } - if(Preview->isChecked()) - mySimulation->SetPosition(myActor, aType, aVTKIds); - } + } + if(Preview->isChecked()) + mySimulation->SetPosition(myActor, aType, aVTKIds); } SMESH::UpdateView(); } @@ -917,9 +993,10 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::onAdd() mySelectionMgr->selectedObjects( selected ); int aNbSel = selected.Extent(); if (aNbSel == 0 || !myActor || myMesh->_is_nil()) return; + + if (this->checkEditLine(false) == -1) return; busy = true; - if ( !(myEditCurrentArgument->text().isEmpty()) ) { myFacesByNodes->insertItem(myEditCurrentArgument->text()); diff --git a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h index 5070b4471..be9dca196 100644 --- a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h +++ b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h @@ -76,6 +76,8 @@ private: int GetConstructorId(); void displaySimulation(); + int checkEditLine(bool checkLast=true); /*! Checking for indices, return 1 if all ok, esle -1*/ + SMESHGUI* mySMESHGUI ; /* Current SMESHGUI object */ LightApp_SelectionMgr* mySelectionMgr ; /* User shape selection */ SVTK_Selector* mySelector; diff --git a/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx b/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx index 90f42d96a..44373571f 100644 --- a/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx @@ -162,9 +162,6 @@ void SMESHGUI_DeleteGroupDlg::Init () connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate())); connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose())); - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); // set selection mode diff --git a/src/SMESHGUI/SMESHGUI_Dialog.cxx b/src/SMESHGUI/SMESHGUI_Dialog.cxx index a3277e0a7..fc5938927 100644 --- a/src/SMESHGUI/SMESHGUI_Dialog.cxx +++ b/src/SMESHGUI/SMESHGUI_Dialog.cxx @@ -62,10 +62,6 @@ SMESHGUI_Dialog::~SMESHGUI_Dialog() void SMESHGUI_Dialog::show() { adjustSize(); - SUIT_Desktop *PP = desktop(); - int x = abs( PP->x() + PP->size().width() - size().width() - 10 ), - y = abs( PP->y() + PP->size().height() - size().height() - 10 ); - move(x, y); LightApp_Dialog::show(); } diff --git a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx index c2d0185b6..9c16af4c1 100644 --- a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx @@ -290,9 +290,6 @@ void SMESHGUI_EditHypothesesDlg::Init() connect(ListHypDefinition, SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(addItem(QListBoxItem*))); connect(ListAlgoDefinition, SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(addItem(QListBoxItem*))); - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); LineEditC1A1->setFocus(); diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx index f99e00ac0..0109f1da3 100644 --- a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx @@ -186,10 +186,6 @@ void SMESHGUI_EditMeshDlg::Init() connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()) , this, SLOT(ClickOnCancel())); - // Move widget on the bottom right corner of main widget - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); // displays Dialog LineEditMesh->setFocus(); diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx index 7b68e4817..47b8e91ed 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx @@ -370,10 +370,7 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod ZSpin->editor()->installEventFilter(this); /***************************************************************/ - // set position and show dialog box - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); + this->show(); // displays Dialog } diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx index 848370451..7860471d7 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx @@ -264,10 +264,7 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule, connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); /***************************************************************/ - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); + this->show(); // displays Dialog ConstructorsClicked(0); diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index cd3d8eb65..547eae30b 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -1855,11 +1855,7 @@ void SMESHGUI_FilterDlg::Init (const QValueList& theTypes) connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate())); connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose())); - - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); - + updateMainButtons(); updateSelection(); diff --git a/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx index a6e560ffa..75b97b4c6 100644 --- a/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx @@ -343,10 +343,6 @@ void SMESHGUI_FilterLibraryDlg::Init (const QValueList& theTypes, myListBox->setCurrentItem(0); } - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); - this->show(); updateMainButtons(); diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx index b9396313b..84c05cac3 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -103,12 +103,6 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name, myGeomGroupBtn->setEnabled(false); myGeomGroupLine->setEnabled(false); } - - - /* Move widget on the botton right corner of main widget */ - int x, y ; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); } //================================================================================= @@ -116,7 +110,7 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name, // purpose : //================================================================================= SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name, - SMESH::SMESH_Group_ptr theGroup, bool modal, WFlags fl) + SMESH::SMESH_GroupBase_ptr theGroup, bool modal, WFlags fl) : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose), mySMESHGUI( theModule ), @@ -136,11 +130,6 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name, myCurrentLineEdit = myMeshGroupLine; setSelectionMode(5); } - - /* Move widget on the botton right corner of main widget */ - int x, y ; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); } //================================================================================= @@ -270,7 +259,7 @@ void SMESHGUI_GroupDlg::initDialog(bool create) myGroupLine = new QLineEdit(aSelectBox, "group line"); myGroupLine->setReadOnly(true); onSelectGroup(false); - + /***************************************************************/ QGridLayout* wg1Layout = new QGridLayout( wg1, 3, 1, 0, 6 ); wg1Layout->addWidget(aContentBox, 0, 0); @@ -287,6 +276,12 @@ void SMESHGUI_GroupDlg::initDialog(bool create) myGeomGroupLine->setReadOnly(true); //VSR ??? onSelectGeomGroup(false); + if (!create) + { + myGeomGroupBtn->setEnabled(false); + myGeomGroupLine->setEnabled(false); + } + /***************************************************************/ QGridLayout* wg2Layout = new QGridLayout( wg2, 2, 3, 0, 6 ); wg2Layout->addWidget(geomObject, 0, 0); @@ -302,6 +297,26 @@ void SMESHGUI_GroupDlg::initDialog(bool create) myWGStack->addWidget( wg2, myGrpTypeGroup->id(rb2) ); /***************************************************************/ + QGroupBox* aColorBox = new QGroupBox(this, "color box"); + aColorBox->setTitle(tr("SMESH_SET_COLOR")); + + mySelectColorGroup = new QCheckBox(aColorBox, "color checkbox"); + mySelectColorGroup->setText(tr("SMESH_CHECK_COLOR")); + mySelectColorGroup->setMinimumSize(50, 0); + + myColorGroupLine = new QLineEdit(aColorBox, "color line"); + myColorGroupLine->setReadOnly(false); + onSelectColorGroup(false); + + /***************************************************************/ + QHBoxLayout* aColorLayout = new QHBoxLayout(aColorBox, 15, 20); + aColorLayout->setAutoAdd(false); + + aColorLayout->addWidget(mySelectColorGroup); + aColorLayout->addWidget(myColorGroupLine); + + /***************************************************************/ + QFrame* aButtons = new QFrame(this, "button box"); aButtons->setFrameStyle(QFrame::Box | QFrame::Sunken); QHBoxLayout* aBtnLayout = new QHBoxLayout(aButtons, 11, 6); @@ -333,7 +348,8 @@ void SMESHGUI_GroupDlg::initDialog(bool create) aMainLayout->addMultiCellWidget(myGrpTypeGroup, 3, 3, 0, 2); aMainLayout->addMultiCellWidget(myWGStack, 4, 4, 0, 2); aMainLayout->setRowStretch( 5, 5 ); - aMainLayout->addMultiCellWidget(aButtons, 6, 6, 0, 2); + aMainLayout->addMultiCellWidget(aColorBox, 6, 6, 0, 2); + aMainLayout->addMultiCellWidget(aButtons, 7, 7, 0, 2); /* signals and slots connections */ connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); @@ -355,7 +371,9 @@ void SMESHGUI_GroupDlg::initDialog(bool create) connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); connect(myGeomGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); - + connect(mySelectColorGroup, SIGNAL(toggled(bool)), this, SLOT(onSelectColorGroup(bool))); + connect(myColorGroupLine, SIGNAL(textChanged(const QString&)), this, SLOT(onNbColorsChanged(const QString&))); + connect(aOKBtn, SIGNAL(clicked()), this, SLOT(onOK())); connect(aApplyBtn, SIGNAL(clicked()), this, SLOT(onApply())); connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(onClose())); @@ -407,6 +425,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh) /* init data from current selection */ myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh); myGroup = SMESH::SMESH_Group::_nil(); + myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil(); myActor = SMESH::FindActorByObject(myMesh); SMESH::SetPickable(myActor); @@ -430,15 +449,17 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh) // function : Init() // purpose : //================================================================================= -void SMESHGUI_GroupDlg::init (SMESH::SMESH_Group_ptr theGroup) +void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup) { myMesh = theGroup->GetMesh(); - myGroup = SMESH::SMESH_Group::_duplicate(theGroup); - myActor = SMESH::FindActorByObject(myMesh); - if ( !myActor ) - myActor = SMESH::FindActorByObject(myGroup); - SMESH::SetPickable(myActor); + myName->setText(theGroup->GetName()); + myName->home(false); + + myColorGroupLine->setText(QString::number(theGroup->GetColorNumber())); + myColorGroupLine->home(false); + + myMeshGroupLine->setText(theGroup->GetName()); int aType = 0; switch(theGroup->GetType()) { @@ -447,27 +468,61 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Group_ptr theGroup) case SMESH::FACE: aType = 2; break; case SMESH::VOLUME: aType = 3; break; } + myTypeGroup->setButton(aType); + + myGroup = SMESH::SMESH_Group::_narrow( theGroup ); - myName->setText(myGroup->GetName()); - myName->home(false); - myMeshGroupLine->setText(myGroup->GetName()); + if ( !myGroup->_is_nil() ) + { + myGrpTypeGroup->setButton(0); + onGrpTypeChanged(0); - myCurrentLineEdit = 0; - myTypeGroup->setButton(aType); - myElements->clear(); - setSelectionMode(aType); - myTypeId = aType; - - myIdList.clear(); - if (!theGroup->IsEmpty()) { - SMESH::long_array_var anElements = myGroup->GetListOfID(); - int k = anElements->length(); - for (int i = 0; i < k; i++) { - myIdList.append(anElements[i]); - myElements->insertItem(QString::number(anElements[i])); + myActor = SMESH::FindActorByObject(myMesh); + if ( !myActor ) + myActor = SMESH::FindActorByObject(myGroup); + SMESH::SetPickable(myActor); + + myCurrentLineEdit = 0; + myElements->clear(); + setSelectionMode(aType); + myTypeId = aType; + + myIdList.clear(); + if (!myGroup->IsEmpty()) { + SMESH::long_array_var anElements = myGroup->GetListOfID(); + int k = anElements->length(); + for (int i = 0; i < k; i++) { + myIdList.append(anElements[i]); + myElements->insertItem(QString::number(anElements[i])); + } + myElements->selectAll(true); + } + } + else + { + myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( theGroup ); + + if ( !myGroupOnGeom->_is_nil() ) + { + myGrpTypeGroup->setButton(1); + onGrpTypeChanged(1); + + myActor = SMESH::FindActorByObject(myMesh); + if ( !myActor ) + myActor = SMESH::FindActorByObject(myGroup); + SMESH::SetPickable(myActor); + + QString aShapeName(""); + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + GEOM::GEOM_Object_var aGroupShape = myGroupOnGeom->GetShape(); + if (!aGroupShape->_is_nil()) + { + _PTR(SObject) aGroupShapeSO = aStudy->FindObjectID(aGroupShape->GetStudyEntry()); + aShapeName = aGroupShapeSO->GetName().c_str(); + } + myGeomGroupLine->setText( aShapeName ); + } } - myElements->selectAll(true); - } } //================================================================================= @@ -481,7 +536,10 @@ void SMESHGUI_GroupDlg::updateButtons() if (myGrpTypeId == 0) enable = !myName->text().stripWhiteSpace().isEmpty() && myElements->count() > 0; else if (myGrpTypeId == 1) - enable = !myName->text().stripWhiteSpace().isEmpty() && !CORBA::is_nil( myGeomGroup ); + { + bool isEditMode = !CORBA::is_nil( myGroupOnGeom ); + enable = !myName->text().stripWhiteSpace().isEmpty() && (!CORBA::is_nil( myGeomGroup ) || isEditMode); + } QPushButton* aBtn; aBtn = (QPushButton*) child("ok", "QPushButton"); if (aBtn) aBtn->setEnabled(enable); @@ -498,6 +556,15 @@ void SMESHGUI_GroupDlg::onNameChanged (const QString& text) updateButtons(); } +//================================================================================= +// function : onNbColorsChanged() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onNbColorsChanged (const QString& text) +{ + updateButtons(); +} + //================================================================================= // function : onTypeChanged() // purpose : Group elements type radio button management @@ -606,14 +673,27 @@ bool SMESHGUI_GroupDlg::onApply() myGroup = SMESH::AddGroup(myMesh, aType, myName->text()); myGroup->Add(anIdList.inout()); - + + int aColorNumber = myColorGroupLine->text().toInt(); + myGroup->SetColorNumber(aColorNumber); + + _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup); + + SMESH::setFileName (aMeshGroupSO, myColorGroupLine->text()); + + SMESH::setFileType (aMeshGroupSO,"COULEURGROUP"); + /* init for next operation */ myName->setText(""); + myColorGroupLine->setText(""); myElements->clear(); myGroup = SMESH::SMESH_Group::_nil(); } else { myGroup->SetName(myName->text()); + + int aColorNumber = myColorGroupLine->text().toInt(); + myGroup->SetColorNumber(aColorNumber); QValueList aAddList; QValueList::iterator anIt; @@ -654,30 +734,50 @@ bool SMESHGUI_GroupDlg::onApply() return true; } else if (myGrpTypeId == 1 && !myName->text().stripWhiteSpace().isEmpty() && - !CORBA::is_nil(myGeomGroup)) + (!CORBA::is_nil(myGeomGroup) || !CORBA::is_nil(myGroupOnGeom))) { - SMESH::ElementType aType = SMESH::ALL; - switch (myTypeId) { - case 0: aType = SMESH::NODE; break; - case 1: aType = SMESH::EDGE; break; - case 2: aType = SMESH::FACE; break; - case 3: aType = SMESH::VOLUME; break; + if (myGroupOnGeom->_is_nil()) { + SMESH::ElementType aType = SMESH::ALL; + switch (myTypeId) { + case 0: aType = SMESH::NODE; break; + case 1: aType = SMESH::EDGE; break; + case 2: aType = SMESH::FACE; break; + case 3: aType = SMESH::VOLUME; break; + } + + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + GEOM::GEOM_IGroupOperations_var aGroupOp = + SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId()); + + myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, myName->text(),myGeomGroup); + + int aColorNumber = myColorGroupLine->text().toInt(); + myGroupOnGeom->SetColorNumber(aColorNumber); + + _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom); + + SMESH::setFileName (aMeshGroupSO, myColorGroupLine->text()); + + SMESH::setFileType (aMeshGroupSO,"COULEURGROUP"); + + /* init for next operation */ + myName->setText(""); + myColorGroupLine->setText(""); + myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil(); } - - _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); - GEOM::GEOM_IGroupOperations_var aGroupOp = - SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId()); - - SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = - myMesh->CreateGroupFromGEOM(aType, myName->text(),myGeomGroup); - + else + { + myGroupOnGeom->SetName(myName->text()); + + int aColorNumber = myColorGroupLine->text().toInt(); + myGroupOnGeom->SetColorNumber(aColorNumber); + } + mySMESHGUI->updateObjBrowser(true); mySelectionMgr->clearSelected(); - /* init for next operation */ - myName->setText(""); return true; } - + return false; } @@ -782,7 +882,7 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() myGeomGroupLine->setEnabled(true); updateButtons(); } else { - SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface(IO); + SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface(IO); if (aGroup->_is_nil()) { myIsBusy = false; @@ -915,6 +1015,8 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() if (!myActor) { if (!myGroup->_is_nil()) myActor = SMESH::FindActorByObject(myGroup); + else if(!myGroupOnGeom->_is_nil()) + myActor = SMESH::FindActorByObject(myGroupOnGeom); else myActor = SMESH::FindActorByObject(myMesh); } @@ -997,6 +1099,23 @@ void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on) } } +//================================================================================= +// function : (onSelectColorGroup) +// purpose : Called when setting a color on group +//================================================================================= +void SMESHGUI_GroupDlg::onSelectColorGroup(bool on) +{ + if (on) { + setSelectionMode(7); + } + else { + myColorGroupLine->setText(""); + myCurrentLineEdit = 0; + if (myTypeId != -1) + setSelectionMode(myTypeId); + } + myColorGroupLine->setEnabled(on); +} //================================================================================= // function : setCurrentSelection() diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.h b/src/SMESHGUI/SMESHGUI_GroupDlg.h index af101fcff..3d741d43d 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.h +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.h @@ -69,7 +69,7 @@ public: bool modal = FALSE, WFlags fl = 0 ); SMESHGUI_GroupDlg( SMESHGUI*, const char* name, - SMESH::SMESH_Group_ptr theGroup, + SMESH::SMESH_GroupBase_ptr theGroup, bool modal = FALSE, WFlags fl = 0 ); ~SMESHGUI_GroupDlg(); @@ -95,18 +95,20 @@ private slots: void onSelectSubMesh(bool on); void onSelectGroup(bool on); void onSelectGeomGroup(bool on); + void onSelectColorGroup(bool on); void setCurrentSelection(); void setFilters(); void onSort(); void onNameChanged(const QString& text); + void onNbColorsChanged(const QString& text); void onFilterAccepted(); private: void initDialog(bool create); void init(SMESH::SMESH_Mesh_ptr theMesh); - void init(SMESH::SMESH_Group_ptr theGroup); + void init(SMESH::SMESH_GroupBase_ptr theGroup); void closeEvent(QCloseEvent* e); void enterEvent (QEvent*); void hideEvent (QHideEvent*); /* ESC key */ @@ -141,12 +143,16 @@ private: QPushButton* myGroupBtn; QLineEdit* myGroupLine; + QCheckBox* mySelectColorGroup; + QLineEdit* myColorGroupLine; + QCheckBox* mySelectGeomGroup; QPushButton* myGeomGroupBtn; QLineEdit* myGeomGroupLine; SMESH::SMESH_Mesh_var myMesh; SMESH::SMESH_Group_var myGroup; + SMESH::SMESH_GroupOnGeom_var myGroupOnGeom; QValueList myIdList; GEOM::GEOM_Object_var myGeomGroup; diff --git a/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx index cdefc1e42..a43bb38ad 100644 --- a/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx @@ -185,9 +185,6 @@ void SMESHGUI_GroupOpDlg::Init() connect(myBtn1, SIGNAL(clicked()), this, SLOT(onFocusChanged())); connect(myBtn2, SIGNAL(clicked()), this, SLOT(onFocusChanged())); - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); // set selection mode diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx index 98d84f8a9..5f4d6d2f4 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx @@ -375,8 +375,8 @@ namespace SMESH{ try { res = aMesh->AddHypothesis(aShapeObject, aHyp); if (res < SMESH::HYP_UNKNOWN_FATAL) { - _PTR(SObject) SH = SMESH::FindSObject(aHyp); - if (SM && SH) { + _PTR(SObject) aSH = SMESH::FindSObject(aHyp); + if (SM && aSH) { SMESH::ModifiedMesh(SM, false); } } diff --git a/src/SMESHGUI/SMESHGUI_MergeNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_MergeNodesDlg.cxx index af1a68a57..d089d8cbd 100644 --- a/src/SMESHGUI/SMESHGUI_MergeNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MergeNodesDlg.cxx @@ -273,10 +273,6 @@ SMESHGUI_MergeNodesDlg::SMESHGUI_MergeNodesDlg( SMESHGUI* theModule, const char* /* to close dialog if study change */ connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); /* displays Dialog */ resize(0,0); diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx index 58fc13179..b1956dce0 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx @@ -364,10 +364,6 @@ SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg (SMESHGUI* theModule, connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged())); - // resize and move dialog, then show - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); // init dialog with current selection diff --git a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx index c7ceb4bb9..53e8c25a7 100755 --- a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx @@ -351,9 +351,6 @@ void SMESHGUI_MeshPatternDlg::Init() activateSelection(); onSelectionDone(); - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); } @@ -431,6 +428,9 @@ bool SMESHGUI_MeshPatternDlg::onApply() SMESH::UpdateView(); mySMESHGUI->updateObjBrowser(true); + + mySelEdit[ Ids ]->setText(""); + return true; } else { QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"), diff --git a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx index 1f8dbe539..c51f49904 100644 --- a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx @@ -224,9 +224,6 @@ void SMESHGUI_MoveNodesDlg::Init() reset(); setEnabled(true); - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); // set selection mode diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx index 74ad155bd..7d1cb9808 100755 --- a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx @@ -388,6 +388,35 @@ SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds() anActor = myActor; if (anActor != 0) { + // skl 07.02.2006 + SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh(); + if( myFilterType == SMESHGUI_TriaFilter || + myFilterType == SMESHGUI_QuadFilter || + myFilterType == SMESHGUI_FaceFilter ) { + SMDS_FaceIteratorPtr it = aMesh->facesIterator(); + while(it->more()) { + const SMDS_MeshFace* f = it->next(); + if(myFilterType == SMESHGUI_FaceFilter) { + myIds.Add(f->GetID()); + } + else if( myFilterType==SMESHGUI_TriaFilter && + ( f->NbNodes()==3 || f->NbNodes()==6 ) ) { + myIds.Add(f->GetID()); + } + else if( myFilterType==SMESHGUI_QuadFilter && + ( f->NbNodes()==4 || f->NbNodes()==8 ) ) { + myIds.Add(f->GetID()); + } + } + } + else if(myFilterType == SMESHGUI_VolumeFilter) { + SMDS_VolumeIteratorPtr it = aMesh->volumesIterator(); + while(it->more()) { + const SMDS_MeshVolume* f = it->next(); + myIds.Add(f->GetID()); + } + } + /* commented by skl 07.02.2006 TVisualObjPtr aVisualObj = anActor->GetObject(); vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid(); if (aGrid != 0) { @@ -411,6 +440,7 @@ SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds() } } } + */ } } diff --git a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx index 0e29413e7..9b77ced9f 100644 --- a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx @@ -374,10 +374,6 @@ void SMESHGUI_NodesDlg::Init () /* to close dialog if study frame change */ connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel())); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); // set selection mode diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx index d51137871..cef1b66eb 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx @@ -199,11 +199,6 @@ void SMESHGUI_Preferences_ColorDlg::Init() connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); /* to close dialog if study change */ connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); - - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); } //================================================================================= diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx index e06f880b9..d9b43c81c 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx @@ -64,15 +64,6 @@ #define MARGIN_SIZE 11 #define SPACING_SIZE 6 -#define DEF_VER_X 0.01 -#define DEF_VER_Y 0.10 -#define DEF_VER_H 0.80 -#define DEF_VER_W 0.10 -#define DEF_HOR_X 0.20 -#define DEF_HOR_Y 0.01 -#define DEF_HOR_H 0.12 -#define DEF_HOR_W 0.60 - using namespace std; // Only one instance is allowed @@ -125,6 +116,14 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* mySMESHGUI( theModule ), mySelectionMgr( property ? SMESH::GetSelectionMgr( theModule ) : 0 ) { + DEF_VER_X = 0.01; + DEF_VER_Y = 0.10; + DEF_VER_H = 0.80; + DEF_VER_W = 0.10; + DEF_HOR_X = 0.20; + DEF_HOR_Y = 0.01; + DEF_HOR_H = 0.12; + DEF_HOR_W = 0.60; setName("SMESHGUI_Preferences_ScalarBarDlg"); setCaption( property ? tr("SMESH_PROPERTIES_SCALARBAR") : tr("SMESH_PREFERENCES_SCALARBAR")); setSizeGripEnabled(TRUE); @@ -756,6 +755,8 @@ void SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize( const double x, //================================================================================================= void SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged() { + this->initScalarBarFromResources(); + int aOrientation = myVertRadioBtn->isChecked(); if ( aOrientation == myIniOrientation ) setOriginAndSize( myIniX, myIniY, myIniW, myIniH ); @@ -765,3 +766,41 @@ void SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged() aOrientation ? DEF_VER_W : DEF_HOR_W, aOrientation ? DEF_VER_H : DEF_HOR_H ); } + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::initScalarBarFromResources() + * + * Rereading vertical and horizontal default positions from resources. + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::initScalarBarFromResources() +{ + SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI ); + QString name; + if (mgr){ + // initialize from resoources + + // horizontal + name = QString("scalar_bar_horizontal_%1"); + if (mgr->hasValue("SMESH", name.arg( "x" ))) + DEF_HOR_X = mgr->doubleValue("SMESH", name.arg( "x" )); + if (mgr->hasValue("SMESH", name.arg( "y" ))) + DEF_HOR_Y = mgr->doubleValue("SMESH", name.arg( "y" )); + if (mgr->hasValue("SMESH", name.arg( "width" ))) + DEF_HOR_W = mgr->doubleValue("SMESH", name.arg( "width" )); + if (mgr->hasValue("SMESH", name.arg( "height" ))) + DEF_HOR_H = mgr->doubleValue("SMESH", name.arg( "height" )); + + // vertical + name = QString("scalar_bar_vertical_%1"); + if (mgr->hasValue("SMESH", name.arg( "x" ))) + DEF_VER_X = mgr->doubleValue("SMESH", name.arg( "x" )); + if (mgr->hasValue("SMESH", name.arg( "y" ))) + DEF_VER_Y = mgr->doubleValue("SMESH", name.arg( "y" )); + if (mgr->hasValue("SMESH", name.arg( "width" ))) + DEF_VER_W = mgr->doubleValue("SMESH", name.arg( "width" )); + if (mgr->hasValue("SMESH", name.arg( "height" ))) + DEF_VER_H = mgr->doubleValue("SMESH", name.arg( "height" )); + } +} diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h index 5d4dce8a9..11fb1a9bd 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h +++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h @@ -63,6 +63,7 @@ protected: static SMESHGUI_Preferences_ScalarBarDlg* myDlg; void closeEvent( QCloseEvent* e ); void setOriginAndSize( const double x, const double y, const double w, const double h ); + void initScalarBarFromResources(); protected slots: void onOk(); @@ -80,6 +81,8 @@ private: SMESH_Actor* myActor; double myIniX, myIniY, myIniW, myIniH; int myIniOrientation; + double DEF_VER_X,DEF_VER_Y,DEF_VER_H,DEF_VER_W; + double DEF_HOR_X,DEF_HOR_Y,DEF_HOR_H,DEF_HOR_W; QGroupBox* myRangeGrp; QLineEdit* myMinEdit; diff --git a/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.cxx index 7606ccf2b..79245d625 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.cxx @@ -205,11 +205,6 @@ SMESHGUI_Preferences_SelectionDlg::SMESHGUI_Preferences_SelectionDlg( SMESHGUI* connect(aOKBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(reject())); - - /* Move widget on the botton right corner of main widget */ - int x, y ; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); } //================================================================================= diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx index ef6dfa0d2..885fd642c 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx @@ -219,10 +219,6 @@ void SMESHGUI_RemoveElementsDlg::Init() connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); /* displays Dialog */ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) diff --git a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx index 775bff01a..48cc0dcf1 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx @@ -218,10 +218,6 @@ void SMESHGUI_RemoveNodesDlg::Init() connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); /* displays Dialog */ SMESH::SetPointRepresentation(true); diff --git a/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx b/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx index fcecbbef2..c16086f13 100644 --- a/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx @@ -211,10 +211,6 @@ void SMESHGUI_RenumberingDlg::Init() /* to close dialog if study change */ connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); /* displays Dialog */ myEditCurrentArgument = LineEditMesh; diff --git a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx index 2722e4f40..57adf2a13 100644 --- a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx @@ -334,10 +334,6 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule, const char* connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); /* displays Dialog */ ConstructorsClicked(0); diff --git a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx index baf1359ce..e0578c538 100644 --- a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx @@ -323,10 +323,6 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule, const char* nam connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); /* displays Dialog */ ConstructorsClicked(0); diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx index 88d44c541..c7fe08a39 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.cxx +++ b/src/SMESHGUI/SMESHGUI_Selection.cxx @@ -110,7 +110,7 @@ QtxValue SMESHGUI_Selection::param( const int ind, const QString& p ) const else if ( p=="hasReference" ) val = QtxValue( hasReference( ind ) ); // else if ( p=="isVisible" ) val = QtxValue( isVisible( ind ) ); - // printf( "--> param() : [%s] = %s (%s)\n", p.latin1(), val.toString().latin1(), val.typeName() ); + // printf( "--> param() : [%s] = %s (%s)\n", p.latin1(), val.toString().latin1(), val.typeName() ); //if ( val.type() == QVariant::List ) //cout << "size: " << val.toList().count() << endl; @@ -401,6 +401,8 @@ int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study ) } if( aFTag>10 ) res = GROUP; + else + res = SUBMESH; break; } diff --git a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx index eed4a15ac..014c89344 100644 --- a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx @@ -313,10 +313,6 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( SMESHGUI* theModule, const char* name, connect(LineEdit5, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); connect(LineEdit6, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); /* displays Dialog */ ConstructorsClicked(0); diff --git a/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx index d437ee1ef..0a43b137c 100644 --- a/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx @@ -203,10 +203,7 @@ void SMESHGUI_ShapeByMeshDlg::Init() activateSelection(); onSelectionDone(); - - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); + this->show(); } diff --git a/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx b/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx index 754232f6a..3cf3f2b2f 100755 --- a/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx @@ -233,9 +233,6 @@ void SMESHGUI_SingleEditDlg::Init() myApplyBtn->setEnabled(false); setEnabled(true); - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); // set selection mode diff --git a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx index c2a8b1312..1b875806b 100644 --- a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx @@ -290,10 +290,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule, const char* n SLOT(onSelectMesh(bool))); /***************************************************************/ - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); + this->show(); // displays Dialog } diff --git a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx index 30b5eb0ea..02c5c042f 100644 --- a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx @@ -164,9 +164,6 @@ SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg( SMESHGUI* theModul // resize and move dialog, then show this->setMinimumSize(270, 428); - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); // init dialog with current selection diff --git a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx index 1137ec4ec..158df488a 100644 --- a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx @@ -317,10 +317,6 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule, const char* nam connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); /* displays Dialog */ ConstructorsClicked(0); diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx index c6c58b328..a4e006c4f 100644 --- a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx @@ -293,10 +293,6 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule, const cha connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); /* displays Dialog */ ConstructorsClicked(0); diff --git a/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx b/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx index b390e717a..4e2a41b7a 100644 --- a/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx @@ -146,10 +146,6 @@ SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( SMESHGUI* theModule, connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnOk())); connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged())); - /* Move widget on the botton right corner of main widget */ - int x, y; - mySMESHGUI->DefineDlgPosition(this, x, y); - this->move(x, y); this->show(); } diff --git a/src/SMESHGUI/SMESHGUI_Utils.cxx b/src/SMESHGUI/SMESHGUI_Utils.cxx index 94714bcd7..383b02c5c 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.cxx +++ b/src/SMESHGUI/SMESHGUI_Utils.cxx @@ -153,6 +153,32 @@ namespace SMESH{ if (aComment) aComment->SetValue(theValue); } + + void setFileName (_PTR(SObject) theSObject, const char* theValue) + { + _PTR(Study) aStudy = GetActiveStudyDocument(); + if (aStudy->GetProperties()->IsLocked()) + return; + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + _PTR(GenericAttribute) anAttr = + aBuilder->FindOrCreateAttribute(theSObject, "AttributeExternalFileDef"); + _PTR(AttributeExternalFileDef) aFileName = anAttr; + if (aFileName) + aFileName->SetValue(theValue); + } + + void setFileType (_PTR(SObject) theSObject, const char* theValue) + { + _PTR(Study) aStudy = GetActiveStudyDocument(); + if (aStudy->GetProperties()->IsLocked()) + return; + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + _PTR(GenericAttribute) anAttr = + aBuilder->FindOrCreateAttribute(theSObject, "AttributeFileType"); + _PTR(AttributeFileType) aFileType = anAttr; + if (aFileType) + aFileType->SetValue(theValue); + } CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject, _PTR(Study) theStudy) diff --git a/src/SMESHGUI/SMESHGUI_Utils.h b/src/SMESHGUI/SMESHGUI_Utils.h index 83278e4a5..d236533fe 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.h +++ b/src/SMESHGUI/SMESHGUI_Utils.h @@ -81,6 +81,8 @@ namespace SMESH { void SetName (_PTR(SObject) theSObject, const char* theName); void SetValue (_PTR(SObject) theSObject, const char* theValue); + void setFileType (_PTR(SObject) theSObject, const char* theValue); + void setFileName (_PTR(SObject) theSObject, const char* theValue); CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject, _PTR(Study) theStudy); diff --git a/src/SMESHGUI/SMESH_icons.po b/src/SMESHGUI/SMESH_icons.po index 60dff5a19..463f6f37a 100644 --- a/src/SMESHGUI/SMESH_icons.po +++ b/src/SMESHGUI/SMESH_icons.po @@ -155,7 +155,33 @@ msgstr "mesh_tetra.png" msgid "ICON_DLG_HEXAS" msgstr "mesh_hexa.png" +#Quadratic Edge +msgid "ICON_DLG_QUADRATIC_EDGE" +msgstr "mesh_quad_edge.png" +#Quadratic Triangle +msgid "ICON_DLG_QUADRATIC_TRIANGLE" +msgstr "mesh_quad_triangle.png" + +#Quadratic Quadrangle +msgid "ICON_DLG_QUADRATIC_QUADRANGLE" +msgstr "mesh_quad_quadrangle.png" + +#Quadratic Tetrahedron +msgid "ICON_DLG_QUADRATIC_TETRAHEDRON" +msgstr "mesh_quad_tetrahedron.png" + +#Quadratic Pyramid +msgid "ICON_DLG_QUADRATIC_PYRAMID" +msgstr "mesh_quad_pyramid.png" + +#Quadratic Pentahedron +msgid "ICON_DLG_QUADRATIC_PENTAHEDRON" +msgstr "mesh_quad_pentahedron.png" + +#Quadratic Hexahedron +msgid "ICON_DLG_QUADRATIC_HEXAHEDRON" +msgstr "mesh_quad_hexahedron.png" #----------------------------------------------------------- # ObjectBrowser #----------------------------------------------------------- diff --git a/src/SMESHGUI/SMESH_images.po b/src/SMESHGUI/SMESH_images.po index 2825f19a8..16737d44a 100644 --- a/src/SMESHGUI/SMESH_images.po +++ b/src/SMESHGUI/SMESH_images.po @@ -170,6 +170,35 @@ msgstr "mesh_hexa.png" #Polyhedre msgid "ICON_DLG_POLYHEDRON" msgstr "mesh_polyhedron.png" + +#Quadratic Edge +msgid "ICON_DLG_QUADRATIC_EDGE" +msgstr "mesh_quad_edge.png" + +#Quadratic Triangle +msgid "ICON_DLG_QUADRATIC_TRIANGLE" +msgstr "mesh_quad_triangle.png" + +#Quadratic Quadrangle +msgid "ICON_DLG_QUADRATIC_QUADRANGLE" +msgstr "mesh_quad_quadrangle.png" + +#Quadratic Tetrahedron +msgid "ICON_DLG_QUADRATIC_TETRAHEDRON" +msgstr "mesh_quad_tetrahedron.png" + +#Quadratic Pyramid +msgid "ICON_DLG_QUADRATIC_PYRAMID" +msgstr "mesh_quad_pyramid.png" + +#Quadratic Pentahedron +msgid "ICON_DLG_QUADRATIC_PENTAHEDRON" +msgstr "mesh_quad_pentahedron.png" + +#Quadratic Hexahedron +msgid "ICON_DLG_QUADRATIC_HEXAHEDRON" +msgstr "mesh_quad_hexahedron.png" + #----------------------------------------------------------- # ObjectBrowser #----------------------------------------------------------- diff --git a/src/SMESHGUI/SMESH_msg_en.po b/src/SMESHGUI/SMESH_msg_en.po index b0c73c29e..3fcce77ae 100644 --- a/src/SMESHGUI/SMESH_msg_en.po +++ b/src/SMESHGUI/SMESH_msg_en.po @@ -144,6 +144,10 @@ msgstr "Activate Link Selection Mode" msgid "SMESH_WRN_EMPTY_NAME" msgstr "Empty name is not valid" +#Smesh polyedre cretion error +msgid "SMESH_POLYEDRE_CREATE_ERROR" +msgstr "Polyedron creation error" + #------------------------------------------------------------------------- # MEN #------------------------------------------------------------------------- @@ -914,6 +918,14 @@ msgstr "Group on geometry" msgid "SMESH_GEOM_GROUP" msgstr "Geometry group" +#Color group +msgid "SMESH_SET_COLOR" +msgstr "Color group" + +#Check color group +msgid "SMESH_CHECK_COLOR" +msgstr "Color number" + #%1 SubMeshes msgid "SMESH_SUBMESH_SELECTED" msgstr "%1 SubMeshes" @@ -1219,6 +1231,9 @@ msgstr "Such dimention hypothesis is already assigned to the shape" msgid "SMESH_HYP_8" msgstr "Hypothesis and submesh dimensions mismatch" +msgid "SMESH_HYP_9" +msgstr "Shape is neither the main one, nor its subshape, nor a valid group" + msgid "MISSING_ALGO" msgstr "%3 %2D algorithm is missing" @@ -1257,6 +1272,13 @@ msgid "SMESH_EXPORT_UNV" msgstr "During export mesh with name - \"%1\" to UNV\n" " pyramid's elements will be missed" +msgid "SMESH_EXPORT_MED_DUPLICATED_GRP" +msgstr "There are duplicated group names in mesh \"%1\".\n" + "You can cancel exporting and rename them,\n" + "otherwise some group names in the resulting MED file\n" + "will not match ones in the study.\n" + "Do you want to continue ?" + msgid "SMESH_EXPORT_MED_V2_1" msgstr "During export mesh with name - \"%1\" to MED 2.1\n" "polygons and polyhedrons elements will be missed\n" @@ -1789,6 +1811,9 @@ msgstr "Faces by nodes" msgid "SMESHGUI_CreatePolyhedralVolumeDlg::SMESH_POLYEDRE_PREVIEW" msgstr "Polyhedron preview" +msgid "SMESHGUI_CreatePolyhedralVolumeDlg::SMESH_POLYEDRE_CREATE_ERROR" +msgstr "Polyhedron creation error." + msgid "SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE" msgstr "Create polyhedral volume" @@ -1801,6 +1826,80 @@ msgstr "Polygon" msgid "SMESH_ADD_POLYGON" msgstr "Add polygon" +msgid "SMESH_ADD_QUADRATIC_EDGE_TITLE" +msgstr "Add Quadratic Edge" + +msgid "SMESH_ADD_QUADRATIC_TRIANGLE_TITLE" +msgstr "Add Quadratic Triangle" + +msgid "SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE" +msgstr "Add Quadratic Quadrangle" + +msgid "SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE" +msgstr "Add Quadratic Tetrahedron" + +msgid "SMESH_ADD_QUADRATIC_PYRAMID_TITLE" +msgstr "Add Quadratic Pyramid" + +msgid "SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE" +msgstr "Add Quadratic Pentahedron" + +msgid "SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE" +msgstr "Add Quadratic Hexahedron" + +msgid "SMESH_QUADRATIC_EDGE" +msgstr "Quadratic Edge" + +msgid "SMESH_QUADRATIC_TRIANGLE" +msgstr "Quadratic Triangle" + +msgid "SMESH_QUADRATIC_QUADRANGLE" +msgstr "Quadratic Quadrangle" + +msgid "SMESH_QUADRATIC_TETRAHEDRON" +msgstr "Quadratic Tetrahedron" + +msgid "SMESH_QUADRATIC_PYRAMID" +msgstr "Quadratic Pyramid" + +msgid "SMESH_QUADRATIC_PENTAHEDRON" +msgstr "Quadratic Pentahedron" + +msgid "SMESH_QUADRATIC_HEXAHEDRON" +msgstr "Quadratic Hexahedron" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_CORNER_NODES" +msgstr "Corner Nodes:" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_EDGE" +msgstr "Add Quadratic Edge" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_TRIANGLE" +msgstr "Add Quadratic Triangle" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_QUADRANGLE" +msgstr "Add Quadratic Quadrangle" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_TETRAHEDRON" +msgstr "Add Quadratic Tetrahedron" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_PYRAMID" +msgstr "Add Quadratic PYRAMID" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_PENTAHEDRON" +msgstr "Add Quadratic Pentahedron" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_ADD_QUADRATIC_HEXAHEDRON" +msgstr "Add Quadratic Hexahedron" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_FIRST" +msgstr "First" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_MIDDLE" +msgstr "Middle" + +msgid "SMESHGUI_AddQuadraticElementDlg::SMESH_LAST" +msgstr "Last" #---------------------------------------------------- msgid "SMESHGUI_CreatePatternDlg::CAPTION" @@ -2015,6 +2114,27 @@ msgstr "Polygon" msgid "MEN_POLYHEDRON" msgstr "Polyhedron" +msgid "MEN_QUADRATIC_EDGE" +msgstr "Quadratic Edge" + +msgid "MEN_QUADRATIC_TRIANGLE" +msgstr "Quadratic Triangle" + +msgid "MEN_QUADRATIC_QUADRANGLE" +msgstr "Quadratic Quadrangle" + +msgid "MEN_QUADRATIC_TETRAHEDRON" +msgstr "Quadratic Tetrahedron" + +msgid "MEN_QUADRATIC_PYRAMID" +msgstr "Quadratic Pyramid" + +msgid "MEN_QUADRATIC_PENTAHEDRON" +msgstr "Quadratic Pentahedron" + +msgid "MEN_QUADRATIC_HEXAHEDRON" +msgstr "Quadratic Hexahedron" + msgid "MEN_NODES" msgstr "Nodes" @@ -2344,6 +2464,27 @@ msgstr "Polygon" msgid "TOP_POLYHEDRON" msgstr "Polyhedron" +msgid "TOP_QUADRATIC_EDGE" +msgstr "Quadratic Edge" + +msgid "TOP_QUADRATIC_TRIANGLE" +msgstr "Quadratic Triangle" + +msgid "TOP_QUADRATIC_QUADRANGLE" +msgstr "Quadratic Quadrangle" + +msgid "TOP_QUADRATIC_TETRAHEDRON" +msgstr "Quadratic Tetrahedron" + +msgid "TOP_QUADRATIC_PYRAMID" +msgstr "Quadratic Pyramid" + +msgid "TOP_QUADRATIC_PENTAHEDRON" +msgstr "Quadratic Pentahedron" + +msgid "TOP_QUADRATIC_HEXAHEDRON" +msgstr "Quadratic Hexahedron" + msgid "TOP_NODES" msgstr "Nodes" @@ -2624,6 +2765,27 @@ msgstr "Polygon" msgid "STB_POLYHEDRON" msgstr "Polyhedron" +msgid "STB_QUADRATIC_EDGE" +msgstr "Quadratic Edge" + +msgid "STB_QUADRATIC_TRIANGLE" +msgstr "Quadratic Triangle" + +msgid "STB_QUADRATIC_QUADRANGLE" +msgstr "Quadratic Quadrangle" + +msgid "STB_QUADRATIC_TETRAHEDRON" +msgstr "Quadratic Tetrahedron" + +msgid "STB_QUADRATIC_PYRAMID" +msgstr "Quadratic Pyramid" + +msgid "STB_QUADRATIC_PENTAHEDRON" +msgstr "Quadratic Pentahedron" + +msgid "STB_QUADRATIC_HEXAHEDRON" +msgstr "Quadratic Hexahedron" + msgid "STB_NODES" msgstr "Nodes" diff --git a/src/SMESH_I/Makefile.in b/src/SMESH_I/Makefile.in index 179743728..c8787fdd3 100644 --- a/src/SMESH_I/Makefile.in +++ b/src/SMESH_I/Makefile.in @@ -74,34 +74,97 @@ LIB_SRC = \ SMESH_Pattern_i.cxx \ SMESH_2smeshpy.cxx -LIB_SERVER_IDL = SMESH_Gen.idl SMESH_Hypothesis.idl SMESH_Mesh.idl \ - SALOME_Component.idl SALOME_Exception.idl \ - SMESH_Filter.idl SMESH_Group.idl SMESH_Pattern.idl - -LIB_CLIENT_IDL = SALOMEDS.idl GEOM_Gen.idl MED.idl SALOMEDS_Attributes.idl SALOME_GenericObj.idl SALOME_Comm.idl +LIB_SERVER_IDL = \ + SMESH_Gen.idl \ + SMESH_Hypothesis.idl \ + SMESH_Mesh.idl \ + SALOME_Component.idl \ + SALOME_Exception.idl \ + SMESH_Filter.idl \ + SMESH_Group.idl \ + SMESH_Pattern.idl + +LIB_CLIENT_IDL = \ + SALOMEDS.idl \ + GEOM_Gen.idl \ + MED.idl \ + SALOMEDS_Attributes.idl \ + SALOME_GenericObj.idl \ + SALOME_Comm.idl # Executables targets BIN = SMESHEngine BIN_SRC = # additionnal information to compil and link file -CPPFLAGS+= $(OCC_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \ - -I${MED_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) -CXXFLAGS+= $(OCC_CXXFLAGS) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \ - -I${MED_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome - -LDFLAGS+= -L${KERNEL_ROOT_DIR}/lib/salome -lSalomeContainer -lSalomeNS -lRegistry -lSalomeHDFPersist -lSalomeLifeCycleCORBA -lTOOLSDS -lSalomeGenericObj \ - -L${GEOM_ROOT_DIR}/lib/salome -lGEOMClient -lSMESHimpl -lSMESHControls \ - $(OCC_LDPATH) -lTKCDF -lTKBO - - -LDFLAGSFORBIN += -lSMDS -lSMESHDS \ - -L${MED_ROOT_DIR}/lib/salome -lMEDWrapper -lMEDWrapperBase -lMEDWrapper_V2_1 -lMEDWrapper_V2_2 -lmed_V2_1 \ - -lMeshDriver -lMeshDriverMED -lMeshDriverUNV -lMeshDriverDAT -lMeshDriverSTL \ - -L${KERNEL_ROOT_DIR}/lib/salome -lSalomeContainer -lSalomeNS -lRegistry -lSalomeResourcesManager \ - -lOpUtil -lSALOMELocalTrace -lSALOMEBasics -lSalomeNotification -lCASCatch \ - -lSalomeHDFPersist -lSalomeLifeCycleCORBA -lTOOLSDS -lSalomeGenericObj \ - -L${GEOM_ROOT_DIR}/lib/salome -lGEOMClient -lSMESHimpl -lSMESHControls -lNMTTools -lNMTDS \ - $(OCC_LDPATH) -lTKCDF -lTKBO -lTKMath +CPPFLAGS+= \ + $(OCC_INCLUDES) \ + $(HDF5_INCLUDES) \ + $(BOOST_CPPFLAGS) \ + -I${KERNEL_ROOT_DIR}/include/salome \ + -I${MED_ROOT_DIR}/include/salome \ + -I${GEOM_ROOT_DIR}/include/salome + +CXXFLAGS+= \ + $(OCC_CXXFLAGS) \ + $(HDF5_INCLUDES) \ + -I${KERNEL_ROOT_DIR}/include/salome \ + -I${MED_ROOT_DIR}/include/salome \ + -I${GEOM_ROOT_DIR}/include/salome + +LDFLAGS+= \ + -L${KERNEL_ROOT_DIR}/lib/salome \ + -lSalomeContainer \ + -lSalomeNS \ + -lRegistry \ + -lSalomeHDFPersist \ + -lSalomeLifeCycleCORBA \ + -lTOOLSDS \ + -lSalomeGenericObj \ + -L${GEOM_ROOT_DIR}/lib/salome \ + -lGEOMClient \ + -lSMESHimpl \ + -lSMESHControls \ + $(OCC_LDPATH) \ + -lTKCDF \ + -lTKBO + +LDFLAGSFORBIN+= \ + -lSMDS \ + -lSMESHDS \ + -L${MED_ROOT_DIR}/lib/salome \ + -lMEDWrapper \ + -lMEDWrapperBase \ + -lMEDWrapper_V2_1 \ + -lMEDWrapper_V2_2 \ + -lmed_V2_1 \ + -lMeshDriver \ + -lMeshDriverMED \ + -lMeshDriverUNV \ + -lMeshDriverDAT \ + -lMeshDriverSTL \ + -L${KERNEL_ROOT_DIR}/lib/salome \ + -lSalomeContainer \ + -lSalomeNS \ + -lRegistry \ + -lSalomeResourcesManager \ + -lOpUtil \ + -lSALOMELocalTrace \ + -lSALOMEBasics \ + -lSalomeNotification \ + -lSalomeHDFPersist \ + -lSalomeLifeCycleCORBA \ + -lTOOLSDS \ + -lSalomeGenericObj \ + -L${GEOM_ROOT_DIR}/lib/salome \ + -lGEOMClient \ + -lSMESHimpl \ + -lSMESHControls \ + -lNMTTools \ + -lNMTDS \ + $(OCC_LDPATH) \ + -lTKCDF \ + -lTKBO \ + -lTKMath @CONCLUDE@ diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 6d8150db8..609abbe43 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -1,3 +1,31 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_2D_Algo_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + // File : SMESH_2smeshpy.cxx // Created : Fri Nov 18 13:20:10 2005 // Author : Edward AGAPOV (eap) @@ -72,10 +100,20 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript, #ifdef DUMP_CONVERSION cout << endl << " ######## RESULT ######## " << endl<< endl; #endif + // reorder commands after conversion + list< Handle(_pyCommand) >::iterator cmd; + bool orderChanges; + do { + orderChanges = false; + for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd ) + if ( (*cmd)->SetDependentCmdsAfter() ) + orderChanges = true; + } while ( orderChanges ); + // concat commands back into a script TCollection_AsciiString aScript; - list< Handle(_pyCommand) >::iterator cmd = theGen->GetCommands().begin(); - for ( ; cmd != theGen->GetCommands().end(); ++cmd ) { + for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd ) + { #ifdef DUMP_CONVERSION cout << "## COM " << (*cmd)->GetOrderNb() << ": "<< (*cmd)->GetString() << endl; #endif @@ -219,7 +257,7 @@ void _pyGen::Flush() if ( !hyp->IsNull() ) { (*hyp)->Flush(); // smeshgen.CreateHypothesis() --> smesh.smesh.CreateHypothesis() - if ( !(*hyp)->GetCreationCmd()->IsEmpty() ) + if ( !(*hyp)->IsWrapped() ) (*hyp)->GetCreationCmd()->SetObject( SMESH_2smeshpy::GenName() ); } } @@ -286,7 +324,10 @@ void _pyGen::ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) th int nb1 = theCmd1->GetOrderNb(); theCmd1->SetOrderNb( theCmd2->GetOrderNb() ); theCmd2->SetOrderNb( nb1 ); +// cout << "BECOME " << theCmd1->GetOrderNb() << "\t" << theCmd1->GetString() << endl +// << "BECOME " << theCmd2->GetOrderNb() << "\t" << theCmd2->GetString() << endl << endl; } + //================================================================================ /*! * \brief Set one command after the other @@ -297,6 +338,7 @@ void _pyGen::ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) th void _pyGen::SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd ) { +// cout << "SET\t" << theCmd->GetString() << endl << "AFTER\t" << theAfterCmd->GetString() << endl << endl; list< Handle(_pyCommand) >::iterator pos; pos = find( myCommands.begin(), myCommands.end(), theCmd ); myCommands.erase( pos ); @@ -401,8 +443,7 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd): _pyObject(theCreation //================================================================================ /*! - case brief: - default: + * \brief Convert a IDL API command of SMESH::Mesh to a method call of python Mesh * \param theCommand - Engine method called for this mesh */ //================================================================================ @@ -501,7 +542,6 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) void _pyMesh::Flush() { list < Handle(_pyCommand) >::iterator cmd, cmd2; - map< _pyID, Handle(_pyCommand) > algo2additionCmd; // try to convert algo addition like this: // mesh.AddHypothesis(geom, ALGO ) --> ALGO = mesh.Algo() @@ -516,7 +556,8 @@ void _pyMesh::Flush() _pyID geom = addCmd->GetArg( 1 ); if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK { - algo2additionCmd[ algo->GetID() ] = addCmd; + // wrapped algo is created atfer mesh creation + GetCreationCmd()->AddDependantCmd( addCmd ); if ( geom != GetGeom() ) // local algo { @@ -529,8 +570,7 @@ void _pyMesh::Flush() if ( geom == subCmd->GetArg( 1 )) { subCmd->SetObject( algo->GetID() ); subCmd->RemoveArgs(); - if ( addCmd->GetOrderNb() > subCmd->GetOrderNb() ) - theGen->SetCommandAfter( subCmd, addCmd ); + addCmd->AddDependantCmd( subCmd ); } } } @@ -561,10 +601,7 @@ void _pyMesh::Flush() if ( !algo.IsNull() && hyp->Addition2Creation( addCmd, this->GetID() )) // OK { addCmd->SetObject( algo->GetID() ); - Handle(_pyCommand) algoCmd = algo2additionCmd[ algo->GetID() ]; - if ( !algoCmd.IsNull() && algoCmd->GetOrderNb() > addCmd->GetOrderNb() ) - // algo was created later than hyp - theGen->ExchangeCommands( algoCmd, addCmd ); + algo->GetCreationCmd()->AddDependantCmd( addCmd ); } else { @@ -663,6 +700,11 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th hyp->myCreationMethod = "Propagation"; hyp->myType = "Regular_1D"; } + else if ( hypType == "QuadraticMesh" ) { + hyp->myDim = 1; + hyp->myCreationMethod = "QuadraticMesh"; + hyp->myType = "Regular_1D"; + } else if ( hypType == "AutomaticLength" ) { hyp->myDim = 1; hyp->myCreationMethod = "AutomaticLength"; @@ -769,6 +811,9 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd, else theCmd->SetArg( i, "[]"); } + // set a new creation command + GetCreationCmd()->Clear(); + SetCreationCmd( theCmd ); // clear commands setting arg values list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin(); @@ -788,10 +833,7 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd, Handle(_pyCommand) afterCmd = myIsWrapped ? theCmd : GetCreationCmd(); list::iterator cmd = myUnknownCommands.begin(); for ( ; cmd != myUnknownCommands.end(); ++cmd ) { - if ( !(*cmd)->IsEmpty() && afterCmd->GetOrderNb() > (*cmd)->GetOrderNb() ) { - theGen->SetCommandAfter( *cmd, afterCmd ); - afterCmd = *cmd; - } + afterCmd->AddDependantCmd( *cmd ); } myArgCommands.clear(); myUnknownCommands.clear(); @@ -830,8 +872,8 @@ void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand) void _pyHypothesis::Flush() { - if ( IsWrapped() ) - GetCreationCmd()->Clear(); +// if ( IsWrapped() ) +// GetCreationCmd()->Clear(); } //================================================================================ @@ -866,7 +908,7 @@ void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand) bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd, const _pyID& theMesh) { - if ( IsWrappable( theMesh ) && myArgs.Length() > 1 ) { + if ( IsWrappable( theMesh ) && myArgs.Length() > 0 ) { list::iterator cmd = myUnknownCommands.begin(); for ( ; cmd != myUnknownCommands.end(); ++cmd ) { // clear SetDistrType() @@ -1228,3 +1270,23 @@ void _pyCommand::RemoveArgs() if ( myBegPos.Length() >= ARG1_IND ) myBegPos.Remove( ARG1_IND, myBegPos.Length() ); } + +//================================================================================ +/*! + * \brief Set dependent commands after this one + */ +//================================================================================ + +bool _pyCommand::SetDependentCmdsAfter() const +{ + bool orderChanged = false; + list< Handle(_pyCommand)>::const_iterator cmd = myDependentCmds.begin(); + for ( ; cmd != myDependentCmds.end(); ++cmd ) { + if ( (*cmd)->GetOrderNb() < GetOrderNb() ) { + orderChanged = true; + theGen->SetCommandAfter( *cmd, this ); + (*cmd)->SetDependentCmdsAfter(); + } + } + return orderChanged; +} diff --git a/src/SMESH_I/SMESH_2smeshpy.hxx b/src/SMESH_I/SMESH_2smeshpy.hxx index ac92276c3..78117eaa3 100644 --- a/src/SMESH_I/SMESH_2smeshpy.hxx +++ b/src/SMESH_I/SMESH_2smeshpy.hxx @@ -84,6 +84,7 @@ class _pyCommand: public Standard_Transient TCollection_AsciiString myRes, myObj, myMeth; TColStd_SequenceOfAsciiString myArgs; TColStd_SequenceOfInteger myBegPos; //!< where myRes, myObj, ... begin + std::list< Handle(_pyCommand) > myDependentCmds; enum { UNKNOWN=-1, EMPTY=0, RESULT_IND, OBJECT_IND, METHOD_IND, ARG1_IND }; int GetBegPos( int thePartIndex ); void SetBegPos( int thePartIndex, int thePosition ); @@ -118,6 +119,10 @@ public: static TCollection_AsciiString GetWord( const TCollection_AsciiString & theSring, int & theStartPos, const bool theForward, const bool dotIsWord = false); + void AddDependantCmd( Handle(_pyCommand) cmd) + { return myDependentCmds.push_back( cmd ); } + bool SetDependentCmdsAfter() const; + DEFINE_STANDARD_RTTI (_pyCommand) }; @@ -128,11 +133,12 @@ typedef TCollection_AsciiString _pyID; class _pyObject: public Standard_Transient { - Handle(_pyCommand) myCreationCmd; + Handle(_pyCommand) myCreationCmd; public: _pyObject(const Handle(_pyCommand)& theCreationCmd): myCreationCmd(theCreationCmd) {} const _pyID& GetID() { return myCreationCmd->GetResultValue(); } const Handle(_pyCommand)& GetCreationCmd() { return myCreationCmd; } + void SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; } int GetCommandNb() { return myCreationCmd->GetOrderNb(); } virtual void Process(const Handle(_pyCommand) & theCommand) = 0; virtual void Flush() = 0; diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 79f87e116..e75216c21 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -46,6 +46,7 @@ #include #include #include +#include #include "Utils_CorbaException.hxx" @@ -92,7 +93,6 @@ #include "Utils_ExceptHandlers.hxx" #include -#include using namespace std; using SMESH::TPythonDump; @@ -244,8 +244,11 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, _thisObj = this ; _id = myPoa->activate_object( _thisObj ); + myIsEmbeddedMode = false; myShapeReader = NULL; // shape reader mySMESHGen = this; + + OSD::SetSignal( true ); } //============================================================================= @@ -377,7 +380,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() // create a new mesh object servant, store it in a map in study context SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() ); // create a new mesh object - meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID() )); + meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode )); // activate the CORBA servant of Mesh SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( meshServant->_this() ); @@ -407,6 +410,32 @@ GEOM_Client* SMESH_Gen_i::GetShapeReader() return myShapeReader; } +//============================================================================= +/*! + * SMESH_Gen_i::SetEmbeddedMode + * + * Set current mode + */ +//============================================================================= + +void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode ) +{ + myIsEmbeddedMode = theMode; +} + +//============================================================================= +/*! + * SMESH_Gen_i::IsEmbeddedMode + * + * Get current mode + */ +//============================================================================= + +CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode() +{ + return myIsEmbeddedMode; +} + //============================================================================= /*! * SMESH_Gen_i::SetCurrentStudy @@ -623,7 +652,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshesFromUNV" ); SMESH::SMESH_Mesh_var aMesh = createMesh(); - string aFileName; // = boost::filesystem::path(theFileName).leaf(); + string aFileName; // publish mesh in the study if ( CanPublishInStudy( aMesh ) ) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); @@ -734,7 +763,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshesFromSTL" ); SMESH::SMESH_Mesh_var aMesh = createMesh(); - string aFileName; // = boost::filesystem::path(theFileName).leaf(); + string aFileName; // publish mesh in the study if ( CanPublishInStudy( aMesh ) ) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index f1cce1453..11f07f75d 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -166,6 +166,11 @@ public: // Interface methods // ***************************************** + // Set current study + void SetEmbeddedMode( CORBA::Boolean theMode ); + // Get current study + CORBA::Boolean IsEmbeddedMode(); + // Set current study void SetCurrentStudy( SALOMEDS::Study_ptr theStudy ); // Get current study @@ -417,6 +422,7 @@ private: GEOM_Client* myShapeReader; // Shape reader SALOMEDS::Study_var myCurrentStudy; // Current study + CORBA::Boolean myIsEmbeddedMode; // Current mode // Dump Python: trace of API methods calls std::map < int, Handle(TColStd_HSequenceOfAsciiString) > myPythonScripts; diff --git a/src/SMESH_I/SMESH_Group_i.cxx b/src/SMESH_I/SMESH_Group_i.cxx index 2720a60f5..9c0a2f52f 100644 --- a/src/SMESH_I/SMESH_Group_i.cxx +++ b/src/SMESH_I/SMESH_Group_i.cxx @@ -419,3 +419,33 @@ GEOM::GEOM_Object_ptr SMESH_GroupOnGeom_i::GetShape() return aGeomObj._retn(); } +//============================================================================= +/*! + * + */ +//============================================================================= +CORBA::Long SMESH_GroupBase_i::GetColorNumber() +{ + SMESHDS_GroupBase* aGroupDS = GetGroupDS(); + if (aGroupDS) + return aGroupDS->GetColorGroup(); + MESSAGE("get color number of a vague group"); + return 0; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void SMESH_GroupBase_i::SetColorNumber(CORBA::Long color) +{ + SMESHDS_GroupBase* aGroupDS = GetGroupDS(); + if (aGroupDS) + return aGroupDS->SetColorGroup(color); + MESSAGE("set color number of a vague group"); + return ; +} + + + diff --git a/src/SMESH_I/SMESH_Group_i.hxx b/src/SMESH_I/SMESH_Group_i.hxx index e9801b258..cc7dabe72 100644 --- a/src/SMESH_I/SMESH_Group_i.hxx +++ b/src/SMESH_I/SMESH_Group_i.hxx @@ -73,6 +73,9 @@ class SMESH_GroupBase_i: SMESH_Group* GetSmeshGroup() const; SMESHDS_GroupBase* GetGroupDS() const; + void SetColorNumber(CORBA::Long color); + CORBA::Long GetColorNumber(); + private: SMESH_Mesh_i* myMeshServant; int myLocalID; diff --git a/src/SMESH_I/SMESH_Hypothesis_i.cxx b/src/SMESH_I/SMESH_Hypothesis_i.cxx index d5cdce9fb..768c37ad8 100644 --- a/src/SMESH_I/SMESH_Hypothesis_i.cxx +++ b/src/SMESH_I/SMESH_Hypothesis_i.cxx @@ -89,7 +89,7 @@ SMESH_Hypothesis_i::~SMESH_Hypothesis_i() char* SMESH_Hypothesis_i::GetName() { - MESSAGE( "SMESH_Hypothesis_i::GetName" ); + //MESSAGE( "SMESH_Hypothesis_i::GetName" ); return CORBA::string_dup( myBaseImpl->GetName() ); }; diff --git a/src/SMESH_I/SMESH_MEDMesh_i.cxx b/src/SMESH_I/SMESH_MEDMesh_i.cxx index 3f1c017d4..bbf959006 100644 --- a/src/SMESH_I/SMESH_MEDMesh_i.cxx +++ b/src/SMESH_I/SMESH_MEDMesh_i.cxx @@ -1121,7 +1121,7 @@ void SMESH_MEDMesh_i::createFamilies() throw(SALOME::SALOME_Exception) if (_creeFamily == false) { _creeFamily = true; - SMESH_subMesh_i *subMeshServant; + //SMESH_subMesh_i *subMeshServant; map < int, SMESH_subMesh_i * >::iterator it; for (it = _mesh_i->_mapSubMesh_i.begin(); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 9aa35ea1e..d85258440 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -128,6 +128,17 @@ CORBA::Boolean SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) TPythonDump() << "isDone = " << this << ".AddEdge([ " << index1 << ", " << index2 <<" ])"; } + if (NbNodes == 3) { + CORBA::Long n1 = IDsOfNodes[0]; + CORBA::Long n2 = IDsOfNodes[1]; + CORBA::Long n12 = IDsOfNodes[2]; + GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1), + GetMeshDS()->FindNode(n2), + GetMeshDS()->FindNode(n12)); + // Update Python script + TPythonDump() << "isDone = " << this << ".AddEdge([ " + <AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); } - else + else if (NbNodes == 6) { - GetMeshDS()->AddPolygonalFace(nodes); + GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5]); + } + else if (NbNodes == 8) + { + GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7]); } // Update Python script @@ -189,6 +206,30 @@ CORBA::Boolean SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) return true; }; +//============================================================================= +/*! + * AddPolygonalFace + */ +//============================================================================= +CORBA::Boolean SMESH_MeshEditor_i::AddPolygonalFace + (const SMESH::long_array & IDsOfNodes) +{ + int NbNodes = IDsOfNodes.length(); + std::vector nodes (NbNodes); + for (int i = 0; i < NbNodes; i++) + nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]); + + GetMeshDS()->AddPolygonalFace(nodes); + + // Update Python script + TPythonDump() <<"isDone = "<FindNode(IDsOfNodes[i]); + SMDS_MeshElement* elem = 0; switch(NbNodes) { - case 4:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break; - case 5:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break; - case 6:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break; - case 8:GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break; + case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break; + case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break; + case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break; + case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break; + case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5], + n[6],n[7],n[8],n[9]); + break; + case 13: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]); + break; + case 15: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]); + break; + case 20: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]); + break; } // Update Python script TPythonDump() << "isDone = " << this << ".AddVolume( " << IDsOfNodes << " )"; @@ -215,7 +270,7 @@ CORBA::Boolean SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNode TPythonDump() << "print 'AddVolume: ', isDone"; #endif - return true; + return elem; }; //============================================================================= diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index aa28198c1..0632747a6 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -50,6 +50,7 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Boolean AddNode(CORBA::Double x, CORBA::Double y, CORBA::Double z); CORBA::Boolean AddEdge(const SMESH::long_array & IDsOfNodes); CORBA::Boolean AddFace(const SMESH::long_array & IDsOfNodes); + CORBA::Boolean AddPolygonalFace(const SMESH::long_array & IDsOfNodes); CORBA::Boolean AddVolume(const SMESH::long_array & IDsOfNodes); CORBA::Boolean AddPolyhedralVolume(const SMESH::long_array & IDsOfNodes, diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index c56c56918..05d8ff0cf 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -316,6 +316,8 @@ static SMESH::Hypothesis_Status ConvertHypothesisStatus res = SMESH::HYP_ALREADY_EXIST; break; case SMESH_Hypothesis::HYP_BAD_DIM: res = SMESH::HYP_BAD_DIM; break; + case SMESH_Hypothesis::HYP_BAD_SUBSHAPE: + res = SMESH::HYP_BAD_SUBSHAPE; break; default: res = SMESH::HYP_UNKNOWN_FATAL; } @@ -1167,6 +1169,11 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() */ //============================================================================= +CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED() +{ + return _impl->HasDuplicatedGroupNamesMED(); +} + static void PrepareForWriting (const char* file) { TCollection_AsciiString aFullName ((char*)file); @@ -1563,3 +1570,14 @@ SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const boo { return ( SMESH::ElementType )_impl->GetElementType( id, iselem ); } + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Long SMESH_Mesh_i::GetMeshPtr() +{ + return (CORBA::Long)_impl; +} diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 42fac7d5d..9167f325d 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -132,12 +132,11 @@ public: throw (SALOME::SALOME_Exception); // --- C++ interface - void SetImpl(::SMESH_Mesh* impl); ::SMESH_Mesh& GetImpl(); // :: force no namespace here SMESH_Gen_i* GetGen() { return _gen_i; } - + int ImportUNVFile( const char* theFileName ) throw (SALOME::SALOME_Exception); @@ -150,6 +149,11 @@ public: SMESH::DriverMED_ReadStatus ImportMEDFile( const char* theFileName, const char* theMeshName ) throw (SALOME::SALOME_Exception); + /*! Check group names for duplications. + * Consider maximum group name length stored in MED file. + */ + CORBA::Boolean HasDuplicatedGroupNamesMED(); + void ExportToMED( const char* file, CORBA::Boolean auto_groups, SMESH::MED_VERSION theVersion ) throw (SALOME::SALOME_Exception); void ExportMED( const char* file, CORBA::Boolean auto_groups ) @@ -250,6 +254,8 @@ public: virtual SMESH::long_array* GetIDs(); + CORBA::Long GetMeshPtr(); + map _mapSubMesh_i; //NRI map _mapSubMesh; //NRI diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx index f8ade30f5..7772524b6 100644 --- a/src/SMESH_I/SMESH_subMesh_i.cxx +++ b/src/SMESH_I/SMESH_subMesh_i.cxx @@ -128,9 +128,8 @@ bool getSubMeshes(::SMESH_subMesh* theSubMesh, list::iterator sh = shapeList.begin(); for ( ; sh != shapeList.end(); ++sh ) { for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) { - ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() ); - if ( aSubMesh ) - getSubMeshes( aSubMesh, theSubMeshList ); + if ( ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() )) + getSubMeshes( aSubMesh, theSubMeshList ); // add found submesh or explore deeper else // no submesh for a compound inside compound shapeList.push_back( it.Value() ); @@ -147,6 +146,9 @@ bool getSubMeshes(::SMESH_subMesh* theSubMesh, } break; } + default: + if ( aSubMeshDS ) + theSubMeshList.push_back( aSubMeshDS ); } return size < theSubMeshList.size(); } @@ -274,7 +276,7 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsId() for ( int i = 0; sm != smList.end(); sm++ ) { SMDS_ElemIteratorPtr anIt = (*sm)->GetElements(); - for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ ) + for ( ; i < nbElems && anIt->more(); i++ ) aResult[i] = anIt->next()->GetID(); } } diff --git a/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py b/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py index 6a4533ea7..31e89c3a1 100644 --- a/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py +++ b/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py @@ -15,9 +15,9 @@ def BuildGroupLyingOn(theMesh, theElemType, theName, theShape): aGroup.Add(anIds) #Example -## from SMESH_test1 import * +from SMESH_test1 import * -## smesh.Compute(mesh, box) -## BuildGroupLyingOn(mesh, SMESH.FACE, "Group of faces lying on edge", edge ) +smesh.Compute(mesh, box) +BuildGroupLyingOn(mesh, SMESH.FACE, "Group of faces lying on edge", edge ) -## salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(1); diff --git a/src/SMESH_SWIG/smesh.py b/src/SMESH_SWIG/smesh.py index fe237e511..ec24cadfa 100644 --- a/src/SMESH_SWIG/smesh.py +++ b/src/SMESH_SWIG/smesh.py @@ -92,6 +92,38 @@ class Mesh_Algorithm: """ return self.algo + def TreatHypoStatus(self, status, hypName, geomName, isAlgo): + """ + Private method. Print error message if a hypothesis was not assigned + """ + if isAlgo: + hypType = "algorithm" + else: + hypType = "hypothesis" + if status == SMESH.HYP_UNKNOWN_FATAL : + reason = "for unknown reason" + elif status == SMESH.HYP_INCOMPATIBLE : + reason = "this hypothesis mismatches algorithm" + elif status == SMESH.HYP_NOTCONFORM : + reason = "not conform mesh would be built" + elif status == SMESH.HYP_ALREADY_EXIST : + reason = hypType + " of the same dimension already assigned to this shape" + elif status == SMESH.HYP_BAD_DIM : + reason = hypType + " mismatches shape" + elif status == SMESH.HYP_CONCURENT : + reason = "there are concurrent hypotheses on sub-shapes" + elif status == SMESH.HYP_BAD_SUBSHAPE : + reason = "shape is neither the main one, nor its subshape, nor a valid group" + else: + return + hypName = '"' + hypName + '"' + geomName= '"' + geomName+ '"' + if status < SMESH.HYP_UNKNOWN_FATAL: + print hypName, "was assigned to", geomName,"but", reason + else: + print hypName, "was not assigned to",geomName,":", reason + pass + def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"): """ Private method @@ -111,7 +143,8 @@ class Mesh_Algorithm: self.algo = smesh.CreateHypothesis(hypo, so) SetName(self.algo, name + "/" + hypo) - mesh.mesh.AddHypothesis(self.geom, self.algo) + status = mesh.mesh.AddHypothesis(self.geom, self.algo) + self.TreatHypoStatus( status, hypo, name, 1 ) def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"): """ @@ -126,8 +159,10 @@ class Mesh_Algorithm: a = a + s + str(args[i]) s = "," i = i + 1 - SetName(hypo, GetName(self.geom) + "/" + hyp + a) - self.mesh.mesh.AddHypothesis(self.geom, hypo) + name = GetName(self.geom) + SetName(hypo, name + "/" + hyp + a) + status = self.mesh.mesh.AddHypothesis(self.geom, hypo) + self.TreatHypoStatus( status, hyp, name, 0 ) return hypo # Public class: Mesh_Segment @@ -206,7 +241,7 @@ class Mesh_Segment(Mesh_Algorithm): """ return self.Hypothesis("Propagation") - def AutomaticLength(self, fineness): + def AutomaticLength(self, fineness=0): """ Define "AutomaticLength" hypothesis \param fineness for the fineness [0-1] @@ -215,6 +250,18 @@ class Mesh_Segment(Mesh_Algorithm): hyp.SetFineness( fineness ) return hyp + def QuadraticMesh(self): + """ + Define "QuadraticMesh" hypothesis, forcing construction of quadratic edges. + If the 2D mesher sees that all boundary edges are quadratic ones, + it generates quadratic faces, else it generates linear faces using + medium nodes as if they were vertex ones. + The 3D mesher generates quadratic volumes only if all boundary faces + are quadratic ones, else it fails. + """ + hyp = self.Hypothesis("QuadraticMesh") + return hyp + # Public class: Mesh_Segment_Python # --------------------------------- @@ -452,24 +499,54 @@ class Mesh: def Compute(self): """ - Compute the mesh and return the status of the computation - """ - b = smesh.Compute(self.mesh, self.geom) + Compute the mesh and return the status of the computation + """ + ok = smesh.Compute(self.mesh, self.geom) + if not ok: + errors = smesh.GetAlgoState( self.mesh, self.geom ) + allReasons = "" + for err in errors: + if err.isGlobalAlgo: + glob = " global " + else: + glob = " local " + pass + dim = str(err.algoDim) + if err.name == SMESH.MISSING_ALGO: + reason = glob + dim + "D algorithm is missing" + elif err.name == SMESH.MISSING_HYPO: + name = '"' + err.algoName + '"' + reason = glob + dim + "D algorithm " + name + " misses " + dim + "D hypothesis" + else: + reason = "Global \"Not Conform mesh allowed\" hypothesis is missing" + pass + if allReasons != "": + allReasons += "\n" + pass + allReasons += reason + pass + if allReasons != "": + print '"' + GetName(self.mesh) + '"',"not computed:" + print allReasons + pass + pass if salome.sg.hasDesktop(): smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(salome.myStudyId) - smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), b ) + smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok ) salome.sg.updateObjBrowser(1) - return b + pass + return ok - def AutomaticTetrahedralization(self): + def AutomaticTetrahedralization(self, fineness=0): """ Compute tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN + The parameter \a fineness [0.-1.] defines mesh fineness """ dim = self.MeshDimension() # assign hypotheses self.RemoveGlobalHypotheses() - self.Segment().AutomaticLength() + self.Segment().AutomaticLength(fineness) if dim > 1 : self.Triangle().LengthFromEdges() pass @@ -478,14 +555,15 @@ class Mesh: pass return self.Compute() - def AutomaticHexahedralization(self): + def AutomaticHexahedralization(self, fineness=0): """ Compute hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron + The parameter \a fineness [0.-1.] defines mesh fineness """ dim = self.MeshDimension() # assign hypotheses self.RemoveGlobalHypotheses() - self.Segment().AutomaticLength() + self.Segment().AutomaticLength(fineness) if dim > 1 : self.Quadrangle() pass @@ -548,7 +626,7 @@ class Mesh: """ Export the mesh in a file with the MED format and choice the \a version of MED format \param f is the file name - \param version values are smesh.MED_V2_1, smesh.MED_V2_2 + \param version values are SMESH.MED_V2_1, SMESH.MED_V2_2 """ self.mesh.ExportToMED(f, opt, version) diff --git a/src/StdMeshers/Makefile.in b/src/StdMeshers/Makefile.in index 592ff2b2b..b38a5dcbf 100644 --- a/src/StdMeshers/Makefile.in +++ b/src/StdMeshers/Makefile.in @@ -50,7 +50,9 @@ EXPORT_HEADERS = \ StdMeshers_Hexa_3D.hxx \ StdMeshers_AutomaticLength.hxx \ StdMeshers_Distribution.hxx \ - StdMeshers_QuadranglePreference.hxx + StdMeshers_QuadranglePreference.hxx \ + StdMeshers_Helper.hxx \ + StdMeshers_QuadraticMesh.hxx EXPORT_PYSCRIPTS = @@ -76,7 +78,9 @@ LIB_SRC = \ StdMeshers_Hexa_3D.cxx \ StdMeshers_AutomaticLength.cxx \ StdMeshers_Distribution.cxx \ - StdMeshers_QuadranglePreference.cxx + StdMeshers_QuadranglePreference.cxx \ + StdMeshers_Helper.cxx \ + StdMeshers_QuadraticMesh.cxx LIB_SERVER_IDL = @@ -87,10 +91,22 @@ BIN = BIN_SRC = # additionnal information to compil and link file -CPPFLAGS+= $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) -CXXFLAGS+= $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome +CPPFLAGS+= \ + $(OCC_INCLUDES) \ + $(BOOST_CPPFLAGS) \ + -I${KERNEL_ROOT_DIR}/include/salome -LDFLAGS+= -lSMESHimpl -lMEFISTO2D $(OCC_LDPATH) -lTKAdvTools -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome \ - -lCASCatch +CXXFLAGS+= \ + $(OCC_CXXFLAGS) \ + -I${KERNEL_ROOT_DIR}/include/salome \ + -I${GEOM_ROOT_DIR}/include/salome + +LDFLAGS+= \ + -lSMESHimpl \ + -lMEFISTO2D \ + $(OCC_LDPATH) \ + -lTKAdvTools \ + -L${KERNEL_ROOT_DIR}/lib/salome \ + -L${GEOM_ROOT_DIR}/lib/salome @CONCLUDE@ diff --git a/src/StdMeshers/StdMeshers_Distribution.cxx b/src/StdMeshers/StdMeshers_Distribution.cxx index 93858296b..1223fc009 100644 --- a/src/StdMeshers/StdMeshers_Distribution.cxx +++ b/src/StdMeshers/StdMeshers_Distribution.cxx @@ -27,10 +27,8 @@ // $Header$ #include "StdMeshers_Distribution.hxx" -#include -#include -#include -#include +#include "CASCatch.hxx" + #include #include @@ -45,9 +43,6 @@ Function::~Function() bool Function::value( const double, double& f ) const { - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - bool ok = true; if( myConv==0 ) { @@ -55,10 +50,9 @@ bool Function::value( const double, double& f ) const { f = pow( 10, f ); } - CASCatch_CATCH(CASCatch_Failure) + CASCatch_CATCH(Standard_Failure) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); f = 0.0; ok = false; } @@ -174,22 +168,17 @@ FunctionExpr::FunctionExpr( const char* str, const int conv ) myVars( 1, 1 ), myValues( 1, 1 ) { - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - bool ok = true; CASCatch_TRY { myExpr = ExprIntrp_GenExp::Create(); myExpr->Process( ( Standard_CString )str ); } - CASCatch_CATCH(CASCatch_Failure) + CASCatch_CATCH(Standard_Failure) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); ok = false; } - aCatchSignals.Deactivate(); if( !ok || !myExpr->IsDone() ) myExpr.Nullify(); @@ -214,23 +203,17 @@ bool FunctionExpr::value( const double t, double& f ) const if( myExpr.IsNull() ) return false; - OSD::SetSignal( true ); - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - ( ( TColStd_Array1OfReal& )myValues ).ChangeValue( 1 ) = t; bool ok = true; CASCatch_TRY { f = myExpr->Expression()->Evaluate( myVars, myValues ); } - CASCatch_CATCH(CASCatch_Failure) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + CASCatch_CATCH(Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); f = 0.0; ok = false; } - aCatchSignals.Deactivate(); ok = Function::value( t, f ) && ok; return ok; } @@ -244,7 +227,7 @@ double FunctionExpr::integral( const double a, const double b ) const if( _int.IsDone() ) res = _int.Value(); } - CASCatch_CATCH(CASCatch_Failure) + CASCatch_CATCH(Standard_Failure) { res = 0.0; MESSAGE( "Exception in integral calculating" ); diff --git a/src/StdMeshers/StdMeshers_Helper.cxx b/src/StdMeshers/StdMeshers_Helper.cxx new file mode 100644 index 000000000..d851e6cb2 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Helper.cxx @@ -0,0 +1,437 @@ +// File: StdMeshers_Helper.cxx +// Created: 15.02.06 15:22:41 +// Author: Sergey KUUL +// Copyright: Open CASCADE 2006 + + +#include "StdMeshers_Helper.hxx" + +#include "SMDS_FacePosition.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_MeshEditor.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//======================================================================= +//function : CheckShape +//purpose : +//======================================================================= + +bool StdMeshers_Helper::IsQuadraticSubMesh(const TopoDS_Shape& aSh) +{ + SMESHDS_Mesh* meshDS = GetMesh()->GetMeshDS(); + myShapeID = meshDS->ShapeToIndex(aSh); + // we can create quadratic elements only if all elements + // created on subshapes of given shape are quadratic + // also we have to fill myNLinkNodeMap + myCreateQuadratic = true; + mySeamShapeIds.clear(); + TopAbs_ShapeEnum subType( aSh.ShapeType()==TopAbs_FACE ? TopAbs_EDGE : TopAbs_FACE ); + SMDSAbs_ElementType elemType( subType==TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge ); + + TopExp_Explorer exp( aSh, subType ); + for (; exp.More() && myCreateQuadratic; exp.Next()) { + if ( SMESHDS_SubMesh * subMesh = meshDS->MeshElements( exp.Current() )) { + if ( SMDS_ElemIteratorPtr it = subMesh->GetElements() ) { + while(it->more()) { + const SMDS_MeshElement* e = it->next(); + if ( e->GetType() != elemType || !e->IsQuadratic() ) { + myCreateQuadratic = false; + break; + } + else { + // fill NLinkNodeMap + switch ( e->NbNodes() ) { + case 3: + AddNLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(2)); break; + case 6: + AddNLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(3)); + AddNLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(4)); + AddNLinkNode(e->GetNode(2),e->GetNode(0),e->GetNode(5)); break; + case 8: + AddNLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(4)); + AddNLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(5)); + AddNLinkNode(e->GetNode(2),e->GetNode(3),e->GetNode(6)); + AddNLinkNode(e->GetNode(3),e->GetNode(0),e->GetNode(7)); + break; + default: + myCreateQuadratic = false; + break; + } + } + } + } + } + } + + if(!myCreateQuadratic) { + myNLinkNodeMap.clear(); + } + else { + // treatment of periodic faces + if ( aSh.ShapeType() == TopAbs_FACE ) { + const TopoDS_Face& face = TopoDS::Face( aSh ); + BRepAdaptor_Surface surface( face ); + if ( surface.IsUPeriodic() || surface.IsVPeriodic() ) { + // look for a seam edge + for ( exp.Init( face, TopAbs_EDGE ); exp.More(); exp.Next()) { + const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); + if ( BRep_Tool::IsClosed( edge, face )) { + // initialize myPar1, myPar2 and myParIndex + if ( mySeamShapeIds.empty() ) { + gp_Pnt2d uv1, uv2; + BRep_Tool::UVPoints( edge, face, uv1, uv2 ); + if ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Abs( uv1.Coord(2) - uv2.Coord(2) )) + { + myParIndex = 1; // U periodic + myPar1 = surface.FirstUParameter(); + myPar2 = surface.LastUParameter(); + } + else { + myParIndex = 2; // V periodic + myPar1 = surface.FirstVParameter(); + myPar2 = surface.LastVParameter(); + } + } + // store shapes indices + mySeamShapeIds.insert( meshDS->ShapeToIndex( exp.Current() )); + for ( TopExp_Explorer v( exp.Current(), TopAbs_VERTEX ); v.More(); v.Next() ) + mySeamShapeIds.insert( meshDS->ShapeToIndex( v.Current() )); + } + } + } + } + } + return myCreateQuadratic; +} + + +//======================================================================= +//function : IsMedium +//purpose : +//======================================================================= + +bool StdMeshers_Helper::IsMedium(const SMDS_MeshNode* node, + const SMDSAbs_ElementType typeToCheck) +{ + return SMESH_MeshEditor::IsMedium( node, typeToCheck ); +} + +//======================================================================= +//function : AddNLinkNode +//purpose : +//======================================================================= +/*! + * Auxilary function for filling myNLinkNodeMap + */ +void StdMeshers_Helper::AddNLinkNode(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) +{ + NLink link( n1, n2 ); + if ( n1 > n2 ) link = NLink( n2, n1 ); + // add new record to map + myNLinkNodeMap.insert( make_pair(link,n12)); +} + +//======================================================================= +/*! + * \brief Select UV on either of 2 pcurves of a seam edge, closest to the given UV + * \param uv1 - UV on the seam + * \param uv2 - UV within a face + * \retval gp_Pnt2d - selected UV + */ +//======================================================================= + +gp_Pnt2d StdMeshers_Helper::GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const +{ + double p1 = uv1.Coord( myParIndex ); + double p2 = uv2.Coord( myParIndex ); + double p3 = ( Abs( p1 - myPar1 ) < Abs( p1 - myPar2 )) ? myPar2 : myPar1; + if ( Abs( p2 - p1 ) > Abs( p2 - p3 )) + p1 = p3; + gp_Pnt2d result = uv1; + result.SetCoord( myParIndex, p1 ); + return result; +} + +//======================================================================= +/*! + * \brief Return node UV on face + * \param F - the face + * \param n - the node + * \param n2 - a medium node will be placed between n and n2 + * \retval gp_XY - resulting UV + * + * Auxilary function called form GetMediumNode() + */ +//======================================================================= + +gp_XY StdMeshers_Helper::GetNodeUV(const TopoDS_Face& F, + const SMDS_MeshNode* n, + const SMDS_MeshNode* n2) +{ + gp_Pnt2d uv; + const SMDS_PositionPtr Pos = n->GetPosition(); + if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE) { + // node has position on face + const SMDS_FacePosition* fpos = + static_cast(n->GetPosition().get()); + uv = gp_Pnt2d(fpos->GetUParameter(),fpos->GetVParameter()); + } + else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) { + // node has position on edge => it is needed to find + // corresponding edge from face, get pcurve for this + // edge and recieve value from this pcurve + const SMDS_EdgePosition* epos = + static_cast(n->GetPosition().get()); + SMESHDS_Mesh* meshDS = GetMesh()->GetMeshDS(); + int edgeID = Pos->GetShapeId(); + TopoDS_Edge E = TopoDS::Edge(meshDS->IndexToShape(edgeID)); + double f, l; + TopLoc_Location loc; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + uv = C2d->Value( epos->GetUParameter() ); + // for a node on a seam edge select one of UVs on 2 pcurves + if ( n2 && mySeamShapeIds.find( edgeID ) != mySeamShapeIds.end() ) + uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 )); + } + else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) { + SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS(); + int vertexID = n->GetPosition()->GetShapeId(); + const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID)); + uv = BRep_Tool::Parameters( V, F ); + if ( n2 && mySeamShapeIds.find( vertexID ) != mySeamShapeIds.end() ) + uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 )); + } + return uv.XY(); +} + + +//======================================================================= +//function : GetMediumNode +//purpose : +//======================================================================= +/*! + * Special function for search or creation medium node + */ +const SMDS_MeshNode* StdMeshers_Helper::GetMediumNode(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const bool force3d) +{ +//cout<<"n1: "<GetMeshDS(); + if(!force3d) { + // we try to create medium node using UV parameters of + // nodes, else - medium between corresponding 3d points + const SMDS_PositionPtr Pos1 = n1->GetPosition(); + const SMDS_PositionPtr Pos2 = n2->GetPosition(); + int faceID = -1; + if( Pos1->GetTypeOfPosition()==SMDS_TOP_FACE ) { + faceID = Pos1->GetShapeId(); + } + else if( Pos2->GetTypeOfPosition()==SMDS_TOP_FACE ) { + faceID = Pos2->GetShapeId(); + } + if(faceID>-1) { + TopoDS_Face F = TopoDS::Face(meshDS->IndexToShape(faceID)); + gp_XY p1 = GetNodeUV(F,n1,n2); + gp_XY p2 = GetNodeUV(F,n2,n1); + double u = (p1.X()+p2.X())/2.; + double v = (p1.Y()+p2.Y())/2.; + Handle(Geom_Surface) S = BRep_Tool::Surface(F); + gp_Pnt P = S->Value(u, v); + n12 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(n12, faceID, u, v); + myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12)); + return n12; + } + } + // 3d variant + double x = ( n1->X() + n2->X() )/2.; + double y = ( n1->Y() + n2->Y() )/2.; + double z = ( n1->Z() + n2->Z() )/2.; + n12 = meshDS->AddNode(x,y,z); + meshDS->SetNodeInVolume(n12, myShapeID); + myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12)); + return n12; + } +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +/*! + * Special function for creation quadratic triangle + */ +SMDS_MeshFace* StdMeshers_Helper::AddFace(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3) +{ + SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS(); + if(!myCreateQuadratic) { + return meshDS->AddFace(n1, n2, n3); + } + + const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,false); + const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,false); + const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,false); + + return meshDS->AddFace(n1, n2, n3, n12, n23, n31); +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +/*! + * Special function for creation quadratic quadrangle + */ +SMDS_MeshFace* StdMeshers_Helper::AddFace(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3, + const SMDS_MeshNode* n4) +{ + SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS(); + if(!myCreateQuadratic) { + return meshDS->AddFace(n1, n2, n3, n4); + } + + const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,false); + const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,false); + const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,false); + const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,false); + + return meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +/*! + * Special function for creation quadratic volume + */ +SMDS_MeshVolume* StdMeshers_Helper::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) +{ + SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS(); + if(!myCreateQuadratic) { + return meshDS->AddVolume(n1, n2, n3, n4, n5, n6); + } + + const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,true); + const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,true); + const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,true); + + const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,true); + const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,true); + const SMDS_MeshNode* n64 = GetMediumNode(n6,n4,true); + + const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,true); + const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,true); + const SMDS_MeshNode* n36 = GetMediumNode(n3,n6,true); + + return meshDS->AddVolume(n1, n2, n3, n4, n5, n6, + n12, n23, n31, n45, n56, n64, n14, n25, n36); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +/*! + * Special function for creation quadratic volume + */ +SMDS_MeshVolume* StdMeshers_Helper::AddVolume(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3, + const SMDS_MeshNode* n4) +{ + SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS(); + if(!myCreateQuadratic) { + return meshDS->AddVolume(n1, n2, n3, n4); + } + + const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,true); + const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,true); + const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,true); + + const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,true); + const SMDS_MeshNode* n24 = GetMediumNode(n2,n4,true); + const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,true); + + return meshDS->AddVolume(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34); +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +/*! + * Special function for creation quadratic volume + */ +SMDS_MeshVolume* StdMeshers_Helper::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* n7, + const SMDS_MeshNode* n8) +{ + SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS(); + if(!myCreateQuadratic) { + return meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8); + } + + const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,true); + const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,true); + const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,true); + const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,true); + + const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,true); + const SMDS_MeshNode* n67 = GetMediumNode(n6,n7,true); + const SMDS_MeshNode* n78 = GetMediumNode(n7,n8,true); + const SMDS_MeshNode* n85 = GetMediumNode(n8,n5,true); + + const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,true); + const SMDS_MeshNode* n26 = GetMediumNode(n2,n6,true); + const SMDS_MeshNode* n37 = GetMediumNode(n3,n7,true); + const SMDS_MeshNode* n48 = GetMediumNode(n4,n8,true); + + return meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8, + n12, n23, n34, n41, n56, n67, + n78, n85, n15, n26, n37, n48); +} + + diff --git a/src/StdMeshers/StdMeshers_Helper.hxx b/src/StdMeshers/StdMeshers_Helper.hxx new file mode 100644 index 000000000..398c48bd5 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Helper.hxx @@ -0,0 +1,179 @@ +// File: StdMeshers_Helper.hxx +// Created: 15.02.06 14:48:09 +// Author: Sergey KUUL +// Copyright: Open CASCADE 2006 + + +#ifndef StdMeshers_Helper_HeaderFile +#define StdMeshers_Helper_HeaderFile + +#include +#include +#include +#include +#include + +#include + +typedef pair NLink; +typedef map NLinkNodeMap; +typedef map::iterator ItNLinkNode; + +/*! + * \brief It helps meshers to add elements + * + * It allow meshers not to care about creation of medium nodes + * when filling a quadratic mesh. Helper does it itself. + * It defines degree of elements to create when IsQuadraticSubMesh() + * is called. + */ + +class StdMeshers_Helper +{ + public: + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor + StdMeshers_Helper(SMESH_Mesh& theMesh) + { myMesh=(void *)&theMesh; myCreateQuadratic = false; } + + SMESH_Mesh* GetMesh() const + { return (SMESH_Mesh*)myMesh; } + + /// Copy constructor + //Standard_EXPORT StdMeshers_Helper (const StdMeshers_Helper& theOther); + + /// Destructor + //Standard_EXPORT virtual ~StdMeshers_Helper (); + + /** + * Check submesh for given shape + * Check if all elements on this shape + * are quadratic, if yes => set true to myCreateQuadratic + * (default value is false). Also fill myNLinkNodeMap + * Returns myCreateQuadratic + */ + bool IsQuadraticSubMesh(const TopoDS_Shape& theShape); + + /*! + * \brief Returns true if given node is medium + * \param n - node to check + * \param typeToCheck - type of elements containing the node to ask about node status + * \retval bool - check result + */ + static bool IsMedium(const SMDS_MeshNode* node, + const SMDSAbs_ElementType typeToCheck = SMDSAbs_All); + + /** + * Auxilary function for filling myNLinkNodeMap + */ + void AddNLinkNode(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12); + + /** + * Auxilary function for filling myNLinkNodeMap + */ + void AddNLinkNodeMap(const NLinkNodeMap& aMap) + { myNLinkNodeMap.insert(aMap.begin(), aMap.end()); } + + /** + * Returns myNLinkNodeMap + */ + const NLinkNodeMap& GetNLinkNodeMap() { return myNLinkNodeMap; } + + /*! + * \brief Return node UV on face + * \param F - the face + * \param n - the node + * \param n2 - a medium node will be placed between n and n2 + * \retval gp_XY - resulting UV + * + * Auxilary function called form GetMediumNode() + */ + gp_XY GetNodeUV(const TopoDS_Face& F, + const SMDS_MeshNode* n, + const SMDS_MeshNode* n2=0); + + /** + * Special function for search or creation medium node + */ + const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const bool force3d); + /** + * Special function for creation quadratic triangle + */ + SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3); + + /** + * Special function for creation quadratic quadrangle + */ + SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3, + const SMDS_MeshNode* n4); + + /** + * Special function for creation quadratic tetraahedron + */ + SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3, + const SMDS_MeshNode* n4); + + /** + * Special function for creation quadratic pentahedron + */ + 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); + + /** + * Special function for creation quadratic hexahedron + */ + 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* n7, + const SMDS_MeshNode* n8); + + + protected: + + /*! + * \brief Select UV on either of 2 pcurves of a seam edge, closest to the given UV + * \param uv1 - UV on the seam + * \param uv2 - UV within a face + * \retval gp_Pnt2d - selected UV + */ + gp_Pnt2d GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const; + + private: + + void* myMesh; + + int myShapeID; + + // Key for creation quadratic faces + bool myCreateQuadratic; + + // special map for using during creation quadratic faces + NLinkNodeMap myNLinkNodeMap; + + std::set< int > mySeamShapeIds; + double myPar1, myPar2; // bounds of a closed periodic surface + int myParIndex; // bounds' index (1-U, 2-V) + +}; + + +#endif diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index a3ed4f11a..21793248a 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -45,6 +45,7 @@ using namespace std; #include #include #include +#include #include #include @@ -70,15 +71,11 @@ static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aSha //============================================================================= StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, - SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen) + SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen) { - MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D"); - _name = "Hexa_3D"; -// _shapeType = TopAbs_SOLID; - _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type -// MESSAGE("_shapeType octal " << oct << _shapeType); - for (int i = 0; i < 6; i++) - _quads[i] = 0; + MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D"); + _name = "Hexa_3D"; + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type } //============================================================================= @@ -89,11 +86,27 @@ StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D() { - MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D"); - for (int i = 0; i < 6; i++) - StdMeshers_Quadrangle_2D::QuadDelete(_quads[i]); + MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D"); } +//================================================================================ +/*! + * \brief Clear fields and return the argument + * \param res - the value to return + * \retval bool - the argument value + */ +//================================================================================ + +bool StdMeshers_Hexa_3D::ClearAndReturn(FaceQuadStruct* theQuads[6], const bool res) +{ + for (int i = 0; i < 6; i++) { + StdMeshers_Quadrangle_2D::QuadDelete(theQuads[i]); + theQuads[i] = NULL; + } + return res; +} + + //============================================================================= /*! * @@ -146,6 +159,7 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& return true; } + //============================================================================= /*! * Hexahedron mesh on hexaedron like form @@ -163,534 +177,535 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - MESSAGE("StdMeshers_Hexa_3D::Compute"); - //bool isOk = false; - SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); - //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS(); - - // 0. - shape and face mesh verification - // 0.1 - shape must be a solid (or a shell) with 6 faces - //MESSAGE("---"); - - vector < SMESH_subMesh * >meshFaces; - for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) - { - SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); - ASSERT(aSubMesh); - meshFaces.push_back(aSubMesh); - } - if (meshFaces.size() != 6) - { - SCRUTE(meshFaces.size()); -// ASSERT(0); - return false; - } - - // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges) - //MESSAGE("---"); - - for (int i = 0; i < 6; i++) - { - TopoDS_Shape aFace = meshFaces[i]->GetSubShape(); - SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace); - string algoName = algo->GetName(); - bool isAllQuad = false; - if (algoName == "Quadrangle_2D") { - SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace ); - if ( sm ) { - isAllQuad = true; - SMDS_ElemIteratorPtr eIt = sm->GetElements(); - while ( isAllQuad && eIt->more() ) - isAllQuad = ( eIt->next()->NbNodes() == 4 ); - } - } - if ( ! isAllQuad ) { - //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f - bool bIsOk; - // - bIsOk=ComputePentahedralMesh(aMesh, aShape); - if (bIsOk) { - return true; - } - //modified by NIZNHY-PKV Wed Nov 17 15:31:42 2004 t - SCRUTE(algoName); - // ASSERT(0); - return false; - } - StdMeshers_Quadrangle_2D *quadAlgo = - dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); - ASSERT(quadAlgo); - try - { - _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace); - // *** to delete after usage - } - catch(SALOME_Exception & S_ex) - { - // *** delete _quads - // *** throw exception - // ASSERT(0); - return false; - } - - // 0.2.1 - number of points on the opposite edges must be the same - if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] || - _quads[i]->nbPts[1] != _quads[i]->nbPts[3]) - { - MESSAGE("different number of points on the opposite edges of face " << i); - // ASSERT(0); - return false; - } - } - - // 1. - identify faces and vertices of the "cube" - // 1.1 - ancestor maps vertex->edges in the cube - //MESSAGE("---"); - - TopTools_IndexedDataMapOfShapeListOfShape MS; - TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS); - - // 1.2 - first face is choosen as face Y=0 of the unit cube - //MESSAGE("---"); - - const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape(); - const TopoDS_Face & F = TopoDS::Face(aFace); - - // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001 - //MESSAGE("---"); - - int i = 0; - TopoDS_Edge E = _quads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube - double f, l; - Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); - TopoDS_Vertex VFirst, VLast; - TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l - bool isForward = - (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); - - if (isForward) - { - _cube.V000 = VFirst; // will be (0,0,0) on the unit cube - _cube.V100 = VLast; // will be (1,0,0) on the unit cube - } - else - { - _cube.V000 = VLast; - _cube.V100 = VFirst; - } - - i = 1; - E = _quads[0]->edge[i]; - C2d = BRep_Tool::CurveOnSurface(E, F, f, l); - TopExp::Vertices(E, VFirst, VLast); - isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); - if (isForward) - _cube.V101 = VLast; // will be (1,0,1) on the unit cube - else - _cube.V101 = VFirst; + MESSAGE("StdMeshers_Hexa_3D::Compute"); + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + + // 0. - shape and face mesh verification + // 0.1 - shape must be a solid (or a shell) with 6 faces + //MESSAGE("---"); + + vector < SMESH_subMesh * >meshFaces; + for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { + SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); + ASSERT(aSubMesh); + meshFaces.push_back(aSubMesh); + } + if (meshFaces.size() != 6) { + SCRUTE(meshFaces.size()); + return false; + } - i = 2; - E = _quads[0]->edge[i]; - C2d = BRep_Tool::CurveOnSurface(E, F, f, l); - TopExp::Vertices(E, VFirst, VLast); - isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); - if (isForward) - _cube.V001 = VLast; // will be (0,0,1) on the unit cube - else - _cube.V001 = VFirst; + // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges) + //MESSAGE("---"); + + // tool for working with quadratic elements + StdMeshers_Helper aTool (aMesh); + _quadraticMesh = aTool.IsQuadraticSubMesh(aShape); + + // cube structure + typedef struct cubeStruct + { + TopoDS_Vertex V000; + TopoDS_Vertex V001; + TopoDS_Vertex V010; + TopoDS_Vertex V011; + TopoDS_Vertex V100; + TopoDS_Vertex V101; + TopoDS_Vertex V110; + TopoDS_Vertex V111; + faceQuadStruct* quad_X0; + faceQuadStruct* quad_X1; + faceQuadStruct* quad_Y0; + faceQuadStruct* quad_Y1; + faceQuadStruct* quad_Z0; + faceQuadStruct* quad_Z1; + Point3DStruct* np; // normalised 3D coordinates + } CubeStruct; + + CubeStruct aCube; + + // bounding faces + FaceQuadStruct* aQuads[6]; + for (int i = 0; i < 6; i++) + aQuads[i] = 0; + + for (int i = 0; i < 6; i++) { + TopoDS_Shape aFace = meshFaces[i]->GetSubShape(); + SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace); + string algoName = algo->GetName(); + bool isAllQuad = false; + if (algoName == "Quadrangle_2D") { + SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace ); + if ( sm ) { + isAllQuad = true; + SMDS_ElemIteratorPtr eIt = sm->GetElements(); + while ( isAllQuad && eIt->more() ) { + const SMDS_MeshElement* elem = eIt->next(); + isAllQuad = ( elem->NbNodes()==4 ||(_quadraticMesh && elem->NbNodes()==8) ); + } + } + } + if ( ! isAllQuad ) { + //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f + bool bIsOk = ComputePentahedralMesh(aMesh, aShape); + return ClearAndReturn( aQuads, bIsOk ); + } + StdMeshers_Quadrangle_2D *quadAlgo = + dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); + ASSERT(quadAlgo); + try { + aQuads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh); + } + catch(SALOME_Exception & S_ex) { + return ClearAndReturn( aQuads, false ); + } - // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0) - // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0) - // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) - // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0) - //MESSAGE("---"); + // 0.2.1 - number of points on the opposite edges must be the same + if (aQuads[i]->nbPts[0] != aQuads[i]->nbPts[2] || + aQuads[i]->nbPts[1] != aQuads[i]->nbPts[3]) { + MESSAGE("different number of points on the opposite edges of face " << i); + // ASSERT(0); + return ClearAndReturn( aQuads, false ); + } + } - TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS); - ASSERT(!E_0Y0.IsNull()); + // 1. - identify faces and vertices of the "cube" + // 1.1 - ancestor maps vertex->edges in the cube + //MESSAGE("---"); - TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS); - ASSERT(!E_1Y0.IsNull()); + TopTools_IndexedDataMapOfShapeListOfShape MS; + TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS); - TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS); - ASSERT(!E_1Y1.IsNull()); + // 1.2 - first face is choosen as face Y=0 of the unit cube + //MESSAGE("---"); - TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS); - ASSERT(!E_0Y1.IsNull()); + const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape(); + const TopoDS_Face & F = TopoDS::Face(aFace); - // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011 - //MESSAGE("---"); + // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001 + //MESSAGE("---"); - TopExp::Vertices(E_0Y0, VFirst, VLast); - if (VFirst.IsSame(_cube.V000)) - _cube.V010 = VLast; - else - _cube.V010 = VFirst; + int i = 0; + TopoDS_Edge E = aQuads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + bool isForward = (((l - f) * (aQuads[0]->last[i] - aQuads[0]->first[i])) > 0); - TopExp::Vertices(E_1Y0, VFirst, VLast); - if (VFirst.IsSame(_cube.V100)) - _cube.V110 = VLast; - else - _cube.V110 = VFirst; - - TopExp::Vertices(E_1Y1, VFirst, VLast); - if (VFirst.IsSame(_cube.V101)) - _cube.V111 = VLast; - else - _cube.V111 = VFirst; + if (isForward) { + aCube.V000 = VFirst; // will be (0,0,0) on the unit cube + aCube.V100 = VLast; // will be (1,0,0) on the unit cube + } + else { + aCube.V000 = VLast; + aCube.V100 = VFirst; + } - TopExp::Vertices(E_0Y1, VFirst, VLast); - if (VFirst.IsSame(_cube.V001)) - _cube.V011 = VLast; - else - _cube.V011 = VFirst; - - // 1.6 - find remaining faces given 4 vertices - //MESSAGE("---"); - - _indY0 = 0; - _cube.quad_Y0 = _quads[_indY0]; - - _indY1 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V010, _cube.V011, _cube.V110, _cube.V111); - _cube.quad_Y1 = _quads[_indY1]; - - _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V000, _cube.V010, _cube.V100, _cube.V110); - _cube.quad_Z0 = _quads[_indZ0]; - - _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V001, _cube.V011, _cube.V101, _cube.V111); - _cube.quad_Z1 = _quads[_indZ1]; - - _indX0 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V000, _cube.V001, _cube.V010, _cube.V011); - _cube.quad_X0 = _quads[_indX0]; - - _indX1 = GetFaceIndex(aMesh, aShape, meshFaces, - _cube.V100, _cube.V101, _cube.V110, _cube.V111); - _cube.quad_X1 = _quads[_indX1]; - - //MESSAGE("---"); - - // 1.7 - get convertion coefs from face 2D normalized to 3D normalized - - Conv2DStruct cx0; // for face X=0 - Conv2DStruct cx1; // for face X=1 - Conv2DStruct cy0; - Conv2DStruct cy1; - Conv2DStruct cz0; - Conv2DStruct cz1; - - GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(), - _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0); - GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(), - _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1); - GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(), - _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0); - GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(), - _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1); - GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(), - _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0); - GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(), - _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1); - - // 1.8 - create a 3D structure for normalized values - - //MESSAGE("---"); - int nbx = _cube.quad_Z0->nbPts[0]; - if (cz0.a1 == 0.) nbx = _cube.quad_Z0->nbPts[1]; + i = 1; + E = aQuads[0]->edge[i]; + C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopExp::Vertices(E, VFirst, VLast); + isForward = (((l - f) * (aQuads[0]->last[i] - aQuads[0]->first[i])) > 0); + if (isForward) + aCube.V101 = VLast; // will be (1,0,1) on the unit cube + else + aCube.V101 = VFirst; + + i = 2; + E = aQuads[0]->edge[i]; + C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopExp::Vertices(E, VFirst, VLast); + isForward = (((l - f) * (aQuads[0]->last[i] - aQuads[0]->first[i])) > 0); + if (isForward) + aCube.V001 = VLast; // will be (0,0,1) on the unit cube + else + aCube.V001 = VFirst; + + // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0) + // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0) + // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) + // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0) + //MESSAGE("---"); + + TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, aCube.V000, MS); + ASSERT(!E_0Y0.IsNull()); + + TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, aCube.V100, MS); + ASSERT(!E_1Y0.IsNull()); + + TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V101, MS); + ASSERT(!E_1Y1.IsNull()); + + TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V001, MS); + ASSERT(!E_0Y1.IsNull()); + + // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011 + //MESSAGE("---"); + + TopExp::Vertices(E_0Y0, VFirst, VLast); + if (VFirst.IsSame(aCube.V000)) + aCube.V010 = VLast; + else + aCube.V010 = VFirst; + + TopExp::Vertices(E_1Y0, VFirst, VLast); + if (VFirst.IsSame(aCube.V100)) + aCube.V110 = VLast; + else + aCube.V110 = VFirst; + + TopExp::Vertices(E_1Y1, VFirst, VLast); + if (VFirst.IsSame(aCube.V101)) + aCube.V111 = VLast; + else + aCube.V111 = VFirst; + + TopExp::Vertices(E_0Y1, VFirst, VLast); + if (VFirst.IsSame(aCube.V001)) + aCube.V011 = VLast; + else + aCube.V011 = VFirst; + + // 1.6 - find remaining faces given 4 vertices + //MESSAGE("---"); + + int _indY0 = 0; + aCube.quad_Y0 = aQuads[_indY0]; + + int _indY1 = GetFaceIndex(aMesh, aShape, meshFaces, + aCube.V010, aCube.V011, aCube.V110, aCube.V111); + aCube.quad_Y1 = aQuads[_indY1]; + + int _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces, + aCube.V000, aCube.V010, aCube.V100, aCube.V110); + aCube.quad_Z0 = aQuads[_indZ0]; + + int _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces, + aCube.V001, aCube.V011, aCube.V101, aCube.V111); + aCube.quad_Z1 = aQuads[_indZ1]; + + int _indX0 = GetFaceIndex(aMesh, aShape, meshFaces, + aCube.V000, aCube.V001, aCube.V010, aCube.V011); + aCube.quad_X0 = aQuads[_indX0]; + + int _indX1 = GetFaceIndex(aMesh, aShape, meshFaces, + aCube.V100, aCube.V101, aCube.V110, aCube.V111); + aCube.quad_X1 = aQuads[_indX1]; + + //MESSAGE("---"); + + // 1.7 - get convertion coefs from face 2D normalized to 3D normalized + + Conv2DStruct cx0; // for face X=0 + Conv2DStruct cx1; // for face X=1 + Conv2DStruct cy0; + Conv2DStruct cy1; + Conv2DStruct cz0; + Conv2DStruct cz1; + + GetConv2DCoefs(*aCube.quad_X0, meshFaces[_indX0]->GetSubShape(), + aCube.V000, aCube.V010, aCube.V011, aCube.V001, cx0); + GetConv2DCoefs(*aCube.quad_X1, meshFaces[_indX1]->GetSubShape(), + aCube.V100, aCube.V110, aCube.V111, aCube.V101, cx1); + GetConv2DCoefs(*aCube.quad_Y0, meshFaces[_indY0]->GetSubShape(), + aCube.V000, aCube.V100, aCube.V101, aCube.V001, cy0); + GetConv2DCoefs(*aCube.quad_Y1, meshFaces[_indY1]->GetSubShape(), + aCube.V010, aCube.V110, aCube.V111, aCube.V011, cy1); + GetConv2DCoefs(*aCube.quad_Z0, meshFaces[_indZ0]->GetSubShape(), + aCube.V000, aCube.V100, aCube.V110, aCube.V010, cz0); + GetConv2DCoefs(*aCube.quad_Z1, meshFaces[_indZ1]->GetSubShape(), + aCube.V001, aCube.V101, aCube.V111, aCube.V011, cz1); + + // 1.8 - create a 3D structure for normalized values + + //MESSAGE("---"); + int nbx = aCube.quad_Z0->nbPts[0]; + if (cz0.a1 == 0.) nbx = aCube.quad_Z0->nbPts[1]; - int nby = _cube.quad_X0->nbPts[0]; - if (cx0.a1 == 0.) nby = _cube.quad_X0->nbPts[1]; + int nby = aCube.quad_X0->nbPts[0]; + if (cx0.a1 == 0.) nby = aCube.quad_X0->nbPts[1]; - int nbz = _cube.quad_Y0->nbPts[0]; - if (cy0.a1 != 0.) nbz = _cube.quad_Y0->nbPts[1]; + int nbz = aCube.quad_Y0->nbPts[0]; + if (cy0.a1 != 0.) nbz = aCube.quad_Y0->nbPts[1]; - int i1, j1, nbxyz = nbx * nby * nbz; - Point3DStruct *np = new Point3DStruct[nbxyz]; + int i1, j1, nbxyz = nbx * nby * nbz; + Point3DStruct *np = new Point3DStruct[nbxyz]; - // 1.9 - store node indexes of faces + // 1.9 - store node indexes of faces - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape()); - - faceQuadStruct *quad = _cube.quad_X0; - int i = 0; // j = x/face , k = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape()); + faceQuadStruct *quad = aCube.quad_X0; + int i = 0; // j = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } - - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face - int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(aTool.IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape()); + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face + int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape()); - faceQuadStruct *quad = _cube.quad_X1; - int i = nbx - 1; // j = x/face , k = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + faceQuadStruct *quad = aCube.quad_X1; + int i = nbx - 1; // j = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face - int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(aTool.IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape()); + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face + int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape()); - faceQuadStruct *quad = _cube.quad_Y0; - int j = 0; // i = x/face , k = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + faceQuadStruct *quad = aCube.quad_Y0; + int j = 0; // i = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face - int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(aTool.IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape()); + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face + int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape()); - faceQuadStruct *quad = _cube.quad_Y1; - int j = nby - 1; // i = x/face , k = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + faceQuadStruct *quad = aCube.quad_Y1; + int j = nby - 1; // i = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face - int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(aTool.IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape()); + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face + int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape()); - faceQuadStruct *quad = _cube.quad_Z0; - int k = 0; // i = x/face , j = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + faceQuadStruct *quad = aCube.quad_Z0; + int k = 0; // i = x/face , j = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face - int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } - - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape()); - - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(aTool.IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - faceQuadStruct *quad = _cube.quad_Z1; - int k = nbz - 1; // i = x/face , j = y/face - int nbdown = quad->nbPts[0]; - int nbright = quad->nbPts[1]; + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face + int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - while(itf->more()) - { - const SMDS_MeshNode * node = itf->next(); - findIJ( node, quad, i1, j1 ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = aCube.quad_Z1; + int k = nbz - 1; // i = x/face , j = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) { + const SMDS_MeshNode * node = itf->next(); + if(aTool.IsMedium(node)) + continue; + findIJ( node, quad, i1, j1 ); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) - { - int ij1 = j1 * nbdown + i1; - int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face - int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) { + int ij1 = j1 * nbdown + i1; + int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face + int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } - // 2.0 - for each node of the cube: - // - get the 8 points 3D = 8 vertices of the cube - // - get the 12 points 3D on the 12 edges of the cube - // - get the 6 points 3D on the 6 faces with their ID - // - compute the point 3D - // - store the point 3D in SMESHDS, store its ID in 3D structure - - int shapeID = meshDS->ShapeToIndex( aShape ); - - Pt3 p000, p001, p010, p011, p100, p101, p110, p111; - Pt3 px00, px01, px10, px11; - Pt3 p0y0, p0y1, p1y0, p1y1; - Pt3 p00z, p01z, p10z, p11z; - Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz; - - GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); - - for (int i = 1; i < nbx - 1; i++) - { - for (int j = 1; j < nby - 1; j++) - { - for (int k = 1; k < nbz - 1; k++) - { - // *** seulement maillage regulier - // 12 points on edges - GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS); - GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS); - GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); - - GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS); - - GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS); - GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS); - GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS); - GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS); - - // 12 points on faces - GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS); - GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS); - GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS); - GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS); - GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS); - - int ijk = k * nbx * nby + j * nbx + i; - double x = double (i) / double (nbx - 1); // *** seulement - double y = double (j) / double (nby - 1); // *** maillage - double z = double (k) / double (nbz - 1); // *** regulier - - Pt3 X; - for (int i = 0; i < 3; i++) - { - X[i] = - (1 - x) * p0yz[i] + x * p1yz[i] - + (1 - y) * px0z[i] + y * px1z[i] - + (1 - z) * pxy0[i] + z * pxy1[i] - - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i]) - - x * ((1 - y) * p10z[i] + y * p11z[i]) - - (1 - y) * ((1 - z) * px00[i] + z * px01[i]) - - y * ((1 - z) * px10[i] + z * px11[i]) - - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i]) - - z * ((1 - x) * p0y1[i] + x * p1y1[i]) - + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i]) - + y * ((1 - z) * p010[i] + z * p011[i])) - + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i]) - + y * ((1 - z) * p110[i] + z * p111[i])); - } - - SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]); - np[ijk].node = node; - meshDS->SetNodeInVolume(node, shapeID); - } - } - } + // 2.0 - for each node of the cube: + // - get the 8 points 3D = 8 vertices of the cube + // - get the 12 points 3D on the 12 edges of the cube + // - get the 6 points 3D on the 6 faces with their ID + // - compute the point 3D + // - store the point 3D in SMESHDS, store its ID in 3D structure + + int shapeID = meshDS->ShapeToIndex( aShape ); + + Pt3 p000, p001, p010, p011, p100, p101, p110, p111; + Pt3 px00, px01, px10, px11; + Pt3 p0y0, p0y1, p1y0, p1y1; + Pt3 p00z, p01z, p10z, p11z; + Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz; + + GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + + for (int i = 1; i < nbx - 1; i++) { + for (int j = 1; j < nby - 1; j++) { + for (int k = 1; k < nbz - 1; k++) { + // *** seulement maillage regulier + // 12 points on edges + GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + + GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS); + + GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS); + GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS); + + // 12 points on faces + GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS); + GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS); + GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS); + + int ijk = k * nbx * nby + j * nbx + i; + double x = double (i) / double (nbx - 1); // *** seulement + double y = double (j) / double (nby - 1); // *** maillage + double z = double (k) / double (nbz - 1); // *** regulier + + Pt3 X; + for (int i = 0; i < 3; i++) { + X[i] = (1 - x) * p0yz[i] + x * p1yz[i] + + (1 - y) * px0z[i] + y * px1z[i] + + (1 - z) * pxy0[i] + z * pxy1[i] + - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i]) + - x * ((1 - y) * p10z[i] + y * p11z[i]) + - (1 - y) * ((1 - z) * px00[i] + z * px01[i]) + - y * ((1 - z) * px10[i] + z * px11[i]) + - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i]) + - z * ((1 - x) * p0y1[i] + x * p1y1[i]) + + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i]) + + y * ((1 - z) * p010[i] + z * p011[i])) + + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i]) + + y * ((1 - z) * p110[i] + z * p111[i])); + } + + SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]); + np[ijk].node = node; + meshDS->SetNodeInVolume(node, shapeID); + } + } + } // find orientation of furute volumes according to MED convention vector< bool > forward( nbx * nby ); SMDS_VolumeTool vTool; - for (int i = 0; i < nbx - 1; i++) - for (int j = 0; j < nby - 1; j++) - { + for (int i = 0; i < nbx - 1; i++) { + for (int j = 0; j < nby - 1; j++) { int n1 = j * nbx + i; int n2 = j * nbx + i + 1; int n3 = (j + 1) * nbx + i + 1; @@ -705,51 +720,53 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, vTool.Set( &tmpVol ); forward[ n1 ] = vTool.IsForward(); } + } - //2.1 - for each node of the cube (less 3 *1 Faces): - // - store hexahedron in SMESHDS - MESSAGE("Storing hexahedron into the DS"); - for (int i = 0; i < nbx - 1; i++) - for (int j = 0; j < nby - 1; j++) - { - bool isForw = forward.at( j * nbx + i ); - for (int k = 0; k < nbz - 1; k++) - { - int n1 = k * nbx * nby + j * nbx + i; - int n2 = k * nbx * nby + j * nbx + i + 1; - int n3 = k * nbx * nby + (j + 1) * nbx + i + 1; - int n4 = k * nbx * nby + (j + 1) * nbx + i; - int n5 = (k + 1) * nbx * nby + j * nbx + i; - int n6 = (k + 1) * nbx * nby + j * nbx + i + 1; - int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1; - int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i; - - SMDS_MeshVolume * elt; - if ( isForw ) - elt = meshDS->AddVolume(np[n1].node, - np[n2].node, - np[n3].node, - np[n4].node, - np[n5].node, - np[n6].node, - np[n7].node, - np[n8].node); - else - elt = meshDS->AddVolume(np[n1].node, - np[n4].node, - np[n3].node, - np[n2].node, - np[n5].node, - np[n8].node, - np[n7].node, - np[n6].node); - - meshDS->SetMeshElementOnShape(elt, shapeID); - } - } + //2.1 - for each node of the cube (less 3 *1 Faces): + // - store hexahedron in SMESHDS + MESSAGE("Storing hexahedron into the DS"); + for (int i = 0; i < nbx - 1; i++) { + for (int j = 0; j < nby - 1; j++) { + bool isForw = forward.at( j * nbx + i ); + for (int k = 0; k < nbz - 1; k++) { + int n1 = k * nbx * nby + j * nbx + i; + int n2 = k * nbx * nby + j * nbx + i + 1; + int n3 = k * nbx * nby + (j + 1) * nbx + i + 1; + int n4 = k * nbx * nby + (j + 1) * nbx + i; + int n5 = (k + 1) * nbx * nby + j * nbx + i; + int n6 = (k + 1) * nbx * nby + j * nbx + i + 1; + int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1; + int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i; + + SMDS_MeshVolume * elt; + if ( isForw ) { + //elt = meshDS->AddVolume(np[n1].node, np[n2].node, + // np[n3].node, np[n4].node, + // np[n5].node, np[n6].node, + // np[n7].node, np[n8].node); + elt = aTool.AddVolume(np[n1].node, np[n2].node, + np[n3].node, np[n4].node, + np[n5].node, np[n6].node, + np[n7].node, np[n8].node); + } + else { + //elt = meshDS->AddVolume(np[n1].node, np[n4].node, + // np[n3].node, np[n2].node, + // np[n5].node, np[n8].node, + // np[n7].node, np[n6].node); + elt = aTool.AddVolume(np[n1].node, np[n4].node, + np[n3].node, np[n2].node, + np[n5].node, np[n8].node, + np[n7].node, np[n6].node); + } + + meshDS->SetMeshElementOnShape(elt, shapeID); + } + } + } if ( np ) delete [] np; - //MESSAGE("End of StdMeshers_Hexa_3D::Compute()"); - return true; + //MESSAGE("End of StdMeshers_Hexa_3D::Compute()"); + return ClearAndReturn( aQuads, true ); } //============================================================================= @@ -1066,3 +1083,4 @@ bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) return bOK; } + diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.hxx b/src/StdMeshers/StdMeshers_Hexa_3D.hxx index a9e20459c..809f95ee7 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.hxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.hxx @@ -25,7 +25,6 @@ // Moved here from SMESH_Hexa_3D.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ #ifndef _SMESH_HEXA_3D_HXX_ #define _SMESH_HEXA_3D_HXX_ @@ -35,9 +34,11 @@ #include "StdMeshers_Quadrangle_2D.hxx" #include "Utils_SALOME_Exception.hxx" +#include "StdMeshers_Helper.hxx" + typedef struct point3Dstruct { - const SMDS_MeshNode * node; + const SMDS_MeshNode * node; } Point3DStruct; typedef double Pt3[3]; @@ -58,25 +59,6 @@ typedef struct conv2dstruct int jc; } Conv2DStruct; -typedef struct cubeStruct -{ - TopoDS_Vertex V000; - TopoDS_Vertex V001; - TopoDS_Vertex V010; - TopoDS_Vertex V011; - TopoDS_Vertex V100; - TopoDS_Vertex V101; - TopoDS_Vertex V110; - TopoDS_Vertex V111; - faceQuadStruct* quad_X0; - faceQuadStruct* quad_X1; - faceQuadStruct* quad_Y0; - faceQuadStruct* quad_Y1; - faceQuadStruct* quad_Z0; - faceQuadStruct* quad_Z1; - Point3DStruct* np; // normalised 3D coordinates -} CubeStruct; - class StdMeshers_Hexa_3D: public SMESH_3D_Algo { @@ -127,14 +109,7 @@ protected: Point3DStruct *np, const SMESHDS_Mesh* meshDS); - CubeStruct _cube; - FaceQuadStruct* _quads[6]; - int _indX0; - int _indX1; - int _indY0; - int _indY1; - int _indZ0; - int _indZ1; + bool ClearAndReturn(FaceQuadStruct* theQuads[6], const bool res); }; #endif diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx index 4852ce4fe..d63d2e6f2 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -62,9 +62,6 @@ using namespace std; #include #include -#include -//#include - //============================================================================= /*! * @@ -72,19 +69,19 @@ using namespace std; //============================================================================= StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, - SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen) + SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen) { - MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D"); - _name = "MEFISTO_2D"; -// _shapeType = TopAbs_FACE; - _shapeType = (1 << TopAbs_FACE); - _compatibleHypothesis.push_back("MaxElementArea"); - _compatibleHypothesis.push_back("LengthFromEdges"); - - _edgeLength = 0; - _maxElementArea = 0; - _hypMaxElementArea = NULL; - _hypLengthFromEdges = NULL; + MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D"); + _name = "MEFISTO_2D"; + _shapeType = (1 << TopAbs_FACE); + _compatibleHypothesis.push_back("MaxElementArea"); + _compatibleHypothesis.push_back("LengthFromEdges"); + + _edgeLength = 0; + _maxElementArea = 0; + _hypMaxElementArea = NULL; + _hypLengthFromEdges = NULL; + myTool = 0; } //============================================================================= @@ -95,7 +92,7 @@ StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D() { - MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D"); + MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D"); } //============================================================================= @@ -184,112 +181,121 @@ bool StdMeshers_MEFISTO_2D::CheckHypothesis bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) { - MESSAGE("StdMeshers_MEFISTO_2D::Compute"); + MESSAGE("StdMeshers_MEFISTO_2D::Compute"); - if (_hypLengthFromEdges) - _edgeLength = ComputeEdgeElementLength(aMesh, aShape); + if (_hypLengthFromEdges) + _edgeLength = ComputeEdgeElementLength(aMesh, aShape); + + bool isOk = false; + //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); - bool isOk = false; - //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); - - const TopoDS_Face & FF = TopoDS::Face(aShape); - bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); - TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); - - Z nblf; //nombre de lignes fermees (enveloppe en tete) - Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee - R2 *uvslf = NULL; - Z nbpti = 0; //nombre points internes futurs sommets de la triangulation - R2 *uvpti = NULL; - - Z nbst; - R2 *uvst = NULL; - Z nbt; - Z *nust = NULL; - Z ierr = 0; - - Z nutysu = 1; // 1: il existe un fonction areteideale_() - // Z nutysu=0; // 0: on utilise aretmx - R aretmx = _edgeLength; // longueur max aretes future triangulation - - nblf = NumberOfWires(F); - - nudslf = new Z[1 + nblf]; - nudslf[0] = 0; - int iw = 1; - int nbpnt = 0; - - myOuterWire = BRepTools::OuterWire(F); - nbpnt += NumberOfPoints(aMesh, myOuterWire); - if ( nbpnt < 3 ) // ex: a circle with 2 segments - return false; - nudslf[iw++] = nbpnt; - - for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) - { - const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); - if (!myOuterWire.IsSame(W)) - { - nbpnt += NumberOfPoints(aMesh, W); - nudslf[iw++] = nbpnt; - } - } + const TopoDS_Face & FF = TopoDS::Face(aShape); + bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); - // avoid passing same uv points for a vertex common to 2 wires - TopTools_IndexedDataMapOfShapeListOfShape VWMap; - if ( iw - 1 > 1 ) // nbofWires > 1 - TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap ); + Z nblf; //nombre de lignes fermees (enveloppe en tete) + Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee + R2 *uvslf = NULL; + Z nbpti = 0; //nombre points internes futurs sommets de la triangulation + R2 *uvpti = NULL; + + Z nbst; + R2 *uvst = NULL; + Z nbt; + Z *nust = NULL; + Z ierr = 0; + + Z nutysu = 1; // 1: il existe un fonction areteideale_() + // Z nutysu=0; // 0: on utilise aretmx + R aretmx = _edgeLength; // longueur max aretes future triangulation + + nblf = NumberOfWires(F); + + nudslf = new Z[1 + nblf]; + nudslf[0] = 0; + int iw = 1; + int nbpnt = 0; + + myTool = new StdMeshers_Helper(aMesh); + _quadraticMesh = myTool->IsQuadraticSubMesh(aShape); + + myOuterWire = BRepTools::OuterWire(F); + nbpnt += NumberOfPoints(aMesh, myOuterWire); + if ( nbpnt < 3 ) { // ex: a circle with 2 segments + delete myTool; myTool = 0; + return false; + } + nudslf[iw++] = nbpnt; + + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!myOuterWire.IsSame(W)) { + nbpnt += NumberOfPoints(aMesh, W); + nudslf[iw++] = nbpnt; + } + } - uvslf = new R2[nudslf[nblf]]; - int m = 0; + // avoid passing same uv points for a vertex common to 2 wires + TopTools_IndexedDataMapOfShapeListOfShape VWMap; + if ( iw - 1 > 1 ) // nbofWires > 1 + TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap ); - double scalex, scaley; - ComputeScaleOnFace(aMesh, F, scalex, scaley); + uvslf = new R2[nudslf[nblf]]; + int m = 0; - map mefistoToDS; // correspondence mefisto index--> points IDNodes - if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m, - mefistoToDS, scalex, scaley, VWMap)) - return false; + double scalex, scaley; + ComputeScaleOnFace(aMesh, F, scalex, scaley); - for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) - { - const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); - if (!myOuterWire.IsSame(W)) - { - if (! LoadPoints(aMesh, F, W, uvslf, m, - mefistoToDS, scalex, scaley, VWMap )) - return false; - } - } + map mefistoToDS; // correspondence mefisto index--> points IDNodes + if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m, + mefistoToDS, scalex, scaley, VWMap) ) { + delete myTool; myTool = 0; + return false; + } - uvst = NULL; - nust = NULL; - aptrte(nutysu, aretmx, - nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr); - - if (ierr == 0) - { - MESSAGE("... End Triangulation Generated Triangle Number " << nbt); - MESSAGE(" Node Number " << nbst); - StoreResult(aMesh, nbst, uvst, nbt, nust, F, - faceIsForward, mefistoToDS, scalex, scaley); - isOk = true; - } - else - { - MESSAGE("Error in Triangulation"); - isOk = false; - } - if (nudslf != NULL) - delete[]nudslf; - if (uvslf != NULL) - delete[]uvslf; - if (uvst != NULL) - delete[]uvst; - if (nust != NULL) - delete[]nust; - return isOk; + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!myOuterWire.IsSame(W)) + { + if (! LoadPoints(aMesh, F, W, uvslf, m, + mefistoToDS, scalex, scaley, VWMap )) { + delete myTool; myTool = 0; + return false; + } + } + } + + uvst = NULL; + nust = NULL; + aptrte(nutysu, aretmx, + nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr); + + if (ierr == 0) + { + MESSAGE("... End Triangulation Generated Triangle Number " << nbt); + MESSAGE(" Node Number " << nbst); + StoreResult(aMesh, nbst, uvst, nbt, nust, F, + faceIsForward, mefistoToDS, scalex, scaley); + isOk = true; + } + else + { + MESSAGE("Error in Triangulation"); + isOk = false; + } + if (nudslf != NULL) + delete[]nudslf; + if (uvslf != NULL) + delete[]uvslf; + if (uvst != NULL) + delete[]uvst; + if (nust != NULL) + delete[]nust; + delete myTool; myTool = 0; + + return isOk; } //======================================================================= @@ -354,7 +360,8 @@ static bool fixCommonVertexUV (gp_Pnt2d & theUV, const TopoDS_Wire& theOW, const TopoDS_Face& theF, const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap, - SMESH_Mesh & theMesh) + SMESH_Mesh & theMesh, + bool CreateQuadratic) { if( theW.IsSame( theOW ) || !theVWMap.Contains( theV )) return false; @@ -417,10 +424,12 @@ static bool fixCommonVertexUV (gp_Pnt2d & theUV, umin = l; umax = f; } - else - { + else { while ( nIt->more() ) { const SMDS_MeshNode* node = nIt->next(); + // check if node is medium + if ( CreateQuadratic && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge )) + continue; const SMDS_EdgePosition* epos = static_cast(node->GetPosition().get()); double u = epos->GetUParameter(); @@ -515,15 +524,17 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh, while ( nodeIt->more() ) { node = nodeIt->next(); + if ( _quadraticMesh && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge )) + continue; const SMDS_EdgePosition* epos = static_cast(node->GetPosition().get()); - params[ epos->GetUParameter() ] = node; - } - int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - if ( nbPoints != params.size()) - { - MESSAGE( "BAD NODE ON EDGE POSITIONS" ); - return false; + double param = epos->GetUParameter(); + if ( !isForward ) param = -param; + if ( !params.insert( make_pair( param, node )).second ) + { + MESSAGE( "BAD NODE ON EDGE POSITIONS" ); + return false; + } } // --- load 2D values into MEFISTO structure, @@ -535,7 +546,7 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh, // vertex node gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale ); - if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh )) + if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh )) myNodesOnCommonV.push_back( idFirst ); mOnVertex.push_back( m ); uvslf[m].x = p.X(); @@ -547,22 +558,13 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh, // internal nodes map::iterator u_n = params.begin(); - map::reverse_iterator u_n_rev = params.rbegin(); - for ( int i = 0; i < nbPoints; ++i ) + for ( int i = 0; u_n != params.end(); ++u_n, ++i ) { - if ( isForward ) { - u = u_n->first; - node = u_n->second; - ++u_n; - } else { - u = u_n_rev->first; - node = u_n_rev->second; - ++u_n_rev; - } + u = isForward ? u_n->first : - u_n->first; gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale ); uvslf[m].x = p.X(); uvslf[m].y = p.Y(); - mefistoToDS[m + 1] = node; + mefistoToDS[m + 1] = u_n->second; //MESSAGE(" "<AddFace(n1, n2, n3); + //elt = meshDS->AddFace(n1, n2, n3); + elt = myTool->AddFace(n1, n2, n3); else - elt = meshDS->AddFace(n1, n3, n2); + //elt = meshDS->AddFace(n1, n3, n2); + elt = myTool->AddFace(n1, n3, n2); meshDS->SetMeshElementOnShape(elt, faceID); m++; } - // remove bad elements build on vertices shared by wires + // remove bad elements built on vertices shared by wires list::iterator itN = myNodesOnCommonV.begin(); for ( ; itN != myNodesOnCommonV.end(); itN++ ) @@ -779,17 +775,14 @@ double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh, //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength"); // **** a mettre dans SMESH_2D_Algo ? - const TopoDS_Face & FF = TopoDS::Face(aShape); + //const TopoDS_Face & FF = TopoDS::Face(aShape); //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); - TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + //TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); double meanElementLength = 100; double wireLength = 0; int wireElementsNumber = 0; - for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) - { - const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); - for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next()) + for (TopExp_Explorer expe(aShape, TopAbs_EDGE); expe.More(); expe.Next()) { const TopoDS_Edge & E = TopoDS::Edge(expe.Current()); int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); @@ -797,7 +790,6 @@ double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh, wireLength += length; wireElementsNumber += nb; } - } if (wireElementsNumber) meanElementLength = wireLength / wireElementsNumber; //SCRUTE(meanElementLength); diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx index fac85f07d..180ceb760 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx @@ -33,6 +33,8 @@ #include "SMESH_2D_Algo.hxx" #include +#include "StdMeshers_Helper.hxx" + class SMDS_MeshNode; class TopTools_IndexedDataMapOfShapeListOfShape; class TopoDS_Face; @@ -95,6 +97,8 @@ protected: TopoDS_Wire myOuterWire; std::list myNodesOnCommonV; + + StdMeshers_Helper* myTool; // toll for working with quadratic elements }; #endif diff --git a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx index 139ea22e6..ba99cb688 100644 --- a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx +++ b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx @@ -33,20 +33,16 @@ #include "SMESHDS_SubMesh.hxx" #include "SMESH_Mesh.hxx" -#include -#include -#include +#include "CASCatch.hxx" + #include #include #include -#include #include #include #include #include -#include - using namespace std; const double PRECISION = 1e-7; @@ -174,8 +170,8 @@ void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor) throw SALOME_Exception(LOCALIZED("not a scale distribution")); if (scaleFactor < PRECISION) throw SALOME_Exception(LOCALIZED("scale factor must be positive")); - if (fabs(scaleFactor - 1.0) < PRECISION) - throw SALOME_Exception(LOCALIZED("scale factor must not be equal to 1")); + //if (fabs(scaleFactor - 1.0) < PRECISION) + // throw SALOME_Exception(LOCALIZED("scale factor must not be equal to 1")); if (fabs(_scaleFactor - scaleFactor) > PRECISION) { @@ -216,10 +212,6 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector& ta double prev = -PRECISION; bool isSame = table.size() == _table.size(); - OSD::SetSignal( true ); - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - bool pos = false; for (i=0; i < table.size()/2; i++) { double par = table[i*2]; @@ -230,10 +222,9 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector& ta { val = pow( 10.0, val ); } - CASCatch_CATCH(CASCatch_Failure) + CASCatch_CATCH(Standard_Failure) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); throw SALOME_Exception( LOCALIZED( "invalid value")); return; } @@ -258,7 +249,6 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector& ta } prev = par; } - aCatchSignals.Deactivate(); if( !pos ) throw SALOME_Exception(LOCALIZED("value of table function is not positive")); @@ -320,10 +310,6 @@ bool process( const TCollection_AsciiString& str, int convMode, bool& non_neg, bool& non_zero, bool& singulars, double& sing_point ) { - OSD::SetSignal( true ); - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - bool parsed_ok = true; Handle( ExprIntrp_GenExp ) myExpr; CASCatch_TRY @@ -331,13 +317,11 @@ bool process( const TCollection_AsciiString& str, int convMode, myExpr = ExprIntrp_GenExp::Create(); myExpr->Process( str.ToCString() ); } - CASCatch_CATCH(CASCatch_Failure) + CASCatch_CATCH(Standard_Failure) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); parsed_ok = false; } - aCatchSignals.Deactivate(); syntax = false; args = false; diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx index ad6ebc831..efa96e08c 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.cxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.cxx @@ -51,6 +51,9 @@ #include #include #include +#include +#include +#include #include #include @@ -70,7 +73,20 @@ StdMeshers_Penta_3D::StdMeshers_Penta_3D() myTol3D=0.1; myWallNodesMaps.resize( SMESH_Block::NbFaces() ); myShapeXYZ.resize( SMESH_Block::NbSubShapes() ); + myTool = 0; } + +//======================================================================= +//function : ~StdMeshers_Penta_3D +//purpose : +//======================================================================= + +StdMeshers_Penta_3D::~StdMeshers_Penta_3D() +{ + if ( myTool ) + delete myTool; +} + //======================================================================= //function : Compute //purpose : @@ -91,33 +107,43 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, if (myErrorStatus){ return bOK; } + + myTool = new StdMeshers_Helper(aMesh); + myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape); + // MakeBlock(); - if (myErrorStatus){ + if (myErrorStatus){ + delete myTool; myTool = 0; + return bOK; + } + // + ClearMeshOnFxy1(); + if (myErrorStatus) { + delete myTool; myTool = 0; return bOK; } // MakeNodes(); if (myErrorStatus){ + delete myTool; myTool = 0; return bOK; } // MakeConnectingMap(); // - ClearMeshOnFxy1(); - if (myErrorStatus) { - return bOK; - } - // MakeMeshOnFxy1(); if (myErrorStatus) { + delete myTool; myTool = 0; return bOK; } // MakeVolumeMesh(); // + delete myTool; myTool = 0; return !bOK; } + //======================================================================= //function : MakeNodes //purpose : @@ -144,12 +170,24 @@ void StdMeshers_Penta_3D::MakeNodes() // 1.1 Horizontal size myJSize=0; for (i=0; iGetSubMeshContaining(aS); ASSERT(aSubMesh); - SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); - iNbN=aSM->NbNodes(); - myJSize+=iNbN; + SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS(); + if(!myCreateQuadratic) { + iNbN = aSM->NbNodes(); + } + else { + iNbN = 0; + SMDS_NodeIteratorPtr itn = aSM->GetNodes(); + while(itn->more()) { + const SMDS_MeshNode* aNode = itn->next(); + if(myTool->IsMedium(aNode)) + continue; + iNbN++; + } + } + myJSize += iNbN; } //printf("*** Horizontal: number of nodes summary=%d\n", myJSize); // @@ -159,9 +197,21 @@ void StdMeshers_Penta_3D::MakeNodes() const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z); SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS); ASSERT(aSubMesh); - SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); - iNbN=aSM->NbNodes(); - myISize+=iNbN; + SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS(); + if(!myCreateQuadratic) { + iNbN = aSM->NbNodes(); + } + else { + iNbN = 0; + SMDS_NodeIteratorPtr itn = aSM->GetNodes(); + while(itn->more()) { + const SMDS_MeshNode* aNode = itn->next(); + if(myTool->IsMedium(aNode)) + continue; + iNbN++; + } + } + myISize += iNbN; } //printf("*** Vertical: number of nodes on edges and vertices=%d\n", myISize); // @@ -177,18 +227,19 @@ void StdMeshers_Penta_3D::MakeNodes() // vertices for (k=0; kGetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); + const TopoDS_Shape& aS = myBlock.Shape(aSID); + SMDS_NodeIteratorPtr ite = pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); while(ite->more()) { const SMDS_MeshNode* aNode = ite->next(); + if(myTool->IsMedium(aNode)) + continue; aNodeID=aNode->GetID(); // aTNode.SetNode(aNode); aTNode.SetShapeSupportID(aSID); aTNode.SetBaseNodeID(aNodeID); // - if ( SMESH_Block::IsEdgeID (aSID)) - { + if ( SMESH_Block::IsEdgeID (aSID)) { const SMDS_EdgePosition* epos = static_cast(aNode->GetPosition().get()); myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords ); @@ -200,7 +251,7 @@ void StdMeshers_Penta_3D::MakeNodes() aP3D.SetCoord(aX, aY, aZ); myBlock.ComputeParameters(aP3D, aS, aCoords); } - iErr=myBlock.ErrorStatus(); + iErr = myBlock.ErrorStatus(); if (iErr) { MESSAGE("StdMeshers_Penta_3D::MakeNodes()," << "SMESHBlock: ComputeParameters operation failed"); @@ -325,8 +376,7 @@ void StdMeshers_Penta_3D::MakeNodes() // 3.3 set XYZ of vertices, and initialize of the rest SMESHDS_Mesh* aMesh = GetMesh()->GetMeshDS(); - for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id ) - { + for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id ) { if ( SMESH_Block::IsVertexID( id )) { TopoDS_Shape V = myBlock.Shape( id ); SMESHDS_SubMesh* sm = aMesh->MeshElements( V ); @@ -344,23 +394,46 @@ void StdMeshers_Penta_3D::MakeNodes() SMESH_Block::TShapeID aSSID, aBNSSID; StdMeshers_TNode aTN; // - for (j=0; jGetMeshDS(); + int topfaceID = meshDS->ShapeToIndex(TopFace); + const TopoDS_Vertex& v001 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V001)); + SMDS_NodeIteratorPtr itn = pMesh->GetSubMeshContaining(v001)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* N = itn->next(); + gp_XY UV001 = myTool->GetNodeUV(TopFace,N); + const TopoDS_Vertex& v101 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V101)); + itn = pMesh->GetSubMeshContaining(v101)->GetSubMeshDS()->GetNodes(); + N = itn->next(); + gp_XY UV101 = myTool->GetNodeUV(TopFace,N); + const TopoDS_Vertex& v011 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V011)); + itn = pMesh->GetSubMeshContaining(v011)->GetSubMeshDS()->GetNodes(); + N = itn->next(); + gp_XY UV011 = myTool->GetNodeUV(TopFace,N); + const TopoDS_Vertex& v111 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V111)); + itn = pMesh->GetSubMeshContaining(v111)->GetSubMeshDS()->GetNodes(); + N = itn->next(); + gp_XY UV111 = myTool->GetNodeUV(TopFace,N); + + for (j=0; j* nColumns[8]; double ratio[4]; // base node position between columns [0.-1.] - if ( createNode ) - for ( k = 0; k < 4; ++k ) + if ( createNode ) { + for ( k = 0; k < 4; ++k ) { ratio[ k ] = SetHorizEdgeXYZ (aBNXYZ, wallFaceID[ k ], nColumns[k*2], nColumns[k*2+1]); + } + } // // XYZ on the bottom and top faces const SMDS_MeshNode* n = aBN.Node(); @@ -368,8 +441,9 @@ void StdMeshers_Penta_3D::MakeNodes() myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( 0., 0., 0. ); // // first create or find a top node, then the rest ones in a column - for (i=myISize-1; i>0; --i) - { + for (i=myISize-1; i>0; --i) { + bIsUpperLayer = (i==(myISize-1)); + gp_XY UV_Ex01, UV_Ex11, UV_E0y1, UV_E1y1; if ( createNode ) { // set XYZ on vertical edges and faces for ( k = 0; k < 4; ++k ) { @@ -377,11 +451,28 @@ void StdMeshers_Penta_3D::MakeNodes() myShapeXYZ[ verticEdgeID[ k ] ].SetCoord( n->X(), n->Y(), n->Z() ); // n = (*nColumns[k*2]) [ i ]; + gp_XY tmp1; + if( i==myISize-1 ) { + tmp1 = myTool->GetNodeUV(TopFace,n); + tmp1 = ( 1. - ratio[ k ]) * tmp1; + } gp_XYZ xyz( n->X(), n->Y(), n->Z() ); myShapeXYZ[ wallFaceID[ k ]] = ( 1. - ratio[ k ]) * xyz; n = (*nColumns[k*2+1]) [ i ]; xyz.SetCoord( n->X(), n->Y(), n->Z() ); myShapeXYZ[ wallFaceID[ k ]] += ratio[ k ] * xyz; + if( i==myISize-1 ) { + gp_XY tmp2 = myTool->GetNodeUV(TopFace,n); + tmp1 += ratio[ k ] * tmp2; + if( k==0 ) + UV_Ex01 = tmp1; + else if( k==1 ) + UV_Ex11 = tmp1; + else if( k==2 ) + UV_E0y1 = tmp1; + else + UV_E1y1 = tmp1; + } } } // fill current node info @@ -395,7 +486,6 @@ void StdMeshers_Penta_3D::MakeNodes() aCoords.SetCoord(aX, aY, aZ); // // suporting shape ID - bIsUpperLayer=(i==(myISize-1)); ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID); if (myErrorStatus) { MESSAGE("StdMeshers_Penta_3D::MakeNodes() "); @@ -418,6 +508,30 @@ void StdMeshers_Penta_3D::MakeNodes() if ( bIsUpperLayer ) { const SMDS_MeshNode* n = aTN.Node(); myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( n->X(), n->Y(), n->Z() ); + // set node on top face: + // find UV parameter for this node + // UV_Ex11 + // UV011+-----+----------+UV111 + // | | + // | | + // UV_E0y1+ +node +UV_E1y1 + // | | + // | | + // | | + // UV001+-----+----------+UV101 + // UV_Ex01 + gp_Pnt2d aP; + double u = aCoords.X(), v = aCoords.Y(); + double u1 = ( 1. - u ), v1 = ( 1. - v ); + aP.ChangeCoord() = UV_Ex01 * v1; + aP.ChangeCoord() += UV_Ex11 * v; + aP.ChangeCoord() += UV_E0y1 * u1; + aP.ChangeCoord() += UV_E1y1 * u; + aP.ChangeCoord() -= UV001 * u1 * v1; + aP.ChangeCoord() -= UV101 * u * v1; + aP.ChangeCoord() -= UV011 * u1 * v; + aP.ChangeCoord() -= UV111 * u * v; + meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y()); } } if (myErrorStatus) { @@ -456,10 +570,13 @@ void StdMeshers_Penta_3D::MakeNodes() */ //DEB t } + + //======================================================================= //function : FindNodeOnShape //purpose : //======================================================================= + void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, const gp_XYZ& aParams, const int z, @@ -470,14 +587,13 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, double aX, aY, aZ, aD, aTol2, minD; gp_Pnt aP1, aP2; // - SMESH_Mesh* pMesh=GetMesh(); - aTol2=myTol3D*myTol3D; + SMESH_Mesh* pMesh = GetMesh(); + aTol2 = myTol3D*myTol3D; minD = 1.e100; - SMDS_MeshNode* pNode=NULL; + SMDS_MeshNode* pNode = NULL; // if ( aS.ShapeType() == TopAbs_FACE || - aS.ShapeType() == TopAbs_EDGE ) - { + aS.ShapeType() == TopAbs_EDGE ) { // find a face ID to which aTN belongs to int faceID; if ( aS.ShapeType() == TopAbs_FACE ) @@ -492,13 +608,13 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, } ASSERT( SMESH_Block::IsFaceID( faceID )); int fIndex = SMESH_Block::ShapeIndex( faceID ); - StdMeshers_IJNodeMap & ijNodes= myWallNodesMaps[ fIndex ]; + StdMeshers_IJNodeMap & ijNodes = myWallNodesMaps[ fIndex ]; // look for a base node in ijNodes const SMDS_MeshNode* baseNode = pMesh->GetMeshDS()->FindNode( aTN.BaseNodeID() ); StdMeshers_IJNodeMap::const_iterator par_nVec = ijNodes.begin(); for ( ; par_nVec != ijNodes.end(); par_nVec++ ) if ( par_nVec->second[ 0 ] == baseNode ) { - pNode=(SMDS_MeshNode*)par_nVec->second.at( z ); + pNode = (SMDS_MeshNode*)par_nVec->second.at( z ); aTN.SetNode(pNode); return; } @@ -510,6 +626,8 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); while(ite->more()) { const SMDS_MeshNode* aNode = ite->next(); + if(myTool->IsMedium(aNode)) + continue; aX=aNode->X(); aY=aNode->Y(); aZ=aNode->Z(); @@ -532,6 +650,7 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, //myErrorStatus=11; // can not find the node; } + //======================================================================= //function : SetHorizEdgeXYZ //purpose : @@ -583,6 +702,7 @@ double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ& aBase return r; } + //======================================================================= //function : MakeVolumeMesh //purpose : @@ -593,20 +713,20 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() // int i, j, ij, ik, i1, i2, aSSID; // - SMESH_Mesh* pMesh =GetMesh(); - SMESHDS_Mesh* meshDS=pMesh->GetMeshDS(); + SMESH_Mesh* pMesh = GetMesh(); + SMESHDS_Mesh* meshDS = pMesh->GetMeshDS(); // int shapeID = meshDS->ShapeToIndex( myShape ); // // 1. Set Node In Volume - ik=myISize-1; + ik = myISize-1; for (i=1; iSetNodeInVolume(aNode, shapeID); } } @@ -621,22 +741,28 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() const TopoDS_Face& aFxy0= TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0)); SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0); - SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS(); + SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS(); // - itf=aSM0->GetElements(); + itf = aSM0->GetElements(); while(itf->more()) { - const SMDS_MeshElement* pE0=itf->next(); + const SMDS_MeshElement* pE0 = itf->next(); // int nbFaceNodes = pE0->NbNodes(); + if(myCreateQuadratic) + nbFaceNodes = nbFaceNodes/2; if ( aN.size() < nbFaceNodes * 2 ) aN.resize( nbFaceNodes * 2 ); // k=0; aItNodes=pE0->nodesIterator(); while (aItNodes->more()) { - const SMDS_MeshElement* pNode=aItNodes->next(); - aID0=pNode->GetID(); - aJ[k]=GetIndexOnLayer(aID0); + //const SMDS_MeshElement* pNode = aItNodes->next(); + const SMDS_MeshNode* pNode = + static_cast (aItNodes->next()); + if(myTool->IsMedium(pNode)) + continue; + aID0 = pNode->GetID(); + aJ[k] = GetIndexOnLayer(aID0); if (myErrorStatus) { MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh"); return; @@ -646,19 +772,19 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() } // bool forward = true; - for (i=0; iAddVolume(aN[0], aN[1], aN[2], - aN[3], aN[4], aN[5]); - else - aV = meshDS->AddVolume(aN[0], aN[2], aN[1], - aN[3], aN[5], aN[4]); + if ( forward ) { + //aV = meshDS->AddVolume(aN[0], aN[1], aN[2], + // aN[3], aN[4], aN[5]); + aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3], aN[4], aN[5]); + } + else { + //aV = meshDS->AddVolume(aN[0], aN[2], aN[1], + // aN[3], aN[5], aN[4]); + aV = myTool->AddVolume(aN[0], aN[2], aN[1], aN[3], aN[5], aN[4]); + } break; case 4: - if ( forward ) - aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3], + if ( forward ) { + //aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3], + // aN[4], aN[5], aN[6], aN[7]); + aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3], aN[4], aN[5], aN[6], aN[7]); - else - aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1], + } + else { + //aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1], + // aN[4], aN[7], aN[6], aN[5]); + aV = myTool->AddVolume(aN[0], aN[3], aN[2], aN[1], aN[4], aN[7], aN[6], aN[5]); + } break; default: continue; @@ -727,74 +863,68 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() const TopoDS_Face& aFxy1= TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1)); // - SMESH_Mesh* pMesh=GetMesh(); + SMESH_Mesh* pMesh = GetMesh(); SMESHDS_Mesh * meshDS = pMesh->GetMeshDS(); // SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0); - SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS(); + SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS(); // // set nodes on aFxy1 - aLevel=myISize-1; - itn=aSM0->GetNodes(); - aNbNodes=aSM0->NbNodes(); + aLevel = myISize-1; + itn = aSM0->GetNodes(); + aNbNodes = aSM0->NbNodes(); //printf("** aNbNodes=%d\n", aNbNodes); - while(itn->more()) { - const SMDS_MeshNode* aN0=itn->next(); - aID0=aN0->GetID(); - aJ=GetIndexOnLayer(aID0); - if (myErrorStatus) { - MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); - return; - } - // - ij=aLevel*myJSize+aJ; - const StdMeshers_TNode& aTN1=myTNodes[ij]; - SMDS_MeshNode* aN1=(SMDS_MeshNode*)aTN1.Node(); - // - meshDS->SetNodeOnFace(aN1, aFxy1); - } + // // set elements on aFxy1 vector aNodes1; // - itf=aSM0->GetElements(); + itf = aSM0->GetElements(); while(itf->more()) { - const SMDS_MeshElement * pE0=itf->next(); - aElementType=pE0->GetType(); + const SMDS_MeshElement* pE0 = itf->next(); + aElementType = pE0->GetType(); if (!aElementType==SMDSAbs_Face) { continue; } - aNbNodes=pE0->NbNodes(); + aNbNodes = pE0->NbNodes(); + if(myCreateQuadratic) + aNbNodes = aNbNodes/2; // if (aNbNodes!=3) { // continue; // } if ( aNodes1.size() < aNbNodes ) aNodes1.resize( aNbNodes ); // - k=aNbNodes-1; // reverse a face - aItNodes=pE0->nodesIterator(); + k = aNbNodes-1; // reverse a face + aItNodes = pE0->nodesIterator(); while (aItNodes->more()) { - const SMDS_MeshElement* pNode=aItNodes->next(); - aID0=pNode->GetID(); - aJ=GetIndexOnLayer(aID0); + //const SMDS_MeshElement* pNode = aItNodes->next(); + const SMDS_MeshNode* pNode = + static_cast (aItNodes->next()); + if(myTool->IsMedium(pNode)) + continue; + aID0 = pNode->GetID(); + aJ = GetIndexOnLayer(aID0); if (myErrorStatus) { MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); return; } // - ij=aLevel*myJSize+aJ; - const StdMeshers_TNode& aTN1=myTNodes[ij]; - const SMDS_MeshNode* aN1=aTN1.Node(); - aNodes1[k]=aN1; + ij = aLevel*myJSize + aJ; + const StdMeshers_TNode& aTN1 = myTNodes[ij]; + const SMDS_MeshNode* aN1 = aTN1.Node(); + aNodes1[k] = aN1; --k; } SMDS_MeshFace * face = 0; switch ( aNbNodes ) { case 3: - face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); + //face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); + face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); break; case 4: - face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); + //face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); + face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); break; default: continue; @@ -802,6 +932,7 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() meshDS->SetMeshElementOnShape(face, aFxy1); } } + //======================================================================= //function : ClearMeshOnFxy1 //purpose : @@ -838,6 +969,7 @@ int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID) j=(*aMapIt).second; return j; } + //======================================================================= //function : MakeConnectingMap //purpose : @@ -852,6 +984,7 @@ void StdMeshers_Penta_3D::MakeConnectingMap() myConnectingMap[aBNID]=j; } } + //======================================================================= //function : CreateNode //purpose : @@ -879,8 +1012,7 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, // // point inside solid // myBlock.Point(aParams, aP); // } - if (bIsUpperLayer) - { + if (bIsUpperLayer) { double u = aParams.X(), v = aParams.Y(); double u1 = ( 1. - u ), v1 = ( 1. - v ); aP.ChangeCoord() = myShapeXYZ[ SMESH_Block::ID_Ex01 ] * v1; @@ -893,8 +1025,7 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V011 ] * u1 * v; aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V111 ] * u * v; } - else - { + else { SMESH_Block::ShellPoint( aParams, myShapeXYZ, aP.ChangeCoord() ); } // @@ -906,12 +1037,14 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, // aX=aP.X(); aY=aP.Y(); aZ=aP.Z(); // - SMESH_Mesh* pMesh=GetMesh(); - SMESHDS_Mesh* pMeshDS=pMesh->GetMeshDS(); + SMESH_Mesh* pMesh = GetMesh(); + SMESHDS_Mesh* pMeshDS = pMesh->GetMeshDS(); // pNode = pMeshDS->AddNode(aX, aY, aZ); + aTN.SetNode(pNode); } + //======================================================================= //function : ShapeSupportID //purpose : @@ -980,21 +1113,21 @@ void StdMeshers_Penta_3D::MakeBlock() SMDSAbs_ElementType aElementType; SMESH_Mesh* pMesh=GetMesh(); // - iCnt=0; - iNbF=aM.Extent(); + iCnt = 0; + iNbF = aM.Extent(); for (i=1; i<=iNbF; ++i) { - const TopoDS_Shape& aF=aM(i); + const TopoDS_Shape& aF = aM(i); SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF); ASSERT(aSubMesh); - SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); - SMDS_ElemIteratorPtr itf=aSM->GetElements(); + SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS(); + SMDS_ElemIteratorPtr itf = aSM->GetElements(); while(itf->more()) { - const SMDS_MeshElement * pElement=itf->next(); - aElementType=pElement->GetType(); + const SMDS_MeshElement * pElement = itf->next(); + aElementType = pElement->GetType(); if (aElementType==SMDSAbs_Face) { - iNbNodes=pElement->NbNodes(); - if (iNbNodes==3) { - aFTr=aF; + iNbNodes = pElement->NbNodes(); + if ( iNbNodes==3 || (myCreateQuadratic && iNbNodes==6) ) { + aFTr = aF; ++iCnt; if (iCnt>1) { MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); @@ -1013,7 +1146,7 @@ void StdMeshers_Penta_3D::MakeBlock() TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES); // // 1.1 Base vertex V000 - iNbE=aME.Extent(); + iNbE = aME.Extent(); if (iNbE!=4){ MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); myErrorStatus=7; // too few edges are in base face aFTr @@ -1080,7 +1213,7 @@ void StdMeshers_Penta_3D::MakeBlock() // 2. Load Block const TopoDS_Shell& aShell=TopoDS::Shell(aME(1)); myBlock.Load(aShell, aV000, aV001); - iErr=myBlock.ErrorStatus(); + iErr = myBlock.ErrorStatus(); if (iErr) { MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); myErrorStatus=100; // SMESHBlock: Load operation failed @@ -1154,10 +1287,10 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, bool rev1, CumOri = false; TopExp_Explorer exp( theFace, TopAbs_EDGE ); int nbEdges = 0; - for ( ; exp.More(); exp.Next() ) - { - if ( ++nbEdges > 4 ) + for ( ; exp.More(); exp.Next() ) { + if ( ++nbEdges > 4 ) { return false; // more than 4 edges in theFace + } TopoDS_Edge e = TopoDS::Edge( exp.Current() ); if ( theBaseEdge.IsSame( e )) continue; @@ -1174,8 +1307,9 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, else e2 = e; } - if ( nbEdges < 4 ) - return false; // lass than 4 edges in theFace + if ( nbEdges < 4 ) { + return false; // less than 4 edges in theFace + } // submeshes corresponding to shapes SMESHDS_SubMesh* smFace = theMesh->MeshElements( theFace ); @@ -1200,13 +1334,32 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, return false; } if ( sm1->NbNodes() * smb->NbNodes() != smFace->NbNodes() ) { - MESSAGE( "Wrong nb face nodes: " << - sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); - return false; + // check quadratic case + if ( myCreateQuadratic ) { + int n1 = sm1->NbNodes()/2; + int n2 = smb->NbNodes()/2; + int n3 = sm1->NbNodes() - n1; + int n4 = smb->NbNodes() - n2; + int nf = sm1->NbNodes()*smb->NbNodes() - n3*n4; + if( nf != smFace->NbNodes() ) { + MESSAGE( "Wrong nb face nodes: " << + sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); + return false; + } + } + else { + MESSAGE( "Wrong nb face nodes: " << + sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); + return false; + } } // IJ size int vsize = sm1->NbNodes() + 2; int hsize = smb->NbNodes() + 2; + if(myCreateQuadratic) { + vsize = vsize - sm1->NbNodes()/2 -1; + hsize = hsize - smb->NbNodes()/2 -1; + } // load nodes from theBaseEdge @@ -1226,12 +1379,15 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, double range = l - f; SMDS_NodeIteratorPtr nIt = smb->GetNodes(); const SMDS_MeshNode* node; - while ( nIt->more() ) - { + while ( nIt->more() ) { node = nIt->next(); + if(myTool->IsMedium(node)) + continue; const SMDS_EdgePosition* pos = dynamic_cast( node->GetPosition().get() ); - if ( !pos ) return false; + if ( !pos ) { + return false; + } double u = ( pos->GetUParameter() - f ) / range; vector & nVec = theIJNodes[ u ]; nVec.resize( vsize, nullNode ); @@ -1246,19 +1402,21 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, map< double, const SMDS_MeshNode*> sortedNodes; // sort by param on edge nIt = sm1->GetNodes(); - while ( nIt->more() ) - { + while ( nIt->more() ) { node = nIt->next(); + if(myTool->IsMedium(node)) + continue; const SMDS_EdgePosition* pos = dynamic_cast( node->GetPosition().get() ); - if ( !pos ) return false; + if ( !pos ) { + return false; + } sortedNodes.insert( make_pair( pos->GetUParameter(), node )); } loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() ); map< double, const SMDS_MeshNode*>::iterator u_n = sortedNodes.begin(); int row = rev1 ? vsize - 1 : 0; - for ( ; u_n != sortedNodes.end(); u_n++ ) - { + for ( ; u_n != sortedNodes.end(); u_n++ ) { if ( rev1 ) row--; else row++; loadedNodes.insert( nVecf[ row ] = u_n->second ); @@ -1285,8 +1443,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1; // loop on columns int col = 0; - for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ ) - { + for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ ) { col++; row = 0; const SMDS_MeshNode* n1 = par_nVec_1->second[ row ]; @@ -1295,10 +1452,10 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, do { // look for a face by 2 nodes face = SMESH_MeshEditor::FindFaceInSet( n1, n2, allFaces, foundFaces ); - if ( face ) - { + if ( face ) { int nbFaceNodes = face->NbNodes(); - if ( nbFaceNodes > 4 ) { + if ( (!myCreateQuadratic && nbFaceNodes>4) || + (myCreateQuadratic && nbFaceNodes>8) ) { MESSAGE(" Too many nodes in a face: " << nbFaceNodes ); return false; } @@ -1308,6 +1465,8 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, eIt = face->nodesIterator() ; while ( !found && eIt->more() ) { node = static_cast( eIt->next() ); + if(myTool->IsMedium(node)) + continue; found = loadedNodes.insert( node ).second; if ( !found && node != n1 && node != n2 ) n3 = node; @@ -1320,18 +1479,21 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, par_nVec_2->second[ row ] = node; foundFaces.insert( face ); n2 = node; - if ( nbFaceNodes == 4 ) + if ( nbFaceNodes==4 || (myCreateQuadratic && nbFaceNodes==8) ) { n1 = par_nVec_1->second[ row ]; + } } - else if (nbFaceNodes == 3 && - n3 == par_nVec_1->second[ row ] ) + else if ( (nbFaceNodes==3 || (myCreateQuadratic && nbFaceNodes==6) ) && + n3 == par_nVec_1->second[ row ] ) { n1 = n3; + } else { MESSAGE( "Not quad mesh, column "<< col ); return false; } } - } while ( face && n1 && n2 ); + } + while ( face && n1 && n2 ); if ( row < vsize - 1 ) { MESSAGE( "Too few nodes in column "<< col <<": "<< row+1); @@ -1390,17 +1552,18 @@ int StdMeshers_SMESHBlock::ErrorStatus() const { return myErrorStatus; } + //======================================================================= //function : Load //purpose : //======================================================================= void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell) { - TopoDS_Vertex aV000, aV001; // Load(theShell, aV000, aV001); } + //======================================================================= //function : Load //purpose : @@ -1416,12 +1579,13 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell, bool bOk; // myShapeIDMap.Clear(); - bOk=myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap); + bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap); if (!bOk) { myErrorStatus=2; return; } } + //======================================================================= //function : ComputeParameters //purpose : @@ -1431,24 +1595,25 @@ void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, { ComputeParameters(thePnt, myShell, theXYZ); } + //======================================================================= //function : ComputeParameters //purpose : //======================================================================= void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, const TopoDS_Shape& theShape, - gp_XYZ& theXYZ) + gp_XYZ& theXYZ) { myErrorStatus=0; // int aID; bool bOk; // - aID=ShapeID(theShape); + aID = ShapeID(theShape); if (myErrorStatus) { return; } - bOk=myTBlock.ComputeParameters(thePnt, theXYZ, aID); + bOk = myTBlock.ComputeParameters(thePnt, theXYZ, aID); if (!bOk) { myErrorStatus=4; // problems with computation Parameters return; @@ -1469,12 +1634,12 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, int aID; bool bOk=false; // - aID=ShapeID(theShape); + aID = ShapeID(theShape); if (myErrorStatus) { return; } if ( SMESH_Block::IsEdgeID( aID )) - bOk=myTBlock.EdgeParameters( aID, theU, theXYZ ); + bOk = myTBlock.EdgeParameters( aID, theU, theXYZ ); if (!bOk) { myErrorStatus=4; // problems with computation Parameters return; @@ -1492,6 +1657,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, // Point(theParams, aS, aP3D); } + //======================================================================= //function : Point //purpose : @@ -1500,15 +1666,15 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, const TopoDS_Shape& theShape, gp_Pnt& aP3D) { - myErrorStatus=0; + myErrorStatus = 0; // int aID; - bool bOk=false; + bool bOk = false; gp_XYZ aXYZ(99.,99.,99.); aP3D.SetXYZ(aXYZ); // if (theShape.IsNull()) { - bOk=myTBlock.ShellPoint(theParams, aXYZ); + bOk = myTBlock.ShellPoint(theParams, aXYZ); } // else { @@ -1518,14 +1684,14 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, } // if (SMESH_Block::IsVertexID(aID)) { - bOk=myTBlock.VertexPoint(aID, aXYZ); + bOk = myTBlock.VertexPoint(aID, aXYZ); } else if (SMESH_Block::IsEdgeID(aID)) { - bOk=myTBlock.EdgePoint(aID, theParams, aXYZ); + bOk = myTBlock.EdgePoint(aID, theParams, aXYZ); } // else if (SMESH_Block::IsFaceID(aID)) { - bOk=myTBlock.FacePoint(aID, theParams, aXYZ); + bOk = myTBlock.FacePoint(aID, theParams, aXYZ); } } if (!bOk) { @@ -1534,6 +1700,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, } aP3D.SetXYZ(aXYZ); } + //======================================================================= //function : ShapeID //purpose : @@ -1561,6 +1728,7 @@ int StdMeshers_SMESHBlock::ShapeID(const TopoDS_Shape& theShape) myErrorStatus=2; // unknown shape; return aID; } + //======================================================================= //function : Shape //purpose : @@ -1580,3 +1748,5 @@ const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID) const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID); return aS; } + + diff --git a/src/StdMeshers/StdMeshers_Penta_3D.hxx b/src/StdMeshers/StdMeshers_Penta_3D.hxx index dc8ba72cf..ae5b03c54 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.hxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.hxx @@ -39,9 +39,12 @@ #include #include #include +#include #include "SMESH_Block.hxx" +#include "StdMeshers_Helper.hxx" + typedef std::map< double, std::vector > StdMeshers_IJNodeMap; class StdMeshers_SMESHBlock { @@ -165,7 +168,7 @@ class StdMeshers_Penta_3D { public: // methods StdMeshers_Penta_3D(); - //~StdMeshers_Penta_3D(); + ~StdMeshers_Penta_3D(); bool Compute(SMESH_Mesh& , const TopoDS_Shape& ); @@ -181,10 +184,10 @@ class StdMeshers_Penta_3D { return myTol3D; } - static bool LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, - const TopoDS_Face& theFace, - const TopoDS_Edge& theBaseEdge, - SMESHDS_Mesh* theMesh); + bool LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, + const TopoDS_Face& theFace, + const TopoDS_Edge& theBaseEdge, + SMESHDS_Mesh* theMesh); // Load nodes bound to theFace into column (vectors) and rows // of theIJNodes. // The value of theIJNodes map is a vector of ordered nodes so @@ -251,6 +254,9 @@ class StdMeshers_Penta_3D { // vector myWallNodesMaps; // nodes on a face vector myShapeXYZ; // point on each sub-shape + + bool myCreateQuadratic; + StdMeshers_Helper* myTool; // toll for working with quadratic elements }; #endif diff --git a/src/StdMeshers/StdMeshers_Propagation.cxx b/src/StdMeshers/StdMeshers_Propagation.cxx index 6672e2565..f2d982bd1 100644 --- a/src/StdMeshers/StdMeshers_Propagation.cxx +++ b/src/StdMeshers/StdMeshers_Propagation.cxx @@ -40,7 +40,7 @@ StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, : SMESH_Hypothesis(hypId, studyId, gen) { _name = GetName(); - _param_algo_dim = -2; + _param_algo_dim = -1; // 1D auxiliary } //============================================================================= diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 9ffa37d1f..da30b6783 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -47,6 +47,7 @@ using namespace std; #include #include #include +#include #include #include @@ -80,6 +81,7 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMES _name = "Quadrangle_2D"; _shapeType = (1 << TopAbs_FACE); _compatibleHypothesis.push_back("QuadranglePreference"); + myTool = 0; } //============================================================================= @@ -91,6 +93,8 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMES StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D() { MESSAGE("StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D"); + if ( myTool ) + delete myTool; } //============================================================================= @@ -128,11 +132,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); aMesh.GetSubMesh(aShape); + if ( !myTool ) + myTool = new StdMeshers_Helper(aMesh); + _quadraticMesh = myTool->IsQuadraticSubMesh(aShape); + //FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape); FaceQuadStruct* quad = CheckNbEdges(aMesh, aShape); - if (!quad) + if (!quad) { + delete myTool; myTool = 0; return false; + } if(myQuadranglePreference) { int n1 = quad->nbPts[0]; @@ -144,14 +154,18 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, ntmp = ntmp*2; if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) { // special path for using only quandrangle faces - return ComputeQuadPref(aMesh, aShape, quad); + bool ok = ComputeQuadPref(aMesh, aShape, quad); + delete myTool; myTool = 0; + return ok; } } // set normalized grid on unit square in parametric domain SetNormalizedGrid(aMesh, aShape, quad); - if (!quad) + if (!quad) { + delete myTool; myTool = 0; return false; + } // --- compute 3D values on points, store points & quadrangles @@ -180,7 +194,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, quad->uv_grid[ij].node = node; } } - + // mesh faces // [2] @@ -194,16 +208,16 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, // 0 > > > > > > > > nbhoriz // i // [0] - + i = 0; int ilow = 0; int iup = nbhoriz - 1; if (quad->isEdgeOut[3]) { ilow++; } else { if (quad->isEdgeOut[1]) iup--; } - + int jlow = 0; int jup = nbvertic - 1; if (quad->isEdgeOut[0]) { jlow++; } else { if (quad->isEdgeOut[2]) jup--; } - + // regular quadrangles for (i = ilow; i < iup; i++) { for (j = jlow; j < jup; j++) { @@ -212,11 +226,12 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, b = quad->uv_grid[j * nbhoriz + i + 1].node; c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node; d = quad->uv_grid[(j + 1) * nbhoriz + i].node; - SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } - + UVPtStruct *uv_e0 = quad->uv_edges[0]; UVPtStruct *uv_e1 = quad->uv_edges[1]; UVPtStruct *uv_e2 = quad->uv_edges[2]; @@ -225,7 +240,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, double eps = Precision::Confusion(); // Boundary quadrangles - + if (quad->isEdgeOut[0]) { // Down edge is out // @@ -237,14 +252,14 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, // . . . . . . . . . __ down edge nodes // // >->->->->->->->->->->->-> -- direction of processing - + int g = 0; // number of last processed node in the regular grid - + // number of last node of the down edge to be processed int stop = nbdown - 1; // if right edge is out, we will stop at a node, previous to the last one if (quad->isEdgeOut[1]) stop--; - + // for each node of the down edge find nearest node // in the first row of the regular grid and link them for (i = 0; i < stop; i++) { @@ -252,18 +267,19 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, a = uv_e0[i].node; b = uv_e0[i + 1].node; gp_Pnt pb (b->X(), b->Y(), b->Z()); - + // find node c in the regular grid, which will be linked with node b int near = g; if (i == stop - 1) { // right bound reached, link with the rightmost node near = iup; c = quad->uv_grid[nbhoriz + iup].node; - } else { + } + else { // find in the grid node c, nearest to the b double mind = RealLast(); for (int k = g; k <= iup; k++) { - + const SMDS_MeshNode *nk; if (k < ilow) // this can be, if left edge is out nk = uv_e3[1].node; // get node from the left edge @@ -283,14 +299,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + SMDS_MeshFace* face = myTool->AddFace(a, b, c); meshDS->SetMeshElementOnShape(face, geomFaceID); - } else { // make quadrangle + } + else { // make quadrangle if (near - 1 < ilow) d = uv_e3[1].node; else d = quad->uv_grid[nbhoriz + near - 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); // if node d is not at position g - make additional triangles @@ -301,7 +320,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e3[1].node; else d = quad->uv_grid[nbhoriz + k - 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } @@ -363,14 +383,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + SMDS_MeshFace* face = myTool->AddFace(a, b, c); meshDS->SetMeshElementOnShape(face, geomFaceID); - } else { // make quadrangle + } + else { // make quadrangle if (near + 1 > iup) d = uv_e1[nbright - 2].node; else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); if (near + 1 < g) { // if d not is at g - make additional triangles @@ -380,7 +403,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e1[nbright - 2].node; else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } @@ -428,14 +452,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + SMDS_MeshFace* face = myTool->AddFace(a, b, c); meshDS->SetMeshElementOnShape(face, geomFaceID); - } else { // make quadrangle + } + else { // make quadrangle if (near - 1 < jlow) d = uv_e0[nbdown - 2].node; else d = quad->uv_grid[nbhoriz*near - 2].node; - SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); if (near - 1 > g) { // if d not is at g - make additional triangles @@ -445,7 +472,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e0[nbdown - 2].node; else d = quad->uv_grid[nbhoriz*k - 2].node; - SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } @@ -490,14 +518,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); + SMDS_MeshFace* face = myTool->AddFace(a, b, c); meshDS->SetMeshElementOnShape(face, geomFaceID); - } else { // make quadrangle + } + else { // make quadrangle if (near + 1 > jup) d = uv_e2[1].node; else d = quad->uv_grid[nbhoriz*(near + 1) + 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); if (near + 1 < g) { // if d not is at g - make additional triangles @@ -507,7 +538,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e2[1].node; else d = quad->uv_grid[nbhoriz*(k + 1) + 1].node; - SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); + SMDS_MeshFace* face = myTool->AddFace(a, c, d); meshDS->SetMeshElementOnShape(face, geomFaceID); } } @@ -518,6 +550,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } QuadDelete(quad); + delete myTool; myTool = 0; + bool isOk = true; return isOk; } @@ -557,7 +591,13 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh, int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); if (nbEdges < 4) { quad->edge[nbEdges] = E; - quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema + if(!_quadraticMesh) { + quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema + } + else { + int tmp = nb/2; + quad->nbPts[nbEdges] = tmp + 2; // internal not medium points + 2 extrema + } } nbEdges++; } @@ -571,18 +611,21 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh, return quad; } - //============================================================================= /*! - * + * CheckAnd2Dcompute */ //============================================================================= FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute - (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) throw(SALOME_Exception) + (SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool CreateQuadratic) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); + _quadraticMesh = CreateQuadratic; + FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape); if(!quad) return 0; @@ -1185,13 +1228,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref for(j=1; jAddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), + myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - meshDS->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1), + myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1), NodesL.Value(i+1,j+1), NodesL.Value(i+1,j)); meshDS->SetMeshElementOnShape(F, geomFaceID); } @@ -1252,13 +1295,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref for(j=1; jAddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), + myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - meshDS->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1), + myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1), NodesR.Value(i+1,j+1), NodesR.Value(i+1,j)); meshDS->SetMeshElementOnShape(F, geomFaceID); } @@ -1335,13 +1378,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref for(j=1; jAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - meshDS->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), + myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), NodesC.Value(i+1,j+1), NodesC.Value(i+1,j)); meshDS->SetMeshElementOnShape(F, geomFaceID); } @@ -1389,16 +1432,47 @@ UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints2 (SMESH_Mesh & aMesh, map params; SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - while(ite->more()) { - const SMDS_MeshNode* node = ite->next(); - const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); - double param = epos->GetUParameter(); - params[param] = node; + if(!_quadraticMesh) { + while(ite->more()) { + const SMDS_MeshNode* node = ite->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } + } + else { + vector nodes(nbPoints+2); + nodes[0] = idFirst; + nodes[nbPoints+1] = idLast; + nbPoints = nbPoints/2; + int nn = 1; + while(ite->more()) { + const SMDS_MeshNode* node = ite->next(); + nodes[nn++] = node; + // check if node is medium + bool IsMedium = false; + SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator(); + while (itn->more()) { + const SMDS_MeshElement* elem = itn->next(); + if ( elem->GetType() != SMDSAbs_Edge ) + continue; + if(elem->IsMediumNode(node)) { + IsMedium = true; + break; + } + } + if(IsMedium) + continue; + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } } - int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); if (nbPoints != params.size()) { MESSAGE( "BAD NODE ON EDGE POSITIONS" ); return 0; @@ -1523,21 +1597,60 @@ UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints (SMESH_Mesh & aMesh, // --- edge internal IDNodes (relies on good order storage, not checked) +// if(_quadraticMesh) { + // fill myNLinkNodeMap +// SMDS_ElemIteratorPtr iter = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetElements(); +// while(iter->more()) { +// const SMDS_MeshElement* elem = iter->next(); +// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); +// const SMDS_MeshNode* n1 = static_cast( nodeIt->next() ); +// const SMDS_MeshNode* n2 = static_cast( nodeIt->next() ); +// const SMDS_MeshNode* n3 = static_cast( nodeIt->next() ); +// NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 )); +// myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n3)); +// myNLinkNodeMap[link] = n3; +// } +// } + map params; SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - while(ite->more()) - { - const SMDS_MeshNode* node = ite->next(); - const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); - double param = epos->GetUParameter(); - params[param] = node; + if(!_quadraticMesh) { + while(ite->more()) { + const SMDS_MeshNode* node = ite->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } + } + else { + nbPoints = nbPoints/2; + while(ite->more()) { + const SMDS_MeshNode* node = ite->next(); + // check if node is medium + bool IsMedium = false; + SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator(); + while (itn->more()) { + const SMDS_MeshElement* elem = itn->next(); + if ( elem->GetType() != SMDSAbs_Edge ) + continue; + if(elem->IsMediumNode(node)) { + IsMedium = true; + break; + } + } + if(IsMedium) + continue; + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } } - int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); - if (nbPoints != params.size()) - { + if (nbPoints != params.size()) { MESSAGE( "BAD NODE ON EDGE POSITIONS" ); return 0; } diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index afb3498cb..9abff008c 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -34,7 +34,11 @@ #include "SMESH_Mesh.hxx" #include "Utils_SALOME_Exception.hxx" -class SMDS_MeshNode; +#include "gp_XY.hxx" + +#include "StdMeshers_Helper.hxx" + +//class SMDS_MeshNode; typedef struct uvPtStruct { @@ -75,11 +79,17 @@ public: throw (SALOME_Exception); FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) + const TopoDS_Shape& aShape, + const bool CreateQuadratic) throw (SALOME_Exception); static void QuadDelete(FaceQuadStruct* quad); + /** + * Returns NLinkNodeMap from myTool + */ + const NLinkNodeMap& GetNLinkNodeMap() { return myTool->GetNLinkNodeMap(); } + ostream & SaveTo(ostream & save); istream & LoadFrom(istream & load); friend ostream & operator << (ostream & save, StdMeshers_Quadrangle_2D & hyp); @@ -120,6 +130,8 @@ protected: // construction of quadrangles if the number of nodes on opposite edges // is not the same in the case where the global number of nodes on edges is even bool myQuadranglePreference; + + StdMeshers_Helper* myTool; // toll for working with quadratic elements }; #endif diff --git a/src/StdMeshers/StdMeshers_QuadraticMesh.cxx b/src/StdMeshers/StdMeshers_QuadraticMesh.cxx new file mode 100644 index 000000000..5ac5bd582 --- /dev/null +++ b/src/StdMeshers/StdMeshers_QuadraticMesh.cxx @@ -0,0 +1,111 @@ +// SMESH StdMeshers_QuadraticMesh : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_QuadraticMesh.cxx +// Module : SMESH +// $Header$ + +#include "StdMeshers_QuadraticMesh.hxx" +#include "utilities.h" + +using namespace std; + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_QuadraticMesh::StdMeshers_QuadraticMesh(int hypId, + int studyId, + SMESH_Gen * gen) + :SMESH_Hypothesis(hypId, studyId, gen) +{ + _name = "QuadraticMesh"; + _param_algo_dim = -1; // it means auxiliary, dim = 1 +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_QuadraticMesh::~StdMeshers_QuadraticMesh() +{ +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_QuadraticMesh::SaveTo(ostream & save) +{ + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_QuadraticMesh::LoadFrom(istream & load) +{ + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_QuadraticMesh & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_QuadraticMesh & hyp) +{ + return hyp.LoadFrom( load ); +} +//================================================================================ +/*! + * \brief Initialize my parameter values by the mesh built on the geometry + * \retval bool - false as this hypothesis does not have parameters values + */ +//================================================================================ + +bool StdMeshers_QuadraticMesh::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&) +{ + return false; +} diff --git a/src/StdMeshers/StdMeshers_QuadraticMesh.hxx b/src/StdMeshers/StdMeshers_QuadraticMesh.hxx new file mode 100644 index 000000000..8b88c93db --- /dev/null +++ b/src/StdMeshers/StdMeshers_QuadraticMesh.hxx @@ -0,0 +1,65 @@ +// SMESH StdMeshers : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_QuadraticMesh.hxx +// Module : SMESH +// $Header$ + +#ifndef _StdMeshers_QuadraticMesh_HXX_ +#define _StdMeshers_QuadraticMesh_HXX_ + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +/*! + * \brief Hypothesis for StdMeshers_Regular_1D, forcing construction of quadratic edges. + * If the 2D mesher sees that all boundary edges are quadratic ones, + * it generates quadratic faces, else it generates linear faces using + * medium nodes as if they were vertex ones. + * The 3D mesher generates quadratic volumes only if all boundary faces + * are quadratic ones, else it fails. + */ +class StdMeshers_QuadraticMesh:public SMESH_Hypothesis +{ + public: + StdMeshers_QuadraticMesh(int hypId, int studyId, SMESH_Gen * gen); + virtual ~ StdMeshers_QuadraticMesh(); + + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + friend std::ostream & operator <<(std::ostream & save, StdMeshers_QuadraticMesh & hyp); + friend std::istream & operator >>(std::istream & load, StdMeshers_QuadraticMesh & hyp); + + /*! + * \brief Initialize my parameter values by the mesh built on the geometry + * \param theMesh - the built mesh + * \param theShape - the geometry of interest + * \retval bool - true if parameter values have been successfully defined + * + * Just return false as this hypothesis does not have parameters values + */ + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); + +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 1723d6549..dc1ec9bb4 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -27,10 +27,14 @@ // Module : SMESH // $Header$ +using namespace std; + #include "StdMeshers_Regular_1D.hxx" #include "StdMeshers_Distribution.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_HypoFilter.hxx" +#include "SMESH_subMesh.hxx" #include "StdMeshers_LocalLength.hxx" #include "StdMeshers_NumberOfSegments.hxx" @@ -42,7 +46,6 @@ #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" #include "SMDS_EdgePosition.hxx" -#include "SMESH_subMesh.hxx" #include "Utils_SALOME_Exception.hxx" #include "utilities.h" @@ -88,6 +91,8 @@ StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId, _compatibleHypothesis.push_back("Deflection1D"); _compatibleHypothesis.push_back("Arithmetic1D"); _compatibleHypothesis.push_back("AutomaticLength"); + + _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!! } //============================================================================= @@ -107,22 +112,37 @@ StdMeshers_Regular_1D::~StdMeshers_Regular_1D() //============================================================================= bool StdMeshers_Regular_1D::CheckHypothesis - (SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, SMESH_Hypothesis::Hypothesis_Status& aStatus) { _hypType = NONE; + _quadraticMesh = false; + + const bool ignoreAuxiliaryHyps = false; + const list & hyps = + GetUsedHypothesis(aMesh, aShape, ignoreAuxiliaryHyps); + + // find non-auxiliary hypothesis + const SMESHDS_Hypothesis *theHyp = 0; + list ::const_iterator h = hyps.begin(); + for ( ; h != hyps.end(); ++h ) { + if ( static_cast(*h)->IsAuxiliary() ) { + if ( strcmp( "QuadraticMesh", (*h)->GetName() ) == 0 ) + _quadraticMesh = true; + } + else { + if ( !theHyp ) + theHyp = *h; // use only the first non-auxiliary hypothesis + } + } - const list &hyps = GetUsedHypothesis(aMesh, aShape); - if (hyps.size() == 0) + if ( !theHyp ) { aStatus = SMESH_Hypothesis::HYP_MISSING; return false; // can't work without a hypothesis } - // use only the first hypothesis - const SMESHDS_Hypothesis *theHyp = hyps.front(); - string hypName = theHyp->GetName(); if (hypName == "LocalLength") @@ -352,17 +372,27 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge { case StdMeshers_NumberOfSegments::DT_Scale: { + int NbSegm = _ivalue[ NB_SEGMENTS_IND ]; double scale = _value[ SCALE_FACTOR_IND ]; - if ( theReverse ) - scale = 1. / scale; - double alpha = pow( scale , 1.0 / (_ivalue[ NB_SEGMENTS_IND ] - 1)); - double factor = (l - f) / (1 - pow( alpha,_ivalue[ NB_SEGMENTS_IND ])); - - int i, NbPoints = 1 + _ivalue[ NB_SEGMENTS_IND ]; - for ( i = 2; i < NbPoints; i++ ) - { - double param = f + factor * (1 - pow(alpha, i - 1)); - theParams.push_back( param ); + + if (fabs(scale - 1.0) < Precision::Confusion()) { + // special case to avoid division on zero + for (int i = 1; i < NbSegm; i++) { + double param = f + (l - f) * i / NbSegm; + theParams.push_back( param ); + } + } else { + // general case of scale distribution + if ( theReverse ) + scale = 1.0 / scale; + + double alpha = pow(scale, 1.0 / (NbSegm - 1)); + double factor = (l - f) / (1.0 - pow(alpha, NbSegm)); + + for (int i = 1; i < NbSegm; i++) { + double param = f + factor * (1.0 - pow(alpha, i)); + theParams.push_back( param ); + } } return true; } @@ -390,7 +420,6 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge return false; } } - GCPnts_UniformAbscissa Discret(C3d, eltSize, f, l); if ( !Discret.IsDone() ) return false; @@ -470,7 +499,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge case DEFLECTION: { - GCPnts_UniformDeflection Discret(C3d, _value[ DEFLECTION_IND ], true); + GCPnts_UniformDeflection Discret(C3d, _value[ DEFLECTION_IND ], f, l, true); if ( !Discret.IsDone() ) return false; @@ -527,24 +556,25 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh ASSERT(!VLast.IsNull()); lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); - if (!lid->more()) - { + if (!lid->more()) { MESSAGE (" NO NODE BUILT ON VERTEX "); return false; } const SMDS_MeshNode * idLast = lid->next(); - if (!Curve.IsNull()) - { + if (!Curve.IsNull()) { list< double > params; bool reversed = false; if ( !_mainEdge.IsNull() ) reversed = aMesh.IsReversedInChain( EE, _mainEdge ); try { - if ( ! computeInternalParameters( E, params, reversed )) + if ( ! computeInternalParameters( E, params, reversed )) { + //cout << "computeInternalParameters() failed" <::iterator itU = params.begin(); itU != params.end(); itU++) - { + for (list::iterator itU = params.begin(); itU != params.end(); itU++) { double param = *itU; gp_Pnt P = Curve->Value(param); @@ -562,17 +597,39 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnEdge(node, shapeID, param); - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); - meshDS->SetMeshElementOnShape(edge, shapeID); + if(_quadraticMesh) { + // create medium node + double prm = ( parPrev + param )/2; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + idPrev = node; + parPrev = param; + } + if(_quadraticMesh) { + double prm = ( parPrev + parLast )/2; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, shapeID); } - SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); - meshDS->SetMeshElementOnShape(edge, shapeID); } - else - { + else { // Edge is a degenerated Edge : We put n = 5 points on the edge. - int NbPoints = 5; + const int NbPoints = 5; BRep_Tool::Range(E, f, l); double du = (l - f) / (NbPoints - 1); //MESSAGE("************* Degenerated edge! *****************"); @@ -582,18 +639,38 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh gp_Pnt P = BRep_Tool::Pnt(V1); const SMDS_MeshNode * idPrev = idFirst; - for (int i = 2; i < NbPoints; i++) - { + for (int i = 2; i < NbPoints; i++) { double param = f + (i - 1) * du; SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); + if(_quadraticMesh) { + // create medium node + double prm = param - du/2.; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, shapeID); + } meshDS->SetNodeOnEdge(node, shapeID, param); - - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); - meshDS->SetMeshElementOnShape(edge, shapeID); idPrev = node; } - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); - meshDS->SetMeshElementOnShape(edge, shapeID); + if(_quadraticMesh) { + // create medium node + double prm = l - du/2.; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, shapeID); + } } return true; } @@ -604,40 +681,47 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh */ //============================================================================= -const list & StdMeshers_Regular_1D::GetUsedHypothesis( - SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +const list & +StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary) { _usedHypList.clear(); - _usedHypList = GetAppliedHypothesis(aMesh, aShape); // copy - int nbHyp = _usedHypList.size(); _mainEdge.Nullify(); + + SMESH_HypoFilter auxiliaryFilter, compatibleFilter; + auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() ); + const bool ignoreAux = true; + InitCompatibleHypoFilter( compatibleFilter, ignoreAux ); + + // get non-auxiliary assigned to aShape + int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false ); + if (nbHyp == 0) { // Check, if propagated from some other edge if (aShape.ShapeType() == TopAbs_EDGE && aMesh.IsPropagatedHypothesis(aShape, _mainEdge)) { - // Propagation of 1D hypothesis from on this edge - //_usedHypList = GetAppliedHypothesis(aMesh, _mainEdge); // copy - // use a general method in order not to nullify _mainEdge - _usedHypList = SMESH_Algo::GetUsedHypothesis(aMesh, _mainEdge); // copy - nbHyp = _usedHypList.size(); + // Propagation of 1D hypothesis from on this edge; + // get non-auxiliary assigned to _mainEdge + nbHyp = aMesh.GetHypotheses( _mainEdge, compatibleFilter, _usedHypList, false ); } } - if (nbHyp == 0) + + if (nbHyp == 0) // nothing propagated nor assigned to aShape { - TopTools_ListIteratorOfListOfShape ancIt( aMesh.GetAncestors( aShape )); - for (; ancIt.More(); ancIt.Next()) - { - const TopoDS_Shape& ancestor = ancIt.Value(); - _usedHypList = GetAppliedHypothesis(aMesh, ancestor); // copy - nbHyp = _usedHypList.size(); - if (nbHyp == 1) - break; - } + SMESH_Algo::GetUsedHypothesis( aMesh, aShape, ignoreAuxiliary ); + nbHyp = _usedHypList.size(); } - if (nbHyp > 1) - _usedHypList.clear(); //only one compatible hypothesis allowed + else + { + // get auxiliary hyps from aShape + aMesh.GetHypotheses( aShape, auxiliaryFilter, _usedHypList, true ); + } + if ( nbHyp > 1 && ignoreAuxiliary ) + _usedHypList.clear(); //only one compatible non-auxiliary hypothesis allowed + return _usedHypList; } diff --git a/src/StdMeshers/StdMeshers_Regular_1D.hxx b/src/StdMeshers/StdMeshers_Regular_1D.hxx index 4ab58e9ce..e2695901b 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.hxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.hxx @@ -49,7 +49,7 @@ public: const TopoDS_Shape& aShape); virtual const std::list & - GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true); ostream & SaveTo(ostream & save); istream & LoadFrom(istream & load); diff --git a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx index 0d66dc53a..e58be313b 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx @@ -1,11 +1,9 @@ #include "StdMeshersGUI_DistrPreview.h" +#include "CASCatch.hxx" + #include #include -#include -#include -#include -#include StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers::StdMeshers_NumberOfSegments_ptr h ) : QwtPlot( p ), @@ -223,20 +221,14 @@ void StdMeshersGUI_DistrPreview::update() delete[] y; x = y = 0; - OSD::SetSignal( true ); - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - CASCatch_TRY { replot(); } - CASCatch_CATCH(CASCatch_Failure) + CASCatch_CATCH(Standard_Failure) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); } - aCatchSignals.Deactivate(); } void StdMeshersGUI_DistrPreview::showError() @@ -273,22 +265,17 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr ) bool StdMeshersGUI_DistrPreview::init( const QString& str ) { - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - bool parsed_ok = true; CASCatch_TRY { myExpr = ExprIntrp_GenExp::Create(); myExpr->Process( ( Standard_CString ) str.latin1() ); } - CASCatch_CATCH(CASCatch_Failure) + CASCatch_CATCH(Standard_Failure) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); parsed_ok = false; } - aCatchSignals.Deactivate(); bool syntax = false, args = false; if( parsed_ok && myExpr->IsDone() ) @@ -318,23 +305,18 @@ double StdMeshersGUI_DistrPreview::funcValue( const double t, bool& ok ) double StdMeshersGUI_DistrPreview::calc( bool& ok ) { - OSD::SetSignal( true ); double res = 0.0; - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - ok = true; CASCatch_TRY { res = myExpr->Expression()->Evaluate( myVars, myValues ); } - CASCatch_CATCH(CASCatch_Failure) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + CASCatch_CATCH(Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); ok = false; res = 0.0; } - aCatchSignals.Deactivate(); + return res; } @@ -345,9 +327,6 @@ bool StdMeshersGUI_DistrPreview::isDone() const bool StdMeshersGUI_DistrPreview::convert( double& v ) const { - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - bool ok = true; switch( myConv ) { @@ -355,12 +334,15 @@ bool StdMeshersGUI_DistrPreview::convert( double& v ) const { CASCatch_TRY { + // in StdMeshers_NumberOfSegments.cc + // const double PRECISION = 1e-7; + // + if(v < -7) v = -7.0; v = pow( 10.0, v ); } - CASCatch_CATCH(CASCatch_Failure) + CASCatch_CATCH(Standard_Failure) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); v = 0.0; ok = false; } @@ -372,6 +354,6 @@ bool StdMeshersGUI_DistrPreview::convert( double& v ) const v = 0; break; } - aCatchSignals.Deactivate(); + return ok; } diff --git a/src/StdMeshersGUI/StdMeshers_images.po b/src/StdMeshersGUI/StdMeshers_images.po index c5978633b..64828da63 100644 --- a/src/StdMeshersGUI/StdMeshers_images.po +++ b/src/StdMeshersGUI/StdMeshers_images.po @@ -80,10 +80,14 @@ msgstr "mesh_tree_algo_quad.png" msgid "ICON_SMESH_TREE_HYPO_MaxElementArea" msgstr "mesh_tree_hypo_area.png" -#mesh_tree_hypo_area +#mesh_tree_hypo_quadranglepreference msgid "ICON_SMESH_TREE_HYPO_QuadranglePreference" msgstr "mesh_tree_algo_quad.png" +#mesh_tree_hypo_quadraticmesh +msgid "ICON_SMESH_TREE_HYPO_QuadraticMesh" +msgstr "mesh_tree_hypo_length.png" + #mesh_tree_hypo_length msgid "ICON_SMESH_TREE_HYPO_LocalLength" msgstr "mesh_tree_hypo_length.png" diff --git a/src/StdMeshers_I/Makefile.in b/src/StdMeshers_I/Makefile.in index cb445cb85..0f5cbcd18 100644 --- a/src/StdMeshers_I/Makefile.in +++ b/src/StdMeshers_I/Makefile.in @@ -52,7 +52,8 @@ EXPORT_HEADERS = \ StdMeshers_MEFISTO_2D_i.hxx \ StdMeshers_Hexa_3D_i.hxx \ StdMeshers_AutomaticLength_i.hxx \ - StdMeshers_QuadranglePreference_i.hxx + StdMeshers_QuadranglePreference_i.hxx \ + StdMeshers_QuadraticMesh_i.hxx # Libraries targets @@ -75,7 +76,8 @@ LIB_SRC = \ StdMeshers_MEFISTO_2D_i.cxx \ StdMeshers_Hexa_3D_i.cxx \ StdMeshers_AutomaticLength_i.cxx \ - StdMeshers_QuadranglePreference_i.cxx + StdMeshers_QuadranglePreference_i.cxx \ + StdMeshers_QuadraticMesh_i.cxx LIB_SERVER_IDL = SMESH_BasicHypothesis.idl diff --git a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx index edc817e3b..12d77a6dd 100644 --- a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx +++ b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx @@ -308,7 +308,7 @@ void StdMeshers_NumberOfSegments_i::SetExpressionFunction(const char* expr) try { this->GetImpl()->SetExpressionFunction( expr ); // Update Python script - SMESH::TPythonDump() << _this() << ".SetExpressionFunction( " << expr << " )"; + SMESH::TPythonDump() << _this() << ".SetExpressionFunction( '" << expr << "' )"; } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), diff --git a/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.cxx b/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.cxx new file mode 100644 index 000000000..7f1818771 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.cxx @@ -0,0 +1,99 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_QuadraticMesh_i.cxx +// Moved here from SMESH_LocalLength_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#include "StdMeshers_QuadraticMesh_i.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +//#include + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_QuadraticMesh_i::StdMeshers_QuadraticMesh_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_QuadraticMesh_i::StdMeshers_QuadraticMesh_i +( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ),SMESH_Hypothesis_i( thePOA ) +{ + myBaseImpl = new ::StdMeshers_QuadraticMesh( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_QuadraticMesh_i::~StdMeshers_QuadraticMesh_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_QuadraticMesh_i::~StdMeshers_QuadraticMesh_i() +{ +} + +//============================================================================= +/*! + * StdMeshers_QuadraticMesh_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_QuadraticMesh* StdMeshers_QuadraticMesh_i::GetImpl() +{ + return ( ::StdMeshers_QuadraticMesh* )myBaseImpl; +} + +//================================================================================ +/*! + * \brief Verify whether hypothesis supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ + +CORBA::Boolean StdMeshers_QuadraticMesh_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_1D; +} + diff --git a/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.hxx b/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.hxx new file mode 100644 index 000000000..c2a3f3f3d --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.hxx @@ -0,0 +1,64 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_QuadraticMesh_i.hxx +// Moved here from SMESH_LocalLength_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_QuadraticMesh_I_HXX_ +#define _SMESH_QuadraticMesh_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_QuadraticMesh.hxx" + +class SMESH_Gen; + +// ====================================================== +// Local Length hypothesis +// ====================================================== +class StdMeshers_QuadraticMesh_i: + public virtual POA_StdMeshers::StdMeshers_QuadraticMesh, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_QuadraticMesh_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_QuadraticMesh_i(); + + // Get implementation + ::StdMeshers_QuadraticMesh* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_i.cxx b/src/StdMeshers_I/StdMeshers_i.cxx index 768d2c4fb..a379e81ac 100644 --- a/src/StdMeshers_I/StdMeshers_i.cxx +++ b/src/StdMeshers_I/StdMeshers_i.cxx @@ -39,6 +39,7 @@ using namespace std; #include "StdMeshers_Propagation_i.hxx" #include "StdMeshers_LengthFromEdges_i.hxx" #include "StdMeshers_QuadranglePreference_i.hxx" +#include "StdMeshers_QuadraticMesh_i.hxx" #include "StdMeshers_MaxElementArea_i.hxx" #include "StdMeshers_MaxElementVolume_i.hxx" #include "StdMeshers_NotConformAllowed_i.hxx" @@ -87,6 +88,8 @@ extern "C" aCreator = new HypothesisCreator_i; else if (strcmp(aHypName, "QuadranglePreference") == 0) aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "QuadraticMesh") == 0) + aCreator = new HypothesisCreator_i; // Algorithms else if (strcmp(aHypName, "Regular_1D") == 0)