From: prascle Date: Mon, 29 Nov 2010 13:20:53 +0000 (+0000) Subject: merge from branch BR_SMDS_MEMIMP 29 nov 2010 X-Git-Tag: V6_2_0a1~9 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=8fa039a796957b302d86d90b22afc0a998573f83;p=modules%2Fsmesh.git merge from branch BR_SMDS_MEMIMP 29 nov 2010 --- 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..e03c6c165 --- /dev/null +++ b/adm_local/unix/config_files/check_f77.m4 @@ -0,0 +1,29 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +AC_DEFUN([CHECK_F77],[ + +AC_PROG_F77 + +AC_F77_LIBRARY_LDFLAGS +AC_F77_WRAPPERS + +])dnl diff --git a/adm_local/unix/config_files/check_qwt.m4 b/adm_local/unix/config_files/check_qwt.m4 new file mode 100644 index 000000000..736c5b5c8 --- /dev/null +++ b/adm_local/unix/config_files/check_qwt.m4 @@ -0,0 +1,187 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +AC_DEFUN([CHECK_QWT],[ +AC_REQUIRE([CHECK_QT])dnl +AC_REQUIRE([AC_LINKER_OPTIONS])dnl + +AC_CHECKING(for qwt) + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +qwt_ok=yes + +dnl where is qwt ? + +AC_ARG_WITH(qwt, + [ --with-qwt=DIR directory path to QWT installation ], + [QWTHOME="$withval" + AC_MSG_RESULT("select $withval as path to QWT") + ]) + +AC_ARG_WITH(qwt_inc, + [ --with-qwt_inc=DIR directory path to QWT includes ], + [QWT_INCDIR="$withval" + AC_MSG_RESULT("select $withval as path to QWT includes") + ]) + +libqwt_name=qwt +if test -z $QWTHOME; then + AC_MSG_RESULT(QWTHOME not defined) + AC_MSG_NOTICE(Trying native Qwt...) + exist_ok=no + if test "x$exist_ok" = "xno"; then + for d in /usr /usr/local ; do + for extension in qwt-qt4 qwt; do + AC_CHECK_FILE(${d}/lib${LIB_LOCATION_SUFFIX}/lib${extension}.so,exist_ok=yes,exist_ok=no) + if test "x$exist_ok" = "xyes"; then + QWTHOME=$d + AC_MSG_RESULT(lib${extension}.so detected in $d/lib) + libqwt_name=${extension} + dnl break, libqwt-qt4.so is choosen before libqwt.so since it is surely the Qt4 version. + break + fi + done + if test "x$exist_ok" = "xyes"; then + break + fi + done + fi + if test "x$exist_ok" = "xno"; then + for d in `echo $LD_LIBRARY_PATH | sed -e "s/:/ /g"` ; do + if test -f $d/libqwt.so ; then + AC_MSG_RESULT(libqwt.so detected in $d) + QWTHOME=$d + QWTHOME=`echo ${QWTHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + exist_ok=yes + break + fi + done + fi + if test "x$exist_ok" = "xyes"; then + if test -z $QWT_INCDIR; then + QWT_INCDIR=$QWTHOME"/include/qwt-qt4" + if test ! -f $QWT_INCDIR/qwt.h ; then + QWT_INCDIR=/usr/include/qwt + fi + if test ! -f $QWT_INCDIR/qwt.h ; then + QWT_INCDIR=$QWTHOME"/include" + fi + if test ! -f $QWT_INCDIR/qwt.h ; then + QWT_INCDIR=/usr/lib/qt4/include/qwt + fi + if test ! -f $QWT_INCDIR/qwt.h ; then + QWT_INCDIR=/usr/include/qwt-qt4 + fi + fi + else + qwt_ok=no + fi +else + AC_MSG_NOTICE(Trying Qwt from $QWTHOME ...) + if test -z $QWT_INCDIR; then + QWT_INCDIR="$QWTHOME/include" + fi +fi + +if test "x$qwt_ok" = xno -o ! -d "$QWTHOME" ; then + AC_MSG_RESULT(no) + AC_MSG_WARN(qwt not found) + qwt_ok=no +else + CPPFLAGS_old=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $QT_INCLUDES -I$QWT_INCDIR" + + AC_CHECK_HEADER(qwt.h,qwt_ok=yes,qwt_ok=no) + CPPFLAGS=$CPPFLAGS_old + + AC_MSG_CHECKING(include of qwt headers) + + if test "x$qwt_ok" = xno ; then + AC_MSG_RESULT(no) + AC_MSG_WARN(qwt not found) + else + AC_MSG_RESULT(yes) + QWT_INCLUDES=-I$QWT_INCDIR + fi + + # + # test Qwt libraries + # + if test "x$qwt_ok" = "xyes" ; then + AC_MSG_CHECKING(linking qwt library) + + LIBS_old=$LIBS + LIBS="$LIBS $QT_LIBS" + if test "x$QWTHOME" = "x/usr" ; then + LIBS="$LIBS -l${libqwt_name}" + else + LIBS="$LIBS -L$QWTHOME/lib -l${libqwt_name}" + fi + + CXXFLAGS_old=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $QT_INCLUDES $QWT_INCLUDES" + + AC_CACHE_VAL(salome_cv_lib_qwt,[ + AC_TRY_LINK( +#include +#include +, int n; + char **s; + QApplication a(n, s); + QwtPlot p; + p.resize( 600, 400 ); + p.show(); + a.exec();, + eval "salome_cv_lib_qwt=yes",eval "salome_cv_lib_qwt=no") + ]) + qwt_ok="$salome_cv_lib_qwt" + + if test "x$qwt_ok" = "xno" ; then + AC_MSG_RESULT(unable to link with qwt library) + AC_MSG_RESULT(QWTHOME environment variable may be wrong) + else + AC_MSG_RESULT(yes) + if test "x$QWTHOME" = "x/usr" ; then + QWT_LIBS=" -l${libqwt_name}" + else + QWT_LIBS="-L$QWTHOME/lib -l${libqwt_name}" + fi + fi + + LIBS=$LIBS_old + CXXFLAGS=$CXXFLAGS_old + fi +fi + +AC_SUBST(QWT_INCLUDES) +AC_SUBST(QWT_LIBS) + +AC_LANG_RESTORE + +AC_MSG_RESULT(for qwt: $qwt_ok) + +# Save cache +AC_CACHE_SAVE + +])dnl +dnl diff --git a/clean_configure b/clean_configure index 05e43a7ff..be3f7f1af 100755 --- a/clean_configure +++ b/clean_configure @@ -28,6 +28,9 @@ find bin -name Makefile.in | xargs rm -f find doc -name Makefile.in | xargs rm -f find idl -name Makefile.in | xargs rm -f find resources -name Makefile.in | xargs rm -f +find salome_adm -name Makefile.in | xargs rm -f find adm_local -name Makefile.in | xargs rm -f find src -name Makefile.in | xargs rm -f rm -f Makefile.in +cd adm_local/unix/config_files +rm -f config.* depcomp install-sh l*.m4 ltmain.sh missing py-compile diff --git a/doc/salome/gui/SMESH/images/image94.gif b/doc/salome/gui/SMESH/images/image94.gif new file mode 100755 index 000000000..7313f5deb Binary files /dev/null and b/doc/salome/gui/SMESH/images/image94.gif differ diff --git a/doc/salome/gui/SMESH/static/header.html b/doc/salome/gui/SMESH/static/header.html new file mode 100755 index 000000000..a70a95e30 --- /dev/null +++ b/doc/salome/gui/SMESH/static/header.html @@ -0,0 +1,12 @@ + + + + + $title + + +
+
+SALOME documentation central +
+
diff --git a/doc/salome/tui/doxyfile.in b/doc/salome/tui/doxyfile.in index 2279c3fc5..56d3277d5 100755 --- a/doc/salome/tui/doxyfile.in +++ b/doc/salome/tui/doxyfile.in @@ -31,7 +31,7 @@ CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = NO +REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = YES INLINE_INHERITED_MEMB = YES @@ -40,6 +40,7 @@ STRIP_FROM_PATH = @top_srcdir@ @top_builddir@ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES @@ -69,7 +70,7 @@ CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES -SORT_MEMBER_DOCS = NO +SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES @@ -91,7 +92,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = +WARN_LOGFILE = log.txt #--------------------------------------------------------------------------- # configuration options related to the input files @@ -117,19 +118,19 @@ FILTER_SOURCE_FILES = YES #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO +SOURCE_BROWSER = YES +INLINE_SOURCES = YES STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO +REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES -USE_HTAGS = NO +#USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 3 +COLS_IN_ALPHA_INDEX = 2 IGNORE_PREFIX = #--------------------------------------------------------------------------- @@ -146,11 +147,11 @@ GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO -BINARY_TOC = YES -TOC_EXPAND = YES +BINARY_TOC = NO +TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO +GENERATE_TREEVIEW = YES TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- @@ -213,14 +214,14 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = NO +SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references @@ -239,23 +240,23 @@ HIDE_UNDOC_RELATIONS = NO HAVE_DOT = YES CLASS_GRAPH = YES COLLABORATION_GRAPH = NO -GROUP_GRAPHS = NO +GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = YES INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = NO +INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = jpg +DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1200 -MAX_DOT_GRAPH_DEPTH = 0 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = NO +GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- diff --git a/doc/salome/tui/images/application.gif b/doc/salome/tui/images/application.gif new file mode 100644 index 000000000..0b05d5c18 Binary files /dev/null and b/doc/salome/tui/images/application.gif differ diff --git a/doc/salome/tui/images/logocorp.gif b/doc/salome/tui/images/logocorp.gif new file mode 100755 index 000000000..7697e0837 Binary files /dev/null and b/doc/salome/tui/images/logocorp.gif differ diff --git a/doc/salome/tui/static/myheader.html b/doc/salome/tui/static/myheader.html new file mode 100755 index 000000000..d2efb75fa --- /dev/null +++ b/doc/salome/tui/static/myheader.html @@ -0,0 +1,13 @@ + + + + + + Main Page + + + + +  + + diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl index c010980be..acc18fad3 100644 --- a/idl/SMESH_MeshEditor.idl +++ b/idl/SMESH_MeshEditor.idl @@ -929,6 +929,19 @@ module SMESH */ boolean Make2DMeshFrom3D(); + /*! + * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. + * The list of groups must describe a partition of the mesh volumes. + * The nodes of the internal faces at the boundaries of the groups are doubled. + * In option, the internal faces are replaced by flat elements. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * \param theDomains - list of groups of volumes + * \param createJointElems - if TRUE, create the elements + * \return TRUE if operation has been completed successfully, FALSE otherwise + */ + boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains, + in boolean createJointElems ); + /*! * \brief Creates missing boundary elements * \param elements - elements whose boundary is to be checked diff --git a/src/Controls/Makefile.am b/src/Controls/Makefile.am index 9401c6d72..57e9551ce 100644 --- a/src/Controls/Makefile.am +++ b/src/Controls/Makefile.am @@ -43,6 +43,7 @@ dist_SMESHControls_SOURCES = \ # additionnal information to compil and link file libSMESHControls_la_CPPFLAGS = \ $(CAS_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ $(KERNEL_CXXFLAGS) \ -I$(srcdir)/../SMDS \ diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 5238b982f..198ea8da4 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -250,11 +250,11 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, if ( anElem->IsQuadratic() ) { switch ( anElem->GetType() ) { case SMDSAbs_Edge: - anIter = static_cast + anIter = dynamic_cast (anElem)->interlacedNodesElemIterator(); break; case SMDSAbs_Face: - anIter = static_cast + anIter = dynamic_cast (anElem)->interlacedNodesElemIterator(); break; default: @@ -1622,10 +1622,10 @@ void Length2D::GetValues(TValues& theValues){ const SMDS_MeshFace* anElem = anIter->next(); if(anElem->IsQuadratic()) { - const SMDS_QuadraticFaceOfNodes* F = - static_cast(anElem); + const SMDS_VtkFace* F = + dynamic_cast(anElem); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); long aNodeId[4]; gp_Pnt P[4]; @@ -1819,7 +1819,7 @@ void MultiConnection2D::GetValues(MValues& theValues){ const SMDS_MeshFace* anElem = anIter->next(); SMDS_ElemIteratorPtr aNodesIter; if ( anElem->IsQuadratic() ) - aNodesIter = static_cast + aNodesIter = dynamic_cast (anElem)->interlacedNodesElemIterator(); else aNodesIter = anElem->nodesIterator(); @@ -1978,7 +1978,7 @@ bool FreeEdges::IsSatisfy( long theId ) SMDS_ElemIteratorPtr anIter; if ( aFace->IsQuadratic() ) { - anIter = static_cast + anIter = dynamic_cast (aFace)->interlacedNodesElemIterator(); } else { @@ -2047,7 +2047,7 @@ void FreeEdges::GetBoreders(TBorders& theBorders) long anElemId = anElem->GetID(); SMDS_ElemIteratorPtr aNodesIter; if ( anElem->IsQuadratic() ) - aNodesIter = static_cast(anElem)-> + aNodesIter = static_cast(anElem)-> interlacedNodesElemIterator(); else aNodesIter = anElem->nodesIterator(); @@ -3225,7 +3225,7 @@ void ManifoldPart::expandBoundary void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink, ManifoldPart::TVectorOfFacePtr& theFaces ) const { - SMDS_Mesh::SetOfFaces aSetOfFaces; + std::set aSetOfFaces; // take all faces that shared first node SMDS_ElemIteratorPtr anItr = theLink.myNode1->facesIterator(); for ( ; anItr->more(); ) @@ -3233,7 +3233,7 @@ void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink, SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next(); if ( !aFace ) continue; - aSetOfFaces.Add( aFace ); + aSetOfFaces.insert( aFace ); } // take all faces that shared second node anItr = theLink.myNode2->facesIterator(); @@ -3241,7 +3241,7 @@ void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink, for ( ; anItr->more(); ) { SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next(); - if ( aSetOfFaces.Contains( aFace ) ) + if ( aSetOfFaces.count( aFace ) ) theFaces.push_back( aFace ); } } diff --git a/src/DriverDAT/Makefile.am b/src/DriverDAT/Makefile.am index 7d5ddc8ad..4d701ec2d 100644 --- a/src/DriverDAT/Makefile.am +++ b/src/DriverDAT/Makefile.am @@ -56,6 +56,7 @@ dist_DAT_Test_SOURCES = \ libMeshDriverDAT_la_CPPFLAGS = \ $(KERNEL_CXXFLAGS) \ $(CAS_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ -I$(srcdir)/../Driver \ -I$(srcdir)/../SMDS \ diff --git a/src/DriverMED/DriverMED_Family.cxx b/src/DriverMED/DriverMED_Family.cxx index 4d0f73ec5..0f0f5709f 100644 --- a/src/DriverMED/DriverMED_Family.cxx +++ b/src/DriverMED/DriverMED_Family.cxx @@ -24,6 +24,7 @@ // File : DriverMED_Family.cxx // Author : Julia DOROVSKIKH // Module : SMESH +// $Header$ // #include "DriverMED_Family.h" #include "MED_Factory.hxx" diff --git a/src/DriverMED/DriverMED_Family.h b/src/DriverMED/DriverMED_Family.h index a05e99b59..8110e56de 100644 --- a/src/DriverMED/DriverMED_Family.h +++ b/src/DriverMED/DriverMED_Family.h @@ -24,6 +24,7 @@ // File : DriverMED_Family.hxx // Author : Julia DOROVSKIKH // Module : SMESH +// $Header$ // #ifndef _INCLUDE_DRIVERMED_FAMILY #define _INCLUDE_DRIVERMED_FAMILY diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx index 5b425f212..c679edd9b 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx @@ -40,7 +40,7 @@ #include #ifdef _DEBUG_ -static int MYDEBUG = 0; +static int MYDEBUG = 1; //#define _DEXCEPT_ #else static int MYDEBUG = 0; @@ -161,9 +161,11 @@ DriverMED_R_SMESHDS_Mesh if(anIsNodeNum) { aNode = myMesh->AddNodeWithID (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem)); + //MESSAGE("AddNodeWithID " << aNodeInfo->GetElemNum(iElem)); } else { - aNode = myMesh->AddNode - (aCoords[0],aCoords[1],aCoords[2]); + aNode = myMesh->AddNodeWithID + (aCoords[0],aCoords[1],aCoords[2], iElem+1); + //MESSAGE("AddNode " << aNode->GetID()); } //cout<GetID()<<": "<X()<<", "<Y()<<", "<Z()<GetElemNum(iElem); anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId); + //MESSAGE("AddPolygonalFaceWithID " << anElemId); } if(!anElement){ vector aNodes(aNbConn); for(TInt iConn = 0; iConn < aNbConn; iConn++) aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]); anElement = myMesh->AddPolygonalFace(aNodes); + //MESSAGE("AddPolygonalFace " << anElement->GetID()); isRenum = anIsElemNum; } #ifndef _DEXCEPT_ @@ -270,21 +274,35 @@ DriverMED_R_SMESHDS_Mesh typedef MED::TVector TQuantities; TQuantities aQuantities(aNbFaces); TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem); + //MESSAGE("--- aNbNodes " << aNbNodes); TNodeIds aNodeIds(aNbNodes); for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){ + //MESSAGE("--- iface " << aNbFaces << " " << iFace); MED::TCConnSlice aConnSlice = aConnSliceArr[iFace]; TInt aNbConn = aConnSlice.size(); aQuantities[iFace] = aNbConn; #ifdef _EDF_NODE_IDS_ + //MESSAGE(anIsNodeNum); if(anIsNodeNum) for(TInt iConn = 0; iConn < aNbConn; iConn++) - aNodeIds[iNode++] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1); + { + //MESSAGE("iConn " << iConn << " aConnSlice[iConn] " << aConnSlice[iConn]); + aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1); + //MESSAGE("aNodeIds[" << iNode << "]=" << aNodeIds[iNode]); + iNode++; + } else for(TInt iConn = 0; iConn < aNbConn; iConn++) + { + //MESSAGE("iConn " << iConn); aNodeIds[iNode++] = aConnSlice[iConn]; + } #else for(TInt iConn = 0; iConn < aNbConn; iConn++) + { + //MESSAGE("iConn " << iConn); aNodeIds[iNode++] = aConnSlice[iConn]; + } #endif } @@ -298,12 +316,14 @@ DriverMED_R_SMESHDS_Mesh if(anIsElemNum){ TInt anElemId = aPolyedreInfo->GetElemNum(iElem); anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId); + //MESSAGE("AddPolyhedralVolumeWithID " << anElemId); } if(!anElement){ vector aNodes(aNbNodes); for(TInt iConn = 0; iConn < aNbNodes; iConn++) aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]); anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities); + //MESSAGE("AddPolyhedralVolume " << anElement->GetID()); isRenum = anIsElemNum; } #ifndef _DEXCEPT_ @@ -378,10 +398,10 @@ DriverMED_R_SMESHDS_Mesh anIsValidConnect = true; #ifndef _DEXCEPT_ }catch(const std::exception& exc){ - //INFOS("Follow exception was cought:\n\t"<AddVolumeWithID(aNodeIds[0], aNodeIds[1], aNodeIds[2], aNodeIds[3], @@ -693,13 +713,18 @@ DriverMED_R_SMESHDS_Mesh } break; } - +// if (anIsElemNum) { +// MESSAGE("add element with id " << aCellInfo->GetElemNum(iElem)); +// } +// else { +// MESSAGE("add element "<< anElement->GetID()); +// } #ifndef _DEXCEPT_ }catch(const std::exception& exc){ - //INFOS("Follow exception was cought:\n\t"<compactMesh(); if(MYDEBUG) MESSAGE("Perform - aResult status = "< DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus) } } }catch(const std::exception& exc){ - INFOS("Follow exception was cought:\n\t"<AddNodeWithID(aCoords[0],aCoords[1],aCoords[2],(int)iNode); + if (!aNode) { + EXCEPTION(runtime_error,"buildMeshGrille Error. Node not created! "<<(int)iNode); + } if((aGrilleInfo->myFamNumNode).size() > 0){ TInt aFamNum = aGrilleInfo->GetFamNumNode(iNode); @@ -999,7 +1029,9 @@ bool DriverMED_R_SMESHDS_Mesh::buildMeshGrille(const MED::PWrapper& theWrapper, default: break; } - + if (!anElement) { + EXCEPTION(runtime_error,"buildMeshGrille Error. Element not created! "<myFamNum).size() > 0){ TInt aFamNum = aGrilleInfo->GetFamNum(iCell); if ( checkFamilyID ( aFamily, aFamNum )){ diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index d44e27675..cbd619696 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -622,6 +622,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() nbElemInfo.NbHexas( ORDER_QUADRATIC ), SMDSAbs_Volume)); if ( polyTypesSupported ) { + //MESSAGE("polyTypesSupported"); aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePOLYEDRE, nbElemInfo.NbPolyhedrons(), @@ -738,18 +739,21 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() // ---------------- else if (aElemTypeData->_geomType == ePOLYEDRE ) { + //MESSAGE("_geomType == ePOLYEDRE"); if ( nbPolyhedronNodes == 0 ) { // Count nb of nodes while ( const SMDS_MeshElement* anElem = elemIterator->next() ) { - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - dynamic_cast( anElem ); - if ( aPolyedre ) { + const SMDS_VtkVolume *aPolyedre = dynamic_cast(anElem); + if ( aPolyedre && aPolyedre->IsPoly()) { nbPolyhedronNodes += aPolyedre->NbNodes(); nbPolyhedronFaces += aPolyedre->NbFaces(); if ( ++iElem == aElemTypeData->_nbElems ) break; } } + //MESSAGE("nbPolyhedronNodes=" << nbPolyhedronNodes); + //MESSAGE("nbPolyhedronFaces=" << nbPolyhedronFaces); + //MESSAGE("_nbElems="<< aElemTypeData->_nbElems); } else { // Store in med file @@ -771,19 +775,22 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() TInt iFace = 0, iNode = 0; while ( const SMDS_MeshElement* anElem = elemIterator->next() ) { - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - dynamic_cast( anElem ); + const SMDS_VtkVolume *aPolyedre = dynamic_cast(anElem); if ( !aPolyedre ) continue; - + if ( !aPolyedre->IsPoly() ) + continue; + //MESSAGE("index[" << iElem << "]=" << index[iElem] << " iElem=" << iElem); // index TInt aNbFaces = aPolyedre->NbFaces(); index[ iElem+1 ] = index[ iElem ] + aNbFaces; + //MESSAGE("index[" << iElem+1 << "]=" << index[iElem+1] << " iElem=" << iElem); // face index for (TInt f = 1; f <= aNbFaces; ++f, ++iFace ) { int aNbFaceNodes = aPolyedre->NbFaceNodes( f ); faces[ iFace+1 ] = faces[ iFace ] + aNbFaceNodes; + //MESSAGE("faces[" << iFace+1 << "]=" << faces[iFace+1] << " iFace=" << iFace); } // connectivity SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator(); @@ -791,8 +798,10 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() const SMDS_MeshElement* aNode = nodeIt->next(); #ifdef _EDF_NODE_IDS_ conn[ iNode ] = aNodeIdMap[aNode->GetID()]; + //MESSAGE("conn["<< iNode << "]=" << conn[iNode] << " aNode->GetID()=" << aNode->GetID()); #else conn[ iNode ] = aNode->GetID(); + //MESSAGE("conn["<< iNode << "]=" << conn[iNode]); #endif ++iNode; } @@ -868,11 +877,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() } catch(const std::exception& exc) { - INFOS("Follow exception was cought:\n\t"<first; const TRecord& aRec = anIter->second; + //MESSAGE("AddNodeWithID " << aLabel << " " << aRec.coord[0] << " " << aRec.coord[1] << " " << aRec.coord[2]); myMesh->AddNodeWithID(aRec.coord[0],aRec.coord[1],aRec.coord[2],aLabel); } } @@ -82,11 +83,13 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() if(IsBeam(aRec.fe_descriptor_id)) { switch ( aRec.node_labels.size() ) { case 2: // edge with two nodes + //MESSAGE("add edge " << aLabel << " " << aRec.node_labels[0] << " " << aRec.node_labels[1]); anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], aRec.node_labels[1], aLabel); break; case 3: // quadratic edge (with 3 nodes) + //MESSAGE("add edge " << aLabel << " " << aRec.node_labels[0] << " " << aRec.node_labels[1] << " " << aRec.node_labels[2]); anElement = myMesh->AddEdgeWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[1], @@ -94,6 +97,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() } } else if(IsFace(aRec.fe_descriptor_id)) { + //MESSAGE("add face " << aLabel); switch(aRec.fe_descriptor_id){ case 41: // Plane Stress Linear Triangle case 51: // Plane Strain Linear Triangle @@ -113,6 +117,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() case 72: // Membrane Parabolic Triangle case 82: // Axisymetric Solid Parabolic Triangle case 92: // Thin Shell Parabolic Triangle + //MESSAGE("add face " << aLabel << " " << aRec.node_labels[0] << " " << aRec.node_labels[1] << " " << aRec.node_labels[2] << " " << aRec.node_labels[3] << " " << aRec.node_labels[4] << " " << aRec.node_labels[5]); anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[4], @@ -154,6 +159,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() } } else if(IsVolume(aRec.fe_descriptor_id)){ + //MESSAGE("add volume " << aLabel); switch(aRec.fe_descriptor_id){ case 111: // Solid Linear Tetrahedron - TET4 @@ -377,5 +383,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() catch(...){ INFOS("Unknown exception was cought !!!"); } + if (myMesh) + myMesh->compactMesh(); return aResult; } diff --git a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx index cf7778300..ffa50cbe7 100644 --- a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx +++ b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx @@ -99,12 +99,10 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() TRecord aRec; aRec.node_labels.reserve(aNbNodes); SMDS_ElemIteratorPtr aNodesIter; + aNodesIter = anElem->nodesIteratorToUNV(); if( anElem->IsQuadratic() ) { - aNodesIter = static_cast - ( anElem )->interlacedNodesElemIterator(); aRec.fe_descriptor_id = 22; } else { - aNodesIter = anElem->nodesIterator(); aRec.fe_descriptor_id = 11; } for(; aNodesIter->more();){ @@ -126,11 +124,7 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() TRecord aRec; aRec.node_labels.reserve(aNbNodes); SMDS_ElemIteratorPtr aNodesIter; - if( anElem->IsQuadratic() ) - aNodesIter = static_cast - ( anElem )->interlacedNodesElemIterator(); - else - aNodesIter = anElem->nodesIterator(); + aNodesIter = anElem->nodesIteratorToUNV(); for(; aNodesIter->more();){ const SMDS_MeshElement* aNode = aNodesIter->next(); aRec.node_labels.push_back(aNode->GetID()); @@ -164,72 +158,59 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform() TElementLab aLabel = anElem->GetID(); int aNbNodes = anElem->NbNodes(); - SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); + //MESSAGE("aNbNodes="<nodesIteratorToUNV(); if ( anElem->IsPoly() ) { - if ( const SMDS_PolyhedralVolumeOfNodes* ph = - dynamic_cast (anElem)) + MESSAGE("anElem->IsPoly"); + if ( const SMDS_VtkVolume* ph = + dynamic_cast (anElem)) { aNbNodes = ph->NbUniqueNodes(); aNodesIter = ph->uniqueNodesIterator(); } } - aConnect.resize(aNbNodes); - GetConnect(aNodesIter,aConnect); int anId = -1; - int* aConn = NULL; switch(aNbNodes){ case 4: { - static int anIds[] = {0,2,1,3}; - aConn = anIds; anId = 111; break; } case 6: { - static int anIds[] = {0,2,1,3,5,4}; - aConn = anIds; anId = 112; break; } case 8: { - static int anIds[] = {0,3,2,1,4,7,6,5}; - aConn = anIds; anId = 115; break; } case 10: { - static int anIds[] = {0,4,2,9,5,3, 1,6,8, 7}; - aConn = anIds; anId = 118; break; } case 13: { - static int anIds[] = {0,6,4,2,7,5,3,1,8,11,10,9,12}; - aConn = anIds; anId = 114; break; } case 15: { - static int anIds[] = {0,4,2,9,13,11,5,3,1,14,12,10,6,8,7}; - aConn = anIds; anId = 113; break; } case 20: { - static int anIds[] = {0,6, 4,2, 12,18,16,14,7, 5, 3, 1, 19,17,15,13,8, 11,10,9}; - aConn = anIds; anId = 116; break; } default: continue; } - if(aConn){ + if(anId>0){ TRecord aRec; aRec.fe_descriptor_id = anId; - aRec.node_labels.resize(aNbNodes); - for(int aNodeId = 0; aNodeId < aNbNodes; aNodeId++){ - aRec.node_labels[aConn[aNodeId]] = aConnect[aNodeId]; + aRec.node_labels.reserve(aNbNodes); + for(; aNodesIter->more();){ + const SMDS_MeshElement* aNode = aNodesIter->next(); + aRec.node_labels.push_back(aNode->GetID()); } aDataSet2412.insert(TDataSet::value_type(aLabel,aRec)); } diff --git a/src/DriverUNV/Makefile.am b/src/DriverUNV/Makefile.am index 982afe8cf..4fa349f3f 100644 --- a/src/DriverUNV/Makefile.am +++ b/src/DriverUNV/Makefile.am @@ -69,6 +69,7 @@ libMeshDriverUNV_la_CPPFLAGS = \ $(CAS_CPPFLAGS) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ -I$(srcdir)/../Driver \ -I$(srcdir)/../SMDS \ diff --git a/src/OBJECT/Makefile.am b/src/OBJECT/Makefile.am index 219350562..88dd738fd 100644 --- a/src/OBJECT/Makefile.am +++ b/src/OBJECT/Makefile.am @@ -37,7 +37,6 @@ salomeinclude_HEADERS = \ SMESH_FaceOrientationFilter.h \ SMESH_ScalarBarActor.h - # Libraries targets lib_LTLIBRARIES = libSMESHObject.la diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx index 4afc7f4ca..4b4f432ff 100644 --- a/src/OBJECT/SMESH_Actor.cxx +++ b/src/OBJECT/SMESH_Actor.cxx @@ -30,6 +30,7 @@ #include "SMESH_DeviceActor.h" #include "SMESH_ObjectDef.h" #include "SMESH_ControlsDef.hxx" +#include "SMDS_UnstructuredGrid.hxx" #include "SMESH_ScalarBarActor.h" #include "VTKViewer_CellCenters.h" #include "VTKViewer_ExtractUnstructuredGrid.h" @@ -82,7 +83,7 @@ #ifdef _DEBUG_ static int MYDEBUG = 1; #else -static int MYDEBUG = 0; +static int MYDEBUG = 1; #endif static int aLineWidthInc = 2; @@ -198,6 +199,10 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); +//#ifdef VTK_HAVE_POLYHEDRON + MESSAGE("RegisterCellsWithType(VTK_POLYHEDRON)"); + aFilter->RegisterCellsWithType(VTK_POLYHEDRON); +//#endif //Definition 1D device of the actor //--------------------------------- @@ -1359,6 +1364,9 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode) aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); +//#ifdef VTK_HAVE_POLYHEDRON + aFilter->RegisterCellsWithType(VTK_POLYHEDRON); +//#endif aHightFilter->RegisterCellsWithType(VTK_TETRA); aHightFilter->RegisterCellsWithType(VTK_VOXEL); @@ -1370,6 +1378,9 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode) aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); +//#ifdef VTK_HAVE_POLYHEDRON + aHightFilter->RegisterCellsWithType(VTK_POLYHEDRON); +//#endif } aFilter->Update(); if (MYDEBUG) MESSAGE(aFilter->GetOutput()->GetNumberOfCells()); diff --git a/src/OBJECT/SMESH_ActorUtils.cxx b/src/OBJECT/SMESH_ActorUtils.cxx index 6808e145e..899e413ec 100644 --- a/src/OBJECT/SMESH_ActorUtils.cxx +++ b/src/OBJECT/SMESH_ActorUtils.cxx @@ -29,6 +29,7 @@ #include "utilities.h" #include +#include #include #ifdef _DEBUG_ @@ -73,9 +74,10 @@ namespace SMESH WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, const char* theFileName) { - vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); + vtkXMLUnstructuredGridWriter* aWriter = vtkXMLUnstructuredGridWriter::New(); aWriter->SetFileName(theFileName); aWriter->SetInput(theGrid); + aWriter->SetDataModeToAscii(); if(theGrid->GetNumberOfCells()){ aWriter->Write(); } diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index 480a0fe3f..709847e9c 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -64,8 +64,8 @@ using namespace std; #endif #ifdef _DEBUG_ -static int MYDEBUG = 0; -static int MYDEBUGWITHFILES = 0; +static int MYDEBUG = 1; +static int MYDEBUGWITHFILES = 1; #else static int MYDEBUG = 0; static int MYDEBUGWITHFILES = 0; @@ -133,11 +133,14 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType, //================================================================================= SMESH_VisualObjDef::SMESH_VisualObjDef() { + MESSAGE("---------------------------------------------SMESH_VisualObjDef::SMESH_VisualObjDef"); myGrid = vtkUnstructuredGrid::New(); + myLocalGrid = false; } SMESH_VisualObjDef::~SMESH_VisualObjDef() { - if ( MYDEBUG ) + MESSAGE("---------------------------------------------SMESH_VisualObjDef::~SMESH_VisualObjDef"); + //if ( MYDEBUG ) MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() ); myGrid->Delete(); } @@ -148,32 +151,53 @@ SMESH_VisualObjDef::~SMESH_VisualObjDef() //================================================================================= vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID ) { - TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID); - return i == myVTK2SMDSNodes.end() ? -1 : i->second; + if (myLocalGrid) + { + TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID); + return i == myVTK2SMDSNodes.end() ? -1 : i->second; + } + return this->GetMesh()->FindNodeVtk(theVTKID)->GetID(); } vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID ) { - TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID); - return i == mySMDS2VTKNodes.end() ? -1 : i->second; + if (myLocalGrid) + { + TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID); + return i == mySMDS2VTKNodes.end() ? -1 : i->second; + } + return this->GetMesh()->FindNode(theObjID)->getVtkId(); } vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID ) { - TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID); - return i == myVTK2SMDSElems.end() ? -1 : i->second; + if (myLocalGrid) + { + TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID); + return i == myVTK2SMDSElems.end() ? -1 : i->second; + } + return this->GetMesh()->fromVtkToSmds(theVTKID); } vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID ) { - TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID); - return i == mySMDS2VTKElems.end() ? -1 : i->second; + if (myLocalGrid) + { + TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID); + return i == mySMDS2VTKElems.end() ? -1 : i->second; + } + return this->GetMesh()->FindElement(theObjID)->getVtkId(); + //return this->GetMesh()->fromSmdsToVtk(theObjID); } //================================================================================= // function : SMESH_VisualObjDef::createPoints // purpose : Create points from nodes //================================================================================= +/*! fills a vtkPoints structure for a submesh. + * fills a std::list of SMDS_MeshElements*, then extract the points. + * fills also conversion id maps between SMDS and VTK. + */ void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints ) { if ( thePoints == 0 ) @@ -182,7 +206,7 @@ void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints ) TEntityList aNodes; vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes ); thePoints->SetNumberOfPoints( nbNodes ); - + int nbPoints = 0; TEntityList::const_iterator anIter; @@ -207,52 +231,70 @@ void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints ) // function : buildPrs // purpose : create VTK cells( fill unstructured grid ) //================================================================================= -void SMESH_VisualObjDef::buildPrs() +void SMESH_VisualObjDef::buildPrs(bool buildGrid) { - try + MESSAGE("----------------------------------------------------------SMESH_VisualObjDef::buildPrs " << buildGrid); + if (buildGrid) { - mySMDS2VTKNodes.clear(); - myVTK2SMDSNodes.clear(); - mySMDS2VTKElems.clear(); - myVTK2SMDSElems.clear(); - - if ( IsNodePrs() ) - buildNodePrs(); - else - buildElemPrs(); + myLocalGrid = true; + try + { + mySMDS2VTKNodes.clear(); + myVTK2SMDSNodes.clear(); + mySMDS2VTKElems.clear(); + myVTK2SMDSElems.clear(); + + if ( IsNodePrs() ) + buildNodePrs(); + else + buildElemPrs(); + } + catch(...) + { + mySMDS2VTKNodes.clear(); + myVTK2SMDSNodes.clear(); + mySMDS2VTKElems.clear(); + myVTK2SMDSElems.clear(); + + myGrid->SetPoints( 0 ); + myGrid->SetCells( 0, 0, 0, 0, 0 ); + throw; + } } - catch(...) + else { - mySMDS2VTKNodes.clear(); - myVTK2SMDSNodes.clear(); - mySMDS2VTKElems.clear(); - myVTK2SMDSElems.clear(); - - myGrid->SetPoints( 0 ); - myGrid->SetCells( 0, 0, 0 ); - throw; + myLocalGrid = false; + if (!GetMesh()->isCompacted()) + { + MESSAGE("*** buildPrs ==> compactMesh!"); + GetMesh()->compactMesh(); + } + vtkUnstructuredGrid *theGrid = GetMesh()->getGrid(); + myGrid->ShallowCopy(theGrid); + //MESSAGE(myGrid->GetReferenceCount()); + //MESSAGE( "Update - myGrid->GetNumberOfCells() = "<GetNumberOfCells() ); + //MESSAGE( "Update - myGrid->GetNumberOfPoints() = "<GetNumberOfPoints() ); + if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"buildPrs.vtu" ); } - - if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<GetNumberOfCells() ); - if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" ); } //================================================================================= // function : buildNodePrs // purpose : create VTK cells for nodes //================================================================================= + void SMESH_VisualObjDef::buildNodePrs() { // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead, // so check remaining memory size for safety - SMDS_Mesh::CheckMemory(); // PAL16631 + // SMDS_Mesh::CheckMemory(); // PAL16631 vtkPoints* aPoints = vtkPoints::New(); createPoints( aPoints ); - SMDS_Mesh::CheckMemory(); + // SMDS_Mesh::CheckMemory(); myGrid->SetPoints( aPoints ); aPoints->Delete(); - myGrid->SetCells( 0, 0, 0 ); + myGrid->SetCells( 0, 0, 0, 0, 0 ); } //================================================================================= @@ -288,12 +330,12 @@ namespace{ void SMESH_VisualObjDef::buildElemPrs() { // Create points - + vtkPoints* aPoints = vtkPoints::New(); createPoints( aPoints ); myGrid->SetPoints( aPoints ); aPoints->Delete(); - + if ( MYDEBUG ) MESSAGE("Update - myGrid->GetNumberOfPoints() = "<GetNumberOfPoints()); @@ -311,7 +353,7 @@ void SMESH_VisualObjDef::buildElemPrs() // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead, // so check remaining memory size for safety - SMDS_Mesh::CheckMemory(); // PAL16631 + // SMDS_Mesh::CheckMemory(); // PAL16631 vtkIdType aCellsSize = 2 * nbEnts[ SMDSAbs_0DElement ] + 3 * nbEnts[ SMDSAbs_Edge ]; @@ -328,7 +370,7 @@ void SMESH_VisualObjDef::buildElemPrs() vtkIdType aNbCells = nbEnts[ SMDSAbs_0DElement ] + nbEnts[ SMDSAbs_Edge ] + nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ]; - + if ( MYDEBUG ) MESSAGE( "Update - aNbCells = "< 0 || GetNbEntities(SMDSAbs_0DElement) > 0 || GetNbEntities(SMDSAbs_Edge) > 0 || @@ -546,6 +596,7 @@ bool SMESH_VisualObjDef::IsValid() const SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh): myClient(SalomeApp_Application::orb(),theMesh) { + myEmptyGrid = 0; if ( MYDEBUG ) MESSAGE("SMESH_MeshObj - this = "<_is_nil() = "<_is_nil()); } @@ -567,13 +618,31 @@ SMESH_MeshObj::~SMESH_MeshObj() bool SMESH_MeshObj::Update( int theIsClear ) { // Update SMDS_Mesh on client part + MESSAGE("SMESH_MeshObj::Update " << this); if ( myClient.Update(theIsClear) || GetUnstructuredGrid()->GetNumberOfPoints()==0) { + MESSAGE("buildPrs"); buildPrs(); // Fill unstructured grid return true; } return false; } +bool SMESH_MeshObj::NulData() +{ + MESSAGE ("SMESH_MeshObj::NulData() =================================================================================="); + if (!myEmptyGrid) + { + myEmptyGrid = SMDS_UnstructuredGrid::New(); + myEmptyGrid->Initialize(); + myEmptyGrid->Allocate(); + vtkPoints* points = vtkPoints::New(); + points->SetNumberOfPoints(0); + myEmptyGrid->SetPoints( points ); + points->Delete(); + myEmptyGrid->BuildLinks(); + } + myGrid->ShallowCopy(myEmptyGrid); +} //================================================================================= // function : GetElemDimension // purpose : Get dimension of element @@ -740,8 +809,9 @@ void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunc //================================================================================= bool SMESH_SubMeshObj::Update( int theIsClear ) { + MESSAGE("SMESH_SubMeshObj::Update " << this) bool changed = myMeshObj->Update( theIsClear ); - buildPrs(); + buildPrs(true); return changed; } diff --git a/src/OBJECT/SMESH_Object.h b/src/OBJECT/SMESH_Object.h index 37a7ff63b..160901d83 100644 --- a/src/OBJECT/SMESH_Object.h +++ b/src/OBJECT/SMESH_Object.h @@ -56,6 +56,7 @@ class SMESHOBJECT_EXPORT SMESH_VisualObj { public: virtual bool Update( int theIsClear = true ) = 0; + virtual bool NulData() = 0; virtual void UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor ) = 0; virtual int GetElemDimension( const int theObjId ) = 0; diff --git a/src/OBJECT/SMESH_ObjectDef.h b/src/OBJECT/SMESH_ObjectDef.h index de41e1628..f8aec86be 100644 --- a/src/OBJECT/SMESH_ObjectDef.h +++ b/src/OBJECT/SMESH_ObjectDef.h @@ -62,6 +62,7 @@ public: virtual ~SMESH_VisualObjDef(); virtual bool Update( int theIsClear = true ) = 0; + virtual bool NulData() {return 0; }; virtual void UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor ) = 0; virtual int GetElemDimension( const int theObjId ) = 0; @@ -77,7 +78,7 @@ public: int& theNodeId1, int& theNodeId2 ) const; - virtual vtkUnstructuredGrid* GetUnstructuredGrid() { return myGrid; } + virtual vtkUnstructuredGrid* GetUnstructuredGrid(); virtual vtkIdType GetNodeObjId( int theVTKID ); virtual vtkIdType GetNodeVTKId( int theObjID ); @@ -87,16 +88,17 @@ public: protected: void createPoints( vtkPoints* ); - void buildPrs(); + void buildPrs(bool buildGrid = false); void buildNodePrs(); void buildElemPrs(); -private: +//private: TMapOfIds mySMDS2VTKNodes; TMapOfIds myVTK2SMDSNodes; TMapOfIds mySMDS2VTKElems; TMapOfIds myVTK2SMDSElems; + bool myLocalGrid; vtkUnstructuredGrid* myGrid; }; @@ -115,6 +117,7 @@ public: virtual ~SMESH_MeshObj(); virtual bool Update( int theIsClear = true ); + virtual bool NulData(); virtual int GetNbEntities( const SMDSAbs_ElementType) const; virtual int GetEntities( const SMDSAbs_ElementType, TEntityList& ) const; @@ -129,6 +132,7 @@ public: protected: SMESH_Client myClient; + vtkUnstructuredGrid* myEmptyGrid; }; diff --git a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx new file mode 100644 index 000000000..bbab763f9 --- /dev/null +++ b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx @@ -0,0 +1,230 @@ +/*========================================================================= + + Program: ParaView + Module: $RCSfile$ + + Copyright (c) Kitware, Inc. + All rights reserved. + See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + + =========================================================================*/ +#include "SMESH_vtkPVUpdateSuppressor.h" + +#include "vtkAlgorithmOutput.h" +#include "vtkCollection.h" +#include "vtkCommand.h" +#include "vtkCompositeDataPipeline.h" +#include "vtkDataObject.h" +#include "vtkDemandDrivenPipeline.h" +#include "vtkInformation.h" +#include "vtkInformationDoubleVectorKey.h" +#include "vtkInformationExecutivePortKey.h" +#include "vtkInformationVector.h" +#include "vtkObjectFactory.h" +#include "vtkPolyData.h" +//#include "vtkProcessModule.h" +#include "vtkSmartPointer.h" +#include "vtkUnstructuredGrid.h" +//#include "vtkUpdateSuppressorPipeline.h" + +#include + +#ifdef MYDEBUG +# define vtkMyDebug(x)\ + cout << x; +#else +# define vtkMyDebug(x) +#endif + +vtkCxxRevisionMacro(vtkPVUpdateSuppressor, "$Revision$") +; +vtkStandardNewMacro(vtkPVUpdateSuppressor) +; +//---------------------------------------------------------------------------- +vtkPVUpdateSuppressor::vtkPVUpdateSuppressor() +{ + this->UpdatePiece = 0; + this->UpdateNumberOfPieces = 1; + + this->UpdateTime = 0.0; + this->UpdateTimeInitialized = false; + + this->Enabled = 1; + + // vtkProcessModule* pm = vtkProcessModule::GetProcessModule(); + // + // if (pm) + // { + // this->UpdateNumberOfPieces = pm->GetNumberOfLocalPartitions(); + // this->UpdatePiece = pm->GetPartitionId(); + // } +} + +//---------------------------------------------------------------------------- +vtkPVUpdateSuppressor::~vtkPVUpdateSuppressor() +{ +} + +//---------------------------------------------------------------------------- +void vtkPVUpdateSuppressor::SetUpdateTime(double utime) +{ + this->UpdateTimeInitialized = true; + if (this->UpdateTime != utime) + { + this->Modified(); + this->UpdateTime = utime; + } +} + +//---------------------------------------------------------------------------- +void vtkPVUpdateSuppressor::SetEnabled(int enable) +{ + if (this->Enabled == enable) + { + return; + } + this->Enabled = enable; + this->Modified(); + // vtkUpdateSuppressorPipeline* executive = + // vtkUpdateSuppressorPipeline::SafeDownCast(this->GetExecutive()); + // if (executive) + // { + // executive->SetEnabled(enable); + // } +} + +//---------------------------------------------------------------------------- +void vtkPVUpdateSuppressor::ForceUpdate() +{ + // Make sure that output type matches input type + this->UpdateInformation(); + + vtkDataObject *input = this->GetInput(); + if (input == 0) + { + vtkErrorMacro("No valid input."); + return; + } + vtkDataObject *output = this->GetOutput(); + + // int fixme; // I do not like this hack. How can we get rid of it? + // Assume the input is the collection filter. + // Client needs to modify the collection filter because it is not + // connected to a pipeline. + vtkAlgorithm *source = input->GetProducerPort()->GetProducer(); + if (source && (source->IsA("vtkMPIMoveData") + || source->IsA("vtkCollectPolyData") || source->IsA("vtkM2NDuplicate") + || source->IsA("vtkM2NCollect") + || source->IsA("vtkOrderedCompositeDistributor") + || source->IsA("vtkClientServerMoveData"))) + { + source->Modified(); + } + + vtkInformation* info = input->GetPipelineInformation(); + vtkStreamingDemandDrivenPipeline + * sddp = + vtkStreamingDemandDrivenPipeline::SafeDownCast( + vtkExecutive::PRODUCER()->GetExecutive( + info)); + if (sddp) + { + sddp->SetUpdateExtent(info, this->UpdatePiece, + this->UpdateNumberOfPieces, 0); + } + else + { + input->SetUpdatePiece(this->UpdatePiece); + input->SetUpdateNumberOfPieces(this->UpdateNumberOfPieces); + input->SetUpdateGhostLevel(0); + } vtkMyDebug("ForceUpdate "); + if (this->UpdateTimeInitialized) + { + info->Set(vtkCompositeDataPipeline::UPDATE_TIME_STEPS(), + &this->UpdateTime, 1); + vtkMyDebug(this->UpdateTime); + } vtkMyDebug(endl); + + input->Update(); + // Input may have changed, we obtain the pointer again. + input = this->GetInput(); + + output->ShallowCopy(input); + this->PipelineUpdateTime.Modified(); +} + +//---------------------------------------------------------------------------- +vtkExecutive* vtkPVUpdateSuppressor::CreateDefaultExecutive() +{ + vtkUpdateSuppressorPipeline* executive = vtkUpdateSuppressorPipeline::New(); + executive->SetEnabled(this->Enabled); + return executive; +} + +//---------------------------------------------------------------------------- +int vtkPVUpdateSuppressor::RequestDataObject( + vtkInformation* vtkNotUsed(reqInfo), + vtkInformationVector** inputVector, + vtkInformationVector* outputVector) +{ + vtkInformation* inInfo = inputVector[0]->GetInformationObject(0); + if (!inInfo) + { + return 0; + } + + vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT()); + if (input) + { + // for each output + for (int i = 0; i < this->GetNumberOfOutputPorts(); ++i) + { + vtkInformation* outInfo = outputVector->GetInformationObject(i); + vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT()); + + if (!output || !output->IsA(input->GetClassName())) + { + vtkDataObject* newOutput = input->NewInstance(); + newOutput->SetPipelineInformation(outInfo); + newOutput->Delete(); + this->GetOutputPortInformation(i)->Set( + vtkDataObject::DATA_EXTENT_TYPE(), + newOutput->GetExtentType()); + } + } + return 1; + } + return 0; + +} + +//---------------------------------------------------------------------------- +int vtkPVUpdateSuppressor::RequestData(vtkInformation* vtkNotUsed(reqInfo), + vtkInformationVector** inputVector, + vtkInformationVector* outputVector) +{ + // RequestData is only called by its executive when + // (Enabled==off) and thus acting as a passthrough filter + vtkInformation *outInfo = outputVector->GetInformationObject(0); + vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); + vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT()); + vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT()); + + output->ShallowCopy(input); + return 1; +} + +//---------------------------------------------------------------------------- +void vtkPVUpdateSuppressor::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os, indent); + os << indent << "UpdatePiece: " << this->UpdatePiece << endl; + os << indent << "UpdateNumberOfPieces: " << this->UpdateNumberOfPieces + << endl; + os << indent << "Enabled: " << this->Enabled << endl; + os << indent << "UpdateTime: " << this->UpdateTime << endl; +} diff --git a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h new file mode 100644 index 000000000..4cd0624e7 --- /dev/null +++ b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h @@ -0,0 +1,98 @@ +/*========================================================================= + + Program: ParaView + Module: $RCSfile$ + + Copyright (c) Kitware, Inc. + All rights reserved. + See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + + =========================================================================*/ +// .NAME vtkPVUpdateSuppressor - prevents propagation of update +// .SECTION Description +// vtkPVUpdateSuppressor now uses the vtkProcessModule singleton to set up the +// default values for UpdateNumberOfPieces and UpdatePiece, so we no longer have +// to set the default values (in most cases). +// .SECTION See Also +// vtkPVCacheKeeper vtkUpdateSuppressorPipeline + +#ifndef __vtkPVUpdateSuppressor_h +#define __vtkPVUpdateSuppressor_h + +#include "vtkDataObjectAlgorithm.h" + +class VTK_EXPORT vtkPVUpdateSuppressor: public vtkDataObjectAlgorithm +{ +public: +vtkTypeRevisionMacro(vtkPVUpdateSuppressor,vtkDataObjectAlgorithm) + ; + void PrintSelf(ostream& os, vtkIndent indent); + + // Description: + // Construct with user-specified implicit function. + static vtkPVUpdateSuppressor *New(); + + // Description: + // Force update on the input. + virtual void ForceUpdate(); + + // Description: + // Set number of pieces and piece on the data. + // This causes the filter to ingore the request from the output. + // It is here because the user may not have celled update on the output + // before calling force update (it is an easy fix). + vtkSetMacro(UpdatePiece, int) + ; + vtkGetMacro(UpdatePiece, int) + ; + vtkSetMacro(UpdateNumberOfPieces, int) + ; + vtkGetMacro(UpdateNumberOfPieces, int) + ; + + // Description: + // Get/Set if the update suppressor is enabled. If the update suppressor + // is not enabled, it won't supress any updates. Enabled by default. + void SetEnabled(int); + vtkGetMacro(Enabled, int) + ; + + // Description: + // Get/Set the update time that is sent up the pipeline. + void SetUpdateTime(double utime); + vtkGetMacro(UpdateTime, double) + ; + +protected: + vtkPVUpdateSuppressor(); + ~vtkPVUpdateSuppressor(); + + int RequestDataObject(vtkInformation* request, + vtkInformationVector **inputVector, + vtkInformationVector *outputVector); + int RequestData(vtkInformation* request, vtkInformationVector **inputVector, + vtkInformationVector *outputVector); + + int UpdatePiece; + int UpdateNumberOfPieces; + double UpdateTime; + + bool UpdateTimeInitialized; + + int Enabled; + + vtkTimeStamp PipelineUpdateTime; + + // Create a default executive. + virtual vtkExecutive* CreateDefaultExecutive(); + +private: + vtkPVUpdateSuppressor(const vtkPVUpdateSuppressor&); // Not implemented. + void operator=(const vtkPVUpdateSuppressor&); // Not implemented. +}; + +#endif diff --git a/src/SMDS/Makefile.am b/src/SMDS/Makefile.am index 869c6677c..c4dd2bf11 100644 --- a/src/SMDS/Makefile.am +++ b/src/SMDS/Makefile.am @@ -27,6 +27,8 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files salomeinclude_HEADERS = \ + chrono.hxx \ + ObjectPool.hxx \ SMDS_TypeOfPosition.hxx \ SMDSAbs_ElementType.hxx \ SMDS_EdgePosition.hxx \ @@ -34,13 +36,17 @@ salomeinclude_HEADERS = \ SMDS_FacePosition.hxx \ SMDS_Mesh.hxx \ SMDS_Mesh0DElement.hxx \ + SMDS_LinearEdge.hxx \ SMDS_MeshEdge.hxx \ SMDS_MeshElement.hxx \ + SMDS_MeshElement.cxx \ SMDS_MeshElementIDFactory.hxx \ + SMDS_MeshCell.hxx \ SMDS_MeshFace.hxx \ SMDS_MeshGroup.hxx \ SMDS_MeshIDFactory.hxx \ SMDS_MeshNode.hxx \ + SMDS_MeshNodeIDFactory.hxx \ SMDS_MeshObject.hxx \ SMDS_MeshVolume.hxx \ SMDS_Position.hxx \ @@ -50,6 +56,10 @@ salomeinclude_HEADERS = \ SMDS_IteratorOfElements.hxx \ SMDS_VolumeOfFaces.hxx \ SMDS_VolumeOfNodes.hxx \ + SMDS_VtkEdge.hxx \ + SMDS_VtkFace.hxx \ + SMDS_VtkVolume.hxx \ + SMDS_VtkCellIterator.hxx \ SMDS_PolyhedralVolumeOfNodes.hxx \ SMDS_FaceOfEdges.hxx \ SMDS_FaceOfNodes.hxx \ @@ -61,6 +71,8 @@ salomeinclude_HEADERS = \ SMDS_SetIterator.hxx \ SMESH_SMDS.hxx \ SMDS_MeshInfo.hxx \ + SMDS_UnstructuredGrid.hxx \ + SMDS_Downward.hxx \ SMDS_StdIterator.hxx @@ -68,8 +80,10 @@ salomeinclude_HEADERS = \ lib_LTLIBRARIES = libSMDS.la dist_libSMDS_la_SOURCES = \ + chrono.cxx \ SMDS_MeshObject.cxx \ SMDS_MeshElement.cxx \ + SMDS_MeshCell.cxx \ SMDS_Position.cxx \ SMDS_EdgePosition.cxx \ SMDS_FacePosition.cxx \ @@ -77,9 +91,11 @@ dist_libSMDS_la_SOURCES = \ SMDS_VertexPosition.cxx \ SMDS_MeshNode.cxx \ SMDS_Mesh0DElement.cxx \ + SMDS_LinearEdge.cxx \ SMDS_MeshEdge.cxx \ SMDS_MeshFace.cxx \ SMDS_MeshVolume.cxx \ + SMDS_MeshNodeIDFactory.cxx \ SMDS_MeshElementIDFactory.cxx \ SMDS_MeshGroup.cxx \ SMDS_MeshIDFactory.cxx \ @@ -87,6 +103,10 @@ dist_libSMDS_la_SOURCES = \ SMDS_IteratorOfElements.cxx \ SMDS_VolumeOfFaces.cxx \ SMDS_VolumeOfNodes.cxx \ + SMDS_VtkEdge.cxx \ + SMDS_VtkFace.cxx \ + SMDS_VtkVolume.cxx \ + SMDS_VtkCellIterator.cxx \ SMDS_PolyhedralVolumeOfNodes.cxx \ SMDS_FaceOfEdges.cxx \ SMDS_FaceOfNodes.cxx \ @@ -94,15 +114,19 @@ dist_libSMDS_la_SOURCES = \ SMDS_VolumeTool.cxx \ SMDS_QuadraticEdge.cxx \ SMDS_QuadraticFaceOfNodes.cxx \ - SMDS_QuadraticVolumeOfNodes.cxx + SMDS_QuadraticVolumeOfNodes.cxx \ + SMDS_UnstructuredGrid.cxx \ + SMDS_Downward.cxx # additionnal information to compil and link file libSMDS_la_CPPFLAGS = \ $(KERNEL_CXXFLAGS) \ $(CAS_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) libSMDS_la_LDFLAGS = \ + $(VTK_LIBS) \ $(KERNEL_LDFLAGS) -lSALOMELocalTrace \ $(CAS_KERNEL) diff --git a/src/SMDS/Notes b/src/SMDS/Notes new file mode 100644 index 000000000..830ffb5ae --- /dev/null +++ b/src/SMDS/Notes @@ -0,0 +1,235 @@ +--> Branche V6_main + +Problemes en cours +================== +- a faire ++ en cours, OK mais perfectible +* OK + ++ visualisation de groupe (type d'element): on voit tout le maillage, mais le groupe est OK + creation d'une structure vtkUnstructuredGrid locale : iteration un peu lourde, et pas de partage avec la structure du maillage (pas evident) +- inversion d'un volume (tetra): exception +- script de creation de noeuds et d'elements: OK, mais pas compatible avec version precedente (numerotation noeuds differente) ++ affichage numeros noeuds: numeros en trop sur (O,0,0) pas systematique, trouver la condition (enlever dans vtkUnstructuredGrid ?) + ==> purge systematique noeuds et cellules en trop dans compactage grid. ++ gestion du mode embedded mal faite lors d'un script python : journal commandes intempestif +- affichage des noeuds apres changement lineaire <--> quadratique à l'IHM : pas pris en compte, alors que maillage OK, + mais script OK + ==> cassé apres mode embedded ou elimination noeuds en trop ? +- extrusion elements 2D along a path : affichage apres calcul pas toujours OK (filaire) +- branche git a ouvrir pour merge avec V5_1_4_BR tag V5_1_4rc1 + +A tester, non pris en compte +============================ +- engine standalone +- polyedres (attendre vtk) + + +=============================== Hypothese de refonte de l'API de SMDS + +n'utiliser que vtkUnstructuredGrid, ne pas avor d'objets SMDS_MeshElement mais seulement des index de vtkUnstructuredGrid. +2987 usages de SMDS_MeshNodes +810 SMDS_MeshElement +... +==> en dernier ressort, lourd +================================================================================ + +Essai a API SMDS a peu pres constante +===================================== + +SMDS_Mesh + static vector _meshList; --> retrouver un SMDS_Mesh + vtkUnstructuredGrid* myGrid; + + vector myNodes; --> meme index que dans le pointSet de myGrid + vector myCells; --> index = ID client, pas le meme index que dans le cellTypes de myGrid (ID vtk) + + + +SMDS_MeshElement + int myID; --> index dans la structure geree par SMDS_Mesh + int myMeshId; --> pour retrouver SMDS_Mesh* dans _meshList + int myShapeId; --> pour retrouver la subShape + + +SMDS_MeshNode: SMDS_MeshElement + SMDS_PositionPtr myPosition; --> A REVOIR : objet position dans la shape geom + ##vector myInverseElements; --> SUPPRIME : pour retrouver les elements, vtkCellLinks + + +SMDS_MeshCell: SMDS_MeshElement --> generique pour tous les elements (cells) + int myVtkID --> A SUPPRIMER + +SMDS_MeshVolume: SMDS_MeshCell + +SMDS_VolumeOfNodes: SMDS_MeshVolume --> Garder temporairement, utilisation dans StdMesher et SMDS_VolumeTool + const SMDS_MeshNode **myNodes; --> Couteux + int myNbNodes; --> "" + +SMDS_VolumeVtkNodes: SMDS_MeshVolume --> Utiliser systematiquement dans SMDS, + --> IMPLEMENTER. + + +SMDS_MeshElementIDFactory: SMDS_MeshNodeIDFactory + vector myIDElements; // index = ID client, value = ID vtk --> A SUPPRIMER, ne sert que dans SMDS_MeshElementIDFactory + vector myVtkIndex; // index = ID vtk, value = ID client --> A REPORTER dans SMDS_Mesh + + + + +========= TODO ============ + +enlever vtkId de SMDS_MeshCell, utiliser SMDS_MeshElementIDFactory. + +ajouter ID dans SMDS_Mesh::createTriangle +verifier ID dans SMDS_Mesh::Find*OrCreate + +=================================================== +occupation memoire cube 100*100*100 sans affichage +NOTES: +- sur Debian Sarge 64 bits, les mesures malloc_stat() semblent coherentes + avec une mesure externe globale(recherche du passage en swap du process). +- sur Ubuntu 9.10 64 bits, les mesures malloc_stat() donnent des resultats bizarres (surestimation ?), + mais la mesure avec l'outil KDE de surveillance systeme est OK avec la recherche du swap. + + +Reference : V513 Debian Sarge 64 bits: --> 463 - 33 = 430 Mo +------------------------------------- +Total (incl. mmap): +system bytes = 43757568 +in use bytes = 32909584 = 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 464670720 +in use bytes = 463105120 = 463M +max mmap regions = 47 +max mmap bytes = 28188672 + +Debian Sarge 64 bits, vtkUnstructuredGrid nodes et hexa, 4 janvier 2010 --> 512 - 41 = 471M +----------------------------------- + +Total (incl. mmap): +system bytes = 52133888 +in use bytes = 41340320 : 41M +max mmap regions = 72 +max mmap bytes = 24625152 +---- +Total (incl. mmap): +system bytes = 520560640 +in use bytes = 518735584 : 512M +max mmap regions = 88 +max mmap bytes = 198385664 + +idem avec pool SMDS_MeshNodes --> 483 -33 = 450M +----------------------------- +Total (incl. mmap): +system bytes = 43696128 +in use bytes = 32915184 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 484806656 +in use bytes = 482980992 : 483M +max mmap regions = 58 +max mmap bytes = 184557568 + +idem ci-dessus + pool SMDS_VolumeVtkNodes --> 475 -33 = 442M (git: add ObjectPool.hxx) +----------------------------------------- + +Total (incl. mmap): +system bytes = 43200512 +in use bytes = 32908576 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 478068736 +in use bytes = 475144400 : 475M +max mmap regions = 59 +max mmap bytes = 184692736 + +remplacement SMDS_PositionPtr: (boost::shared_ptr --> SMDS_Position*) --> 436 - 35 = 401M (git SMDS_Position) +------------------------------------------------------------------------------------ +Total (incl. mmap): +system bytes = 45408256 +in use bytes = 35097680 : 35M +max mmap regions = 47 +max mmap bytes = 18116608 +---- +Total (incl. mmap): +system bytes = 438935552 +in use bytes = 436116560 : 436M +max mmap regions = 65 +max mmap bytes = 186437632 + +simplification SMDS_SpacePosition (pas de double[3]) --> 418 -33 = 385M (git SMDS_SpacePosition) +---------------------------------------------------- +Total (incl. mmap): +system bytes = 42582016 +in use bytes = 32883552 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 421728256 +in use bytes = 418378000 : 418M +max mmap regions = 58 +max mmap bytes = 183640064 + +sizeof(SMDS_MeshElement) 16 +sizeof(SMDS_MeshNode) 24 +sizeof(SMDS_MeshCell) 24 +sizeof(SMDS_VolumeVtkNodes) 24 +sizeof(SMDS_Position) 16 +sizeof(SMDS_SpacePosition) 16 + +impact d'un int en plus dans SMDS_MeshElement --> 426 - 33 = 393M +--------------------------------------------- + +sizeof(SMDS_MeshElement) 24 +sizeof(SMDS_MeshNode) 32 --> on retrouve bien les 8M +sizeof(SMDS_MeshCell) 24 +sizeof(SMDS_VolumeVtkNodes) 24 +sizeof(SMDS_Position) 16 +sizeof(SMDS_SpacePosition) 16 + +Total (incl. mmap): +system bytes = 43192320 +in use bytes = 32681088 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 429334528 +in use bytes = 426424576 : 426M +max mmap regions = 59 +max mmap bytes = 184692736 + +remplacement std::set par std::vector dans SMESHDS_SubMesh --> 347 - 35 = 312M +---------------------------------------------------------- +sizeof(SMDS_MeshElement) 24 +sizeof(SMDS_MeshNode) 32 +sizeof(SMDS_MeshCell) 24 +sizeof(SMDS_VolumeVtkNodes) 24 +sizeof(SMDS_Position) 16 +sizeof(SMDS_SpacePosition) 16 + +Total (incl. mmap): +system bytes = 45404160 +in use bytes = 35132160 --> 35M +max mmap regions = 49 +max mmap bytes = 17723392 +---- +Total (incl. mmap): +system bytes = 349831168 +in use bytes = 346885424 --> 347M +max mmap regions = 73 +max mmap bytes = 204148736 + +Ce resultat est coherent avec une recherche de swap sur une machine a 8Go de memoire: +Cube a 270**3 mailles (~20M mailles) --> 6.2 Go (idem Debian Sarge et Ubuntu 9.10, 64 bits) +Le meme avec V5.1.3 --> 14 Go (swap) + diff --git a/src/SMDS/ObjectPool.hxx b/src/SMDS/ObjectPool.hxx new file mode 100644 index 000000000..6e2fc1d2a --- /dev/null +++ b/src/SMDS/ObjectPool.hxx @@ -0,0 +1,115 @@ +#ifndef _OBJECTPOOL_HXX_ +#define _OBJECTPOOL_HXX_ + +#include +#include +#include + +template class ObjectPool +{ + +private: + std::vector _chunkList; + std::vector _freeList; + int _nextFree; + int _maxAvail; + int _chunkSize; + + int getNextFree() + { + for (int i = _nextFree; i < _maxAvail; i++) + if (_freeList[i] == true) + { + return i; + break; + } + return _maxAvail; + } + + void checkDelete(int chunkId) + { + int i0 = _chunkSize * chunkId; + int i1 = _chunkSize * (chunkId + 1); + for (int i = i0; i < i1; i++) + if (_freeList[i] == false) + return; + std::cerr << "a chunk to delete" << std::endl; + // compactage des vecteurs un peu lourd, pas necessaire + //X* chunk = _chunkList[chunkId]; + //delete [] chunk; + } + +public: + ObjectPool(int nblk) + { + _chunkSize = nblk; + _nextFree = 0; + _maxAvail = 0; + _chunkList.clear(); + _freeList.clear(); + } + + virtual ~ObjectPool() + { + for (int i = 0; i < _chunkList.size(); i++) + delete[] _chunkList[i]; + } + + X* getNew() + { + X *obj = 0; + _nextFree = getNextFree(); + if (_nextFree == _maxAvail) + { + X* newChunk = new X[_chunkSize]; + _chunkList.push_back(newChunk); + _freeList.insert(_freeList.end(), _chunkSize, true); + _maxAvail += _chunkSize; + _freeList[_nextFree] = false; + obj = newChunk; // &newChunk[0]; + } + else + { + int chunkId = _nextFree / _chunkSize; + int rank = _nextFree - chunkId * _chunkSize; + _freeList[_nextFree] = false; + obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank]; + } + //obj->init(); + return obj; + } + + void destroy(X* obj) + { + long adrobj = (long) (obj); + for (int i = 0; i < _chunkList.size(); i++) + { + X* chunk = _chunkList[i]; + long adrmin = (long) (chunk); + if (adrobj < adrmin) + continue; + long adrmax = (long) (chunk + _chunkSize); + if (adrobj >= adrmax) + continue; + int rank = (adrobj - adrmin) / sizeof(X); + int toFree = i * _chunkSize + rank; + _freeList[toFree] = true; + if (toFree < _nextFree) + _nextFree = toFree; + //obj->clean(); + //checkDelete(i); compactage non fait + break; + } + } + + // void destroy(int toFree) + // { + // // no control 0<= toFree < _freeList.size() + // _freeList[toFree] = true; + // if (toFree < _nextFree) + // _nextFree = toFree; + // } + +}; + +#endif diff --git a/src/SMDS/SMDS_Downward.cxx b/src/SMDS/SMDS_Downward.cxx new file mode 100644 index 000000000..f735c820a --- /dev/null +++ b/src/SMDS/SMDS_Downward.cxx @@ -0,0 +1,1981 @@ +/* + * SMDS_Downward.cxx + * + * Created on: Jun 3, 2010 + * Author: prascle + */ + +#include "SMDS_Downward.hxx" +#include "SMDS_Mesh.hxx" +#include "utilities.h" + +#include +#include + +#include + +using namespace std; + +// --------------------------------------------------------------------------- + +vector SMDS_Downward::_cellDimension; + +/*! get the dimension of a cell (1,2,3 for 1D, 2D 3D) given the vtk cell type + * + * @param cellType vtk cell type @see vtkCellType.h + * @return 1,2 or 3 + */ +int SMDS_Downward::getCellDimension(unsigned char cellType) +{ + return _cellDimension[cellType]; +} + +// --------------------------------------------------------------------------- + +/*! Generic constructor for all the downward connectivity structures (one per vtk cell type). + * The static structure for cell dimension is set only once. + * @param grid unstructured grid associated to the mesh. + * @param nbDownCells number of downward entities associated to this vtk type of cell. + * @return + */ +SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) : + _grid(grid), _nbDownCells(nbDownCells) +{ + this->_maxId = 0; + this->_cellIds.clear(); + this->_cellTypes.clear(); + if (_cellDimension.empty()) + { + _cellDimension.resize(VTK_MAXTYPE + 1, 0); + _cellDimension[VTK_LINE] = 1; + _cellDimension[VTK_QUADRATIC_EDGE] = 1; + _cellDimension[VTK_TRIANGLE] = 2; + _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2; + _cellDimension[VTK_QUAD] = 2; + _cellDimension[VTK_QUADRATIC_QUAD] = 2; + _cellDimension[VTK_TETRA] = 3; + _cellDimension[VTK_QUADRATIC_TETRA] = 3; + _cellDimension[VTK_HEXAHEDRON] = 3; + _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3; + _cellDimension[VTK_WEDGE] = 3; + _cellDimension[VTK_QUADRATIC_WEDGE] = 3; + _cellDimension[VTK_PYRAMID] = 3; + _cellDimension[VTK_QUADRATIC_PYRAMID] = 3; + } +} + +SMDS_Downward::~SMDS_Downward() +{ +} + +/*! Give or create an entry for downward connectivity structure relative to a cell. + * If the entry already exists, just return its id, otherwise, create it. + * The internal storage memory is allocated if needed. + * The SMDS_UnstructuredGrid::_cellIdToDownId vector is completed for vtkUnstructuredGrid cells. + * @param vtkId for a vtkUnstructuredGrid cell or -1 (default) for a created downward cell. + * @return the rank in downward[vtkType] structure. + */ +int SMDS_Downward::addCell(int vtkId) +{ + int localId = -1; + if (vtkId >= 0) + localId = _grid->CellIdToDownId(vtkId); + if (localId >= 0) + return localId; + + localId = this->_maxId; + this->_maxId++; + this->allocate(_maxId); + if (vtkId >= 0) + { + this->_vtkCellIds[localId] = vtkId; + _grid->setCellIdToDownId(vtkId, localId); + } + this->initCell(localId); + return localId; +} + +/*! generic method do nothing. see derived methods + * + * @param cellId + */ +void SMDS_Downward::initCell(int cellId) +{ +} + +/*! Get the number of downward entities associated to a cell (always the same for a given vtk type of cell) + * + * @param cellId not used here. + * @return + */ +int SMDS_Downward::getNumberOfDownCells(int cellId) +{ + return _nbDownCells; +} + +/*! get a pointer on the downward entities id's associated to a cell. + * @see SMDS_Downward::getNumberOfDownCells for the number of downward entities. + * @see SMDS_Downward::getDownTypes for the vtk cell types associated to the downward entities. + * @param cellId index of the cell in the downward structure relative to a given vtk cell type. + * @return table of downward entities id's. + */ +const int* SMDS_Downward::getDownCells(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_cellIds[_nbDownCells * cellId]; +} + +/*! get a list of vtk cell types associated to downward entities of a given cell, in the same order + * than the downward entities id's list (@see SMDS_Downward::getDownCells). + * + * @param cellId index of the cell in the downward structure relative to a vtk cell type. + * @return table of downward entities types. + */ +const unsigned char* SMDS_Downward::getDownTypes(int cellId) +{ + return &_cellTypes[0]; +} + +/*! add a downward entity of dimension n-1 (cell or node) to a given cell. + * Actual implementation is done in derived methods. + * @param cellId index of the parent cell (dimension n) in the downward structure relative to a vtk cell type. + * @param lowCellId index of the children cell to add (dimension n-1) + * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add). + */ +void SMDS_Downward::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + ASSERT(0); // must be re-implemented in derived class +} + +/*! add a downward entity of dimension n+1 to a given cell. + * Actual implementation is done in derived methods. + * @param cellId index of the children cell (dimension n) in the downward structure relative to a vtk cell type. + * @param upCellId index of the parent cell to add (dimension n+1) + * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add). + */ +void SMDS_Downward::addUpCell(int cellId, int upCellId, unsigned char aType) +{ + ASSERT(0); // must be re-implemented in derived class +} + +int SMDS_Downward::getNodeSet(int cellId, int* nodeSet) +{ + return 0; +} + +// --------------------------------------------------------------------------- + +SMDS_Down1D::SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells) : + SMDS_Downward(grid, nbDownCells) +{ + _upCellIdsVector.clear(); + _upCellTypesVector.clear(); + _upCellIds.clear(); + _upCellTypes.clear(); + _upCellIndex.clear(); +} + +SMDS_Down1D::~SMDS_Down1D() +{ +} + +/*! clear vectors used to reference 2D cells containing the edge + * + * @param cellId + */ +void SMDS_Down1D::initCell(int cellId) +{ + _upCellIdsVector[cellId].clear(); + _upCellTypesVector[cellId].clear(); +} + +/*! Resize the downward connectivity storage vector if needed. + * + * @param nbElems total number of elements of the same type required + */ +void SMDS_Down1D::allocate(int nbElems) +{ + if (nbElems >= _vtkCellIds.size()) + { + _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1); + _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1); + _upCellIdsVector.resize(nbElems + SMDS_Mesh::chunkSize); + _upCellTypesVector.resize(nbElems + SMDS_Mesh::chunkSize); + } +} + +void SMDS_Down1D::compactStorage() +{ + _cellIds.resize(_nbDownCells * _maxId); + _vtkCellIds.resize(_maxId); + + int sizeUpCells = 0; + for (int i = 0; i < _maxId; i++) + sizeUpCells += _upCellIdsVector[i].size(); + _upCellIds.resize(sizeUpCells, -1); + _upCellTypes.resize(sizeUpCells); + _upCellIndex.resize(_maxId + 1, -1); // id and types of rank i correspond to [ _upCellIndex[i], _upCellIndex[i+1] [ + int current = 0; + for (int i = 0; i < _maxId; i++) + { + _upCellIndex[i] = current; + for (int j = 0; j < _upCellIdsVector[i].size(); j++) + { + _upCellIds[current] = _upCellIdsVector[i][j]; + _upCellTypes[current] = _upCellTypesVector[i][j]; + current++; + } + } + _upCellIndex[_maxId] = current; + + _upCellIdsVector.clear(); + _upCellTypesVector.clear(); +} + +void SMDS_Down1D::addUpCell(int cellId, int upCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int nbFaces = _upCellIdsVector[cellId].size(); + for (int i = 0; i < nbFaces; i++) + { + if ((_upCellIdsVector[cellId][i] == upCellId) && (_upCellTypesVector[cellId][i] == aType)) + { + return; // already done + } + } + _upCellIdsVector[cellId].push_back(upCellId); + _upCellTypesVector[cellId].push_back(aType); +} + +int SMDS_Down1D::getNumberOfUpCells(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return _upCellIndex[cellId + 1] - _upCellIndex[cellId]; +} + +const int* SMDS_Down1D::getUpCells(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_upCellIds[_upCellIndex[cellId]]; +} + +const unsigned char* SMDS_Down1D::getUpTypes(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_upCellTypes[_upCellIndex[cellId]]; +} + +void SMDS_Down1D::getNodeIds(int cellId, std::set& nodeSet) +{ + for (int i = 0; i < _nbDownCells; i++) + nodeSet.insert(_cellIds[_nbDownCells * cellId + i]); +} + +int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet) +{ + for (int i = 0; i < _nbDownCells; i++) + nodeSet[i] = _cellIds[_nbDownCells * cellId + i]; + return _nbDownCells; +} + +void SMDS_Down1D::setNodes(int cellId, int vtkId) +{ + vtkIdType npts = 0; + vtkIdType *pts; // will refer to the point id's of the face + _grid->GetCellPoints(vtkId, npts, pts); + // MESSAGE(vtkId << " " << npts << " " << _nbDownCells); + //ASSERT(npts == _nbDownCells); + for (int i = 0; i < npts; i++) + { + _cellIds[_nbDownCells * cellId + i] = pts[i]; + } +} + +void SMDS_Down1D::setNodes(int cellId, const int* nodeIds) +{ + //ASSERT(nodeIds.size() == _nbDownCells); + for (int i = 0; i < _nbDownCells; i++) + { + _cellIds[_nbDownCells * cellId + i] = nodeIds[i]; + } +} + +/*! Build the list of vtkUnstructuredGrid cells containing the edge. + * We keep in the list the cells that contains all the nodes, we keep only volumes and faces. + * @param cellId id of the edge in the downward structure + * @param vtkIds vector of vtk id's + * @return number of vtk cells (size of vector) + */ +int SMDS_Down1D::computeVtkCells(int cellId, std::vector& vtkIds) +{ + vtkIds.clear(); + + // --- find all the cells the points belong to, and how many of the points belong to a given cell + + int *pts = &_cellIds[_nbDownCells * cellId]; + int ncells = this->computeVtkCells(pts, vtkIds); + return ncells; +} + +/*! Build the list of vtkUnstructuredGrid cells containing the edge. + * + * @param pts list of points id's defining an edge + * @param vtkIds vector of vtk id's + * @return number of vtk cells (size of vector) + */ +int SMDS_Down1D::computeVtkCells(int *pts, std::vector& vtkIds) +{ + + // --- find all the cells the points belong to, and how many of the points belong to a given cell + + int cellIds[1000]; + int cellCnt[1000]; + int cnt = 0; + for (int i = 0; i < _nbDownCells; i++) + { + vtkIdType point = pts[i]; + int numCells = _grid->GetLinks()->GetNcells(point); + vtkIdType *cells = _grid->GetLinks()->GetCells(point); + for (int j = 0; j < numCells; j++) + { + int vtkCellId = cells[j]; + bool found = false; + for (int k = 0; k < cnt; k++) + { + if (cellIds[k] == vtkCellId) + { + cellCnt[k] += 1; + found = true; + break; + } + } + if (!found) + { + cellIds[cnt] = vtkCellId; + cellCnt[cnt] = 1; + // TODO ASSERT(cnt<1000); + cnt++; + } + } + } + + // --- find the face and volume cells: they contains all the points and are of type volume or face + + int ncells = 0; + for (int i = 0; i < cnt; i++) + { + if (cellCnt[i] == _nbDownCells) + { + int vtkElemId = cellIds[i]; + int vtkType = _grid->GetCellType(vtkElemId); + if (SMDS_Downward::getCellDimension(vtkType) > 1) + { + vtkIds.push_back(vtkElemId); + ncells++; + } + } + } + + return ncells; +} + +/*! Build the list of downward faces from a list of vtk cells. + * + * @param cellId id of the edge in the downward structure + * @param vtkIds vector of vtk id's + * @param downFaces vector of face id's in downward structures + * @param downTypes vector of face types + * @return number of downward faces + */ +int SMDS_Down1D::computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes) +{ + int *pts = &_cellIds[_nbDownCells * cellId]; + int nbFaces = this->computeFaces(pts, vtkIds, nbcells, downFaces, downTypes); + return nbFaces; +} + +/*! Build the list of downward faces from a list of vtk cells. + * + * @param pts list of points id's defining an edge + * @param vtkIds vector of vtk id's + * @param downFaces vector of face id's in downward structures + * @param downTypes vector of face types + * @return number of downward faces + */ +int SMDS_Down1D::computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes) +{ + int cnt = 0; + for (int i = 0; i < nbcells; i++) + { + int vtkId = vtkIds[i]; + int vtkType = _grid->GetCellType(vtkId); + if (SMDS_Downward::getCellDimension(vtkType) == 2) + { + int faceId = _grid->CellIdToDownId(vtkId); + downFaces[cnt] = faceId; + downTypes[cnt] = vtkType; + cnt++; + } + else + { + int volId = _grid->CellIdToDownId(vtkId); + SMDS_Downward * downvol = _grid->getDownArray(vtkType); + const int *downIds = downvol->getDownCells(volId); + const unsigned char* downTypesVol = downvol->getDownTypes(volId); + int nbFaces = downvol->getNumberOfDownCells(volId); + const int* faceIds = downvol->getDownCells(volId); + for (int n = 0; n < nbFaces; n++) + { + SMDS_Down2D *downFace = static_cast (_grid->getDownArray(downTypesVol[n])); + bool isInFace = downFace->isInFace(faceIds[n], pts, _nbDownCells); + if (isInFace) + { + bool alreadySet = false; + for (int k = 0; k < cnt; k++) + if (faceIds[n] == downFaces[k]) + { + alreadySet = true; + break; + } + if (!alreadySet) + { + downFaces[cnt] = faceIds[n]; + downTypes[cnt] = downTypesVol[n]; + cnt++; + } + } + } + } + } + return cnt; +} + +// --------------------------------------------------------------------------- + +SMDS_Down2D::SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells) : + SMDS_Downward(grid, nbDownCells) +{ + _upCellIds.clear(); + _upCellTypes.clear(); + _tempNodes.clear(); + _nbNodes = 0; +} + +SMDS_Down2D::~SMDS_Down2D() +{ +} + +int SMDS_Down2D::getNumberOfUpCells(int cellId) +{ + int nbup = 0; + if (_upCellIds[2 * cellId] >= 0) + nbup++; + if (_upCellIds[2 * cellId + 1] >= 0) + nbup++; + return nbup; +} + +const int* SMDS_Down2D::getUpCells(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_upCellIds[2 * cellId]; +} + +const unsigned char* SMDS_Down2D::getUpTypes(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_upCellTypes[2 * cellId]; +} + +void SMDS_Down2D::getNodeIds(int cellId, std::set& nodeSet) +{ + for (int i = 0; i < _nbDownCells; i++) + { + int downCellId = _cellIds[_nbDownCells * cellId + i]; + unsigned char cellType = _cellTypes[i]; + this->_grid->getDownArray(cellType)->getNodeIds(downCellId, nodeSet); + } +} + +/*! Find in vtkUnstructuredGrid the volumes containing a face already stored in vtkUnstructuredGrid. + * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses + * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes. + * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid. + * @param cellId the face cell id in vkUnstructuredGrid + * @param ids a couple of vtkId, initialized at -1 (no parent volume) + * @return number of volumes (0, 1 or 2) + */ +int SMDS_Down2D::computeVolumeIds(int cellId, int* ids) +{ + // --- find point id's of the face + + vtkIdType npts = 0; + vtkIdType *pts; // will refer to the point id's of the face + _grid->GetCellPoints(cellId, npts, pts); + vector nodes; + for (int i = 0; i < npts; i++) + nodes.push_back(pts[i]); + int nvol = this->computeVolumeIdsFromNodesFace(&nodes[0], npts, ids); + return nvol; +} + +/*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes + * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses + * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes. + * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid. + * @param faceByNodes + * @param ids a couple of vtkId, initialized at -1 (no parent volume) + * @return number of volumes (0, 1 or 2) + */ +int SMDS_Down2D::computeVolumeIds(ElemByNodesType& faceByNodes, int* ids) +{ + int nvol = this->computeVolumeIdsFromNodesFace(&faceByNodes.nodeIds[0], faceByNodes.nbNodes, ids); + return nvol; +} + +/*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes + * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses + * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes. + * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid. + * @param pts array of vtk node id's + * @param npts number of nodes + * @param ids + * @return number of volumes (0, 1 or 2) + */ +int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids) +{ + + // --- find all the cells the points belong to, and how many of the points belong to a given cell + + int cellIds[1000]; + int cellCnt[1000]; + int cnt = 0; + for (int i = 0; i < npts; i++) + { + vtkIdType point = pts[i]; + int numCells = _grid->GetLinks()->GetNcells(point); + //MESSAGE("cells pour " << i << " " << numCells); + vtkIdType *cells = _grid->GetLinks()->GetCells(point); + for (int j = 0; j < numCells; j++) + { + int vtkCellId = cells[j]; + bool found = false; + for (int k = 0; k < cnt; k++) + { + if (cellIds[k] == vtkCellId) + { + cellCnt[k] += 1; + found = true; + break; + } + } + if (!found) + { + cellIds[cnt] = vtkCellId; + cellCnt[cnt] = 1; + // TODO ASSERT(cnt<1000); + cnt++; + } + } + } + + // --- find the volume cells: they contains all the points and are of type volume + + int nvol = 0; + for (int i = 0; i < cnt; i++) + { + //MESSAGE("cell " << cellIds[i] << " points " << cellCnt[i]); + if (cellCnt[i] == npts) + { + int vtkElemId = cellIds[i]; + int vtkType = _grid->GetCellType(vtkElemId); + if (SMDS_Downward::getCellDimension(vtkType) == 3) + { + ids[nvol] = vtkElemId; // store the volume id in given vector + nvol++; + } + } + if (nvol == 2) + break; + } + + return nvol; +} + +void SMDS_Down2D::setTempNodes(int cellId, int vtkId) +{ + vtkIdType npts = 0; + vtkIdType *pts; // will refer to the point id's of the face + _grid->GetCellPoints(vtkId, npts, pts); + // MESSAGE(vtkId << " " << npts << " " << _nbNodes); + //ASSERT(npts == _nbNodes); + for (int i = 0; i < npts; i++) + { + _tempNodes[_nbNodes * cellId + i] = pts[i]; + } +} + +void SMDS_Down2D::setTempNodes(int cellId, ElemByNodesType& faceByNodes) +{ + for (int i = 0; i < faceByNodes.nbNodes; i++) + _tempNodes[_nbNodes * cellId + i] = faceByNodes.nodeIds[i]; +} + +/*! Find if all the nodes belongs to the face. + * + * @param cellId the face cell Id + * @param nodeSet set of node id's to be found in the face list of nodes + * @return + */ +bool SMDS_Down2D::isInFace(int cellId, int *pts, int npts) +{ + int nbFound = 0; + int *nodes = &_tempNodes[_nbNodes * cellId]; + for (int j = 0; j < npts; j++) + { + int point = pts[j]; + for (int i = 0; i < _nbNodes; i++) + { + if (nodes[i] == point) + { + nbFound++; + break; + } + } + } + return (nbFound == npts); +} + +/*! Resize the downward connectivity storage vector if needed. + * + * @param nbElems total number of elements of the same type required + */ +void SMDS_Down2D::allocate(int nbElems) +{ + if (nbElems >= _vtkCellIds.size()) + { + _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1); + _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1); + _upCellIds.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1); + _upCellTypes.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1); + _tempNodes.resize(_nbNodes * (nbElems + SMDS_Mesh::chunkSize), -1); + } +} + +void SMDS_Down2D::compactStorage() +{ + _cellIds.resize(_nbDownCells * _maxId); + _upCellIds.resize(2 * _maxId); + _upCellTypes.resize(2 * _maxId); + _vtkCellIds.resize(_maxId); + _tempNodes.clear(); +} + +void SMDS_Down2D::addUpCell(int cellId, int upCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + int *vols = &_upCellIds[2 * cellId]; + unsigned char *types = &_upCellTypes[2 * cellId]; + for (int i = 0; i < 2; i++) + { + if (vols[i] < 0) + { + vols[i] = upCellId; // use non affected volume + types[i] = aType; + return; + } + if ((vols[i] == upCellId) && (types[i] == aType)) // already done + return; + } + ASSERT(0); +} + +int SMDS_Down2D::getNodeSet(int cellId, int* nodeSet) +{ + for (int i = 0; i < _nbNodes; i++) + nodeSet[i] = _tempNodes[_nbNodes * cellId + i]; + return _nbNodes; +} + +int SMDS_Down2D::FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes) +{ + int *edges = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if ((edges[i] >= 0) && (edgeByNodes.vtkType == _cellTypes[i])) + { + int nodeSet[3]; + int npts = this->_grid->getDownArray(edgeByNodes.vtkType)->getNodeSet(edges[i], nodeSet); + bool found = false; + for (int j = 0; j < npts; j++) + { + int point = edgeByNodes.nodeIds[j]; + found = false; + for (int k = 0; k < npts; k++) + { + if (nodeSet[k] == point) + { + found = true; + break; + } + } + if (!found) + break; + } + if (found) + return edges[i]; + } + } + return -1; +} + +// --------------------------------------------------------------------------- + +SMDS_Down3D::SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells) : + SMDS_Downward(grid, nbDownCells) +{ +} + +SMDS_Down3D::~SMDS_Down3D() +{ +} + +void SMDS_Down3D::allocate(int nbElems) +{ + if (nbElems >= _vtkCellIds.size()) + { + _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1); + _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1); + } +} + +void SMDS_Down3D::compactStorage() +{ + // nothing to do, size was known before +} + +int SMDS_Down3D::getNumberOfUpCells(int cellId) +{ + return 0; +} + +const int* SMDS_Down3D::getUpCells(int cellId) +{ + return 0; +} + +const unsigned char* SMDS_Down3D::getUpTypes(int cellId) +{ + return 0; +} + +void SMDS_Down3D::getNodeIds(int cellId, std::set& nodeSet) +{ + int vtkId = this->_vtkCellIds[cellId]; + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(vtkId, npts, nodes); + for (int i = 0; i < npts; i++) + nodeSet.insert(nodes[i]); +} + +int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes) +{ + int *faces = &_cellIds[_nbDownCells * cellId]; + int faceNodeSet[10]; + int npoints = 0; + + for (int i = 0; i < _nbDownCells; i++) + { + if ((faces[i] >= 0) && (faceByNodes.vtkType == _cellTypes[i])) + { + if (npoints == 0) + { + for (int j = 0; j < faceByNodes.nbNodes; j++) + faceNodeSet[j] = faceByNodes.nodeIds[j]; + npoints = faceByNodes.nbNodes; + } + + int nodeSet[10]; + int npts = this->_grid->getDownArray(faceByNodes.vtkType)->getNodeSet(faces[i], nodeSet); + if (npts != npoints) + continue; // skip this face + bool found = false; + for (int j = 0; j < npts; j++) + { + int point = faceByNodes.nodeIds[j]; + found = false; + for (int k = 0; k < npts; k++) + { + if (nodeSet[k] == point) + { + found = true; + break; // point j is in the 2 faces, skip remaining k values + } + } + if (!found) + break; // point j is not in the 2 faces, skip the remaining tests + } + if (found) + return faces[i]; + } + } + return -1; +} + +// --------------------------------------------------------------------------- + +SMDS_DownEdge::SMDS_DownEdge(SMDS_UnstructuredGrid *grid) : + SMDS_Down1D(grid, 2) +{ + _cellTypes.push_back(VTK_VERTEX); + _cellTypes.push_back(VTK_VERTEX); +} + +SMDS_DownEdge::~SMDS_DownEdge() +{ +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadEdge::SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid) : + SMDS_Down1D(grid, 3) +{ + _cellTypes.push_back(VTK_VERTEX); + _cellTypes.push_back(VTK_VERTEX); + _cellTypes.push_back(VTK_VERTEX); +} + +SMDS_DownQuadEdge::~SMDS_DownQuadEdge() +{ +} + +// --------------------------------------------------------------------------- + +SMDS_DownTriangle::SMDS_DownTriangle(SMDS_UnstructuredGrid *grid) : + SMDS_Down2D(grid, 3) +{ + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _nbNodes = 3; +} + +SMDS_DownTriangle::~SMDS_DownTriangle() +{ +} + +void SMDS_DownTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) +{ + int *nodes = &_tempNodes[_nbNodes * cellId]; + edgesWithNodes.nbElems = 3; + + edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; + edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; + edgesWithNodes.elems[0].nbNodes = 2; + edgesWithNodes.elems[0].vtkType = VTK_LINE; + + edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; + edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; + edgesWithNodes.elems[1].nbNodes = 2; + edgesWithNodes.elems[1].vtkType = VTK_LINE; + + edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; + edgesWithNodes.elems[2].nodeIds[1] = nodes[0]; + edgesWithNodes.elems[2].nbNodes = 2; + edgesWithNodes.elems[2].vtkType = VTK_LINE; +} + +void SMDS_DownTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_LINE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadTriangle::SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid) : + SMDS_Down2D(grid, 3) +{ + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _nbNodes = 6; +} + +SMDS_DownQuadTriangle::~SMDS_DownQuadTriangle() +{ +} + +void SMDS_DownQuadTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) +{ + int *nodes = &_tempNodes[_nbNodes * cellId]; + edgesWithNodes.nbElems = 3; + + edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; + edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; + edgesWithNodes.elems[0].nodeIds[2] = nodes[3]; + edgesWithNodes.elems[0].nbNodes = 3; + edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; + edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; + edgesWithNodes.elems[1].nodeIds[2] = nodes[4]; + edgesWithNodes.elems[1].nbNodes = 3; + edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; + edgesWithNodes.elems[2].nodeIds[1] = nodes[0]; + edgesWithNodes.elems[2].nodeIds[2] = nodes[5]; + edgesWithNodes.elems[2].nbNodes = 3; + edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE; +} + +void SMDS_DownQuadTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_QUADRATIC_EDGE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadrangle::SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid) : + SMDS_Down2D(grid, 4) +{ + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _nbNodes = 4; +} + +SMDS_DownQuadrangle::~SMDS_DownQuadrangle() +{ +} + +void SMDS_DownQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) +{ + int *nodes = &_tempNodes[_nbNodes * cellId]; + edgesWithNodes.nbElems = 4; + + edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; + edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; + edgesWithNodes.elems[0].nbNodes = 2; + edgesWithNodes.elems[0].vtkType = VTK_LINE; + + edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; + edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; + edgesWithNodes.elems[1].nbNodes = 2; + edgesWithNodes.elems[1].vtkType = VTK_LINE; + + edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; + edgesWithNodes.elems[2].nodeIds[1] = nodes[3]; + edgesWithNodes.elems[2].nbNodes = 2; + edgesWithNodes.elems[2].vtkType = VTK_LINE; + + edgesWithNodes.elems[3].nodeIds[0] = nodes[3]; + edgesWithNodes.elems[3].nodeIds[1] = nodes[0]; + edgesWithNodes.elems[3].nbNodes = 2; + edgesWithNodes.elems[3].vtkType = VTK_LINE; +} + +void SMDS_DownQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_LINE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadQuadrangle::SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid) : + SMDS_Down2D(grid, 4) +{ + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _nbNodes = 8; +} + +SMDS_DownQuadQuadrangle::~SMDS_DownQuadQuadrangle() +{ +} + +void SMDS_DownQuadQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) +{ + int *nodes = &_tempNodes[_nbNodes * cellId]; + edgesWithNodes.nbElems = 4; + + edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; + edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; + edgesWithNodes.elems[0].nodeIds[2] = nodes[4]; + edgesWithNodes.elems[0].nbNodes = 3; + edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; + edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; + edgesWithNodes.elems[1].nodeIds[2] = nodes[5]; + edgesWithNodes.elems[1].nbNodes = 3; + edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; + edgesWithNodes.elems[2].nodeIds[1] = nodes[3]; + edgesWithNodes.elems[2].nodeIds[2] = nodes[6]; + edgesWithNodes.elems[2].nbNodes = 3; + edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[3].nodeIds[0] = nodes[3]; + edgesWithNodes.elems[3].nodeIds[1] = nodes[0]; + edgesWithNodes.elems[3].nodeIds[2] = nodes[7]; + edgesWithNodes.elems[3].nbNodes = 3; + edgesWithNodes.elems[3].vtkType = VTK_QUADRATIC_EDGE; +} + +void SMDS_DownQuadQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_QUADRATIC_EDGE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +// --------------------------------------------------------------------------- + +SMDS_DownTetra::SMDS_DownTetra(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 4) +{ + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); +} + +SMDS_DownTetra::~SMDS_DownTetra() +{ +} + +void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + set setNodes; + setNodes.clear(); + for (int i = 0; i < orderedNodes.size(); i++) + setNodes.insert(orderedNodes[i]); + //MESSAGE("cellId = " << cellId); + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); + + set tofind; + int ids[12] = { 0, 1, 2, 0, 1, 3, 0, 2, 3, 1, 2, 3 }; + for (int k = 0; k < 4; k++) + { + tofind.clear(); + for (int i = 0; i < 3; i++) + tofind.insert(nodes[ids[3 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 3; i++) + orderedNodes[i] = nodes[ids[3 * k + i]]; + return; + } + } + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); + MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); +} + +void SMDS_DownTetra::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_TRIANGLE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The linear tetrahedron is defined by four points. + * @see vtkTetra.h in Filtering. + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 4; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nbNodes = 3; + facesWithNodes.elems[0].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[1].nodeIds[0] = nodes[0]; + facesWithNodes.elems[1].nodeIds[1] = nodes[1]; + facesWithNodes.elems[1].nodeIds[2] = nodes[3]; + facesWithNodes.elems[1].nbNodes = 3; + facesWithNodes.elems[1].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[2]; + facesWithNodes.elems[2].nodeIds[2] = nodes[3]; + facesWithNodes.elems[2].nbNodes = 3; + facesWithNodes.elems[2].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[3].nodeIds[0] = nodes[1]; + facesWithNodes.elems[3].nodeIds[1] = nodes[2]; + facesWithNodes.elems[3].nodeIds[2] = nodes[3]; + facesWithNodes.elems[3].nbNodes = 3; + facesWithNodes.elems[3].vtkType = VTK_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadTetra::SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 4) +{ + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); +} + +SMDS_DownQuadTetra::~SMDS_DownQuadTetra() +{ +} + +void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + // TODO +} + +void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The ordering of the ten points defining the quadratic tetrahedron cell is point id's (0-3,4-9) + * where id's 0-3 are the four tetrahedron vertices; + * and point id's 4-9 are the mid-edge nodes between (0,1), (1,2), (2,0), (0,3), (1,3), and (2,3). + * @see vtkQuadraticTetra.h in Filtering. + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 4; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[4]; + facesWithNodes.elems[0].nodeIds[4] = nodes[5]; + facesWithNodes.elems[0].nodeIds[5] = nodes[6]; + facesWithNodes.elems[0].nbNodes = 6; + facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[1].nodeIds[0] = nodes[0]; + facesWithNodes.elems[1].nodeIds[1] = nodes[1]; + facesWithNodes.elems[1].nodeIds[2] = nodes[3]; + facesWithNodes.elems[1].nodeIds[3] = nodes[4]; + facesWithNodes.elems[1].nodeIds[4] = nodes[7]; + facesWithNodes.elems[1].nodeIds[5] = nodes[8]; + facesWithNodes.elems[1].nbNodes = 6; + facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[2]; + facesWithNodes.elems[2].nodeIds[2] = nodes[3]; + facesWithNodes.elems[2].nodeIds[3] = nodes[6]; + facesWithNodes.elems[2].nodeIds[4] = nodes[7]; + facesWithNodes.elems[2].nodeIds[5] = nodes[9]; + facesWithNodes.elems[2].nbNodes = 6; + facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[3].nodeIds[0] = nodes[1]; + facesWithNodes.elems[3].nodeIds[1] = nodes[2]; + facesWithNodes.elems[3].nodeIds[2] = nodes[3]; + facesWithNodes.elems[3].nodeIds[3] = nodes[5]; + facesWithNodes.elems[3].nodeIds[4] = nodes[8]; + facesWithNodes.elems[3].nodeIds[5] = nodes[9]; + facesWithNodes.elems[3].nbNodes = 6; + facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownPyramid::SMDS_DownPyramid(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 5) +{ + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); +} + +SMDS_DownPyramid::~SMDS_DownPyramid() +{ +} + +void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + // TODO +} + +void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + if (aType == VTK_QUAD) + { + if (faces[0] < 0) + { + faces[0] = lowCellId; + return; + } + if (faces[0] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_TRIANGLE); + for (int i = 1; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The pyramid is defined by the five points (0-4) where (0,1,2,3) is the base of the pyramid which, + * using the right hand rule, forms a quadrilateral whose normal points in the direction of the + * pyramid apex at vertex #4. + * @see vtkPyramid.h in Filtering. + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 5; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nbNodes = 4; + facesWithNodes.elems[0].vtkType = VTK_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[0]; + facesWithNodes.elems[1].nodeIds[1] = nodes[1]; + facesWithNodes.elems[1].nodeIds[2] = nodes[4]; + facesWithNodes.elems[1].nbNodes = 3; + facesWithNodes.elems[1].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[2].nodeIds[0] = nodes[1]; + facesWithNodes.elems[2].nodeIds[1] = nodes[2]; + facesWithNodes.elems[2].nodeIds[2] = nodes[4]; + facesWithNodes.elems[2].nbNodes = 3; + facesWithNodes.elems[2].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[3].nodeIds[0] = nodes[2]; + facesWithNodes.elems[3].nodeIds[1] = nodes[3]; + facesWithNodes.elems[3].nodeIds[2] = nodes[4]; + facesWithNodes.elems[3].nbNodes = 3; + facesWithNodes.elems[3].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[4].nodeIds[0] = nodes[3]; + facesWithNodes.elems[4].nodeIds[1] = nodes[0]; + facesWithNodes.elems[4].nodeIds[2] = nodes[4]; + facesWithNodes.elems[4].nbNodes = 3; + facesWithNodes.elems[4].vtkType = VTK_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadPyramid::SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 5) +{ + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); +} + +SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid() +{ +} + +void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + // TODO +} + +void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + if (aType == VTK_QUADRATIC_QUAD) + { + if (faces[0] < 0) + { + faces[0] = lowCellId; + return; + } + if (faces[0] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); + for (int i = 1; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The ordering of the thirteen points defining the quadratic pyramid cell is point id's (0-4,5-12) + * where point id's 0-4 are the five corner vertices of the pyramid; followed + * by eight mid-edge nodes (5-12). Note that these mid-edge nodes lie on the edges defined by + * 5(0,1), 6(1,2), 7(2,3), 8(3,0), 9(0,4), 10(1,4), 11(2,4), 12(3,4). + * @see vtkQuadraticPyramid.h in Filtering. + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 5; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nodeIds[4] = nodes[5]; + facesWithNodes.elems[0].nodeIds[5] = nodes[6]; + facesWithNodes.elems[0].nodeIds[6] = nodes[7]; + facesWithNodes.elems[0].nodeIds[7] = nodes[8]; + facesWithNodes.elems[0].nbNodes = 8; + facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[0]; + facesWithNodes.elems[1].nodeIds[1] = nodes[1]; + facesWithNodes.elems[1].nodeIds[2] = nodes[4]; + facesWithNodes.elems[1].nodeIds[3] = nodes[5]; + facesWithNodes.elems[1].nodeIds[4] = nodes[9]; + facesWithNodes.elems[1].nodeIds[5] = nodes[10]; + facesWithNodes.elems[1].nbNodes = 6; + facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[2].nodeIds[0] = nodes[1]; + facesWithNodes.elems[2].nodeIds[1] = nodes[2]; + facesWithNodes.elems[2].nodeIds[2] = nodes[4]; + facesWithNodes.elems[2].nodeIds[3] = nodes[6]; + facesWithNodes.elems[2].nodeIds[4] = nodes[10]; + facesWithNodes.elems[2].nodeIds[5] = nodes[11]; + facesWithNodes.elems[2].nbNodes = 6; + facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[3].nodeIds[0] = nodes[2]; + facesWithNodes.elems[3].nodeIds[1] = nodes[3]; + facesWithNodes.elems[3].nodeIds[2] = nodes[4]; + facesWithNodes.elems[3].nodeIds[3] = nodes[7]; + facesWithNodes.elems[3].nodeIds[4] = nodes[11]; + facesWithNodes.elems[3].nodeIds[5] = nodes[12]; + facesWithNodes.elems[3].nbNodes = 6; + facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[4].nodeIds[0] = nodes[3]; + facesWithNodes.elems[4].nodeIds[1] = nodes[0]; + facesWithNodes.elems[4].nodeIds[2] = nodes[4]; + facesWithNodes.elems[4].nodeIds[3] = nodes[8]; + facesWithNodes.elems[4].nodeIds[4] = nodes[9]; + facesWithNodes.elems[4].nodeIds[5] = nodes[12]; + facesWithNodes.elems[4].nbNodes = 6; + facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownPenta::SMDS_DownPenta(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 5) +{ + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); +} + +SMDS_DownPenta::~SMDS_DownPenta() +{ +} + +void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + // TODO +} + +void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + if (aType == VTK_QUAD) + for (int i = 0; i < 2; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_TRIANGLE); + for (int i = 2; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's. + * A wedge or pentahedron consists of two triangular and three quadrilateral faces + * and is defined by the six points (0-5) where (0,1,2) is the base of the wedge which, + * using the right hand rule, forms a triangle whose normal points outward + * (away from the triangular face (3,4,5)). + * @see vtkWedge.h in Filtering + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 5; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[2]; + facesWithNodes.elems[0].nodeIds[2] = nodes[5]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nbNodes = 4; + facesWithNodes.elems[0].vtkType = VTK_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[1]; + facesWithNodes.elems[1].nodeIds[1] = nodes[2]; + facesWithNodes.elems[1].nodeIds[2] = nodes[5]; + facesWithNodes.elems[1].nodeIds[3] = nodes[4]; + facesWithNodes.elems[1].nbNodes = 4; + facesWithNodes.elems[1].vtkType = VTK_QUAD; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[1]; + facesWithNodes.elems[2].nodeIds[2] = nodes[4]; + facesWithNodes.elems[2].nodeIds[3] = nodes[3]; + facesWithNodes.elems[2].nbNodes = 4; + facesWithNodes.elems[2].vtkType = VTK_QUAD; + + facesWithNodes.elems[3].nodeIds[0] = nodes[0]; + facesWithNodes.elems[3].nodeIds[1] = nodes[1]; + facesWithNodes.elems[3].nodeIds[2] = nodes[2]; + facesWithNodes.elems[3].nbNodes = 3; + facesWithNodes.elems[3].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[4].nodeIds[0] = nodes[3]; + facesWithNodes.elems[4].nodeIds[1] = nodes[4]; + facesWithNodes.elems[4].nodeIds[2] = nodes[5]; + facesWithNodes.elems[4].nbNodes = 3; + facesWithNodes.elems[4].vtkType = VTK_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadPenta::SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 5) +{ + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); +} + +SMDS_DownQuadPenta::~SMDS_DownQuadPenta() +{ +} + +void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + // TODO +} + +void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + if (aType == VTK_QUADRATIC_QUAD) + for (int i = 0; i < 2; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); + for (int i = 2; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The quadratic wedge (or pentahedron) is defined by fifteen points. + * The ordering of the fifteen points defining the cell is point id's (0-5,6-14) + * where point id's 0-5 are the six corner vertices of the wedge, followed by + * nine mid-edge nodes (6-14). Note that these mid-edge nodes lie on the edges defined by + * (0,1), (1,2), (2,0), (3,4), (4,5), (5,3), (0,3), (1,4), (2,5). + * @see vtkQuadraticWedge.h in Filtering + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownQuadPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 5; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[2]; + facesWithNodes.elems[0].nodeIds[2] = nodes[5]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nodeIds[4] = nodes[8]; + facesWithNodes.elems[0].nodeIds[5] = nodes[14]; + facesWithNodes.elems[0].nodeIds[6] = nodes[11]; + facesWithNodes.elems[0].nodeIds[7] = nodes[12]; + facesWithNodes.elems[0].nbNodes = 8; + facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[1]; + facesWithNodes.elems[1].nodeIds[1] = nodes[2]; + facesWithNodes.elems[1].nodeIds[2] = nodes[5]; + facesWithNodes.elems[1].nodeIds[3] = nodes[4]; + facesWithNodes.elems[1].nodeIds[4] = nodes[7]; + facesWithNodes.elems[1].nodeIds[5] = nodes[14]; + facesWithNodes.elems[1].nodeIds[6] = nodes[10]; + facesWithNodes.elems[1].nodeIds[7] = nodes[13]; + facesWithNodes.elems[1].nbNodes = 8; + facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[1]; + facesWithNodes.elems[2].nodeIds[2] = nodes[4]; + facesWithNodes.elems[2].nodeIds[3] = nodes[3]; + facesWithNodes.elems[2].nodeIds[4] = nodes[6]; + facesWithNodes.elems[2].nodeIds[5] = nodes[13]; + facesWithNodes.elems[2].nodeIds[6] = nodes[9]; + facesWithNodes.elems[2].nodeIds[7] = nodes[12]; + facesWithNodes.elems[2].nbNodes = 8; + facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[3].nodeIds[0] = nodes[0]; + facesWithNodes.elems[3].nodeIds[1] = nodes[1]; + facesWithNodes.elems[3].nodeIds[2] = nodes[2]; + facesWithNodes.elems[3].nodeIds[3] = nodes[6]; + facesWithNodes.elems[3].nodeIds[4] = nodes[7]; + facesWithNodes.elems[3].nodeIds[5] = nodes[8]; + facesWithNodes.elems[3].nbNodes = 6; + facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[4].nodeIds[0] = nodes[3]; + facesWithNodes.elems[4].nodeIds[1] = nodes[4]; + facesWithNodes.elems[4].nodeIds[2] = nodes[5]; + facesWithNodes.elems[4].nodeIds[3] = nodes[9]; + facesWithNodes.elems[4].nodeIds[4] = nodes[10]; + facesWithNodes.elems[4].nodeIds[5] = nodes[11]; + facesWithNodes.elems[4].nbNodes = 6; + facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownHexa::SMDS_DownHexa(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 6) +{ + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); +} + +SMDS_DownHexa::~SMDS_DownHexa() +{ +} + +void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + // TODO +} + +void SMDS_DownHexa::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); + // MESSAGE("-------------------------------------> trop de faces ! " << cellId << " " << lowCellId); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The hexahedron is defined by the eight points (0-7), where (0,1,2,3) is the base + * of the hexahedron which, using the right hand rule, forms a quadrilateral whose normal + * points in the direction of the opposite face (4,5,6,7). + * @see vtkHexahedron.h in Filtering + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 6; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nbNodes = 4; + facesWithNodes.elems[0].vtkType = VTK_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[4]; + facesWithNodes.elems[1].nodeIds[1] = nodes[5]; + facesWithNodes.elems[1].nodeIds[2] = nodes[6]; + facesWithNodes.elems[1].nodeIds[3] = nodes[7]; + facesWithNodes.elems[1].nbNodes = 4; + facesWithNodes.elems[1].vtkType = VTK_QUAD; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[1]; + facesWithNodes.elems[2].nodeIds[2] = nodes[5]; + facesWithNodes.elems[2].nodeIds[3] = nodes[4]; + facesWithNodes.elems[2].nbNodes = 4; + facesWithNodes.elems[2].vtkType = VTK_QUAD; + + facesWithNodes.elems[3].nodeIds[0] = nodes[1]; + facesWithNodes.elems[3].nodeIds[1] = nodes[2]; + facesWithNodes.elems[3].nodeIds[2] = nodes[6]; + facesWithNodes.elems[3].nodeIds[3] = nodes[5]; + facesWithNodes.elems[3].nbNodes = 4; + facesWithNodes.elems[3].vtkType = VTK_QUAD; + + facesWithNodes.elems[4].nodeIds[0] = nodes[2]; + facesWithNodes.elems[4].nodeIds[1] = nodes[6]; + facesWithNodes.elems[4].nodeIds[2] = nodes[7]; + facesWithNodes.elems[4].nodeIds[3] = nodes[3]; + facesWithNodes.elems[4].nbNodes = 4; + facesWithNodes.elems[4].vtkType = VTK_QUAD; + + facesWithNodes.elems[5].nodeIds[0] = nodes[3]; + facesWithNodes.elems[5].nodeIds[1] = nodes[7]; + facesWithNodes.elems[5].nodeIds[2] = nodes[4]; + facesWithNodes.elems[5].nodeIds[3] = nodes[0]; + facesWithNodes.elems[5].nbNodes = 4; + facesWithNodes.elems[5].vtkType = VTK_QUAD; +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadHexa::SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 6) +{ + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); +} + +SMDS_DownQuadHexa::~SMDS_DownQuadHexa() +{ +} + +void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + // TODO +} + +void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The ordering of the twenty points defining the quadratic hexahedron cell is point id's (0-7,8-19) + * where point id's 0-7 are the eight corner vertices of the cube, followed by twelve mid-edge nodes (8-19). + * Note that these mid-edge nodes lie on the edges defined by + * (0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7). + * @see vtkQuadraticHexahedron.h in Filtering + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownQuadHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 6; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nodeIds[4] = nodes[8]; + facesWithNodes.elems[0].nodeIds[5] = nodes[9]; + facesWithNodes.elems[0].nodeIds[6] = nodes[10]; + facesWithNodes.elems[0].nodeIds[7] = nodes[11]; + facesWithNodes.elems[0].nbNodes = 8; + facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[4]; + facesWithNodes.elems[1].nodeIds[1] = nodes[5]; + facesWithNodes.elems[1].nodeIds[2] = nodes[6]; + facesWithNodes.elems[1].nodeIds[3] = nodes[7]; + facesWithNodes.elems[1].nodeIds[4] = nodes[12]; + facesWithNodes.elems[1].nodeIds[5] = nodes[13]; + facesWithNodes.elems[1].nodeIds[6] = nodes[14]; + facesWithNodes.elems[1].nodeIds[7] = nodes[15]; + facesWithNodes.elems[1].nbNodes = 8; + facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[1]; + facesWithNodes.elems[2].nodeIds[2] = nodes[5]; + facesWithNodes.elems[2].nodeIds[3] = nodes[4]; + facesWithNodes.elems[2].nodeIds[4] = nodes[8]; + facesWithNodes.elems[2].nodeIds[5] = nodes[17]; + facesWithNodes.elems[2].nodeIds[6] = nodes[12]; + facesWithNodes.elems[2].nodeIds[7] = nodes[16]; + facesWithNodes.elems[2].nbNodes = 8; + facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[3].nodeIds[0] = nodes[1]; + facesWithNodes.elems[3].nodeIds[1] = nodes[2]; + facesWithNodes.elems[3].nodeIds[2] = nodes[6]; + facesWithNodes.elems[3].nodeIds[3] = nodes[5]; + facesWithNodes.elems[3].nodeIds[4] = nodes[9]; + facesWithNodes.elems[3].nodeIds[5] = nodes[18]; + facesWithNodes.elems[3].nodeIds[6] = nodes[13]; + facesWithNodes.elems[3].nodeIds[7] = nodes[17]; + facesWithNodes.elems[3].nbNodes = 8; + facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[4].nodeIds[0] = nodes[2]; + facesWithNodes.elems[4].nodeIds[1] = nodes[6]; + facesWithNodes.elems[4].nodeIds[2] = nodes[7]; + facesWithNodes.elems[4].nodeIds[3] = nodes[3]; + facesWithNodes.elems[4].nodeIds[4] = nodes[18]; + facesWithNodes.elems[4].nodeIds[5] = nodes[14]; + facesWithNodes.elems[4].nodeIds[6] = nodes[19]; + facesWithNodes.elems[4].nodeIds[7] = nodes[10]; + facesWithNodes.elems[4].nbNodes = 8; + facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[5].nodeIds[0] = nodes[3]; + facesWithNodes.elems[5].nodeIds[1] = nodes[7]; + facesWithNodes.elems[5].nodeIds[2] = nodes[4]; + facesWithNodes.elems[5].nodeIds[3] = nodes[0]; + facesWithNodes.elems[5].nodeIds[4] = nodes[19]; + facesWithNodes.elems[5].nodeIds[5] = nodes[15]; + facesWithNodes.elems[5].nodeIds[6] = nodes[16]; + facesWithNodes.elems[5].nodeIds[7] = nodes[11]; + facesWithNodes.elems[5].nbNodes = 8; + facesWithNodes.elems[5].vtkType = VTK_QUADRATIC_QUAD; +} + +// --------------------------------------------------------------------------- + diff --git a/src/SMDS/SMDS_Downward.hxx b/src/SMDS/SMDS_Downward.hxx new file mode 100644 index 000000000..d9b12a054 --- /dev/null +++ b/src/SMDS/SMDS_Downward.hxx @@ -0,0 +1,363 @@ +/* + * SMDS_Downward.hxx + * + * Created on: Jun 3, 2010 + * Author: prascle + */ + +#ifndef SMDS_DOWNWARD_HXX_ +#define SMDS_DOWNWARD_HXX_ + +#include "SMDS_UnstructuredGrid.hxx" + +#include +#include + +typedef struct +{ + int nodeIds[8]; //!< max number of nodes in a face or edge: quad quad = 8 + int nbNodes; + unsigned char vtkType; +} ElemByNodesType; // TODO resize for polyhedrons + +typedef struct +{ + ElemByNodesType elems[6]; //!< max number of faces in a volume or edges in a face : hexahedron = 6 + int nbElems; +} ListElemByNodesType; // TODO resize for polyhedrons + +class DownIdType +{ +public: + DownIdType(int a, unsigned char b) : + cellId(a), cellType(b) + { + } + int cellId; + unsigned char cellType; +}; + +struct DownIdCompare +{ + bool operator ()(const DownIdType e1, const DownIdType e2) const + { + if (e1.cellId == e2.cellId) + return (e1.cellType < e2.cellType); + else + return (e1.cellId < e2.cellId); + } +}; + +class SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; + friend class SMDS_Down2D; + friend class SMDS_Down3D; +public: + virtual int getNumberOfDownCells(int cellId); + virtual const int* getDownCells(int cellId); + virtual const unsigned char* getDownTypes(int cellId); + virtual int getNumberOfUpCells(int cellId) = 0; + virtual const int* getUpCells(int cellId) = 0; + virtual const unsigned char* getUpTypes(int cellId) = 0; + virtual void getNodeIds(int cellId, std::set& nodeSet) = 0; + int getVtkCellId(int cellId) + { + return _vtkCellIds[cellId]; + } + int getMaxId() + { + return _maxId; + } + static int getCellDimension(unsigned char cellType); +protected: + SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Downward(); + int addCell(int vtkId = -1); + virtual void initCell(int cellId); + virtual void allocate(int nbElems) = 0; + virtual void compactStorage() = 0; + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's + virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's + virtual int getNodeSet(int cellId, int* nodeSet); + + SMDS_UnstructuredGrid* _grid; + int _maxId; + int _nbDownCells; //!< the same number for all cells of a derived class + std::vector _cellIds; //!< growing size: all the down cell id's, size = _maxId * _nbDownCells + std::vector _vtkCellIds; //!< growing size: size = _maxId, either vtkId or -1 + std::vector _cellTypes; //!< fixed size: the same vector for all cells of a derived class + + static std::vector _cellDimension; //!< conversion table: type --> dimension +}; + +class SMDS_Down1D: public SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; +public: + virtual int getNumberOfUpCells(int cellId); + virtual const int* getUpCells(int cellId); + virtual const unsigned char* getUpTypes(int cellId); + virtual void getNodeIds(int cellId, std::set& nodeSet); +protected: + SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Down1D(); + virtual void initCell(int cellId); + virtual void allocate(int nbElems); + virtual void compactStorage(); + virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's + virtual int getNodeSet(int cellId, int* nodeSet); + void setNodes(int cellId, int vtkId); + void setNodes(int cellId, const int* nodeIds); + int computeVtkCells(int cellId, std::vector& vtkIds); + int computeVtkCells(int* pts, std::vector& vtkIds); + int computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes); + int computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes); + + std::vector > _upCellIdsVector; //!< the number of faces sharing an edge is not known + std::vector > _upCellTypesVector; //!< the number of faces sharing an edge is not known + std::vector _upCellIds; //!< compacted storage after connectivity calculation + std::vector _upCellTypes; //!< compacted storage after connectivity calculation + std::vector _upCellIndex; //!< compacted storage after connectivity calculation +}; + +class SMDS_Down2D: public SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; + friend class SMDS_Down1D; +public: + virtual int getNumberOfUpCells(int cellId); + virtual const int* getUpCells(int cellId); + virtual const unsigned char* getUpTypes(int cellId); + virtual void getNodeIds(int cellId, std::set& nodeSet); +protected: + SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Down2D(); + virtual void allocate(int nbElems); + virtual void compactStorage(); + virtual void addUpCell(int cellId, int upCellId, unsigned char aType); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0; + virtual int getNodeSet(int cellId, int* nodeSet); + int computeVolumeIds(int cellId, int* ids); + int computeVolumeIds(ElemByNodesType& faceByNodes, int* ids); + int computeVolumeIdsFromNodesFace(int* nodes, int nbNodes, int* ids); + void setTempNodes(int cellId, int vtkId); + void setTempNodes(int cellId, ElemByNodesType& faceByNodes); + bool isInFace(int cellId, int *pts, int npts); + int FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes); + + std::vector _upCellIds; //!< 2 volumes max. per face + std::vector _upCellTypes; //!< 2 volume types per face + std::vector _tempNodes; //!< temporary storage of nodes, until downward connectivity completion + int _nbNodes; //!< number of nodes in a face +}; + +class SMDS_Down3D: public SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; +public: + virtual int getNumberOfUpCells(int cellId); + virtual const int* getUpCells(int cellId); + virtual const unsigned char* getUpTypes(int cellId); + virtual void getNodeIds(int cellId, std::set& nodeSet); + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) = 0; +protected: + SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Down3D(); + virtual void allocate(int nbElems); + virtual void compactStorage(); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0; + int FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes); +}; + +class SMDS_DownEdge: public SMDS_Down1D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownEdge(SMDS_UnstructuredGrid *grid); + ~SMDS_DownEdge(); +}; + +class SMDS_DownQuadEdge: public SMDS_Down1D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadEdge(); +}; + +class SMDS_DownTriangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownTriangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownTriangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +class SMDS_DownQuadTriangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadTriangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +class SMDS_DownQuadrangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadrangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +class SMDS_DownQuadQuadrangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadQuadrangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +//class SMDS_DownPolygon: public SMDS_Down2D +//{ +//public: +// SMDS_DownPolygon(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownPolygon(); +//protected: +//}; + +//class SMDS_DownQuadPolygon: public SMDS_Down2D +//{ +//public: +// SMDS_DownQuadPolygon(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownQuadPolygon(); +//protected: +//}; + +class SMDS_DownTetra: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownTetra(SMDS_UnstructuredGrid *grid); + ~SMDS_DownTetra(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadTetra: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadTetra(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownPyramid: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownPyramid(SMDS_UnstructuredGrid *grid); + ~SMDS_DownPyramid(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadPyramid: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadPyramid(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownPenta: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownPenta(SMDS_UnstructuredGrid *grid); + ~SMDS_DownPenta(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadPenta: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadPenta(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownHexa: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownHexa(SMDS_UnstructuredGrid *grid); + ~SMDS_DownHexa(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadHexa: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadHexa(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +//class SMDS_DownPolyhedra: public SMDS_Down3D +//{ +//public: +// SMDS_DownPolyhedra(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownPolyhedra(); +//protected: +//}; + +//class SMDS_DownQuadPolyhedra: public SMDS_Down3D +//{ +//public: +// SMDS_DownQuadPolyhedra(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownQuadPolyhedra(); +//protected: +//}; + +#endif /* SMDS_DOWNWARD_HXX_ */ diff --git a/src/SMDS/SMDS_EdgePosition.cxx b/src/SMDS/SMDS_EdgePosition.cxx index 76df7471c..1f96b7483 100644 --- a/src/SMDS/SMDS_EdgePosition.cxx +++ b/src/SMDS/SMDS_EdgePosition.cxx @@ -36,32 +36,22 @@ using namespace std; //purpose : //======================================================================= -SMDS_EdgePosition::SMDS_EdgePosition(const int aEdgeId, - const double aUParam):SMDS_Position(aEdgeId), myUParameter(aUParam) +SMDS_EdgePosition::SMDS_EdgePosition(const double aUParam): myUParameter(aUParam) { -} - -//======================================================================= -//function : Coords -//purpose : -//======================================================================= - -const double *SMDS_EdgePosition::Coords() const -{ - static double origin[]={0,0,0}; - MESSAGE("SMDS_EdgePosition::Coords not implemented"); - return origin; + //MESSAGE("********************************* SMDS_EdgePosition " << myUParameter); } /** */ SMDS_TypeOfPosition SMDS_EdgePosition::GetTypeOfPosition() const { + //MESSAGE("###################################### SMDS_EdgePosition::GetTypeOfPosition"); return SMDS_TOP_EDGE; } void SMDS_EdgePosition::SetUParameter(double aUparam) { + //MESSAGE("############################### SMDS_EdgePosition::SetUParameter " << aUparam); myUParameter = aUparam; } @@ -72,5 +62,6 @@ void SMDS_EdgePosition::SetUParameter(double aUparam) double SMDS_EdgePosition::GetUParameter() const { + //MESSAGE("########################## SMDS_EdgePosition::GetUParameter " << myUParameter); return myUParameter; } diff --git a/src/SMDS/SMDS_EdgePosition.hxx b/src/SMDS/SMDS_EdgePosition.hxx index 8c2148dfe..dc4afa983 100644 --- a/src/SMDS/SMDS_EdgePosition.hxx +++ b/src/SMDS/SMDS_EdgePosition.hxx @@ -35,8 +35,7 @@ class SMDS_EXPORT SMDS_EdgePosition:public SMDS_Position { public: - SMDS_EdgePosition(const int aEdgeId=0, const double aUParam=0); - const virtual double * Coords() const; + SMDS_EdgePosition(const double aUParam=0); SMDS_TypeOfPosition GetTypeOfPosition() const; void SetUParameter(double aUparam); double GetUParameter() const; diff --git a/src/SMDS/SMDS_FaceOfEdges.cxx b/src/SMDS/SMDS_FaceOfEdges.cxx index 2d545861d..c02ad1a2b 100644 --- a/src/SMDS/SMDS_FaceOfEdges.cxx +++ b/src/SMDS/SMDS_FaceOfEdges.cxx @@ -29,6 +29,7 @@ #include "SMDS_FaceOfEdges.hxx" #include "SMDS_IteratorOfElements.hxx" #include "SMDS_MeshNode.hxx" +#include "utilities.h" using namespace std; @@ -111,6 +112,7 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, const SMDS_MeshEdge* edge2, const SMDS_MeshEdge* edge3) { + //MESSAGE("****************************************************** SMDS_FaceOfEdges"); myNbEdges = 3; myEdges[0]=edge1; myEdges[1]=edge2; @@ -123,6 +125,7 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, const SMDS_MeshEdge* edge3, const SMDS_MeshEdge* edge4) { + //MESSAGE("****************************************************** SMDS_FaceOfEdges"); myNbEdges = 4; myEdges[0]=edge1; myEdges[1]=edge2; diff --git a/src/SMDS/SMDS_FaceOfEdges.hxx b/src/SMDS/SMDS_FaceOfEdges.hxx index 91acdb17a..bb757e852 100644 --- a/src/SMDS/SMDS_FaceOfEdges.hxx +++ b/src/SMDS/SMDS_FaceOfEdges.hxx @@ -20,7 +20,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMDS : implementaion of Salome mesh data structure +// SMESH SMDS : implementation of Salome mesh data structure // #ifndef _SMDS_FaceOfEdges_HeaderFile #define _SMDS_FaceOfEdges_HeaderFile @@ -48,6 +48,7 @@ class SMDS_EXPORT SMDS_FaceOfEdges:public SMDS_MeshFace SMDSAbs_ElementType GetType() const; virtual SMDSAbs_EntityType GetEntityType() const; + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;}; int NbNodes() const; int NbEdges() const; int NbFaces() const; diff --git a/src/SMDS/SMDS_FaceOfNodes.cxx b/src/SMDS/SMDS_FaceOfNodes.cxx index d92a89a3e..ce99398ca 100644 --- a/src/SMDS/SMDS_FaceOfNodes.cxx +++ b/src/SMDS/SMDS_FaceOfNodes.cxx @@ -133,6 +133,7 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1, const SMDS_MeshNode* node2, const SMDS_MeshNode* node3) { + //MESSAGE("******************************************************* SMDS_FaceOfNodes"); myNbNodes = 3; myNodes[0]=node1; myNodes[1]=node2; @@ -145,6 +146,7 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1, const SMDS_MeshNode* node3, const SMDS_MeshNode* node4) { + //MESSAGE("******************************************************* SMDS_FaceOfNodes"); myNbNodes = 4; myNodes[0]=node1; myNodes[1]=node2; diff --git a/src/SMDS/SMDS_FacePosition.cxx b/src/SMDS/SMDS_FacePosition.cxx index da93899b6..01421cb6f 100644 --- a/src/SMDS/SMDS_FacePosition.cxx +++ b/src/SMDS/SMDS_FacePosition.cxx @@ -36,23 +36,11 @@ using namespace std; //purpose : //======================================================================= -SMDS_FacePosition::SMDS_FacePosition(const int aEdgeId, - const double aUParam, +SMDS_FacePosition::SMDS_FacePosition(const double aUParam, const double aVParam) - :SMDS_Position(aEdgeId), - myUParameter(aUParam),myVParameter(aVParam) + : myUParameter(aUParam),myVParameter(aVParam) { -} - -//======================================================================= -//function : Coords -//purpose : -//======================================================================= -const double *SMDS_FacePosition::Coords() const -{ - static double origin[]={0,0,0}; - MESSAGE("SMDS_EdgePosition::Coords not implemented"); - return origin; + //MESSAGE("******************************************************** SMDS_FacePosition"); } /** diff --git a/src/SMDS/SMDS_FacePosition.hxx b/src/SMDS/SMDS_FacePosition.hxx index 1b8967dc0..4efb60684 100644 --- a/src/SMDS/SMDS_FacePosition.hxx +++ b/src/SMDS/SMDS_FacePosition.hxx @@ -35,9 +35,7 @@ class SMDS_EXPORT SMDS_FacePosition:public SMDS_Position { public: - SMDS_FacePosition(int aFaceId=0, double aUParam=0, - double aVParam=0); - const virtual double * Coords() const; + SMDS_FacePosition(double aUParam=0, double aVParam=0); SMDS_TypeOfPosition GetTypeOfPosition() const; void SetUParameter(double aUparam); void SetVParameter(double aVparam); diff --git a/src/SMDS/SMDS_LinearEdge.cxx b/src/SMDS/SMDS_LinearEdge.cxx new file mode 100644 index 000000000..7bb1ea2ae --- /dev/null +++ b/src/SMDS/SMDS_LinearEdge.cxx @@ -0,0 +1,163 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_LinearEdge.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_LinearEdge.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : SMDS_LinearEdge +//purpose : +//======================================================================= + +SMDS_LinearEdge::SMDS_LinearEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) +{ + //MESSAGE("SMDS_LinearEdge " << GetID()); + myNodes[0] = node1; + myNodes[1] = node2; +} + +//======================================================================= +//function : Print +//purpose : +//======================================================================= + +void SMDS_LinearEdge::Print(ostream & OS) const +{ + OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1] + << ") " << endl; +} + +int SMDS_LinearEdge::NbNodes() const +{ + return 2; +} + +int SMDS_LinearEdge::NbEdges() const +{ + return 1; +} + +class SMDS_LinearEdge_MyNodeIterator: public SMDS_ElemIterator +{ + const SMDS_MeshNode * const * myNodes; + int myIndex; +public: + SMDS_LinearEdge_MyNodeIterator(const SMDS_MeshNode * const * nodes) : + myNodes(nodes), myIndex(0) + { + } + + bool more() + { + return myIndex < 2; + } + + const SMDS_MeshElement* next() + { + myIndex++; + return myNodes[myIndex - 1]; + } +}; + +SMDS_ElemIteratorPtr SMDS_LinearEdge::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Edge: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_LinearEdge_MyNodeIterator(myNodes)); + default: + return SMDS_ElemIteratorPtr( + new SMDS_IteratorOfElements( + this, + type, + SMDS_ElemIteratorPtr( + new SMDS_LinearEdge_MyNodeIterator( + myNodes)))); + } +} + +bool operator<(const SMDS_LinearEdge & e1, const SMDS_LinearEdge & e2) +{ + int id11 = e1.myNodes[0]->getVtkId(); + int id21 = e2.myNodes[0]->getVtkId(); + int id12 = e1.myNodes[1]->getVtkId(); + int id22 = e2.myNodes[1]->getVtkId(); + int tmp; + + if (id11 >= id12) + { + tmp = id11; + id11 = id12; + id12 = tmp; + } + if (id21 >= id22) + { + tmp = id21; + id21 = id22; + id22 = tmp; + } + + if (id11 < id21) + return true; + else if (id11 == id21) + return (id21 < id22); + else + return false; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_LinearEdge::GetNode(const int ind) const +{ + return myNodes[ind]; +} + +//======================================================================= +//function : ChangeNodes +//purpose : +//======================================================================= + +bool SMDS_LinearEdge::ChangeNodes(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) +{ + myNodes[0] = node1; + myNodes[1] = node2; + return true; +} diff --git a/src/SMDS/SMDS_LinearEdge.hxx b/src/SMDS/SMDS_LinearEdge.hxx new file mode 100644 index 000000000..e7c66d7cf --- /dev/null +++ b/src/SMDS/SMDS_LinearEdge.hxx @@ -0,0 +1,69 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_LinearEdge.hxx +// Module : SMESH +// +#ifndef _SMDS_LinearEdge_HeaderFile +#define _SMDS_LinearEdge_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshEdge.hxx" +#include + +class SMDS_EXPORT SMDS_LinearEdge: public SMDS_MeshEdge +{ + +public: + SMDS_LinearEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + void Print(std::ostream & OS) const; + + virtual SMDSAbs_EntityType GetEntityType() const + { + return SMDSEntity_Edge; + } + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) + { + return false; + } + int NbNodes() const; + int NbEdges() const; + friend bool operator<(const SMDS_LinearEdge& e1, const SMDS_LinearEdge& e2); + + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + +protected: + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + +protected: + const SMDS_MeshNode* myNodes[3]; + +}; +#endif diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index d3d41b135..d6f7e1813 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -20,7 +20,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMDS : implementaion of Salome mesh data structure +// SMESH SMDS : implementation of Salome mesh data structure // #ifdef _MSC_VER #pragma warning(disable:4786) @@ -37,18 +37,33 @@ #include "SMDS_QuadraticEdge.hxx" #include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_QuadraticVolumeOfNodes.hxx" +#include "SMDS_SpacePosition.hxx" +#include "SMDS_UnstructuredGrid.hxx" + +#include +#include +#include +#include +#include +#include #include #include +#include +#include using namespace std; #ifndef WIN32 #include #endif -// number of added entitis to check memory after +// number of added entities to check memory after #define CHECKMEMORY_INTERVAL 1000 +vector SMDS_Mesh::_meshList = vector(); +int SMDS_Mesh::chunkSize = 1024; + + //================================================================================ /*! * \brief Raise an exception if free memory (ram+swap) too low @@ -105,11 +120,45 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::SMDS_Mesh() :myParent(NULL), - myNodeIDFactory(new SMDS_MeshElementIDFactory()), - myElementIDFactory(new SMDS_MeshElementIDFactory()), - myHasConstructionEdges(false), myHasConstructionFaces(false), - myHasInverseElements(true) -{ + myNodeIDFactory(new SMDS_MeshNodeIDFactory()), + myElementIDFactory(new SMDS_MeshElementIDFactory()), + myHasConstructionEdges(false), myHasConstructionFaces(false), + myHasInverseElements(true), + myNodeMin(0), myNodeMax(0), + myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0), + myModified(false), myModifTime(0), myCompactTime(0), + xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0) +{ + myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector + MESSAGE("myMeshId=" << myMeshId); + MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) ); + MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) ); + MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) ); + MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) ); + MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) ); + MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) ); + myNodeIDFactory->SetMesh(this); + myElementIDFactory->SetMesh(this); + _meshList.push_back(this); + myNodePool = new ObjectPool(SMDS_Mesh::chunkSize); + myEdgePool = new ObjectPool(SMDS_Mesh::chunkSize); + myFacePool = new ObjectPool(SMDS_Mesh::chunkSize); + myVolumePool = new ObjectPool(SMDS_Mesh::chunkSize); + + myNodes.clear(); + myCells.clear(); + //myCellIdSmdsToVtk.clear(); + myCellIdVtkToSmds.clear(); + myGrid = SMDS_UnstructuredGrid::New(); + myGrid->setSMDS_mesh(this); + myGrid->Initialize(); + myGrid->Allocate(); + vtkPoints* points = vtkPoints::New(); + points->SetNumberOfPoints(SMDS_Mesh::chunkSize); + myGrid->SetPoints( points ); + points->Delete(); + myGrid->BuildLinks(); + this->Modified(); } /////////////////////////////////////////////////////////////////////////////// @@ -119,9 +168,13 @@ SMDS_Mesh::SMDS_Mesh() /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent) :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory), - myElementIDFactory(parent->myElementIDFactory), - myHasConstructionEdges(false), myHasConstructionFaces(false), - myHasInverseElements(true) + myElementIDFactory(parent->myElementIDFactory), + myHasConstructionEdges(false), myHasConstructionFaces(false), + myHasInverseElements(true), + myNodePool(parent->myNodePool), + myEdgePool(parent->myEdgePool), + myFacePool(parent->myFacePool), + myVolumePool(parent->myVolumePool) { } @@ -157,11 +210,25 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) // find the MeshNode corresponding to ID const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); if(!node){ - if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z); - myNodes.Add(node); + // TODO ID < 1 + if (ID <= 0) + { + MESSAGE("=============> Bad Node Id: " << ID); + ID = myNodeIDFactory->GetFreeID(); + } + myNodeIDFactory->adjustMaxId(ID); + SMDS_MeshNode * node = myNodePool->getNew(); + node->init(ID, myMeshId, 0, x, y, z); + if (ID >= myNodes.size()) + { + myNodes.resize(ID+SMDS_Mesh::chunkSize, 0); + MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize); + } + myNodes[ID] = node; myNodeIDFactory->BindID(ID,node); myInfo.myNbNodes++; + myModified = true; + this->adjustBoundingBox(x, y, z); return node; }else return NULL; @@ -198,13 +265,14 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int I { if (!n) return 0; - if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); - + //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); + //MESSAGE("Add0DElementWithID" << ID) SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n); if (myElementIDFactory->BindID(ID, el0d)) { SMDS_MeshNode *node = const_cast(n); - node->AddInverseElement(el0d); - my0DElements.Add(el0d); + //node->AddInverseElement(el0d);// --- fait avec BindID + adjustmyCellsCapacity(ID); + myCells[ID] = el0d; myInfo.myNb0DElements++; return el0d; } @@ -251,24 +319,33 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, int ID) { if ( !n1 || !n2 ) return 0; + SMDS_MeshEdge * edge = 0; - if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + // --- retreive nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); - SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2); - if(myElementIDFactory->BindID(ID, edge)) { - SMDS_MeshNode *node1,*node2; - node1=const_cast(n1); - node2=const_cast(n2); - node1->AddInverseElement(edge); - node2->AddInverseElement(edge); - myEdges.Add(edge); - myInfo.myNbEdges++; - return edge; - } - else { - delete edge; - return NULL; - } + SMDS_VtkEdge *edgevtk = myEdgePool->getNew(); + edgevtk->init(nodeIds, this); + if (!this->registerElement(ID,edgevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL); + myEdgePool->destroy(edgevtk); + return 0; + } + edge = edgevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = edge; + myInfo.myNbEdges++; + +// if (edge && !registerElement(ID, edge)) +// { +// RemoveElement(edge, false); +// edge = NULL; +// } + return edge; } /////////////////////////////////////////////////////////////////////////////// @@ -305,12 +382,13 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n3, int ID) { - SMDS_MeshFace * face=createTriangle(n1, n2, n3); + //MESSAGE("AddFaceWithID " << ID) + SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID); - if (face && !registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; - } +// if (face && !registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } return face; } @@ -356,12 +434,13 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, int ID) { - SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4); + //MESSAGE("AddFaceWithID " << ID); + SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID); - if (face && !registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; - } +// if (face && !registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } return face; } @@ -376,7 +455,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, { if (!hasConstructionEdges()) return NULL; - return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID()); + //MESSAGE("AddFaceWithID"); + return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -392,15 +472,18 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, return NULL; if ( !e1 || !e2 || !e3 ) return 0; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + MESSAGE("AddFaceWithID" << ID); SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); - myFaces.Add(face); + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbTriangles++; if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + registerElement(myElementIDFactory->GetFreeID(), face); + //RemoveElement(face, false); + //face = NULL; } return face; } @@ -417,7 +500,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, { if (!hasConstructionEdges()) return NULL; - return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID()); + //MESSAGE("AddFaceWithID" ); + return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -432,16 +516,19 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, { if (!hasConstructionEdges()) return NULL; + MESSAGE("AddFaceWithID" << ID); if ( !e1 || !e2 || !e3 || !e4 ) return 0; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); - myFaces.Add(face); + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbQuadrangles++; if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + registerElement(myElementIDFactory->GetFreeID(), face); + //RemoveElement(face, false); + //face = NULL; } return face; } @@ -457,6 +544,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4) { int ID = myElementIDFactory->GetFreeID(); + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID); if(v==NULL) myElementIDFactory->ReleaseID(ID); return v; @@ -475,6 +563,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode4, int ID) { + //MESSAGE("AddVolumeWithID" << ID); SMDS_MeshNode *node1, *node2, *node3, *node4; node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); @@ -496,16 +585,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4) return volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4); SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4); SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbTetras++; } else if(hasConstructionEdges()) { @@ -513,15 +604,32 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return NULL; } else { - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbTetras++; } - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } +// if (!registerElement(ID, volume)) { +// RemoveElement(volume, false); +// volume = NULL; +// } return volume; } @@ -538,6 +646,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5) { int ID = myElementIDFactory->GetFreeID(); + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID); if(v==NULL) myElementIDFactory->ReleaseID(ID); return v; @@ -558,6 +667,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode5, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); @@ -582,16 +692,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5); SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5); SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPyramids++; } else if(hasConstructionEdges()) { @@ -599,15 +711,33 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return NULL; } else { - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPyramids++; } - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } +// if (!registerElement(ID, volume)) { +// RemoveElement(volume, false); +// volume = NULL; +// } return volume; } @@ -625,6 +755,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n6) { int ID = myElementIDFactory->GetFreeID(); + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); if(v==NULL) myElementIDFactory->ReleaseID(ID); return v; @@ -646,6 +777,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode6, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); @@ -672,9 +804,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n6, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6); @@ -682,7 +815,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3); SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPrisms++; } else if(hasConstructionEdges()) { @@ -690,15 +824,34 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return NULL; } else { - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPrisms++; } - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } +// if (!registerElement(ID, volume)) { +// RemoveElement(volume, false); +// volume = NULL; +// } return volume; } @@ -718,7 +871,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n8) { int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); + //MESSAGE("AddVolumeWithID " << ID); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); if(v==NULL) myElementIDFactory->ReleaseID(ID); return v; } @@ -741,6 +895,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode8, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); @@ -774,9 +929,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n8, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8); @@ -785,7 +941,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6); SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbHexas++; } else if(hasConstructionEdges()) { @@ -793,16 +950,36 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return NULL; } else { -// volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n8->getVtkId()); + nodeIds.push_back(n7->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbHexas++; } - - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } + +// if (!registerElement(ID, volume)) { +// RemoveElement(volume, false); +// volume = NULL; +// } return volume; } @@ -816,6 +993,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, const SMDS_MeshFace * f3, const SMDS_MeshFace * f4) { + //MESSAGE("AddVolumeWithID"); if (!hasConstructionFaces()) return NULL; return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID()); @@ -833,17 +1011,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, const SMDS_MeshFace * f4, int ID) { + MESSAGE("AddVolumeWithID" << ID); if (!hasConstructionFaces()) return NULL; if ( !f1 || !f2 || !f3 || !f4) return 0; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbTetras++; if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + registerElement(myElementIDFactory->GetFreeID(), volume); + //RemoveElement(volume, false); + //volume = NULL; } return volume; } @@ -859,7 +1040,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, const SMDS_MeshFace * f4, const SMDS_MeshFace * f5) { - if (!hasConstructionFaces()) + //MESSAGE("AddVolumeWithID"); + if (!hasConstructionFaces()) return NULL; return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID()); } @@ -877,17 +1059,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, const SMDS_MeshFace * f5, int ID) { + MESSAGE("AddVolumeWithID" << ID); if (!hasConstructionFaces()) return NULL; if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPyramids++; if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + registerElement(myElementIDFactory->GetFreeID(), volume); + //RemoveElement(volume, false); + //volume = NULL; } return volume; } @@ -904,7 +1089,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, const SMDS_MeshFace * f5, const SMDS_MeshFace * f6) { - if (!hasConstructionFaces()) + //MESSAGE("AddVolumeWithID" ); + if (!hasConstructionFaces()) return NULL; return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID()); } @@ -923,17 +1109,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, const SMDS_MeshFace * f6, int ID) { + MESSAGE("AddVolumeWithID" << ID); if (!hasConstructionFaces()) return NULL; if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPrisms++; if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + registerElement(myElementIDFactory->GetFreeID(), volume); + //RemoveElement(volume, false); + //volume = NULL; } return volume; } @@ -964,26 +1153,51 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID { SMDS_MeshFace * face; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if (hasConstructionEdges()) - { - MESSAGE("Error : Not implemented"); - return NULL; - } + { + MESSAGE("Error : Not implemented"); + return NULL; + } else - { - for ( int i = 0; i < nodes.size(); ++i ) - if ( !nodes[ i ] ) return 0; - face = new SMDS_PolygonalFaceOfNodes(nodes); - myFaces.Add(face); - myInfo.myNbPolygons++; - } + { +//#ifdef VTK_HAVE_POLYHEDRON + MESSAGE("AddPolygonalFaceWithID vtk " << ID); + vector nodeIds; + nodeIds.clear(); + vector::iterator it = nodes.begin(); + for ( ; it != nodes.end(); ++it) + nodeIds.push_back((*it)->getVtkId()); + + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->initPoly(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; +//#else +// MESSAGE("AddPolygonalFaceWithID smds " << ID); +// for ( int i = 0; i < nodes.size(); ++i ) +// if ( !nodes[ i ] ) return 0; +// face = new SMDS_PolygonalFaceOfNodes(nodes); +//#endif + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbPolygons++; + } - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; - } - return face; +//#ifndef VTK_HAVE_POLYHEDRON +// if (!registerElement(ID, face)) +// { +// registerElement(myElementIDFactory->GetFreeID(), face); +// //RemoveElement(face, false); +// //face = NULL; +// } +//#endif + return face; } /////////////////////////////////////////////////////////////////////////////// @@ -1026,28 +1240,58 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID (vector nodes, vector quantities, - const int ID) + const int ID) { SMDS_MeshVolume* volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (hasConstructionFaces()) { - MESSAGE("Error : Not implemented"); - return NULL; - } else if (hasConstructionEdges()) { - MESSAGE("Error : Not implemented"); - return NULL; - } else { - for ( int i = 0; i < nodes.size(); ++i ) - if ( !nodes[ i ] ) return 0; - volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities); - myVolumes.Add(volume); - myInfo.myNbPolyhedrons++; - } + //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if (hasConstructionFaces()) + { + MESSAGE("Error : Not implemented"); + return NULL; + } + else if (hasConstructionEdges()) + { + MESSAGE("Error : Not implemented"); + return NULL; + } + else + { +//#ifdef VTK_HAVE_POLYHEDRON + MESSAGE("AddPolyhedralVolumeWithID vtk " << ID); + vector nodeIds; + nodeIds.clear(); + vector::iterator it = nodes.begin(); + for (; it != nodes.end(); ++it) + nodeIds.push_back((*it)->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->initPoly(nodeIds, quantities, this); + if (!this->registerElement(ID, volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; +//#else +// MESSAGE("AddPolyhedralVolumeWithID smds " << ID); +// for ( int i = 0; i < nodes.size(); ++i ) +// if ( !nodes[ i ] ) return 0; +// volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities); +//#endif + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbPolyhedrons++; + } - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } +//#ifndef VTK_HAVE_POLYHEDRON +// if (!registerElement(ID, volume)) +// { +// registerElement(myElementIDFactory->GetFreeID(), volume); +// //RemoveElement(volume, false); +// //volume = NULL; +// } +//#endif return volume; } @@ -1066,41 +1310,139 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume return v; } +SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector& vtkNodeIds) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID); + if (v == NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector& vtkNodeIds, const int ID) +{ + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(vtkNodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + vtkIdType aVtkType = volvtk->GetVtkType(); + switch (aVtkType) + { + case VTK_TETRA: + myInfo.myNbTetras++; + break; + case VTK_PYRAMID: + myInfo.myNbPyramids++; + break; + case VTK_WEDGE: + myInfo.myNbPrisms++; + break; + case VTK_HEXAHEDRON: + myInfo.myNbHexas++; + break; + case VTK_QUADRATIC_TETRA: + myInfo.myNbQuadTetras++; + break; + case VTK_QUADRATIC_PYRAMID: + myInfo.myNbQuadPyramids++; + break; + case VTK_QUADRATIC_WEDGE: + myInfo.myNbQuadPrisms++; + break; + case VTK_QUADRATIC_HEXAHEDRON: + myInfo.myNbQuadHexas++; + break; +//#ifdef VTK_HAVE_POLYHEDRON + case VTK_POLYHEDRON: + myInfo.myNbPolyhedrons++; + break; +//#endif + default: + myInfo.myNbPolyhedrons++; + break; + } + return volvtk; +} + /////////////////////////////////////////////////////////////////////////////// /// Registers element with the given ID, maintains inverse connections /////////////////////////////////////////////////////////////////////////////// -bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element) +bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element) { - if (myElementIDFactory->BindID(ID, element)) { - SMDS_ElemIteratorPtr it = element->nodesIterator(); - while (it->more()) { - SMDS_MeshNode *node = static_cast - (const_cast(it->next())); - node->AddInverseElement(element); - } - return true; + //MESSAGE("registerElement " << ID); + if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound + { + MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId()); + return false; } - return false; + + element->myID = ID; + element->myMeshId = myMeshId; + + SMDS_MeshCell *cell = dynamic_cast(element); + MYASSERT(cell); + int vtkId = cell->getVtkId(); + if (vtkId == -1) + vtkId = myElementIDFactory->SetInVtkGrid(element); + + if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector + { + MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize); + myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1); + } + myCellIdVtkToSmds[vtkId] = ID; + + myElementIDFactory->updateMinMax(ID); + return true; } /////////////////////////////////////////////////////////////////////////////// -/// Return the node whose ID is 'ID'. +/// Return the node whose SMDS ID is 'ID'. /////////////////////////////////////////////////////////////////////////////// const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const { - return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID); + if (ID < 1 || ID >= myNodes.size()) + { + MESSAGE("------------------------------------------------------------------------- "); + MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size()); + MESSAGE("------------------------------------------------------------------------- "); + return 0; + } + return (const SMDS_MeshNode *)myNodes[ID]; } /////////////////////////////////////////////////////////////////////////////// -///Create a triangle and add it to the current mesh. This methode do not bind a +/// Return the node whose VTK ID is 'vtkId'. +/////////////////////////////////////////////////////////////////////////////// +const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const +{ + // TODO if needed use mesh->nodeIdFromVtkToSmds + if (vtkId < 0 || vtkId >= (myNodes.size() -1)) + { + MESSAGE("------------------------------------------------------------------------- "); + MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size()); + MESSAGE("------------------------------------------------------------------------- "); + return 0; + } + return (const SMDS_MeshNode *)myNodes[vtkId+1]; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a triangle and add it to the current mesh. This method do not bind an ///ID to the create triangle. /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3) + const SMDS_MeshNode * node3, + int ID) { if ( !node1 || !node2 || !node3) return 0; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); +// if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionEdges()) { SMDS_MeshEdge *edge1, *edge2, *edge3; @@ -1108,15 +1450,35 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, edge2=FindEdgeOrCreate(node2,node3); edge3=FindEdgeOrCreate(node3,node1); + //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3); - myFaces.Add(face); + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbTriangles++; return face; } else { - SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3); - myFaces.Add(face); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(node1->getVtkId()); + nodeIds.push_back(node2->getVtkId()); + nodeIds.push_back(node3->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + //MESSAGE("createTriangle " << ID << " " << face); myInfo.myNbTriangles++; return face; } @@ -1129,12 +1491,14 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4) + const SMDS_MeshNode * node4, + int ID) { if ( !node1 || !node2 || !node3 || !node4 ) return 0; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); +// if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionEdges()) { + //MESSAGE("createQuadrangle hasConstructionEdges "<< ID); SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4; edge1=FindEdgeOrCreate(node1,node2); edge2=FindEdgeOrCreate(node2,node3); @@ -1142,14 +1506,33 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, edge4=FindEdgeOrCreate(node4,node1); SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4); - myFaces.Add(face); + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbQuadrangles++; return face; } else { - SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4); - myFaces.Add(face); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(node1->getVtkId()); + nodeIds.push_back(node2->getVtkId()); + nodeIds.push_back(node3->getVtkId()); + nodeIds.push_back(node4->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbQuadrangles++; return face; } @@ -1161,6 +1544,7 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node) { + MESSAGE("RemoveNode"); RemoveElement(node, true); } @@ -1170,6 +1554,7 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node) void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d) { + MESSAGE("Remove0DElement"); RemoveElement(elem0d,true); } @@ -1179,6 +1564,7 @@ void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d) void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge) { + MESSAGE("RemoveEdge"); RemoveElement(edge,true); } @@ -1188,6 +1574,7 @@ void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge) void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face) { + MESSAGE("RemoveFace"); RemoveElement(face, true); } @@ -1197,6 +1584,7 @@ void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face) void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume) { + MESSAGE("RemoveVolume"); RemoveElement(volume, true); } @@ -1243,58 +1631,21 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, const SMDS_MeshNode * nodes[], const int nbnodes) { + MESSAGE("SMDS_Mesh::ChangeElementNodes"); // keep current nodes of elem set oldNodes; SMDS_ElemIteratorPtr itn = element->nodesIterator(); while(itn->more()) - oldNodes.insert( itn->next() ); - - if ( !element->IsPoly() ) - myInfo.remove( element ); // element may change type + oldNodes.insert(itn->next()); // change nodes bool Ok = false; - SMDS_MeshElement* elem = const_cast(element); - switch ( elem->GetType() ) - { - case SMDSAbs_0DElement: { - if ( SMDS_Mesh0DElement* elem0d = dynamic_cast( elem )) - Ok = elem0d->ChangeNode( nodes[0] ); - break; - } - case SMDSAbs_Edge: { - if ( nbnodes == 2 ) { - if ( SMDS_MeshEdge* edge = dynamic_cast( elem )) - Ok = edge->ChangeNodes( nodes[0], nodes[1] ); - } - else if ( nbnodes == 3 ) { - if ( SMDS_QuadraticEdge* edge = dynamic_cast( elem )) - Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] ); + SMDS_MeshCell* cell = dynamic_cast((SMDS_MeshElement*) element); + if (cell) + { + Ok = cell->vtkOrder(nodes, nbnodes); + Ok = cell->ChangeNodes(nodes, nbnodes); } - break; - } - case SMDSAbs_Face: { - if ( SMDS_FaceOfNodes* face = dynamic_cast( elem )) - Ok = face->ChangeNodes( nodes, nbnodes ); - else - if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast( elem )) - Ok = QF->ChangeNodes( nodes, nbnodes ); - else - if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem)) - Ok = face->ChangeNodes(nodes, nbnodes); - break; - } - case SMDSAbs_Volume: { - if ( SMDS_VolumeOfNodes* vol = dynamic_cast( elem )) - Ok = vol->ChangeNodes( nodes, nbnodes ); - else - if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast( elem )) - Ok = QV->ChangeNodes( nodes, nbnodes ); - break; - } - default: - MESSAGE ( "WRONG ELEM TYPE"); - } if ( Ok ) { // update InverseElements @@ -1305,7 +1656,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, it = oldNodes.find( nodes[i] ); if ( it == oldNodes.end() ) // new node - const_cast( nodes[i] )->AddInverseElement( elem ); + const_cast( nodes[i] )->AddInverseElement( cell ); else // remove from oldNodes a node that remains in elem oldNodes.erase( it ); @@ -1315,13 +1666,10 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, { SMDS_MeshNode * n = static_cast (const_cast( *it )); - n->RemoveInverseElement( elem ); + n->RemoveInverseElement( cell ); } } - if ( !element->IsPoly() ) - myInfo.add( element ); // element may change type - return Ok; } @@ -1338,7 +1686,7 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, return false; } - const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast(elem); + const SMDS_VtkVolume* vol = dynamic_cast(elem); if (!vol) { return false; } @@ -1351,7 +1699,9 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, } // change nodes - bool Ok = const_cast(vol)->ChangeNodes(nodes, quantities); + // TODO remove this function + //bool Ok = const_cast(vol)->ChangeNodes(nodes, quantities); + bool Ok = false; if (!Ok) { return false; } @@ -1412,19 +1762,19 @@ const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node) //function : Find0DElementOrCreate //purpose : //======================================================================= -SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node) -{ - if (!node) return 0; - SMDS_Mesh0DElement * toReturn = NULL; - toReturn = const_cast(Find0DElement(node)); - if (toReturn == NULL) { - if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); - toReturn = new SMDS_Mesh0DElement(node); - my0DElements.Add(toReturn); - myInfo.myNb0DElements++; - } - return toReturn; -} +//SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node) +//{ +// if (!node) return 0; +// SMDS_Mesh0DElement * toReturn = NULL; +// toReturn = const_cast(Find0DElement(node)); +// if (toReturn == NULL) { +// //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); +// toReturn = new SMDS_Mesh0DElement(node); +// my0DElements.Add(toReturn); +// myInfo.myNb0DElements++; +// } +// return toReturn; +//} //======================================================================= @@ -1475,9 +1825,24 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, SMDS_MeshEdge * toReturn=NULL; toReturn=const_cast(FindEdge(node1,node2)); if(toReturn==NULL) { - if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - toReturn=new SMDS_MeshEdge(node1,node2); - myEdges.Add(toReturn); + //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element + adjustmyCellsCapacity(ID); + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(node1->getVtkId()); + nodeIds.push_back(node2->getVtkId()); + + SMDS_VtkEdge *edgevtk = myEdgePool->getNew(); + edgevtk->init(nodeIds, this); + if (!this->registerElement(ID,edgevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL); + myEdgePool->destroy(edgevtk); + return 0; + } + toReturn = edgevtk; + myCells[ID] = toReturn; myInfo.myNbEdges++; } return toReturn; @@ -1574,7 +1939,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, SMDS_MeshFace * toReturn=NULL; toReturn = const_cast(FindFace(node1,node2,node3)); if(toReturn==NULL) { - toReturn = createTriangle(node1,node2,node3); + int ID = myElementIDFactory->GetFreeID(); + toReturn = createTriangle(node1,node2,node3, ID); } return toReturn; } @@ -1632,7 +1998,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, SMDS_MeshFace * toReturn=NULL; toReturn=const_cast(FindFace(node1,node2,node3,node4)); if(toReturn==NULL) { - toReturn=createQuadrangle(node1,node2,node3,node4); + int ID = myElementIDFactory->GetFreeID(); + toReturn=createQuadrangle(node1,node2,node3,node4,ID); } return toReturn; } @@ -1756,7 +2123,16 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const { - return myElementIDFactory->MeshElement(IDelem); + if ((IDelem <= 0) || IDelem >= myCells.size()) + { + MESSAGE("--------------------------------------------------------------------------------- "); + MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size()); + MESSAGE("--------------------------------------------------------------------------------- "); + // TODO raise an exception + //assert(0); + return 0; + } + return myCells[IDelem]; } //======================================================================= @@ -1828,7 +2204,7 @@ void SMDS_Mesh::DumpNodes() const { MESSAGE("dump nodes of mesh : "); SMDS_NodeIteratorPtr itnode=nodesIterator(); - while(itnode->more()) MESSAGE(itnode->next()); + while(itnode->more()) ; //MESSAGE(itnode->next()); } //======================================================================= @@ -1839,7 +2215,7 @@ void SMDS_Mesh::Dump0DElements() const { MESSAGE("dump 0D elements of mesh : "); SMDS_0DElementIteratorPtr it0d = elements0dIterator(); - while(it0d->more()) MESSAGE(it0d->next()); + while(it0d->more()) ; //MESSAGE(it0d->next()); } //======================================================================= @@ -1851,7 +2227,7 @@ void SMDS_Mesh::DumpEdges() const { MESSAGE("dump edges of mesh : "); SMDS_EdgeIteratorPtr itedge=edgesIterator(); - while(itedge->more()) MESSAGE(itedge->next()); + while(itedge->more()) ; //MESSAGE(itedge->next()); } //======================================================================= @@ -1863,7 +2239,7 @@ void SMDS_Mesh::DumpFaces() const { MESSAGE("dump faces of mesh : "); SMDS_FaceIteratorPtr itface=facesIterator(); - while(itface->more()) MESSAGE(itface->next()); + while(itface->more()) ; //MESSAGE(itface->next()); } //======================================================================= @@ -1875,7 +2251,7 @@ void SMDS_Mesh::DumpVolumes() const { MESSAGE("dump volumes of mesh : "); SMDS_VolumeIteratorPtr itvol=volumesIterator(); - while(itvol->more()) MESSAGE(itvol->next()); + while(itvol->more()) ; //MESSAGE(itvol->next()); } //======================================================================= @@ -1933,7 +2309,10 @@ void SMDS_Mesh::DebugStats() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbNodes() const { - return myNodes.Size(); + //MESSAGE(myGrid->GetNumberOfPoints()); + //MESSAGE(myInfo.NbNodes()); + //MESSAGE(myNodeMax); + return myInfo.NbNodes(); } /////////////////////////////////////////////////////////////////////////////// @@ -1941,7 +2320,7 @@ int SMDS_Mesh::NbNodes() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::Nb0DElements() const { - return my0DElements.Size(); + return myInfo.Nb0DElements(); // -PR- a verfier } /////////////////////////////////////////////////////////////////////////////// @@ -1949,7 +2328,7 @@ int SMDS_Mesh::Nb0DElements() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbEdges() const { - return myEdges.Size(); + return myInfo.NbEdges(); // -PR- a verfier } /////////////////////////////////////////////////////////////////////////////// @@ -1957,7 +2336,7 @@ int SMDS_Mesh::NbEdges() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbFaces() const { - return myFaces.Size(); + return myInfo.NbFaces(); // -PR- a verfier } /////////////////////////////////////////////////////////////////////////////// @@ -1965,7 +2344,7 @@ int SMDS_Mesh::NbFaces() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbVolumes() const { - return myVolumes.Size(); + return myInfo.NbVolumes(); // -PR- a verfier } /////////////////////////////////////////////////////////////////////////////// @@ -2000,43 +2379,49 @@ SMDS_Mesh::~SMDS_Mesh() { SMDS_ElemIteratorPtr eIt = elementsIterator(); while ( eIt->more() ) - myElementIDFactory->ReleaseID(eIt->next()->GetID()); + { + const SMDS_MeshElement *elem = eIt->next(); + myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId()); + } SMDS_NodeIteratorPtr itn = nodesIterator(); while (itn->more()) - myNodeIDFactory->ReleaseID(itn->next()->GetID()); + { + const SMDS_MeshNode *node = itn->next(); + myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId()); + } } - SetOfNodes::Iterator itn(myNodes); - for (; itn.More(); itn.Next()) - delete itn.Value(); +// SetOfNodes::Iterator itn(myNodes); +// for (; itn.More(); itn.Next()) +// delete itn.Value(); - SetOf0DElements::Iterator it0d (my0DElements); - for (; it0d.More(); it0d.Next()) - { - SMDS_MeshElement* elem = it0d.Value(); - delete elem; - } +// SetOf0DElements::Iterator it0d (my0DElements); +// for (; it0d.More(); it0d.Next()) +// { +// SMDS_MeshElement* elem = it0d.Value(); +// delete elem; +// } - SetOfEdges::Iterator ite(myEdges); - for (; ite.More(); ite.Next()) - { - SMDS_MeshElement* elem = ite.Value(); - delete elem; - } +// SetOfEdges::Iterator ite(myEdges); +// for (; ite.More(); ite.Next()) +// { +// SMDS_MeshElement* elem = ite.Value(); +// delete elem; +// } - SetOfFaces::Iterator itf(myFaces); - for (; itf.More(); itf.Next()) - { - SMDS_MeshElement* elem = itf.Value(); - delete elem; - } +// SetOfFaces::Iterator itf(myFaces); +// for (; itf.More(); itf.Next()) +// { +// SMDS_MeshElement* elem = itf.Value(); +// delete elem; +// } - SetOfVolumes::Iterator itv(myVolumes); - for (; itv.More(); itv.Next()) - { - SMDS_MeshElement* elem = itv.Value(); - delete elem; - } +// SetOfVolumes::Iterator itv(myVolumes); +// for (; itv.More(); itv.Next()) +// { +// SMDS_MeshElement* elem = itv.Value(); +// delete elem; +// } } //================================================================================ @@ -2047,49 +2432,81 @@ SMDS_Mesh::~SMDS_Mesh() void SMDS_Mesh::Clear() { - if (myParent!=NULL) { + MESSAGE("SMDS_Mesh::Clear"); + if (myParent!=NULL) + { SMDS_ElemIteratorPtr eIt = elementsIterator(); while ( eIt->more() ) - myElementIDFactory->ReleaseID(eIt->next()->GetID()); + { + const SMDS_MeshElement *elem = eIt->next(); + myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId()); + } SMDS_NodeIteratorPtr itn = nodesIterator(); while (itn->more()) - myNodeIDFactory->ReleaseID(itn->next()->GetID()); - } - else { + { + const SMDS_MeshNode *node = itn->next(); + myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId()); + } + } + else + { myNodeIDFactory->Clear(); myElementIDFactory->Clear(); - } + } - SMDS_VolumeIteratorPtr itv = volumesIterator(); + SMDS_ElemIteratorPtr itv = elementsIterator(); while (itv->more()) - delete itv->next(); - myVolumes.Clear(); - - SMDS_FaceIteratorPtr itf = facesIterator(); - while (itf->more()) - delete itf->next(); - myFaces.Clear(); - - SMDS_EdgeIteratorPtr ite = edgesIterator(); - while (ite->more()) - delete ite->next(); - myEdges.Clear(); - - SMDS_0DElementIteratorPtr it0d = elements0dIterator(); - while (it0d->more()) - delete it0d->next(); - my0DElements.Clear(); + { + SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next()); + SMDSAbs_ElementType aType = elem->GetType(); + switch (aType) + { + case SMDSAbs_0DElement: + delete elem; + break; + case SMDSAbs_Edge: + myEdgePool->destroy(static_cast(elem)); + break; + case SMDSAbs_Face: + myFacePool->destroy(static_cast(elem)); + break; + case SMDSAbs_Volume: + myVolumePool->destroy(static_cast(elem)); + break; + default: + break; + } + } + myCells.clear(); + myCellIdVtkToSmds.clear(); + //myCellIdSmdsToVtk.clear(); SMDS_NodeIteratorPtr itn = nodesIterator(); while (itn->more()) - delete itn->next(); - myNodes.Clear(); + { + SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next()); + myNodePool->destroy(node); + } + myNodes.clear(); list::iterator itc=myChildren.begin(); while(itc!=myChildren.end()) (*itc)->Clear(); + myModified = false; + xmin = 0; xmax = 0; + ymin = 0; ymax = 0; + zmin = 0; zmax = 0; + myInfo.Clear(); + + myGrid->Initialize(); + myGrid->Allocate(); + vtkPoints* points = vtkPoints::New(); + points->SetNumberOfPoints(SMDS_Mesh::chunkSize); + myGrid->SetPoints( points ); + points->Delete(); + myGrid->BuildLinks(); } /////////////////////////////////////////////////////////////////////////////// @@ -2153,35 +2570,78 @@ void SMDS_Mesh::setInverseElements(bool b) namespace { - /////////////////////////////////////////////////////////////////////////////// - ///Iterator on NCollection_Map - /////////////////////////////////////////////////////////////////////////////// - template - struct MYNCollection_Map_Iterator: public FATHER +/////////////////////////////////////////////////////////////////////////////// +///Iterator on NCollection_Map +/////////////////////////////////////////////////////////////////////////////// +template +struct MYNode_Map_Iterator: public FATHER +{ + int _ctr; + const MAP& _map; + MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector { - typename MAP::Iterator myIterator; + _ctr = 0; + } - MYNCollection_Map_Iterator(const MAP& map):myIterator(map){} + bool more() + { + while (_ctr < _map.size()) + { + if (_map[_ctr]) + return true; + _ctr++; + } + return false; + } - bool more() - { - while(myIterator.More()) + ELEM next() + { + ELEM current = _map[_ctr]; + _ctr++; + return current; + } +}; + +template +struct MYElem_Map_Iterator: public FATHER +{ + int _ctr; + int _type; + const MAP& _map; + MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector + { + _ctr = 0; + _type = typ; + while (_ctr < _map.size()) // go to the first valid element { - if(myIterator.Value()->GetID()!=-1) - return true; - myIterator.Next(); + if (_map[_ctr]) + if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type)) + break; + _ctr++; } - return false; - } + } - ELEM next() - { - ELEM current = (ELEM) myIterator.Value(); - myIterator.Next(); - return current; - } - }; - //================================================================================ +bool more() + { + while (_ctr < _map.size()) + { + if (_map[_ctr]) + if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type)) + return true; + _ctr++; + } + return false; + } + + ELEM next() + { + ELEM current = dynamic_cast (_map[_ctr]); + _ctr++; + return current; + } +}; + +//================================================================================ /*! * \brief Iterator on elements in id increasing order */ @@ -2232,12 +2692,14 @@ namespace { SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const { - typedef MYNCollection_Map_Iterator + typedef MYNode_Map_Iterator < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator; - typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator; - return ( idInceasingOrder ? - SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) : - SMDS_NodeIteratorPtr( new TIterator(myNodes))); + return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID + +// typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator; +// return ( idInceasingOrder ? +// SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) : +// SMDS_NodeIteratorPtr( new TIterator(myNodes))); } /////////////////////////////////////////////////////////////////////////////// @@ -2246,14 +2708,18 @@ SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const { - typedef MYNCollection_Map_Iterator - < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator; - typedef IdSortedIterator< const SMDS_Mesh0DElement* > TSortedIterator; - return ( idInceasingOrder ? - SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory, - SMDSAbs_0DElement, - Nb0DElements() )) : - SMDS_0DElementIteratorPtr( new TIterator(my0DElements))); + typedef MYElem_Map_Iterator + < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator; + return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID + +// typedef MYNCollection_Map_Iterator +// < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator; +// typedef IdSortedIterator< const SMDS_Mesh0DElement* > TSortedIterator; +// return ( idInceasingOrder ? +// SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory, +// SMDSAbs_0DElement, +// Nb0DElements() )) : +// SMDS_0DElementIteratorPtr( new TIterator(my0DElements))); } /////////////////////////////////////////////////////////////////////////////// @@ -2262,14 +2728,18 @@ SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) c SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const { - typedef MYNCollection_Map_Iterator - < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator; - typedef IdSortedIterator< const SMDS_MeshEdge* > TSortedIterator; - return ( idInceasingOrder ? - SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory, - SMDSAbs_Edge, - NbEdges() )) : - SMDS_EdgeIteratorPtr(new TIterator(myEdges))); + typedef MYElem_Map_Iterator + < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator; + return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID + +// typedef MYNCollection_Map_Iterator +// < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator; +// typedef IdSortedIterator< const SMDS_MeshEdge* > TSortedIterator; +// return ( idInceasingOrder ? +// SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory, +// SMDSAbs_Edge, +// NbEdges() )) : +// SMDS_EdgeIteratorPtr(new TIterator(myEdges))); } /////////////////////////////////////////////////////////////////////////////// @@ -2278,14 +2748,18 @@ SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const { - typedef MYNCollection_Map_Iterator - < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator; - typedef IdSortedIterator< const SMDS_MeshFace* > TSortedIterator; - return ( idInceasingOrder ? - SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory, - SMDSAbs_Face, - NbFaces() )) : - SMDS_FaceIteratorPtr(new TIterator(myFaces))); + typedef MYElem_Map_Iterator + < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator; + return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID + +// typedef MYNCollection_Map_Iterator +// < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator; +// typedef IdSortedIterator< const SMDS_MeshFace* > TSortedIterator; +// return ( idInceasingOrder ? +// SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory, +// SMDSAbs_Face, +// NbFaces() )) : +// SMDS_FaceIteratorPtr(new TIterator(myFaces))); } /////////////////////////////////////////////////////////////////////////////// @@ -2294,14 +2768,18 @@ SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const { - typedef MYNCollection_Map_Iterator - < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator; - typedef IdSortedIterator< const SMDS_MeshVolume* > TSortedIterator; - return ( idInceasingOrder ? - SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory, - SMDSAbs_Volume, - NbVolumes() )) : - SMDS_VolumeIteratorPtr(new TIterator(myVolumes))); + typedef MYElem_Map_Iterator + < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator; + return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID + + // typedef MYNCollection_Map_Iterator +// < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator; +// typedef IdSortedIterator< const SMDS_MeshVolume* > TSortedIterator; +// return ( idInceasingOrder ? +// SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory, +// SMDSAbs_Volume, +// NbVolumes() )) : +// SMDS_VolumeIteratorPtr(new TIterator(myVolumes))); } /////////////////////////////////////////////////////////////////////////////// @@ -2311,17 +2789,19 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const { switch (type) { case SMDSAbs_All: + return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All)); break; case SMDSAbs_Volume: - return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfVolumes >(myVolumes)); + return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume)); case SMDSAbs_Face: - return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfFaces >(myFaces)); + return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face)); case SMDSAbs_Edge: - return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfEdges >(myEdges)); + return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge)); case SMDSAbs_0DElement: - return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOf0DElements >(my0DElements)); + return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement)); case SMDSAbs_Node: - return myNodeIDFactory->elementsIterator(); + return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All)); + //return myNodeIDFactory->elementsIterator(); default:; } return myElementIDFactory->elementsIterator(); @@ -2350,7 +2830,9 @@ static set * intersectionOfSets( } /////////////////////////////////////////////////////////////////////////////// -/// Return the list of finit elements owning the given element +/// Return the list of finite elements owning the given element: elements +/// containing all the nodes of the given element, for instance faces and +/// volumes containing a given edge. /////////////////////////////////////////////////////////////////////////////// static set * getFinitElements(const SMDS_MeshElement * element) { @@ -2362,16 +2844,24 @@ static set * getFinitElements(const SMDS_MeshElement * int i=0; while(itNodes->more()) { - const SMDS_MeshNode * n=static_cast(itNodes->next()); + const SMDS_MeshElement* node = itNodes->next(); + MYASSERT(node); + const SMDS_MeshNode * n=static_cast(node); SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); //initSet[i]=set(); while(itFe->more()) - initSet[i].insert(itFe->next()); + { + const SMDS_MeshElement* elem = itFe->next(); + MYASSERT(elem); + initSet[i].insert(elem); + + } i++; } set *retSet=intersectionOfSets(initSet, numberOfSets); + MESSAGE("nb elems " << i << " intersection " << retSet->size()); delete [] initSet; return retSet; } @@ -2416,7 +2906,7 @@ void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren switch(element->GetType()) { case SMDSAbs_Node: - MESSAGE("Internal Error: This should not happend"); + MESSAGE("Internal Error: This should not happen"); break; case SMDSAbs_0DElement: { @@ -2486,8 +2976,8 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, /////////////////////////////////////////////////////////////////////////////// ///@param elem The element to delete -///@param removedElems contains all removed elements -///@param removedNodes contains all removed nodes +///@param removedElems to be filled with all removed elements +///@param removedNodes to be filled with all removed nodes ///@param removenodes if true remaining nodes will be removed /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, @@ -2495,105 +2985,143 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, list& removedNodes, bool removenodes) { + //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes); // get finite elements built on elem set * s1; - if (elem->GetType() == SMDSAbs_0DElement || - elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() || - elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() || - elem->GetType() == SMDSAbs_Volume) - { - s1 = new set(); - s1->insert(elem); - } + if (elem->GetType() == SMDSAbs_0DElement || elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() + || elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() || elem->GetType() == SMDSAbs_Volume) + { + s1 = new set (); + s1->insert(elem); + } else s1 = getFinitElements(elem); // get exclusive nodes (which would become free afterwards) set * s2; if (elem->GetType() == SMDSAbs_Node) // a node is removed - { - // do not remove nodes except elem - s2 = new set(); - s2->insert(elem); - removenodes = true; - } + { + // do not remove nodes except elem + s2 = new set (); + s2->insert(elem); + removenodes = true; + } else s2 = getExclusiveNodes(*s1); // form the set of finite and construction elements to remove set s3; - set::iterator it=s1->begin(); - while(it!=s1->end()) - { - addChildrenWithNodes(s3, *it ,*s2); - s3.insert(*it); - it++; - } - if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem); - - // remove finite and construction elements - it=s3.begin(); - while(it!=s3.end()) - { - // Remove element from of its nodes - SMDS_ElemIteratorPtr itn=(*it)->nodesIterator(); - while(itn->more()) + set::iterator it = s1->begin(); + while (it != s1->end()) { - SMDS_MeshNode * n = static_cast - (const_cast(itn->next())); - n->RemoveInverseElement( (*it) ); + addChildrenWithNodes(s3, *it, *s2); + s3.insert(*it); + it++; } + if (elem->GetType() != SMDSAbs_Node) + s3.insert(elem); - switch((*it)->GetType()) + // remove finite and construction elements + it = s3.begin(); + while (it != s3.end()) { - case SMDSAbs_Node: - MESSAGE("Internal Error: This should not happen"); - break; - case SMDSAbs_0DElement: - my0DElements.Remove(static_cast - (const_cast(*it))); - //myInfo.Remove0DElement(*it); - myInfo.remove(*it); - break; - case SMDSAbs_Edge: - myEdges.Remove(static_cast - (const_cast(*it))); - myInfo.RemoveEdge(*it); - break; - case SMDSAbs_Face: - myFaces.Remove(static_cast - (const_cast(*it))); - myInfo.RemoveFace(*it); - break; - case SMDSAbs_Volume: - myVolumes.Remove(static_cast - (const_cast(*it))); - myInfo.RemoveVolume(*it); - break; + // Remove element from of its nodes + SMDS_ElemIteratorPtr itn = (*it)->nodesIterator(); + while (itn->more()) + { + SMDS_MeshNode * n = static_cast (const_cast (itn->next())); + n->RemoveInverseElement((*it)); + } + int IdToRemove = (*it)->GetID(); + int vtkid = (*it)->getVtkId(); + //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid << + // " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType()); + switch ((*it)->GetType()) + { + case SMDSAbs_Node: + MYASSERT("Internal Error: This should not happen") + ; + break; + case SMDSAbs_0DElement: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ? + myInfo.remove(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + delete (*it); + break; + case SMDSAbs_Edge: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.RemoveEdge(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_VtkEdge* vtkElem = dynamic_cast(*it)) + myEdgePool->destroy((SMDS_VtkEdge*) vtkElem); + else + delete (*it); + break; + case SMDSAbs_Face: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.RemoveFace(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_VtkFace* vtkElem = dynamic_cast(*it)) + myFacePool->destroy((SMDS_VtkFace*) vtkElem); + else + delete (*it); + break; + case SMDSAbs_Volume: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.RemoveVolume(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_VtkVolume* vtkElem = dynamic_cast(*it)) + myVolumePool->destroy((SMDS_VtkVolume*) vtkElem); + else + delete (*it); + break; + } + if (vtkid >= 0) + { + //MESSAGE("VTK_EMPTY_CELL in " << vtkid); + this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL); + } + it++; } - //MESSAGE( "SMDS: RM elem " << (*it)->GetID() ); - removedElems.push_back( (*it) ); - myElementIDFactory->ReleaseID((*it)->GetID()); - delete (*it); - it++; - } // remove exclusive (free) nodes - if(removenodes) - { - it=s2->begin(); - while(it!=s2->end()) + if (removenodes) { - //MESSAGE( "SMDS: RM node " << (*it)->GetID() ); - myNodes.Remove(static_cast - (const_cast(*it))); - myInfo.myNbNodes--; - myNodeIDFactory->ReleaseID((*it)->GetID()); - removedNodes.push_back( (*it) ); - delete *it; - it++; + it = s2->begin(); + while (it != s2->end()) + { + int IdToRemove = (*it)->GetID(); + //MESSAGE( "SMDS: RM node " << IdToRemove); + if (IdToRemove >= 0) + { + myNodes[IdToRemove] = 0; + myInfo.myNbNodes--; + } + myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId()); + removedNodes.push_back((*it)); + if (const SMDS_MeshNode* vtkElem = dynamic_cast(*it)) + myNodePool->destroy((SMDS_MeshNode*) vtkElem); + else + delete (*it); + it++; + } } - } delete s2; delete s1; @@ -2605,22 +3133,28 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) { + int elemId = elem->GetID(); + int vtkId = elem->getVtkId(); + //MESSAGE("RemoveFreeElement " << elemId); SMDSAbs_ElementType aType = elem->GetType(); + SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem); if (aType == SMDSAbs_Node) { + //MESSAGE("Remove free node " << elemId); // only free node can be removed by this method - const SMDS_MeshNode* n = static_cast(elem); + const SMDS_MeshNode* n = static_cast(todest); SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); if (!itFe->more()) { // free node - myNodes.Remove(const_cast(n)); + myNodes[elemId] = 0; myInfo.myNbNodes--; - myNodeIDFactory->ReleaseID(elem->GetID()); - delete elem; + myNodePool->destroy(static_cast(todest)); + myNodeIDFactory->ReleaseID(elemId, vtkId); } } else { if (hasConstructionEdges() || hasConstructionFaces()) // this methods is only for meshes without descendants return; + //MESSAGE("Remove free element " << elemId); // Remove element from of its nodes SMDS_ElemIteratorPtr itn = elem->nodesIterator(); while (itn->more()) { @@ -2630,33 +3164,34 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) } // in meshes without descendants elements are always free - switch (aType) { + switch (aType) { case SMDSAbs_0DElement: - my0DElements.Remove(static_cast - (const_cast(elem))); - //myInfo.Remove0DElement(elem); + myCells[elemId] = 0; myInfo.remove(elem); + delete elem; break; case SMDSAbs_Edge: - myEdges.Remove(static_cast - (const_cast(elem))); + myCells[elemId] = 0; myInfo.RemoveEdge(elem); + myEdgePool->destroy(static_cast(todest)); break; case SMDSAbs_Face: - myFaces.Remove(static_cast - (const_cast(elem))); + myCells[elemId] = 0; myInfo.RemoveFace(elem); + myFacePool->destroy(static_cast(todest)); break; case SMDSAbs_Volume: - myVolumes.Remove(static_cast - (const_cast(elem))); + myCells[elemId] = 0; myInfo.RemoveVolume(elem); + myVolumePool->destroy(static_cast(todest)); break; default: break; } - myElementIDFactory->ReleaseID(elem->GetID()); - delete elem; + myElementIDFactory->ReleaseID(elemId, vtkId); + + this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL); + // --- to do: keep vtkid in a list of reusable cells } } @@ -2698,7 +3233,7 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const int SMDS_Mesh::MaxNodeID() const { - return myNodeIDFactory->GetMaxID(); + return myNodeMax; } //======================================================================= @@ -2708,7 +3243,7 @@ int SMDS_Mesh::MaxNodeID() const int SMDS_Mesh::MinNodeID() const { - return myNodeIDFactory->GetMinID(); + return myNodeMin; } //======================================================================= @@ -2738,10 +3273,11 @@ int SMDS_Mesh::MinElementID() const void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) { + MESSAGE("Renumber"); if ( deltaID == 0 ) return; - SMDS_MeshElementIDFactory * idFactory = + SMDS_MeshNodeIDFactory * idFactory = isNodes ? myNodeIDFactory : myElementIDFactory; // get existing elements in the order of ID increasing @@ -2836,23 +3372,34 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, int ID) { if ( !n1 || !n2 || !n12 ) return 0; - 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); - myInfo.myNbQuadEdges++; - return edge; - } - else { - delete edge; - return NULL; - } + + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + SMDS_MeshEdge * edge = 0; + SMDS_VtkEdge *edgevtk = myEdgePool->getNew(); + edgevtk->init(nodeIds, this); + if (!this->registerElement(ID,edgevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL); + myEdgePool->destroy(edgevtk); + return 0; + } + edge = edgevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = edge; + myInfo.myNbQuadEdges++; + +// if (!registerElement(ID, edge)) { +// RemoveElement(edge, false); +// edge = NULL; +// } + return edge; + } @@ -2905,16 +3452,38 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, // creation quadratic edges - not implemented return 0; } - SMDS_QuadraticFaceOfNodes* face = - new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31); - myFaces.Add(face); - myInfo.myNbQuadTriangles++; - - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + else + { + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n31->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbQuadTriangles++; + +// if (!registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } + return face; } - return face; } @@ -2971,17 +3540,42 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0; if(hasConstructionEdges()) { // creation quadratic edges - not implemented + return 0; } - SMDS_QuadraticFaceOfNodes* face = - new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41); - myFaces.Add(face); - myInfo.myNbQuadQuadrangles++; - - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + else + { + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n41->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbQuadQuadrangles++; + +// if (!registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } + return face; } - return face; } @@ -3051,16 +3645,39 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, // creation quadratic faces - not implemented return 0; } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + + nodeIds.push_back(n31->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + nodeIds.push_back(n14->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n24->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; myInfo.myNbQuadTetras++; - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } - return volume; +// if (!registerElement(ID, volvtk)) { +// RemoveElement(volvtk, false); +// volvtk = NULL; +// } + return volvtk; } @@ -3141,17 +3758,42 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, // creation quadratic faces - not implemented return 0; } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23, - n34,n41,n15,n25,n35,n45); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + + nodeIds.push_back(n41->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + nodeIds.push_back(n15->getVtkId()); + nodeIds.push_back(n45->getVtkId()); + nodeIds.push_back(n35->getVtkId()); + nodeIds.push_back(n25->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; myInfo.myNbQuadPyramids++; - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } - return volume; +// if (!registerElement(ID, volvtk)) { +// RemoveElement(volvtk, false); +// volvtk = NULL; +// } + return volvtk; } @@ -3240,17 +3882,46 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, // creation quadratic faces - not implemented return 0; } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31, - n45,n56,n64,n14,n25,n36); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n31->getVtkId()); + + nodeIds.push_back(n45->getVtkId()); + nodeIds.push_back(n56->getVtkId()); + nodeIds.push_back(n64->getVtkId()); + + nodeIds.push_back(n14->getVtkId()); + nodeIds.push_back(n25->getVtkId()); + nodeIds.push_back(n36->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; myInfo.myNbQuadPrisms++; - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } - return volume; +// if (!registerElement(ID, volvtk)) { +// RemoveElement(volvtk, false); +// volvtk = NULL; +// } + return volvtk; } @@ -3354,15 +4025,213 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return 0; // 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); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n8->getVtkId()); + nodeIds.push_back(n7->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + nodeIds.push_back(n41->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + nodeIds.push_back(n85->getVtkId()); + nodeIds.push_back(n78->getVtkId()); + nodeIds.push_back(n67->getVtkId()); + nodeIds.push_back(n56->getVtkId()); + + nodeIds.push_back(n15->getVtkId()); + nodeIds.push_back(n48->getVtkId()); + nodeIds.push_back(n37->getVtkId()); + nodeIds.push_back(n26->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; myInfo.myNbQuadHexas++; - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; +// if (!registerElement(ID, volvtk)) { +// RemoveElement(volvtk, false); +// volvtk = NULL; +// } + return volvtk; +} + +void SMDS_Mesh::updateNodeMinMax() +{ + myNodeMin = 0; + if (myNodes.size() == 0) + { + myNodeMax=0; + return; } - return volume; + while (!myNodes[myNodeMin] && (myNodeMin=0)) + myNodeMin--; +} + +void SMDS_Mesh::incrementNodesCapacity(int nbNodes) +{ +// int val = myCellIdSmdsToVtk.size(); +// MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes); +// myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1 + int val = myNodes.size(); + MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes); + myNodes.resize(val +nbNodes, 0); +} + +void SMDS_Mesh::incrementCellsCapacity(int nbCells) +{ + int val = myCellIdVtkToSmds.size(); + MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells); + myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1 + val = myCells.size(); + MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells); + myNodes.resize(val +nbCells, 0); +} + +void SMDS_Mesh::adjustStructure() +{ + myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()); +} + +void SMDS_Mesh::dumpGrid(string ficdump) +{ + MESSAGE("SMDS_Mesh::dumpGrid " << ficdump); +// vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); +// aWriter->SetFileName(ficdump.c_str()); +// aWriter->SetInput(myGrid); +// if(myGrid->GetNumberOfCells()) +// { +// aWriter->Write(); +// } +// aWriter->Delete(); + ficdump = ficdump + "_connectivity"; + ofstream ficcon(ficdump.c_str(), ios::out); + int nbPoints = myGrid->GetNumberOfPoints(); + ficcon << "-------------------------------- points " << nbPoints << endl; + for (int i=0; iGetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl; + } + int nbCells = myGrid->GetNumberOfCells(); + ficcon << "-------------------------------- cells " << nbCells << endl; + for (int i=0; iGetCell(i)); +// MESSAGE(" " << myGrid->GetCell(i)->GetCellType()); + ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -"; + int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints(); + vtkIdList *listid = myGrid->GetCell(i)->GetPointIds(); + for (int j=0; jGetId(j); + } + ficcon << endl; + } + ficcon << "-------------------------------- connectivity " << nbPoints << endl; + vtkCellLinks *links = myGrid->GetCellLinks(); + for (int i=0; iGetNcells(i); + vtkIdType *cells = links->GetCells(i); + ficcon << i << " - " << ncells << " -"; + for (int j=0; j= 0 && vtkid < myCellIdVtkToSmds.size()) + return myCellIdVtkToSmds[vtkid]; + throw SALOME_Exception(LOCALIZED ("vtk id out of bounds")); +} + +void SMDS_Mesh::updateBoundingBox() +{ + xmin = 0; xmax = 0; + ymin = 0; ymax = 0; + zmin = 0; zmax = 0; + vtkPoints *points = myGrid->GetPoints(); + int myNodesSize = this->myNodes.size(); + for (int i = 0; i < myNodesSize; i++) + { + if (SMDS_MeshNode *n = myNodes[i]) + { + double coords[3]; + points->GetPoint(n->myVtkID, coords); + if (coords[0] < xmin) xmin = coords[0]; + else if (coords[0] > xmax) xmax = coords[0]; + if (coords[1] < ymin) ymin = coords[1]; + else if (coords[1] > ymax) ymax = coords[1]; + if (coords[2] < zmin) zmin = coords[2]; + else if (coords[2] > zmax) zmax = coords[2]; + } + } +} + +double SMDS_Mesh::getMaxDim() +{ + double dmax = 1.e-3; + if ((xmax - xmin) > dmax) dmax = xmax -xmin; + if ((ymax - ymin) > dmax) dmax = ymax -ymin; + if ((zmax - zmin) > dmax) dmax = zmax -zmin; + MESSAGE("getMaxDim " << dmax); + return dmax; +} + +//! modification that needs compact structure and redraw +void SMDS_Mesh::Modified() +{ + if (this->myModified) + { + this->myModifTime++; + MESSAGE("modified"); + myModified = false; + } +} + +//! get last modification timeStamp +unsigned long SMDS_Mesh::GetMTime() +{ + return this->myModifTime; +} + +bool SMDS_Mesh::isCompacted() +{ + if (this->myModifTime > this->myCompactTime) + { + MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime); + this->myCompactTime = this->myModifTime; + return false; + } + return true; } diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index e9397b6a2..6daf98478 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -30,23 +30,47 @@ #include "SMESH_SMDS.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_MeshCell.hxx" #include "SMDS_Mesh0DElement.hxx" #include "SMDS_MeshEdge.hxx" #include "SMDS_MeshFace.hxx" #include "SMDS_MeshVolume.hxx" +#include "SMDS_MeshNodeIDFactory.hxx" #include "SMDS_MeshElementIDFactory.hxx" #include "SMDS_MeshInfo.hxx" #include "SMDS_ElemIterator.hxx" -#include +#include "SMDS_VolumeOfNodes.hxx" +#include "SMDS_VtkEdge.hxx" +#include "SMDS_VtkFace.hxx" +#include "SMDS_VtkVolume.hxx" +#include "ObjectPool.hxx" +#include "SMDS_UnstructuredGrid.hxx" #include #include #include +#include +#include + +#include "Utils_SALOME_Exception.hxx" +#define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified")); class SMDS_EXPORT SMDS_Mesh:public SMDS_MeshObject{ public: + friend class SMDS_MeshIDFactory; + friend class SMDS_MeshNodeIDFactory; + friend class SMDS_MeshElementIDFactory; + friend class SMDS_MeshVolumeVtkNodes; + friend class SMDS_MeshNode; SMDS_Mesh(); + + //! to retreive this SMDS_Mesh instance from its elements (index stored in SMDS_Elements) + static std::vector _meshList; + + //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid + inline SMDS_UnstructuredGrid* getGrid() {return myGrid; }; + inline int getMeshId() {return myMeshId; }; SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const; SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const; @@ -420,6 +444,11 @@ public: (std::vector nodes, std::vector quantities); + virtual SMDS_MeshVolume* AddVolumeFromVtkIds(const std::vector& vtkNodeIds); + + virtual SMDS_MeshVolume* AddVolumeFromVtkIdsWithID(const std::vector& vtkNodeIds, + const int ID); + virtual void RemoveElement(const SMDS_MeshElement * elem, std::list& removedElems, std::list& removedNodes, @@ -451,8 +480,10 @@ public: virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1); // Renumber all nodes or elements. + virtual void compactMesh(); const SMDS_MeshNode *FindNode(int idnode) const; + const SMDS_MeshNode *FindNodeVtk(int idnode) const; const SMDS_Mesh0DElement* Find0DElement(int idnode) const; const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const; const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2, int idnode3) const; @@ -541,23 +572,40 @@ public: */ bool Contains (const SMDS_MeshElement* elem) const; - typedef NCollection_Map SetOfNodes; - typedef NCollection_Map SetOf0DElements; - typedef NCollection_Map SetOfEdges; - typedef NCollection_Map SetOfFaces; - typedef NCollection_Map SetOfVolumes; + typedef std::vector SetOfNodes; + typedef std::vector SetOfCells; + + void updateNodeMinMax(); + void updateBoundingBox(); + double getMaxDim(); + int fromVtkToSmds(int vtkid); + + void incrementNodesCapacity(int nbNodes); + void incrementCellsCapacity(int nbCells); + void adjustStructure(); + void dumpGrid(string ficdump="dumpGrid"); + static int chunkSize; -private: + //! low level modification: add, change or remove node or element + inline void setMyModified() { this->myModified = true; }; + + void Modified(); + unsigned long GetMTime(); + bool isCompacted(); + +protected: SMDS_Mesh(SMDS_Mesh * parent); SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3); + const SMDS_MeshNode * node3, + int ID); SMDS_MeshFace * createQuadrangle(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4); - SMDS_Mesh0DElement* Find0DElementOrCreate(const SMDS_MeshNode * n); + const SMDS_MeshNode * node4, + int ID); +// SMDS_Mesh0DElement* Find0DElementOrCreate(const SMDS_MeshNode * n); SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2); SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1, @@ -574,22 +622,77 @@ private: const SMDS_MeshElement * element, std::set& nodes); + inline void adjustmyCellsCapacity(int ID) + { + assert(ID >= 0); + myElementIDFactory->adjustMaxId(ID); + if (ID >= myCells.size()) + myCells.resize(ID+SMDS_Mesh::chunkSize,0); + }; + + inline void adjustBoundingBox(double x, double y, double z) + { + if (x > xmax) xmax = x; + else if (x < xmin) xmin = x; + if (y > ymax) ymax = y; + else if (y < ymin) ymin = y; + if (z > zmax) zmax = z; + else if (z < zmin) zmin = z; + }; + // Fields PRIVATE + //! index of this SMDS_mesh in the static vector _meshList + int myMeshId; + + //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid + SMDS_UnstructuredGrid* myGrid; + + //! Small objects like SMDS_MeshNode are allocated by chunks to limit memory costs of new + ObjectPool* myNodePool; + + //! Small objects like SMDS_VtkVolume are allocated by chunks to limit memory costs of new + ObjectPool* myVolumePool; + ObjectPool* myFacePool; + ObjectPool* myEdgePool; + + //! SMDS_MeshNodes refer to vtk nodes (vtk id = index in myNodes),store reference to this mesh, and subshape SetOfNodes myNodes; - SetOf0DElements my0DElements; - SetOfEdges myEdges; - SetOfFaces myFaces; - SetOfVolumes myVolumes; + + //! SMDS_MeshCells refer to vtk cells (vtk id != index in myCells),store reference to this mesh, and subshape + SetOfCells myCells; + + //! for cells only: index = ID for SMDS users, value = ID in vtkUnstructuredGrid + //std::vector myCellIdSmdsToVtk; + + //! for cells only: index = ID in vtkUnstructuredGrid, value = ID for SMDS users + std::vector myCellIdVtkToSmds; + SMDS_Mesh * myParent; std::list myChildren; - SMDS_MeshElementIDFactory *myNodeIDFactory; + SMDS_MeshNodeIDFactory *myNodeIDFactory; SMDS_MeshElementIDFactory *myElementIDFactory; SMDS_MeshInfo myInfo; + //! use a counter to keep track of modifications + unsigned long myModifTime, myCompactTime; + + int myNodeMin; + int myNodeMax; + bool myHasConstructionEdges; bool myHasConstructionFaces; bool myHasInverseElements; + + //! any add, remove or change of node or cell + bool myModified; + + double xmin; + double xmax; + double ymin; + double ymax; + double zmin; + double zmax; }; diff --git a/src/SMDS/SMDS_Mesh0DElement.cxx b/src/SMDS/SMDS_Mesh0DElement.cxx index fec865937..49b4d4abc 100644 --- a/src/SMDS/SMDS_Mesh0DElement.cxx +++ b/src/SMDS/SMDS_Mesh0DElement.cxx @@ -29,6 +29,7 @@ #include "SMDS_Mesh0DElement.hxx" #include "SMDS_IteratorOfElements.hxx" #include "SMDS_MeshNode.hxx" +#include "utilities.h" using namespace std; @@ -37,7 +38,8 @@ using namespace std; //purpose : //======================================================================= SMDS_Mesh0DElement::SMDS_Mesh0DElement (const SMDS_MeshNode * node) -{ +{ + MESSAGE("SMDS_Mesh0DElement " << GetID()); myNode = node; } @@ -77,6 +79,11 @@ SMDSAbs_ElementType SMDS_Mesh0DElement::GetType() const return SMDSAbs_0DElement; } +vtkIdType SMDS_Mesh0DElement::GetVtkType() const +{ + return VTK_VERTEX; +} + //======================================================================= //function : elementsIterator //purpose : @@ -124,8 +131,8 @@ SMDS_ElemIteratorPtr SMDS_Mesh0DElement::elementsIterator (SMDSAbs_ElementType t //======================================================================= bool operator< (const SMDS_Mesh0DElement & e1, const SMDS_Mesh0DElement & e2) { - int id1 = e1.myNode->GetID(); - int id2 = e2.myNode->GetID(); + int id1 = e1.myNode->getVtkId(); + int id2 = e2.myNode->getVtkId(); return (id1 < id2); } diff --git a/src/SMDS/SMDS_Mesh0DElement.hxx b/src/SMDS/SMDS_Mesh0DElement.hxx index 7e5abd52b..b13722291 100644 --- a/src/SMDS/SMDS_Mesh0DElement.hxx +++ b/src/SMDS/SMDS_Mesh0DElement.hxx @@ -26,18 +26,20 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshCell.hxx" #include -class SMDS_EXPORT SMDS_Mesh0DElement: public SMDS_MeshElement +class SMDS_EXPORT SMDS_Mesh0DElement: public SMDS_MeshCell { public: SMDS_Mesh0DElement (const SMDS_MeshNode * node); bool ChangeNode (const SMDS_MeshNode * node); + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;}; void Print (std::ostream & OS) const; SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; SMDSAbs_EntityType GetEntityType() const {return SMDSEntity_0D;} int NbNodes() const; int NbEdges() const; diff --git a/src/SMDS/SMDS_MeshCell.cxx b/src/SMDS/SMDS_MeshCell.cxx new file mode 100644 index 000000000..4cfd2a0a7 --- /dev/null +++ b/src/SMDS/SMDS_MeshCell.cxx @@ -0,0 +1,18 @@ +#include "SMDS_MeshCell.hxx" +#include "utilities.h" + +using namespace std; + +int SMDS_MeshCell::nbCells = 0; + +SMDS_MeshCell::SMDS_MeshCell() : + SMDS_MeshElement(-1) +{ + nbCells++; + myVtkID = -1; +} + +SMDS_MeshCell::~SMDS_MeshCell() +{ + nbCells--; +} diff --git a/src/SMDS/SMDS_MeshCell.hxx b/src/SMDS/SMDS_MeshCell.hxx new file mode 100644 index 000000000..792696f73 --- /dev/null +++ b/src/SMDS/SMDS_MeshCell.hxx @@ -0,0 +1,30 @@ +#ifndef _SMDS_MESHCELL_HXX_ +#define _SMDS_MESHCELL_HXX_ + +#include "SMDS_MeshElement.hxx" + +/*! + * \brief Base class for all cells + */ + +class SMDS_EXPORT SMDS_MeshCell: public SMDS_MeshElement +{ +public: + SMDS_MeshCell(); + virtual ~SMDS_MeshCell(); + + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)= 0; + virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) {return true; }; + + static int nbCells; + +protected: + inline void exchange(const SMDS_MeshNode* nodes[],int a, int b) + { + const SMDS_MeshNode* noda = nodes[a]; + nodes[a] = nodes[b]; + nodes[b] = noda; + } +}; + +#endif diff --git a/src/SMDS/SMDS_MeshEdge.cxx b/src/SMDS/SMDS_MeshEdge.cxx index 1910a3a4b..fc1e3c55a 100644 --- a/src/SMDS/SMDS_MeshEdge.cxx +++ b/src/SMDS/SMDS_MeshEdge.cxx @@ -1,159 +1,11 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// SMESH SMDS : implementaion of Salome mesh data structure -// File : SMDS_MeshEdge.cxx -// Author : Jean-Michel BOULCOURT -// Module : SMESH -// -#ifdef _MSC_VER -#pragma warning(disable:4786) -#endif - #include "SMDS_MeshEdge.hxx" -#include "SMDS_IteratorOfElements.hxx" -#include "SMDS_MeshNode.hxx" - -using namespace std; - -//======================================================================= -//function : SMDS_MeshEdge -//purpose : -//======================================================================= - -SMDS_MeshEdge::SMDS_MeshEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) -{ - myNodes[0]=node1; - myNodes[1]=node2; -} - -//======================================================================= -//function : Print -//purpose : -//======================================================================= - -void SMDS_MeshEdge::Print(ostream & OS) const -{ - OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1] << - ") " << endl; -} - -int SMDS_MeshEdge::NbNodes() const -{ - return 2; -} - -int SMDS_MeshEdge::NbEdges() const -{ - return 1; -} SMDSAbs_ElementType SMDS_MeshEdge::GetType() const { - return SMDSAbs_Edge; + return SMDSAbs_Edge; } -class SMDS_MeshEdge_MyNodeIterator:public SMDS_ElemIterator -{ - const SMDS_MeshNode *const* myNodes; - int myIndex; - public: - SMDS_MeshEdge_MyNodeIterator(const SMDS_MeshNode * const* nodes): - myNodes(nodes),myIndex(0) {} - - bool more() - { - return myIndex<2; - } - - const SMDS_MeshElement* next() - { - myIndex++; - return myNodes[myIndex-1]; - } -}; - -SMDS_ElemIteratorPtr SMDS_MeshEdge:: - elementsIterator(SMDSAbs_ElementType type) const -{ - switch(type) - { - case SMDSAbs_Edge: - return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); - case SMDSAbs_Node: - return SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes)); - default: - return SMDS_ElemIteratorPtr - (new SMDS_IteratorOfElements - (this,type, SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes)))); - } -} - -bool operator<(const SMDS_MeshEdge & e1, const SMDS_MeshEdge & e2) -{ - int id11=e1.myNodes[0]->GetID(); - int id21=e2.myNodes[0]->GetID(); - int id12=e1.myNodes[1]->GetID(); - int id22=e2.myNodes[1]->GetID(); - int tmp; - - if(id11>=id12) - { - tmp=id11; - id11=id12; - id12=tmp; - } - if(id21>=id22) - { - tmp=id21; - id21=id22; - id22=tmp; - } - - if(id11 +#include "SMDS_MeshCell.hxx" -class SMDS_EXPORT SMDS_MeshEdge:public SMDS_MeshElement +class SMDS_EXPORT SMDS_MeshEdge:public SMDS_MeshCell { - + public: - SMDS_MeshEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2); - bool ChangeNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2); - void Print(std::ostream & OS) const; - - virtual SMDSAbs_ElementType GetType() const; - virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Edge; } - 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 - */ - virtual const SMDS_MeshNode* GetNode(const int ind) const; - - protected: - SMDS_ElemIteratorPtr - elementsIterator(SMDSAbs_ElementType type) const; - - protected: - const SMDS_MeshNode* myNodes[3]; - + SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; }; #endif diff --git a/src/SMDS/SMDS_MeshElement.cxx b/src/SMDS/SMDS_MeshElement.cxx index 185b3c549..3b4cd2520 100644 --- a/src/SMDS/SMDS_MeshElement.cxx +++ b/src/SMDS/SMDS_MeshElement.cxx @@ -35,7 +35,12 @@ using namespace std; -SMDS_MeshElement::SMDS_MeshElement(int ID):myID(ID) +SMDS_MeshElement::SMDS_MeshElement(int ID):myID(ID), myMeshId(-1), myShapeId(0), myIdInShape(-1) +{ +} + +SMDS_MeshElement::SMDS_MeshElement(int id, ShortType meshId, ShortType shapeId): + myID(id), myMeshId(meshId), myShapeId(shapeId), myIdInShape(-1) { } @@ -146,6 +151,7 @@ class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator return myElement; } }; + SMDS_ElemIteratorPtr SMDS_MeshElement:: elementsIterator(SMDSAbs_ElementType type) const { @@ -162,12 +168,18 @@ SMDS_ElemIteratorPtr SMDS_MeshElement:: } } -/////////////////////////////////////////////////////////////////////////////// -///Return the ID of the element -/////////////////////////////////////////////////////////////////////////////// -int SMDS_MeshElement::GetID() const +//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes +SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIteratorToUNV() const +{ + MESSAGE("Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); +} + +//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes +SMDS_ElemIteratorPtr SMDS_MeshElement::interlacedNodesElemIterator() const { - return myID; + MESSAGE("Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); } bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2) diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx index 593b7fe00..d4f32a51b 100644 --- a/src/SMDS/SMDS_MeshElement.hxx +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -38,9 +38,16 @@ #include #include +#include +#include + +//typedef unsigned short UShortType; +typedef short ShortType; + class SMDS_MeshNode; class SMDS_MeshEdge; -class SMDS_MeshFace; +class SMDS_MeshFace; +class SMDS_Mesh; // ============================================================ /*! @@ -48,6 +55,7 @@ class SMDS_MeshFace; */ // ============================================================ + class SMDS_EXPORT SMDS_MeshElement:public SMDS_MeshObject { public: @@ -56,6 +64,8 @@ public: SMDS_ElemIteratorPtr edgesIterator() const; SMDS_ElemIteratorPtr facesIterator() const; virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; // std-like iteration on nodes typedef SMDS_StdIterator< const SMDS_MeshNode*, SMDS_ElemIteratorPtr > iterator; @@ -65,11 +75,12 @@ public: virtual int NbNodes() const; virtual int NbEdges() const; virtual int NbFaces() const; - int GetID() const; + inline int GetID() const { return myID; }; ///Return the type of the current element virtual SMDSAbs_ElementType GetType() const = 0; - virtual bool IsPoly() const { return false; } + virtual vtkIdType GetVtkType() const = 0; + virtual bool IsPoly() const { return false; }; virtual bool IsQuadratic() const; //! Return type of entity virtual SMDSAbs_EntityType GetEntityType() const = 0; @@ -78,7 +89,11 @@ public: virtual int NbCornerNodes() const; friend SMDS_EXPORT std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *); - friend SMDS_EXPORT bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem); + friend SMDS_EXPORT bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement* elem); + friend class SMDS_Mesh; + friend class SMESHDS_Mesh; + friend class SMESHDS_SubMesh; + friend class SMDS_MeshElementIDFactory; // =========================== // Access to nodes by index @@ -124,14 +139,33 @@ public: */ int GetNodeIndex( const SMDS_MeshNode* node ) const; + inline ShortType getMeshId() const {return myMeshId; }; + inline ShortType getshapeId() const {return myShapeId; }; + inline int getIdInShape() const { return myIdInShape; }; + inline int getVtkId() const { return myVtkID; }; + protected: + inline void setId(int id) {myID = id; }; + inline void setShapeId(ShortType shapeId) {myShapeId = shapeId; }; + inline void setIdInShape(int id) { myIdInShape = id; }; + inline void setVtkId(int vtkId) { myVtkID = vtkId; }; SMDS_MeshElement(int ID=-1); + SMDS_MeshElement(int id, ShortType meshId, ShortType shapeId = 0); virtual void Print(std::ostream & OS) const; -private: + //! Element index in vector SMDS_Mesh::myNodes or SMDS_Mesh::myCells int myID; + //! index in vtkUnstructuredGrid + int myVtkID; + //! SMDS_Mesh identification in SMESH + ShortType myMeshId; + //! SubShape and SubMesh identification in SMESHDS + ShortType myShapeId; + //! Element index in SMESHDS_SubMesh vector + int myIdInShape; }; + // ============================================================ /*! * \brief Comparator of elements by ID for usage in std containers diff --git a/src/SMDS/SMDS_MeshElementIDFactory.cxx b/src/SMDS/SMDS_MeshElementIDFactory.cxx index b86ddad9e..1278192dc 100644 --- a/src/SMDS/SMDS_MeshElementIDFactory.cxx +++ b/src/SMDS/SMDS_MeshElementIDFactory.cxx @@ -31,6 +31,12 @@ #include "SMDS_MeshElementIDFactory.hxx" #include "SMDS_MeshElement.hxx" +#include "SMDS_Mesh.hxx" + +#include "utilities.h" + +#include +#include using namespace std; @@ -39,86 +45,110 @@ using namespace std; //purpose : //======================================================================= SMDS_MeshElementIDFactory::SMDS_MeshElementIDFactory(): - SMDS_MeshIDFactory(), - myMin(0), myMax(0) + SMDS_MeshNodeIDFactory() +{ +// myIDElements.clear(); +// myVtkIndex.clear(); + myVtkCellTypes.clear(); + myVtkCellTypes.reserve(SMDSEntity_Last); + myVtkCellTypes[SMDSEntity_Node] = VTK_VERTEX; + myVtkCellTypes[SMDSEntity_0D] = VTK_VERTEX; + myVtkCellTypes[SMDSEntity_Edge] = VTK_LINE; + myVtkCellTypes[SMDSEntity_Quad_Edge] = VTK_QUADRATIC_EDGE; + myVtkCellTypes[SMDSEntity_Triangle] = VTK_TRIANGLE; + myVtkCellTypes[SMDSEntity_Quad_Triangle] = VTK_QUADRATIC_TRIANGLE; + myVtkCellTypes[SMDSEntity_Quadrangle] = VTK_QUAD; + myVtkCellTypes[SMDSEntity_Quad_Quadrangle] = VTK_QUADRATIC_TRIANGLE; + myVtkCellTypes[SMDSEntity_Polygon] = VTK_POLYGON; + myVtkCellTypes[SMDSEntity_Quad_Polygon] = VTK_POLYGON; // -PR- verifer + myVtkCellTypes[SMDSEntity_Tetra] = VTK_TETRA; + myVtkCellTypes[SMDSEntity_Quad_Tetra] = VTK_QUADRATIC_TETRA; + myVtkCellTypes[SMDSEntity_Pyramid] = VTK_PYRAMID; + myVtkCellTypes[SMDSEntity_Quad_Pyramid] = VTK_CONVEX_POINT_SET; + myVtkCellTypes[SMDSEntity_Hexa] = VTK_HEXAHEDRON; + myVtkCellTypes[SMDSEntity_Quad_Hexa] = VTK_QUADRATIC_HEXAHEDRON; + myVtkCellTypes[SMDSEntity_Penta] = VTK_WEDGE; + myVtkCellTypes[SMDSEntity_Quad_Penta] = VTK_QUADRATIC_WEDGE; +//#ifdef VTK_HAVE_POLYHEDRON + myVtkCellTypes[SMDSEntity_Polyhedra] = VTK_POLYHEDRON; +//#else +// myVtkCellTypes[SMDSEntity_Polyhedra] = VTK_CONVEX_POINT_SET; +//#endif + myVtkCellTypes[SMDSEntity_Quad_Polyhedra] = VTK_CONVEX_POINT_SET; +} + +int SMDS_MeshElementIDFactory::SetInVtkGrid(SMDS_MeshElement * elem) { + // --- retrieve nodes ID + + SMDS_MeshCell *cell = dynamic_cast(elem); + assert(cell); + vector nodeIds; + SMDS_ElemIteratorPtr it = elem->nodesIterator(); + while(it->more()) + { + int nodeId = (static_cast(it->next()))->getVtkId(); + MESSAGE(" node in cell " << cell->getVtkId() << " : " << nodeId) + nodeIds.push_back(nodeId); + } + + // --- insert cell in vtkUnstructuredGrid + + vtkUnstructuredGrid * grid = myMesh->getGrid(); + int typ = GetVtkCellType(elem->GetType()); + int cellId = grid->InsertNextLinkedCell(typ, nodeIds.size(), &nodeIds[0]); + cell->setVtkId(cellId); + //MESSAGE("SMDS_MeshElementIDFactory::SetInVtkGrid " << cellId); + return cellId; } //======================================================================= //function : BindID //purpose : //======================================================================= + bool SMDS_MeshElementIDFactory::BindID(int ID, SMDS_MeshElement * elem) { - if (myIDElements.IsBound(ID)) - return false; - myIDElements.Bind(ID,elem); - elem->myID=ID; - updateMinMax (ID); - return true; + MESSAGE("SMDS_MeshElementIDFactory::BindID " << ID); + SetInVtkGrid(elem); + return myMesh->registerElement(ID, elem); } //======================================================================= //function : MeshElement //purpose : //======================================================================= -SMDS_MeshElement* SMDS_MeshElementIDFactory::MeshElement(int ID) const +SMDS_MeshElement* SMDS_MeshElementIDFactory::MeshElement(int ID) { - if (!myIDElements.IsBound(ID)) + if ((ID<1) || (ID>=myMesh->myCells.size())) return NULL; - return myIDElements.Find(ID); -} - - -//======================================================================= -//function : GetFreeID -//purpose : -//======================================================================= -int SMDS_MeshElementIDFactory::GetFreeID() -{ - int ID; - do { - ID = SMDS_MeshIDFactory::GetFreeID(); - } while (myIDElements.IsBound(ID)); - return ID; + const SMDS_MeshElement* elem = GetMesh()->FindElement(ID); + return (SMDS_MeshElement*)(elem); } //======================================================================= //function : ReleaseID //purpose : //======================================================================= -void SMDS_MeshElementIDFactory::ReleaseID(const int ID) +void SMDS_MeshElementIDFactory::ReleaseID(int ID, int vtkId) { - myIDElements.UnBind(ID); + if (ID < 1) // TODO check case ID == O + { + MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID ID = " << ID); + return; + } + //MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID smdsId vtkId " << ID << " " << vtkId); + if (vtkId >= 0) + { + assert(vtkId < myMesh->myCellIdVtkToSmds.size()); + myMesh->myCellIdVtkToSmds[vtkId] = -1; + myMesh->setMyModified(); + } SMDS_MeshIDFactory::ReleaseID(ID); if (ID == myMax) myMax = 0; if (ID == myMin) - myMin = 0; -} - -//======================================================================= -//function : GetMaxID -//purpose : -//======================================================================= - -int SMDS_MeshElementIDFactory::GetMaxID() const -{ - if (myMax == 0) - updateMinMax(); - return myMax; -} - -//======================================================================= -//function : GetMinID -//purpose : -//======================================================================= - -int SMDS_MeshElementIDFactory::GetMinID() const -{ - if (myMin == 0) - updateMinMax(); - return myMin; + myMax = 0; } //======================================================================= @@ -130,9 +160,17 @@ void SMDS_MeshElementIDFactory::updateMinMax() const { myMin = IntegerLast(); myMax = 0; - SMDS_IdElementMap::Iterator it(myIDElements); - for (; it.More(); it.Next()) - updateMinMax (it.Key()); + for (int i = 0; i < myMesh->myCells.size(); i++) + { + if (myMesh->myCells[i]) + { + int id = myMesh->myCells[i]->GetID(); + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; + } + } if (myMin == IntegerLast()) myMin = 0; } @@ -142,35 +180,21 @@ void SMDS_MeshElementIDFactory::updateMinMax() const //purpose : Return an iterator on elements of the factory //======================================================================= -class SMDS_Fact_MyElemIterator:public SMDS_ElemIterator -{ - SMDS_IdElementMap::Iterator myIterator; - public: - SMDS_Fact_MyElemIterator(const SMDS_IdElementMap& s):myIterator(s) - {} - - bool more() - { - return myIterator.More() != Standard_False; - } - - const SMDS_MeshElement* next() - { - const SMDS_MeshElement* current = myIterator.Value(); - myIterator.Next(); - return current; - } -}; - SMDS_ElemIteratorPtr SMDS_MeshElementIDFactory::elementsIterator() const { - return SMDS_ElemIteratorPtr - (new SMDS_Fact_MyElemIterator(myIDElements)); + return myMesh->elementsIterator(SMDSAbs_All); } void SMDS_MeshElementIDFactory::Clear() { - myIDElements.Clear(); + //myMesh->myCellIdSmdsToVtk.clear(); + myMesh->myCellIdVtkToSmds.clear(); myMin = myMax = 0; SMDS_MeshIDFactory::Clear(); } + +int SMDS_MeshElementIDFactory::GetVtkCellType(int SMDSType) +{ + assert((SMDSType >=0) && (SMDSType< SMDSEntity_Last)); + return myVtkCellTypes[SMDSType]; +} diff --git a/src/SMDS/SMDS_MeshElementIDFactory.hxx b/src/SMDS/SMDS_MeshElementIDFactory.hxx index 548cd452a..3ce1674b4 100644 --- a/src/SMDS/SMDS_MeshElementIDFactory.hxx +++ b/src/SMDS/SMDS_MeshElementIDFactory.hxx @@ -29,28 +29,28 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_MeshIDFactory.hxx" -#include "SMDS_ElemIterator.hxx" +#include "SMDS_MeshNodeIDFactory.hxx" -#include +#include class SMDS_MeshElement; +class SMDS_Mesh; -typedef NCollection_DataMap SMDS_IdElementMap; - -class SMDS_EXPORT SMDS_MeshElementIDFactory:public SMDS_MeshIDFactory +class SMDS_EXPORT SMDS_MeshElementIDFactory:public SMDS_MeshNodeIDFactory { public: + friend class SMDS_Mesh; + SMDS_MeshElementIDFactory(); bool BindID(int ID, SMDS_MeshElement * elem); - SMDS_MeshElement * MeshElement(int ID) const; - virtual int GetFreeID(); - virtual void ReleaseID(int ID); - int GetMaxID() const; - int GetMinID() const; + int SetInVtkGrid(SMDS_MeshElement * elem); + SMDS_MeshElement * MeshElement(int ID); + virtual void ReleaseID(int ID, int vtkId = -1); SMDS_ElemIteratorPtr elementsIterator() const; virtual void Clear(); -private: + int GetVtkCellType(int SMDSType); + +protected: void updateMinMax() const; void updateMinMax(int id) const { @@ -58,8 +58,7 @@ private: if (id < myMin) myMin = id; } - SMDS_IdElementMap myIDElements; - mutable int myMin, myMax; + std::vector myVtkCellTypes; }; diff --git a/src/SMDS/SMDS_MeshFace.cxx b/src/SMDS/SMDS_MeshFace.cxx index 45598898a..691bdc116 100644 --- a/src/SMDS/SMDS_MeshFace.cxx +++ b/src/SMDS/SMDS_MeshFace.cxx @@ -28,3 +28,8 @@ SMDSAbs_ElementType SMDS_MeshFace::GetType() const { return SMDSAbs_Face; } + +vtkIdType SMDS_MeshFace::GetVtkType() const +{ + return VTK_POLY_LINE; // --- must be reimplemented in derived classes +} diff --git a/src/SMDS/SMDS_MeshFace.hxx b/src/SMDS/SMDS_MeshFace.hxx index 2e59ce53e..6587b2960 100644 --- a/src/SMDS/SMDS_MeshFace.hxx +++ b/src/SMDS/SMDS_MeshFace.hxx @@ -29,12 +29,13 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshCell.hxx" -class SMDS_EXPORT SMDS_MeshFace:public SMDS_MeshElement +class SMDS_EXPORT SMDS_MeshFace:public SMDS_MeshCell { public: SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; }; #endif diff --git a/src/SMDS/SMDS_MeshIDFactory.cxx b/src/SMDS/SMDS_MeshIDFactory.cxx index 5d79cf34a..f254c7003 100644 --- a/src/SMDS/SMDS_MeshIDFactory.cxx +++ b/src/SMDS/SMDS_MeshIDFactory.cxx @@ -26,6 +26,8 @@ // Module : SMESH // #include "SMDS_MeshIDFactory.hxx" +#include "SMDS_Mesh.hxx" +#include "utilities.h" using namespace std; @@ -34,27 +36,33 @@ using namespace std; //purpose : //======================================================================= -SMDS_MeshIDFactory::SMDS_MeshIDFactory():myMaxID(0) +SMDS_MeshIDFactory::SMDS_MeshIDFactory():myMaxID(0), myMesh(0) { } int SMDS_MeshIDFactory::GetFreeID() { - if (myPoolOfID.empty()) return ++myMaxID; + int newid; + if (myPoolOfID.empty()) + { + newid = ++myMaxID; + //MESSAGE("GetFreeID new " << newid); + } else { set::iterator i = myPoolOfID.begin(); - int ID = *i;//myPoolOfID.top(); + newid = *i;//myPoolOfID.top(); myPoolOfID.erase( i );//myPoolOfID.pop(); - return ID; + //MESSAGE("GetFreeID pool " << newid); } + return newid; } //======================================================================= //function : ReleaseID //purpose : //======================================================================= -void SMDS_MeshIDFactory::ReleaseID(const int ID) +void SMDS_MeshIDFactory::ReleaseID(int ID, int vtkId) { if ( ID > 0 ) { @@ -83,6 +91,24 @@ void SMDS_MeshIDFactory::ReleaseID(const int ID) void SMDS_MeshIDFactory::Clear() { - myMaxID = 0; - myPoolOfID.clear(); + myMaxID = 0; + myPoolOfID.clear(); +} + +void SMDS_MeshIDFactory::SetMesh(SMDS_Mesh *mesh) +{ + myMesh = mesh; +} + +SMDS_Mesh* SMDS_MeshIDFactory::GetMesh() +{ + return myMesh; +} + +void SMDS_MeshIDFactory::emptyPool(int maxId) +{ + MESSAGE("SMDS_MeshIDFactory::emptyPool " << myMaxID << " --> " << maxId); + myMaxID = maxId; + myPoolOfID.clear(); } + diff --git a/src/SMDS/SMDS_MeshIDFactory.hxx b/src/SMDS/SMDS_MeshIDFactory.hxx index b86abf550..fed18dc69 100644 --- a/src/SMDS/SMDS_MeshIDFactory.hxx +++ b/src/SMDS/SMDS_MeshIDFactory.hxx @@ -32,18 +32,25 @@ #include "SMDS_MeshObject.hxx" #include +class SMDS_Mesh; class SMDS_EXPORT SMDS_MeshIDFactory:public SMDS_MeshObject { public: - virtual int GetFreeID(); - virtual void ReleaseID(int ID); + int GetFreeID(); + virtual void ReleaseID(int ID, int vtkId = -1); virtual void Clear(); - protected: - SMDS_MeshIDFactory(); - int myMaxID; - std::set myPoolOfID; + void SetMesh(SMDS_Mesh *mesh); + SMDS_Mesh* GetMesh(); + inline bool isPoolIdEmpty() { return myPoolOfID.empty(); }; + virtual void emptyPool(int maxId); + inline void adjustMaxId(int ID) { if (ID > myMaxID) myMaxID = ID;}; +protected: + SMDS_MeshIDFactory(); + int myMaxID; + std::set myPoolOfID; + SMDS_Mesh *myMesh; }; #endif diff --git a/src/SMDS/SMDS_MeshNode.cxx b/src/SMDS/SMDS_MeshNode.cxx index 9df6348a5..c574b8671 100644 --- a/src/SMDS/SMDS_MeshNode.cxx +++ b/src/SMDS/SMDS_MeshNode.cxx @@ -29,18 +29,61 @@ #include "SMDS_MeshNode.hxx" #include "SMDS_SpacePosition.hxx" #include "SMDS_IteratorOfElements.hxx" +#include "SMDS_Mesh.hxx" +#include + +#define protected public +#include +#define protected protected + +#include "utilities.h" +#include "Utils_SALOME_Exception.hxx" +#include using namespace std; +int SMDS_MeshNode::nbNodes =0; + //======================================================================= //function : SMDS_MeshNode //purpose : //======================================================================= +SMDS_MeshNode::SMDS_MeshNode() : + SMDS_MeshElement(-1, -1, 0), + myPosition(SMDS_SpacePosition::originSpacePosition()) +{ + nbNodes++; +} + +SMDS_MeshNode::SMDS_MeshNode(int id, int meshId, int shapeId, double x, double y, double z): + SMDS_MeshElement(id, meshId, shapeId), + myPosition(SMDS_SpacePosition::originSpacePosition()) +{ + nbNodes++; + init(id, meshId, shapeId, x, y ,z); +} + +void SMDS_MeshNode::init(int id, int meshId, int shapeId, double x, double y, double z) +{ + myVtkID = id -1; + assert(myVtkID >= 0); + myID = id; + myMeshId = meshId; + myShapeId = shapeId; + myIdInShape = -1; + //MESSAGE("Node " << myID << " " << myVtkID << " (" << x << ", " << y << ", " << z << ")"); + SMDS_Mesh* mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkUnstructuredGrid * grid = mesh->getGrid(); + vtkPoints *points = grid->GetPoints(); + points->InsertPoint(myVtkID, x, y, z); + vtkCellLinks *cellLinks = grid->GetCellLinks(); + if (myVtkID >=cellLinks->Size) + cellLinks->Resize(myVtkID+SMDS_Mesh::chunkSize); +} -SMDS_MeshNode::SMDS_MeshNode(double x, double y, double z): - myX(x), myY(y), myZ(z), - myPosition(SMDS_SpacePosition::originSpacePosition()) +SMDS_MeshNode::~SMDS_MeshNode() { + nbNodes--; } //======================================================================= @@ -50,14 +93,10 @@ SMDS_MeshNode::SMDS_MeshNode(double x, double y, double z): void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent) { - NCollection_List::Iterator it(myInverseElements); - while (it.More()) { - const SMDS_MeshElement* elem = it.Value(); - if (elem == parent) - myInverseElements.Remove(it); - else - it.Next(); - } + //MESSAGE("RemoveInverseElement " << myID << " " << parent->GetID()); + const SMDS_MeshCell* cell = dynamic_cast(parent); + MYASSERT(cell); + SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId()); } //======================================================================= @@ -67,8 +106,8 @@ void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent) void SMDS_MeshNode::Print(ostream & OS) const { - OS << "Node <" << GetID() << "> : X = " << myX << " Y = " - << myY << " Z = " << myZ << endl; + OS << "Node <" << myID << "> : X = " << X() << " Y = " + << Y() << " Z = " << Z() << endl; } //======================================================================= @@ -97,77 +136,116 @@ const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const */ //======================================================================= -class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator +class SMDS_MeshNode_MyInvIterator: public SMDS_ElemIterator { - NCollection_List::Iterator myIterator; - SMDSAbs_ElementType myType; - public: - SMDS_MeshNode_MyInvIterator(const NCollection_List& s, - SMDSAbs_ElementType type): - myIterator(s), myType(type) - {} +private: + SMDS_Mesh* myMesh; + vtkIdType* myCells; + int myNcells; + SMDSAbs_ElementType myType; + int iter; + vector cellList; + +public: + SMDS_MeshNode_MyInvIterator(SMDS_Mesh *mesh, vtkIdType* cells, int ncells, SMDSAbs_ElementType type) : + myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0) + { + //MESSAGE("SMDS_MeshNode_MyInvIterator : ncells " << myNcells); + cellList.clear(); + if (type == SMDSAbs_All) + for (int i = 0; i < ncells; i++) + cellList.push_back(cells[i]); + else for (int i = 0; i < ncells; i++) + { + int vtkId = cells[i]; + int smdsId = myMesh->fromVtkToSmds(vtkId); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (elem->GetType() == type) + { + //MESSAGE("Add element vtkId " << vtkId << " " << elem->GetType()) + cellList.push_back(vtkId); + } + } + myCells = &cellList[0]; + myNcells = cellList.size(); + //MESSAGE("myNcells="<GetType() != myType) - myIterator.Next(); - } - return myIterator.More() != Standard_False; + //MESSAGE("iter " << iter << " ncells " << myNcells); + return (iter < myNcells); } const SMDS_MeshElement* next() { - if ( !more() ) return 0; - const SMDS_MeshElement* current=myIterator.Value(); - myIterator.Next(); - return current; - } + int vtkId = myCells[iter]; + int smdsId = myMesh->fromVtkToSmds(vtkId); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (!elem) + { + MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element"); + throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element"); + } + //MESSAGE("vtkId " << vtkId << " smdsId " << smdsId << " " << elem->GetType()); + iter++; + return elem; + } }; SMDS_ElemIteratorPtr SMDS_MeshNode:: GetInverseElementIterator(SMDSAbs_ElementType type) const { - return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements,type)); + vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); + //MESSAGE("myID " << myID << " ncells " << l.ncells); + return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type)); } // Same as GetInverseElementIterator but the create iterator only return // wanted type elements. class SMDS_MeshNode_MyIterator:public SMDS_ElemIterator { - NCollection_List mySet; - NCollection_List::Iterator myIterator; +private: + SMDS_Mesh* myMesh; + vtkIdType* myCells; + int myNcells; + SMDSAbs_ElementType myType; + int iter; + vector myFiltCells; + public: - SMDS_MeshNode_MyIterator(SMDSAbs_ElementType type, - const NCollection_List& s) + SMDS_MeshNode_MyIterator(SMDS_Mesh *mesh, + vtkIdType* cells, + int ncells, + SMDSAbs_ElementType type): + myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0) { - const SMDS_MeshElement * e; - bool toInsert; - NCollection_List::Iterator it(s); - for(; it.More(); it.Next()) - { - e=it.Value(); - switch(type) - { - case SMDSAbs_Edge: toInsert=true; break; - case SMDSAbs_Face: toInsert=(e->GetType()!=SMDSAbs_Edge); break; - case SMDSAbs_Volume: toInsert=(e->GetType()==SMDSAbs_Volume); break; - } - if(toInsert) mySet.Append(e); - } - myIterator.Init(mySet); + //MESSAGE("myNcells " << myNcells); + for (; iterfromVtkToSmds(vtkId); + //MESSAGE("vtkId " << vtkId << " smdsId " << smdsId); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (elem->GetType() == type) + myFiltCells.push_back((SMDS_MeshElement*)elem); + } + myNcells = myFiltCells.size(); + //MESSAGE("myNcells " << myNcells); + iter = 0; + //MESSAGE("SMDS_MeshNode_MyIterator (filter) " << ncells << " " << myNcells); } bool more() { - return myIterator.More() != Standard_False; + return (iter< myNcells); } const SMDS_MeshElement* next() { - const SMDS_MeshElement* current=myIterator.Value(); - myIterator.Next(); - return current; + const SMDS_MeshElement* elem = myFiltCells[iter]; + iter++; + return elem; } }; @@ -177,10 +255,10 @@ SMDS_ElemIteratorPtr SMDS_MeshNode:: if(type==SMDSAbs_Node) return SMDS_MeshElement::elementsIterator(SMDSAbs_Node); else - return SMDS_ElemIteratorPtr - (new SMDS_IteratorOfElements - (this,type, - SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(type, myInverseElements)))); + { + vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); + return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type)); + } } int SMDS_MeshNode::NbNodes() const @@ -188,26 +266,37 @@ int SMDS_MeshNode::NbNodes() const return 1; } +double* SMDS_MeshNode::getCoord() const +{ + return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetPoint(myVtkID); +} + double SMDS_MeshNode::X() const { - return myX; + double *coord = getCoord(); + return coord[0]; } double SMDS_MeshNode::Y() const { - return myY; + double *coord = getCoord(); + return coord[1]; } double SMDS_MeshNode::Z() const { - return myZ; + double *coord = getCoord(); + return coord[2]; } +//* resize the vtkPoints structure every SMDS_Mesh::chunkSize points void SMDS_MeshNode::setXYZ(double x, double y, double z) { - myX=x; - myY=y; - myZ=z; + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkPoints *points = mesh->getGrid()->GetPoints(); + points->InsertPoint(myVtkID, x, y, z); + mesh->adjustBoundingBox(x, y, z); + mesh->setMyModified(); } SMDSAbs_ElementType SMDS_MeshNode::GetType() const @@ -215,19 +304,20 @@ SMDSAbs_ElementType SMDS_MeshNode::GetType() const return SMDSAbs_Node; } +vtkIdType SMDS_MeshNode::GetVtkType() const +{ + return VTK_VERTEX; +} + //======================================================================= //function : AddInverseElement //purpose : //======================================================================= void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME) { - NCollection_List::Iterator it(myInverseElements); - for (; it.More(); it.Next()) { - const SMDS_MeshElement* elem = it.Value(); - if (elem == ME) - return; - } - myInverseElements.Append(ME); + const SMDS_MeshCell *cell = dynamic_cast(ME); + assert(cell); + SMDS_Mesh::_meshList[myMeshId]->getGrid()->AddReferenceToCell(myVtkID, cell->getVtkId()); } //======================================================================= @@ -236,7 +326,13 @@ void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME) //======================================================================= void SMDS_MeshNode::ClearInverseElements() { - myInverseElements.Clear(); + SMDS_Mesh::_meshList[myMeshId]->getGrid()->ResizeCellList(myVtkID, 0); +} + +bool SMDS_MeshNode::emptyInverseElements() +{ + vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); + return (l.ncells == 0); } //================================================================================ @@ -247,13 +343,19 @@ void SMDS_MeshNode::ClearInverseElements() int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const { + vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); + if ( type == SMDSAbs_All ) - return myInverseElements.Extent(); + return l.ncells; + int nb = 0; - NCollection_List::Iterator it( myInverseElements ); - for ( ; it.More(); it.Next() ) - if ( it.Value()->GetType() == type ) - nb++; + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + for (int i=0; iFindElement(mesh->fromVtkToSmds(l.cells[i])); + if (elem->GetType() == type) + nb++; + } return nb; } @@ -262,7 +364,7 @@ int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const /////////////////////////////////////////////////////////////////////////////// bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2) { - return e1.GetID() class SMDS_EXPORT SMDS_MeshNode:public SMDS_MeshElement { - public: - SMDS_MeshNode(double x, double y, double z); + friend class SMESHDS_Mesh; + friend class SMDS_Mesh; + friend class ObjectPool; + void Print(std::ostream & OS) const; double X() const; double Y() const; double Z() const; - void setXYZ(double x, double y, double z); - - void AddInverseElement(const SMDS_MeshElement * ME); - void RemoveInverseElement(const SMDS_MeshElement * parent); - void ClearInverseElements(); SMDS_ElemIteratorPtr GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; int NbInverseElements(SMDSAbs_ElementType type=SMDSAbs_All) const; - - void SetPosition(const SMDS_PositionPtr& aPos); const SMDS_PositionPtr& GetPosition() const; - SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; SMDSAbs_EntityType GetEntityType() const {return SMDSEntity_Node;} + int NbNodes() const; friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2); - void Print(std::ostream & OS) const; - /*! - * \brief Return node by its index - * \param ind - node index - * \retval const SMDS_MeshNode* - the node - */ - virtual const SMDS_MeshNode* GetNode(const int) const { return this; } - virtual int NbNodes() const; + void SetPosition(const SMDS_PositionPtr& aPos); + void setXYZ(double x, double y, double z); + + static int nbNodes; protected: + SMDS_MeshNode(); + SMDS_MeshNode(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0); + virtual ~SMDS_MeshNode(); + void init(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0); + inline void setVtkId(int vtkId) { myVtkID = vtkId; }; + double* getCoord() const; + void AddInverseElement(const SMDS_MeshElement * ME); + void RemoveInverseElement(const SMDS_MeshElement * parent); + void ClearInverseElements(); + bool emptyInverseElements(); + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; private: - double myX, myY, myZ; SMDS_PositionPtr myPosition; - NCollection_List myInverseElements; }; #endif diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.cxx b/src/SMDS/SMDS_MeshNodeIDFactory.cxx new file mode 100644 index 000000000..4a310419d --- /dev/null +++ b/src/SMDS/SMDS_MeshNodeIDFactory.cxx @@ -0,0 +1,136 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_MeshNodeIDFactory.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_MeshNodeIDFactory.hxx" +#include "SMDS_MeshElement.hxx" +#include "SMDS_Mesh.hxx" + +#include +#include + +using namespace std; + +//======================================================================= +//function : SMDS_MeshNodeIDFactory +//purpose : +//======================================================================= +SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory() : + SMDS_MeshIDFactory(), myMin(0), myMax(0) +{ +} + +//======================================================================= +//function : BindID +//purpose : +//======================================================================= +bool SMDS_MeshNodeIDFactory::BindID(int ID, SMDS_MeshElement * elem) +{ + updateMinMax(ID); + return true; +} + +//======================================================================= +//function : MeshElement +//purpose : +//======================================================================= +SMDS_MeshElement* SMDS_MeshNodeIDFactory::MeshElement(int ID) +{ + if ((ID < 1) || (ID > myMax)) + return NULL; + const SMDS_MeshElement* elem = GetMesh()->FindNode(ID); + return (SMDS_MeshElement*) (elem); +} + +//======================================================================= +//function : ReleaseID +//purpose : +//======================================================================= +void SMDS_MeshNodeIDFactory::ReleaseID(const int ID, int vtkId) +{ + SMDS_MeshIDFactory::ReleaseID(ID); + myMesh->setMyModified(); + if (ID == myMax) + myMax = 0; // --- force updateMinMax + if (ID == myMin) + myMax = 0; // --- force updateMinMax +} + +//======================================================================= +//function : GetMaxID +//purpose : +//======================================================================= + +int SMDS_MeshNodeIDFactory::GetMaxID() const +{ + if (myMax == 0) + updateMinMax(); + return myMax; +} + +//======================================================================= +//function : GetMinID +//purpose : +//======================================================================= + +int SMDS_MeshNodeIDFactory::GetMinID() const +{ + if (myMax == 0) + updateMinMax(); + return myMin; +} + +//======================================================================= +//function : updateMinMax +//purpose : +//======================================================================= + +void SMDS_MeshNodeIDFactory::updateMinMax() const +{ + myMesh->updateNodeMinMax(); + myMin = myMesh->MinNodeID(); + myMax = myMesh->MaxNodeID(); +} + +SMDS_ElemIteratorPtr SMDS_MeshNodeIDFactory::elementsIterator() const +{ + return myMesh->elementsIterator(SMDSAbs_Node); +} + +void SMDS_MeshNodeIDFactory::Clear() +{ + myMin = myMax = 0; + SMDS_MeshIDFactory::Clear(); +} + +void SMDS_MeshNodeIDFactory::emptyPool(int maxId) +{ + SMDS_MeshIDFactory::emptyPool(maxId); + myMax = maxId; +} diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.hxx b/src/SMDS/SMDS_MeshNodeIDFactory.hxx new file mode 100644 index 000000000..a79d68ea1 --- /dev/null +++ b/src/SMDS/SMDS_MeshNodeIDFactory.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_MeshElementIDFactory.hxx +// Module : SMESH +// +#ifndef _SMDS_MeshNodeIDFactory_HeaderFile +#define _SMDS_MeshNodeIDFactory_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshIDFactory.hxx" +#include "SMDS_ElemIterator.hxx" + +#include + +class SMDS_MeshElement; + +class SMDS_EXPORT SMDS_MeshNodeIDFactory: public SMDS_MeshIDFactory +{ +public: + SMDS_MeshNodeIDFactory(); + bool BindID(int ID, SMDS_MeshElement * elem); + SMDS_MeshElement * MeshElement(int ID); + virtual void ReleaseID(int ID, int vtkId = -1); + int GetMaxID() const; + int GetMinID() const; + SMDS_ElemIteratorPtr elementsIterator() const; + virtual void Clear(); + virtual void emptyPool(int maxId); + +protected: + void updateMinMax() const; + void updateMinMax(int id) const + { + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; + } + + mutable int myMin, myMax; + +}; + +#endif diff --git a/src/SMDS/SMDS_MeshVolume.cxx b/src/SMDS/SMDS_MeshVolume.cxx index d4bef7da5..dae6ee1db 100644 --- a/src/SMDS/SMDS_MeshVolume.cxx +++ b/src/SMDS/SMDS_MeshVolume.cxx @@ -36,3 +36,7 @@ SMDSAbs_ElementType SMDS_MeshVolume::GetType() const return SMDSAbs_Volume; } +vtkIdType SMDS_MeshVolume::GetVtkType() const +{ + return VTK_CONVEX_POINT_SET; // --- must be reimplemented in derived classes +} diff --git a/src/SMDS/SMDS_MeshVolume.hxx b/src/SMDS/SMDS_MeshVolume.hxx index ca703b379..0aac68b71 100644 --- a/src/SMDS/SMDS_MeshVolume.hxx +++ b/src/SMDS/SMDS_MeshVolume.hxx @@ -29,12 +29,13 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshCell.hxx" -class SMDS_EXPORT SMDS_MeshVolume:public SMDS_MeshElement +class SMDS_EXPORT SMDS_MeshVolume:public SMDS_MeshCell { public: SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; }; #endif diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx index b441db266..9d7be9028 100644 --- a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx +++ b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx @@ -43,6 +43,7 @@ using namespace std; SMDS_PolygonalFaceOfNodes::SMDS_PolygonalFaceOfNodes (std::vector nodes) { + //MESSAGE("******************************************** SMDS_PolygonalFaceOfNodes"); myNodes = nodes; } diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx index 54143251a..1de208b1b 100644 --- a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx +++ b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx @@ -45,6 +45,7 @@ SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes vector quantities) : SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL) { + //MESSAGE("****************************************** SMDS_PolyhedralVolumeOfNodes"); ChangeNodes(nodes, quantities); } diff --git a/src/SMDS/SMDS_Position.cxx b/src/SMDS/SMDS_Position.cxx index a2dfc7847..e0c6d853d 100644 --- a/src/SMDS/SMDS_Position.cxx +++ b/src/SMDS/SMDS_Position.cxx @@ -26,34 +26,16 @@ // Module : SMESH // #include "SMDS_Position.hxx" +#include "utilities.h" //======================================================================= //function : SMDS_Position //purpose : //======================================================================= -SMDS_Position::SMDS_Position(int aShapeId) :myShapeId(aShapeId) +SMDS_Position::SMDS_Position() { -} - -//======================================================================= -//function : SetShapeId -//purpose : -//======================================================================= - -void SMDS_Position::SetShapeId(int aShapeId) -{ - myShapeId = aShapeId; -} - -//======================================================================= -//function : GetShapeId -//purpose : -//======================================================================= - -int SMDS_Position::GetShapeId() const -{ - return myShapeId; + //MESSAGE("########################## SMDS_Position "); } //======================================================================= diff --git a/src/SMDS/SMDS_Position.hxx b/src/SMDS/SMDS_Position.hxx index 11168fc85..31449526a 100644 --- a/src/SMDS/SMDS_Position.hxx +++ b/src/SMDS/SMDS_Position.hxx @@ -33,24 +33,19 @@ #include class SMDS_Position; -typedef boost::shared_ptr SMDS_PositionPtr; +//typedef boost::shared_ptr SMDS_PositionPtr; +typedef SMDS_Position* SMDS_PositionPtr; class SMDS_EXPORT SMDS_Position { public: - const virtual double * Coords() const = 0; virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0; virtual int GetDim() const; - void SetShapeId(int aShapeId); - int GetShapeId() const; virtual ~SMDS_Position() {} protected: - SMDS_Position(int aShapeId); - - private: - int myShapeId; + SMDS_Position(); }; diff --git a/src/SMDS/SMDS_QuadraticEdge.cxx b/src/SMDS/SMDS_QuadraticEdge.cxx index 2e41ad296..46d0e0f1c 100644 --- a/src/SMDS/SMDS_QuadraticEdge.cxx +++ b/src/SMDS/SMDS_QuadraticEdge.cxx @@ -30,6 +30,7 @@ #include "SMDS_SetIterator.hxx" #include "SMDS_IteratorOfElements.hxx" #include "SMDS_MeshNode.hxx" +#include "utilities.h" using namespace std; @@ -41,8 +42,9 @@ using namespace std; SMDS_QuadraticEdge::SMDS_QuadraticEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, const SMDS_MeshNode * node12) - :SMDS_MeshEdge(node1,node2) -{ + :SMDS_LinearEdge(node1,node2) +{ + //MESSAGE("******************************************************* SMDS_QuadraticEdge"); myNodes[2]=node12; } diff --git a/src/SMDS/SMDS_QuadraticEdge.hxx b/src/SMDS/SMDS_QuadraticEdge.hxx index c0d15ad4d..367f3b041 100644 --- a/src/SMDS/SMDS_QuadraticEdge.hxx +++ b/src/SMDS/SMDS_QuadraticEdge.hxx @@ -29,10 +29,10 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_MeshEdge.hxx" +#include "SMDS_LinearEdge.hxx" #include -class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_MeshEdge +class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_LinearEdge { public: diff --git a/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx b/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx index 6b69227ce..5170f492b 100644 --- a/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx +++ b/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx @@ -49,6 +49,7 @@ SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31) { + //MESSAGE("********************************************** SMDS_QuadraticFaceOfNodes 1"); myNodes.resize( 6 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -73,6 +74,7 @@ SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41) { + //MESSAGE("********************************************* SMDS_QuadraticFaceOfNodes 2"); myNodes.resize( 8 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; diff --git a/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx index ea1147a4c..ff5e4eacd 100644 --- a/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx +++ b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx @@ -54,6 +54,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes const SMDS_MeshNode * n24, const SMDS_MeshNode * n34) { + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); myNodes.resize( 10 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -88,6 +89,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes const SMDS_MeshNode * n35, const SMDS_MeshNode * n45) { + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); myNodes.resize( 13 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -127,6 +129,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes const SMDS_MeshNode * n25, const SMDS_MeshNode * n36) { + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); myNodes.resize( 15 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -173,6 +176,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes const SMDS_MeshNode * n37, const SMDS_MeshNode * n48) { + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); myNodes.resize( 20 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; diff --git a/src/SMDS/SMDS_SpacePosition.cxx b/src/SMDS/SMDS_SpacePosition.cxx index d42acecaa..5835b6434 100644 --- a/src/SMDS/SMDS_SpacePosition.cxx +++ b/src/SMDS/SMDS_SpacePosition.cxx @@ -25,35 +25,21 @@ // Author : Jean-Michel BOULCOURT // Module : SMESH // + #include "SMDS_SpacePosition.hxx" -//======================================================================= -//function : SMDS_SpacePosition -//purpose : -//======================================================================= +SMDS_SpacePosition* SMDS_SpacePosition::_originPosition = new SMDS_SpacePosition(); -SMDS_SpacePosition::SMDS_SpacePosition(double x, double y, double z): - SMDS_Position(0) +SMDS_SpacePosition::SMDS_SpacePosition(double x, double y, double z) { - myCoords[0]=x; - myCoords[1]=y; - myCoords[2]=z; } -/** -*/ SMDS_TypeOfPosition SMDS_SpacePosition::GetTypeOfPosition() const { - return SMDS_TOP_3DSPACE; -} - -const double * SMDS_SpacePosition::Coords() const -{ - return myCoords; + return SMDS_TOP_3DSPACE; } SMDS_PositionPtr SMDS_SpacePosition::originSpacePosition() { - static SMDS_PositionPtr staticpos (new SMDS_SpacePosition()); - return staticpos; + return _originPosition; } diff --git a/src/SMDS/SMDS_SpacePosition.hxx b/src/SMDS/SMDS_SpacePosition.hxx index 4f46dd699..49b7c89e4 100644 --- a/src/SMDS/SMDS_SpacePosition.hxx +++ b/src/SMDS/SMDS_SpacePosition.hxx @@ -34,14 +34,12 @@ class SMDS_EXPORT SMDS_SpacePosition:public SMDS_Position { - public: - SMDS_SpacePosition(double x=0, double y=0, double z=0); - const virtual double * Coords() const; - virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const; - inline void SetCoords(const double x, const double y, const double z); - static SMDS_PositionPtr originSpacePosition(); - private: - double myCoords[3]; +public: + SMDS_SpacePosition(double x=0, double y=0, double z=0); + virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const; + static SMDS_PositionPtr originSpacePosition(); +private: + static SMDS_SpacePosition* _originPosition; }; #endif diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx new file mode 100644 index 000000000..7b65dfdb9 --- /dev/null +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -0,0 +1,841 @@ +#define CHRONODEF +#include "SMDS_UnstructuredGrid.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_MeshInfo.hxx" +#include "SMDS_Downward.hxx" + +#include "utilities.h" + +#include +#include +#include +#include + +#include + +using namespace std; + +SMDS_UnstructuredGrid* SMDS_UnstructuredGrid::New() +{ + MESSAGE("SMDS_UnstructuredGrid::New"); + return new SMDS_UnstructuredGrid(); +} + +SMDS_UnstructuredGrid::SMDS_UnstructuredGrid() : + vtkUnstructuredGrid() +{ + _cellIdToDownId.clear(); + _downTypes.clear(); + _downArray.clear(); + _mesh = 0; +} + +SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid() +{ +} + +unsigned long SMDS_UnstructuredGrid::GetMTime() +{ + unsigned long mtime = vtkUnstructuredGrid::GetMTime(); + MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime); + return mtime; +} + +void SMDS_UnstructuredGrid::Update() +{ + MESSAGE("SMDS_UnstructuredGrid::Update"); + return vtkUnstructuredGrid::Update(); +} + +void SMDS_UnstructuredGrid::UpdateInformation() +{ + MESSAGE("SMDS_UnstructuredGrid::UpdateInformation"); + return vtkUnstructuredGrid::UpdateInformation(); +} + +vtkPoints* SMDS_UnstructuredGrid::GetPoints() +{ + // TODO erreur incomprehensible de la macro vtk GetPoints apparue avec la version paraview de fin aout 2010 + //MESSAGE("*********************** SMDS_UnstructuredGrid::GetPoints " << this->Points << " " << vtkUnstructuredGrid::GetPoints()); + return this->Points; +} + +//#ifdef VTK_HAVE_POLYHEDRON +int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *pts) +{ + if (type != VTK_POLYHEDRON) + return vtkUnstructuredGrid::InsertNextLinkedCell(type, npts, pts); + + // --- type = VTK_POLYHEDRON + MESSAGE("InsertNextLinkedCell VTK_POLYHEDRON"); + int cellid = this->InsertNextCell(type, npts, pts); + + set setOfNodes; + setOfNodes.clear(); + int nbfaces = npts; + int i = 0; + for (int nf = 0; nf < nbfaces; nf++) + { + int nbnodes = pts[i]; + i++; + for (int k = 0; k < nbnodes; k++) + { + MESSAGE(" cell " << cellid << " face " << nf << " node " << pts[i]); + setOfNodes.insert(pts[i]); + i++; + } + } + + set::iterator it = setOfNodes.begin(); + for (; it != setOfNodes.end(); ++it) + { + MESSAGE("reverse link for node " << *it << " cell " << cellid); + this->Links->ResizeCellList(*it, 1); + this->Links->AddCellReference(cellid, *it); + } + + return cellid; +} +//#endif + +void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh) +{ + _mesh = mesh; +} + +void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int newNodeSize, + std::vector& idCellsOldToNew, int newCellSize) +{ + // TODO utiliser mieux vtk pour faire plus simple (plus couteux ?) + + MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize);CHRONO(1); + int startHole = 0; + int endHole = 0; + int startBloc = 0; + int endBloc = 0; + int alreadyCopied = 0; + int holes = 0; + + typedef enum + { + lookHoleStart, lookHoleEnd, lookBlocEnd + } enumState; + enumState compactState = lookHoleStart; + + // if (this->Links) + // { + // this->Links->UnRegister(this); + // this->Links = 0; + // } + + // --- if newNodeSize, create a new compacted vtkPoints + + vtkPoints *newPoints = 0; + if (newNodeSize) + { + MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize); + newPoints = vtkPoints::New(); + newPoints->Initialize(); + newPoints->Allocate(newNodeSize); + newPoints->SetNumberOfPoints(newNodeSize); + int oldNodeSize = idNodesOldToNew.size(); + + for (int i = 0; i < oldNodeSize; i++) + { + //MESSAGE(" " << i << " " << idNodesOldToNew[i]); + switch (compactState) + { + case lookHoleStart: + if (idNodesOldToNew[i] < 0) + { + MESSAGE("-------------- newNodeSize, startHole " << i << " " << oldNodeSize); + startHole = i; + if (!alreadyCopied) // copy the first bloc + { + MESSAGE("--------- copy first nodes before hole " << i << " " << oldNodeSize); + copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, startHole); + } + compactState = lookHoleEnd; + } + break; + case lookHoleEnd: + if (idNodesOldToNew[i] >= 0) + { + MESSAGE("-------------- newNodeSize, endHole " << i << " " << oldNodeSize); + endHole = i; + startBloc = i; + compactState = lookBlocEnd; + } + break; + case lookBlocEnd: + if (idNodesOldToNew[i] < 0) + endBloc = i; // see nbPoints below + else if (i == (oldNodeSize - 1)) + endBloc = i + 1; + if (endBloc) + { + MESSAGE("-------------- newNodeSize, endbloc " << endBloc << " " << oldNodeSize); + copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc); + compactState = lookHoleEnd; + startHole = i; + endHole = 0; + startBloc = 0; + endBloc = 0; + } + break; + } + } + if (!alreadyCopied) // no hole, but shorter, no need to modify idNodesOldToNew + { + MESSAGE("------------- newNodeSize, shorter " << oldNodeSize); + copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, newNodeSize); + } + newPoints->Squeeze(); + } + + // --- create new compacted Connectivity, Locations and Types + + int oldCellSize = this->Types->GetNumberOfTuples(); + + vtkCellArray *newConnectivity = vtkCellArray::New(); + newConnectivity->Initialize(); + int oldCellDataSize = this->Connectivity->GetData()->GetSize(); + newConnectivity->Allocate(oldCellDataSize); + MESSAGE("oldCellSize="<< oldCellSize << " oldCellDataSize=" << oldCellDataSize); + + vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New(); + newTypes->Initialize(); + newTypes->SetNumberOfValues(newCellSize); + + vtkIdTypeArray *newLocations = vtkIdTypeArray::New(); + newLocations->Initialize(); + newLocations->SetNumberOfValues(newCellSize); + + startHole = 0; + endHole = 0; + startBloc = 0; + endBloc = 0; + alreadyCopied = 0; + holes = 0; + compactState = lookHoleStart; + + // TODO some polyhedron may be huge (only in some tests) + vtkIdType tmpid[NBMAXNODESINCELL]; + vtkIdType *pointsCell = &tmpid[0]; // --- points id to fill a new cell + + for (int i = 0; i < oldCellSize; i++) + { + switch (compactState) + { + case lookHoleStart: + if (this->Types->GetValue(i) == VTK_EMPTY_CELL) + { + MESSAGE(" -------- newCellSize, startHole " << i << " " << oldCellSize); + startHole = i; + compactState = lookHoleEnd; + if (!alreadyCopied) // copy the first bloc + { + MESSAGE("--------- copy first bloc before hole " << i << " " << oldCellSize); + copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, + alreadyCopied, 0, startHole); + } + } + break; + case lookHoleEnd: + if (this->Types->GetValue(i) != VTK_EMPTY_CELL) + { + MESSAGE(" -------- newCellSize, EndHole " << i << " " << oldCellSize); + endHole = i; + startBloc = i; + compactState = lookBlocEnd; + holes += endHole - startHole; + } + break; + case lookBlocEnd: + endBloc = 0; + if (this->Types->GetValue(i) == VTK_EMPTY_CELL) + endBloc = i; + else if (i == (oldCellSize - 1)) + endBloc = i + 1; + if (endBloc) + { + MESSAGE(" -------- newCellSize, endBloc " << endBloc << " " << oldCellSize); + copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, + alreadyCopied, startBloc, endBloc); + compactState = lookHoleEnd; + } + break; + } + } + if (!alreadyCopied) // no hole, but shorter + { + MESSAGE(" -------- newCellSize, shorter " << oldCellSize); + copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, 0, + oldCellSize); + } + + newConnectivity->Squeeze(); + //newTypes->Squeeze(); + //newLocations->Squeeze(); + + if (newNodeSize) + { + MESSAGE("------- newNodeSize, setPoints"); + this->SetPoints(newPoints); + MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints()); + } +//#ifdef VTK_HAVE_POLYHEDRON + // TODO compact faces for Polyhedrons + // refaire completement faces et faceLocation + // pour chaque cell, recup oldCellId, oldFacesId, recopie dans newFaces de la faceStream + // en changeant les numeros de noeuds +// vtkIdTypeArray *newFaceLocations = vtkIdTypeArray::New(); +// newFaceLocations->Initialize(); +// vtkIdTypeArray *newFaces = vtkIdTypeArray::New(); +// newFaces->Initialize(); +// newFaceLocations->DeepCopy(this->FaceLocations); +// newFaces->DeepCopy(this->Faces); +// this->SetCells(newTypes, newLocations, newConnectivity, newFaceLocations, newFaces); +// newFaceLocations->Delete(); +// newFaces->Delete(); + if (this->FaceLocations) this->FaceLocations->Register(this); + if (this->Faces) this->Faces->Register(this); + this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces); +//#else +// this->SetCells(newTypes, newLocations, newConnectivity); +//#endif + newTypes->Delete(); + newLocations->Delete(); + newConnectivity->Delete(); + this->BuildLinks(); +} + +void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints, std::vector& idNodesOldToNew, int& alreadyCopied, + int start, int end) +{ + MESSAGE("copyNodes " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); + void *target = newPoints->GetVoidPointer(3 * alreadyCopied); + void *source = this->Points->GetVoidPointer(3 * start); + int nbPoints = end - start; + if (nbPoints > 0) + { + memcpy(target, source, 3 * sizeof(float) * nbPoints); + for (int j = start; j < end; j++) + idNodesOldToNew[j] = alreadyCopied++; // old vtkId --> new vtkId + //idNodesOldToNew[alreadyCopied++] = idNodesOldToNew[j]; // new vtkId --> old SMDS id + } +} + +void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, std::vector& idCellsOldToNew, + std::vector& idNodesOldToNew, vtkCellArray* newConnectivity, + vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied, + int start, int end) +{ + MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); + for (int j = start; j < end; j++) + { + newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); + idCellsOldToNew[j] = alreadyCopied; // old vtkId --> new vtkId + vtkIdType oldLoc = this->Locations->GetValue(j); + vtkIdType nbpts; + vtkIdType *oldPtsCell = 0; + this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell); + assert(nbpts < NBMAXNODESINCELL); + //MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts ); + for (int l = 0; l < nbpts; l++) + { + int oldval = oldPtsCell[l]; + pointsCell[l] = idNodesOldToNew[oldval]; + //MESSAGE(" " << oldval << " " << pointsCell[l]); + } + int newcnt = newConnectivity->InsertNextCell(nbpts, pointsCell); + int newLoc = newConnectivity->GetInsertLocation(nbpts); + //MESSAGE(newcnt << " " << newLoc); + newLocations->SetValue(alreadyCopied, newLoc); + alreadyCopied++; + } +} + +int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId) +{ + // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size())); + return _cellIdToDownId[vtkCellId]; +} + +void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId) +{ + // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size())); + _cellIdToDownId[vtkCellId] = downId; +} + +/*! Build downward connectivity: to do only when needed because heavy memory load. + * Downward connectivity is no more valid if vtkUnstructuredGrid is modified. + * + */ +void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) +{ + MESSAGE("SMDS_UnstructuredGrid::BuildDownwardConnectivity");CHRONO(2); + // TODO calcul partiel sans edges + + // --- erase previous data if any + + for (int i = 0; i < _downArray.size(); i++) + { + if (_downArray[i]) + delete _downArray[i]; + _downArray[i] = 0; + } + _cellIdToDownId.clear(); + + // --- create SMDS_Downward structures (in _downArray vector[vtkCellType]) + + _downArray.resize(VTK_MAXTYPE + 1, 0); // --- max. type value = VTK_QUADRATIC_PYRAMID + + _downArray[VTK_LINE] = new SMDS_DownEdge(this); + _downArray[VTK_QUADRATIC_EDGE] = new SMDS_DownQuadEdge(this); + _downArray[VTK_TRIANGLE] = new SMDS_DownTriangle(this); + _downArray[VTK_QUADRATIC_TRIANGLE] = new SMDS_DownQuadTriangle(this); + _downArray[VTK_QUAD] = new SMDS_DownQuadrangle(this); + _downArray[VTK_QUADRATIC_QUAD] = new SMDS_DownQuadQuadrangle(this); + _downArray[VTK_TETRA] = new SMDS_DownTetra(this); + _downArray[VTK_QUADRATIC_TETRA] = new SMDS_DownQuadTetra(this); + _downArray[VTK_PYRAMID] = new SMDS_DownPyramid(this); + _downArray[VTK_QUADRATIC_PYRAMID] = new SMDS_DownQuadPyramid(this); + _downArray[VTK_WEDGE] = new SMDS_DownPenta(this); + _downArray[VTK_QUADRATIC_WEDGE] = new SMDS_DownQuadPenta(this); + _downArray[VTK_HEXAHEDRON] = new SMDS_DownHexa(this); + _downArray[VTK_QUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this); + + // --- get detailed info of number of cells of each type, allocate SMDS_downward structures + + const SMDS_MeshInfo &meshInfo = _mesh->GetMeshInfo(); + + int nbLinTetra = meshInfo.NbTetras(ORDER_LINEAR); + int nbQuadTetra = meshInfo.NbTetras(ORDER_QUADRATIC); + int nbLinPyra = meshInfo.NbPyramids(ORDER_LINEAR); + int nbQuadPyra = meshInfo.NbPyramids(ORDER_QUADRATIC); + int nbLinPrism = meshInfo.NbPrisms(ORDER_LINEAR); + int nbQuadPrism = meshInfo.NbPrisms(ORDER_QUADRATIC); + int nbLinHexa = meshInfo.NbHexas(ORDER_LINEAR); + int nbQuadHexa = meshInfo.NbHexas(ORDER_QUADRATIC); + + int nbLineGuess = int((4.0 / 3.0) * nbLinTetra + 2 * nbLinPrism + 2.5 * nbLinPyra + 3 * nbLinHexa); + int nbQuadEdgeGuess = int((4.0 / 3.0) * nbQuadTetra + 2 * nbQuadPrism + 2.5 * nbQuadPyra + 3 * nbQuadHexa); + int nbLinTriaGuess = 2 * nbLinTetra + nbLinPrism + 2 * nbLinPyra; + int nbQuadTriaGuess = 2 * nbQuadTetra + nbQuadPrism + 2 * nbQuadPyra; + int nbLinQuadGuess = int((2.0 / 3.0) * nbLinPrism + (1.0 / 2.0) * nbLinPyra + 3 * nbLinHexa); + int nbQuadQuadGuess = int((2.0 / 3.0) * nbQuadPrism + (1.0 / 2.0) * nbQuadPyra + 3 * nbQuadHexa); + + int GuessSize[VTK_QUADRATIC_TETRA]; + GuessSize[VTK_LINE] = nbLineGuess; + GuessSize[VTK_QUADRATIC_EDGE] = nbQuadEdgeGuess; + GuessSize[VTK_TRIANGLE] = nbLinTriaGuess; + GuessSize[VTK_QUADRATIC_TRIANGLE] = nbQuadTriaGuess; + GuessSize[VTK_QUAD] = nbLinQuadGuess; + GuessSize[VTK_QUADRATIC_QUAD] = nbQuadQuadGuess; + GuessSize[VTK_TETRA] = nbLinTetra; + GuessSize[VTK_QUADRATIC_TETRA] = nbQuadTetra; + GuessSize[VTK_PYRAMID] = nbLinPyra; + GuessSize[VTK_QUADRATIC_PYRAMID] = nbQuadPyra; + GuessSize[VTK_WEDGE] = nbLinPrism; + GuessSize[VTK_QUADRATIC_WEDGE] = nbQuadPrism; + GuessSize[VTK_HEXAHEDRON] = nbLinHexa; + GuessSize[VTK_QUADRATIC_HEXAHEDRON] = nbQuadHexa; + + _downArray[VTK_LINE]->allocate(nbLineGuess); + _downArray[VTK_QUADRATIC_EDGE]->allocate(nbQuadEdgeGuess); + _downArray[VTK_TRIANGLE]->allocate(nbLinTriaGuess); + _downArray[VTK_QUADRATIC_TRIANGLE]->allocate(nbQuadTriaGuess); + _downArray[VTK_QUAD]->allocate(nbLinQuadGuess); + _downArray[VTK_QUADRATIC_QUAD]->allocate(nbQuadQuadGuess); + _downArray[VTK_TETRA]->allocate(nbLinTetra); + _downArray[VTK_QUADRATIC_TETRA]->allocate(nbQuadTetra); + _downArray[VTK_PYRAMID]->allocate(nbLinPyra); + _downArray[VTK_QUADRATIC_PYRAMID]->allocate(nbQuadPyra); + _downArray[VTK_WEDGE]->allocate(nbLinPrism); + _downArray[VTK_QUADRATIC_WEDGE]->allocate(nbQuadPrism); + _downArray[VTK_HEXAHEDRON]->allocate(nbLinHexa); + _downArray[VTK_QUADRATIC_HEXAHEDRON]->allocate(nbQuadHexa); + + // --- iteration on vtkUnstructuredGrid cells, only faces + // for each vtk face: + // create a downward face entry with its downward id. + // compute vtk volumes, create downward volumes entry. + // mark face in downward volumes + // mark volumes in downward face + + MESSAGE("--- iteration on vtkUnstructuredGrid cells, only faces");CHRONO(20); + int cellSize = this->Types->GetNumberOfTuples(); + _cellIdToDownId.resize(cellSize, -1); + + for (int i = 0; i < cellSize; i++) + { + int vtkFaceType = this->GetCellType(i); + if (SMDS_Downward::getCellDimension(vtkFaceType) == 2) + { + int vtkFaceId = i; + //ASSERT(_downArray[vtkFaceType]); + int connFaceId = _downArray[vtkFaceType]->addCell(vtkFaceId); + SMDS_Down2D* downFace = static_cast (_downArray[vtkFaceType]); + downFace->setTempNodes(connFaceId, vtkFaceId); + int vols[2] = { -1, -1 }; + int nbVolumes = downFace->computeVolumeIds(vtkFaceId, vols); + //MESSAGE("nbVolumes="<< nbVolumes); + for (int ivol = 0; ivol < nbVolumes; ivol++) + { + int vtkVolId = vols[ivol]; + int vtkVolType = this->GetCellType(vtkVolId); + //ASSERT(_downArray[vtkVolType]); + int connVolId = _downArray[vtkVolType]->addCell(vtkVolId); + _downArray[vtkVolType]->addDownCell(connVolId, connFaceId, vtkFaceType); + _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId, vtkVolType); + // MESSAGE("Face " << vtkFaceId << " belongs to volume " << vtkVolId); + } + } + } + + // --- iteration on vtkUnstructuredGrid cells, only volumes + // for each vtk volume: + // create downward volumes entry if not already done + // build a temporary list of faces described with their nodes + // for each face + // compute the vtk volumes containing this face + // check if the face is already listed in the volumes (comparison of ordered list of nodes) + // if not, create a downward face entry (resizing of structure required) + // (the downward faces store a temporary list of nodes to ease the comparison) + // create downward volumes entry if not already done + // mark volumes in downward face + // mark face in downward volumes + + CHRONOSTOP(20); + MESSAGE("--- iteration on vtkUnstructuredGrid cells, only volumes");CHRONO(21); + + for (int i = 0; i < cellSize; i++) + { + int vtkType = this->GetCellType(i); + if (SMDS_Downward::getCellDimension(vtkType) == 3) + { + //CHRONO(31); + int vtkVolId = i; + // MESSAGE("vtk volume " << vtkVolId); + //ASSERT(_downArray[vtkType]); + int connVolId = _downArray[vtkType]->addCell(vtkVolId); + + // --- find all the faces of the volume, describe the faces by their nodes + + SMDS_Down3D* downVol = static_cast (_downArray[vtkType]); + ListElemByNodesType facesWithNodes; + downVol->computeFacesWithNodes(vtkVolId, facesWithNodes); + // MESSAGE("vtk volume " << vtkVolId << " contains " << facesWithNodes.nbElems << " faces"); + //CHRONOSTOP(31); + for (int iface = 0; iface < facesWithNodes.nbElems; iface++) + { + // --- find the volumes containing the face + + //CHRONO(32); + int vtkFaceType = facesWithNodes.elems[iface].vtkType; + SMDS_Down2D* downFace = static_cast (_downArray[vtkFaceType]); + int vols[2] = { -1, -1 }; + int *nodes = &facesWithNodes.elems[iface].nodeIds[0]; + int lg = facesWithNodes.elems[iface].nbNodes; + int nbVolumes = downFace->computeVolumeIdsFromNodesFace(nodes, lg, vols); + // MESSAGE("vtk volume " << vtkVolId << " face " << iface << " belongs to " << nbVolumes << " volumes"); + + // --- check if face is registered in the volumes + //CHRONOSTOP(32); + + //CHRONO(33); + int connFaceId = -1; + for (int ivol = 0; ivol < nbVolumes; ivol++) + { + int vtkVolId2 = vols[ivol]; + int vtkVolType = this->GetCellType(vtkVolId2); + //ASSERT(_downArray[vtkVolType]); + int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2); + SMDS_Down3D* downVol2 = static_cast (_downArray[vtkVolType]); + connFaceId = downVol2->FindFaceByNodes(connVolId2, facesWithNodes.elems[iface]); + if (connFaceId >= 0) + break; // --- face already created + }//CHRONOSTOP(33); + + // --- if face is not registered in the volumes, create face + + //CHRONO(34); + if (connFaceId < 0) + { + connFaceId = _downArray[vtkFaceType]->addCell(); + downFace->setTempNodes(connFaceId, facesWithNodes.elems[iface]); + }//CHRONOSTOP(34); + + // --- mark volumes in downward face and mark face in downward volumes + + //CHRONO(35); + for (int ivol = 0; ivol < nbVolumes; ivol++) + { + int vtkVolId2 = vols[ivol]; + int vtkVolType = this->GetCellType(vtkVolId2); + //ASSERT(_downArray[vtkVolType]); + int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2); + _downArray[vtkVolType]->addDownCell(connVolId2, connFaceId, vtkFaceType); + _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId2, vtkVolType); + // MESSAGE(" From volume " << vtkVolId << " face " << connFaceId << " belongs to volume " << vtkVolId2); + }//CHRONOSTOP(35); + } + } + } + + // --- iteration on vtkUnstructuredGrid cells, only edges + // for each vtk edge: + // create downward edge entry + // store the nodes id's in downward edge (redundant with vtkUnstructuredGrid) + // find downward faces + // (from vtk faces or volumes, get downward faces, they have a temporary list of nodes) + // mark edge in downward faces + // mark faces in downward edge + + CHRONOSTOP(21); + MESSAGE("--- iteration on vtkUnstructuredGrid cells, only edges");CHRONO(22); + + for (int i = 0; i < cellSize; i++) + { + int vtkEdgeType = this->GetCellType(i); + if (SMDS_Downward::getCellDimension(vtkEdgeType) == 1) + { + int vtkEdgeId = i; + //ASSERT(_downArray[vtkEdgeType]); + int connEdgeId = _downArray[vtkEdgeType]->addCell(vtkEdgeId); + SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); + downEdge->setNodes(connEdgeId, vtkEdgeId); + vector vtkIds; + int nbVtkCells = downEdge->computeVtkCells(connEdgeId, vtkIds); + int downFaces[1000]; + unsigned char downTypes[1000]; + int nbDownFaces = downEdge->computeFaces(connEdgeId, &vtkIds[0], nbVtkCells, downFaces, downTypes); + for (int n = 0; n < nbDownFaces; n++) + { + _downArray[downTypes[n]]->addDownCell(downFaces[n], connEdgeId, vtkEdgeType); + _downArray[vtkEdgeType]->addUpCell(connEdgeId, downFaces[n], downTypes[n]); + } + } + } + + // --- iteration on downward faces (they are all listed now) + // for each downward face: + // build a temporary list of edges with their ordered list of nodes + // for each edge: + // find all the vtk cells containing this edge + // then identify all the downward faces containing the edge, from the vtk cells + // check if the edge is already listed in the faces (comparison of ordered list of nodes) + // if not, create a downward edge entry with the node id's + // mark edge in downward faces + // mark downward faces in edge (size of list unknown, to be allocated) + + CHRONOSTOP(22);CHRONO(23); + + for (int vtkFaceType = 0; vtkFaceType < VTK_QUADRATIC_PYRAMID; vtkFaceType++) + { + if (SMDS_Downward::getCellDimension(vtkFaceType) != 2) + continue; + + // --- find all the edges of the face, describe the edges by their nodes + + SMDS_Down2D* downFace = static_cast (_downArray[vtkFaceType]); + int maxId = downFace->getMaxId(); + for (int faceId = 0; faceId < maxId; faceId++) + { + //CHRONO(40); + ListElemByNodesType edgesWithNodes; + downFace->computeEdgesWithNodes(faceId, edgesWithNodes); + // MESSAGE("downward face type " << vtkFaceType << " num " << faceId << " contains " << edgesWithNodes.nbElems << " edges"); + + //CHRONOSTOP(40); + for (int iedge = 0; iedge < edgesWithNodes.nbElems; iedge++) + { + + // --- check if the edge is already registered by exploration of the faces + + //CHRONO(41); + vector vtkIds; + unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType; + int *pts = &edgesWithNodes.elems[iedge].nodeIds[0]; + SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); + int nbVtkCells = downEdge->computeVtkCells(pts, vtkIds); + //CHRONOSTOP(41);CHRONO(42); + int downFaces[1000]; + unsigned char downTypes[1000]; + int nbDownFaces = downEdge->computeFaces(pts, &vtkIds[0], nbVtkCells, downFaces, downTypes); + //CHRONOSTOP(42); + + //CHRONO(43); + int connEdgeId = -1; + for (int idf = 0; idf < nbDownFaces; idf++) + { + int faceId2 = downFaces[idf]; + int faceType = downTypes[idf]; + //ASSERT(_downArray[faceType]); + SMDS_Down2D* downFace2 = static_cast (_downArray[faceType]); + connEdgeId = downFace2->FindEdgeByNodes(faceId2, edgesWithNodes.elems[iedge]); + if (connEdgeId >= 0) + break; // --- edge already created + }//CHRONOSTOP(43); + + // --- if edge is not registered in the faces, create edge + + if (connEdgeId < 0) + { + //CHRONO(44); + connEdgeId = _downArray[vtkEdgeType]->addCell(); + downEdge->setNodes(connEdgeId, edgesWithNodes.elems[iedge].nodeIds); + //CHRONOSTOP(44); + } + + // --- mark faces in downward edge and mark edge in downward faces + + //CHRONO(45); + for (int idf = 0; idf < nbDownFaces; idf++) + { + int faceId2 = downFaces[idf]; + int faceType = downTypes[idf]; + //ASSERT(_downArray[faceType]); + SMDS_Down2D* downFace2 = static_cast (_downArray[faceType]); + _downArray[vtkEdgeType]->addUpCell(connEdgeId, faceId2, faceType); + _downArray[faceType]->addDownCell(faceId2, connEdgeId, vtkEdgeType); + // MESSAGE(" From face t:" << vtkFaceType << " " << faceId << + // " edge " << connEdgeId << " belongs to face t:" << faceType << " " << faceId2); + }//CHRONOSTOP(45); + } + } + } + + CHRONOSTOP(23);CHRONO(24); + + // compact downward connectivity structure: adjust downward arrays size, replace vector> by a single vector + // 3D first then 2D and last 1D to release memory before edge upCells reorganization, (temporary memory use) + + for (int vtkType = VTK_QUADRATIC_PYRAMID; vtkType >= 0; vtkType--) + { + if (SMDS_Downward *down = _downArray[vtkType]) + { + down->compactStorage(); + } + } + + // --- Statistics + + for (int vtkType = 0; vtkType <= VTK_QUADRATIC_PYRAMID; vtkType++) + { + if (SMDS_Downward *down = _downArray[vtkType]) + { + if (down->getMaxId()) + { + MESSAGE("Cells of Type " << vtkType << " : number of entities, est: " + << GuessSize[vtkType] << " real: " << down->getMaxId()); + } + } + }CHRONOSTOP(24);CHRONOSTOP(2); + counters::stats(); +} + +/*! Get the neighbors of a cell. + * Only the neighbors having the dimension of the cell are taken into account + * (neighbors of a volume are the volumes sharing a face with this volume, + * neighbors of a face are the faces sharing an edge with this face...). + * @param neighborsVtkIds vector of neighbors vtk id's to fill (reserve enough space). + * @param downIds downward id's of cells of dimension n-1, to fill (reserve enough space). + * @param downTypes vtk types of cells of dimension n-1, to fill (reserve enough space). + * @param vtkId the vtk id of the cell + * @return number of neighbors + */ +int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId) +{ + int vtkType = this->GetCellType(vtkId); + int cellDim = SMDS_Downward::getCellDimension(vtkType); + if (cellDim != 3) + return 0; // TODO voisins des faces ou edges + int cellId = this->_cellIdToDownId[vtkId]; + + int nbCells = _downArray[vtkType]->getNumberOfDownCells(cellId); + const int *downCells = _downArray[vtkType]->getDownCells(cellId); + const unsigned char* downTyp = _downArray[vtkType]->getDownTypes(cellId); + + // --- iteration on faces of the 3D cell. + + int nb = 0; + for (int i = 0; i < nbCells; i++) + { + int downId = downCells[i]; + int cellType = downTyp[i]; + int nbUp = _downArray[cellType]->getNumberOfUpCells(downId); + const int *upCells = _downArray[cellType]->getUpCells(downId); + const unsigned char* upTypes = _downArray[cellType]->getUpTypes(downId); + + // --- max 2 upCells, one is this cell, the other is a neighbor + + for (int j = 0; j < nbUp; j++) + { + if ((upCells[j] == cellId) && (upTypes[j] == vtkType)) + continue; + int vtkNeighbor = _downArray[upTypes[j]]->getVtkCellId(upCells[j]); + neighborsVtkIds[nb] = vtkNeighbor; + downIds[nb] = downId; + downTypes[nb] = cellType; + nb++; + } + if (nb >= NBMAXNEIGHBORS) + assert(0); + } + return nb; +} + +/*! get the node id's of a cell. + * The cell is defined by it's downward connectivity id and type. + * @param nodeSet set of of vtk node id's to fill. + * @param downId downward connectivity id of the cell. + * @param downType type of cell. + */ +void SMDS_UnstructuredGrid::GetNodeIds(std::set& nodeSet, int downId, unsigned char downType) +{ + _downArray[downType]->getNodeIds(downId, nodeSet); +} + +/*! change some nodes in cell without modifying type or internal connectivity. + * Nodes inverse connectivity is maintained up to date. + * @param vtkVolId vtk id of the cell + * @param localClonedNodeIds map old node id to new node id. + */ +void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map localClonedNodeIds) +{ + vtkIdType npts = 0; + vtkIdType *pts; // will refer to the point id's of the face + this->GetCellPoints(vtkVolId, npts, pts); + for (int i = 0; i < npts; i++) + { + if (localClonedNodeIds.count(pts[i])) + { + vtkIdType oldpt = pts[i]; + pts[i] = localClonedNodeIds[oldpt]; + //MESSAGE(oldpt << " --> " << pts[i]); + //this->RemoveReferenceToCell(oldpt, vtkVolId); + //this->AddReferenceToCell(pts[i], vtkVolId); + } + } +} + +/*! Create a volume (prism or hexahedron) by duplication of a face. + * the nodes of the new face are already created. + * @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face. + * @param localClonedNodeIds map old node id to new node id. + * @return vtk id of the new volume. + */ +int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, std::vector& orderedNodes) +{ + int vtkType = this->GetCellType(vtkVolId); + int cellDim = SMDS_Downward::getCellDimension(vtkType); + if (cellDim != 3) + return 0; + SMDS_Down3D *downvol = static_cast (_downArray[vtkType]); + int downVolId = this->_cellIdToDownId[vtkVolId]; + downvol->getOrderedNodesOfFace(downVolId, orderedNodes); + return orderedNodes.size(); +} + diff --git a/src/SMDS/SMDS_UnstructuredGrid.hxx b/src/SMDS/SMDS_UnstructuredGrid.hxx new file mode 100644 index 000000000..808a4edf5 --- /dev/null +++ b/src/SMDS/SMDS_UnstructuredGrid.hxx @@ -0,0 +1,80 @@ +/* + * File: SMDS_UnstructuredGrid.hxx + * Author: prascle + * + * Created on September 16, 2009, 10:28 PM + */ + +#ifndef _SMDS_UNSTRUCTUREDGRID_HXX +#define _SMDS_UNSTRUCTUREDGRID_HXX + +#include +#include "chrono.hxx" + +#include +#include +#include + +//#define VTK_HAVE_POLYHEDRON +//#ifdef VTK_HAVE_POLYHEDRON + #define VTK_MAXTYPE VTK_POLYHEDRON +//#else +// #define VTK_MAXTYPE VTK_QUADRATIC_PYRAMID +//#endif + +#define NBMAXNEIGHBORS 100 + +// allow very huge polyhedrons in tests +#define NBMAXNODESINCELL 5000 + +class SMDS_Downward; +class SMDS_Mesh; + +class SMDS_UnstructuredGrid: public vtkUnstructuredGrid +{ +public: + void setSMDS_mesh(SMDS_Mesh *mesh); + void compactGrid(std::vector& idNodesOldToNew, int newNodeSize, std::vector& idCellsOldToNew, + int newCellSize); + + virtual unsigned long GetMTime(); + virtual void Update(); + virtual void UpdateInformation(); + virtual vtkPoints *GetPoints(); + +//#ifdef VTK_HAVE_POLYHEDRON + int InsertNextLinkedCell(int type, int npts, vtkIdType *pts); +//#endif + + int CellIdToDownId(int vtkCellId); + void setCellIdToDownId(int vtkCellId, int downId); + void BuildDownwardConnectivity(bool withEdges); + int GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId); + void GetNodeIds(std::set& nodeSet, int downId, unsigned char downType); + void ModifyCellNodes(int vtkVolId, std::map localClonedNodeIds); + int getOrderedNodesOfFace(int vtkVolId, std::vector& orderedNodes); + vtkCellLinks* GetLinks() + { + return Links; + } + SMDS_Downward* getDownArray(unsigned char vtkType) + { + return _downArray[vtkType]; + } + static SMDS_UnstructuredGrid* New(); + SMDS_Mesh *_mesh; +protected: + SMDS_UnstructuredGrid(); + ~SMDS_UnstructuredGrid(); + void copyNodes(vtkPoints *newPoints, std::vector& idNodesOldToNew, int& alreadyCopied, int start, int end); + void copyBloc(vtkUnsignedCharArray *newTypes, std::vector& idCellsOldToNew, std::vector& idNodesOldToNew, + vtkCellArray* newConnectivity, vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied, + int start, int end); + + std::vector _cellIdToDownId; //!< convert vtk Id to downward[vtkType] id, initialized with -1 + std::vector _downTypes; + std::vector _downArray; +}; + +#endif /* _SMDS_UNSTRUCTUREDGRID_HXX */ + diff --git a/src/SMDS/SMDS_VertexPosition.cxx b/src/SMDS/SMDS_VertexPosition.cxx index 6a2b7dc0d..efc13b792 100644 --- a/src/SMDS/SMDS_VertexPosition.cxx +++ b/src/SMDS/SMDS_VertexPosition.cxx @@ -36,25 +36,13 @@ using namespace std; //purpose : //======================================================================= -SMDS_VertexPosition:: SMDS_VertexPosition(const int aVertexId) - :SMDS_Position(aVertexId) +SMDS_VertexPosition:: SMDS_VertexPosition() { + //MESSAGE("*********************************************** SMDS_VertexPosition " << aVertexId); } -//======================================================================= -//function : Coords -//purpose : -//======================================================================= - -const double *SMDS_VertexPosition::Coords() const -{ - const static double origin[]={0,0,0}; - MESSAGE("SMDS_VertexPosition::Coords not implemented"); - return origin; -} - - SMDS_TypeOfPosition SMDS_VertexPosition::GetTypeOfPosition() const { + //MESSAGE("################################################# GetTypeOfPosition"); return SMDS_TOP_VERTEX; } diff --git a/src/SMDS/SMDS_VertexPosition.hxx b/src/SMDS/SMDS_VertexPosition.hxx index 845f20aaf..0fbfd1b86 100644 --- a/src/SMDS/SMDS_VertexPosition.hxx +++ b/src/SMDS/SMDS_VertexPosition.hxx @@ -36,8 +36,7 @@ class SMDS_EXPORT SMDS_VertexPosition:public SMDS_Position public: SMDS_TypeOfPosition GetTypeOfPosition() const; - SMDS_VertexPosition(int aVertexId=0); - const double *Coords() const; + SMDS_VertexPosition(); }; #endif diff --git a/src/SMDS/SMDS_VolumeOfFaces.cxx b/src/SMDS/SMDS_VolumeOfFaces.cxx index 6b006b938..4b3cabc1f 100644 --- a/src/SMDS/SMDS_VolumeOfFaces.cxx +++ b/src/SMDS/SMDS_VolumeOfFaces.cxx @@ -31,6 +31,7 @@ #include "SMDS_VolumeOfFaces.hxx" #include "SMDS_IteratorOfElements.hxx" +#include "utilities.h" using namespace std; @@ -96,6 +97,7 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, const SMDS_MeshFace * face3, const SMDS_MeshFace * face4) { + //MESSAGE("****************************************************** SMDS_VolumeOfFaces"); myNbFaces = 4; myFaces[0]=face1; myFaces[1]=face2; @@ -111,6 +113,7 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, const SMDS_MeshFace * face4, const SMDS_MeshFace * face5) { + //MESSAGE("****************************************************** SMDS_VolumeOfFaces"); myNbFaces = 5; myFaces[0]=face1; myFaces[1]=face2; @@ -127,6 +130,7 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, const SMDS_MeshFace * face5, const SMDS_MeshFace * face6) { + //MESSAGE("****************************************************** SMDS_VolumeOfFaces"); myNbFaces = 6; myFaces[0]=face1; myFaces[1]=face2; diff --git a/src/SMDS/SMDS_VolumeOfFaces.hxx b/src/SMDS/SMDS_VolumeOfFaces.hxx index 05d96422c..1b93c68a0 100644 --- a/src/SMDS/SMDS_VolumeOfFaces.hxx +++ b/src/SMDS/SMDS_VolumeOfFaces.hxx @@ -56,8 +56,9 @@ class SMDS_EXPORT SMDS_VolumeOfFaces:public SMDS_MeshVolume const SMDS_MeshFace * face6); virtual SMDSAbs_EntityType GetEntityType() const; + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;}; void Print(std::ostream & OS) const; - + int NbFaces() const; protected: diff --git a/src/SMDS/SMDS_VolumeOfNodes.cxx b/src/SMDS/SMDS_VolumeOfNodes.cxx index 7c7795563..c17e21d26 100644 --- a/src/SMDS/SMDS_VolumeOfNodes.cxx +++ b/src/SMDS/SMDS_VolumeOfNodes.cxx @@ -30,10 +30,9 @@ #include "SMDS_MeshNode.hxx" #include "SMDS_SetIterator.hxx" #include "SMDS_VolumeTool.hxx" +#include "SMDS_Mesh.hxx" #include "utilities.h" -#include - using namespace std; /////////////////////////////////////////////////////////////////////////////// @@ -50,6 +49,7 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( const SMDS_MeshNode * node7, const SMDS_MeshNode * node8) { + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); myNbNodes = 8; myNodes = new const SMDS_MeshNode* [myNbNodes]; myNodes[0]=node1; @@ -68,6 +68,7 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( const SMDS_MeshNode * node3, const SMDS_MeshNode * node4) { + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); myNbNodes = 4; myNodes = new const SMDS_MeshNode* [myNbNodes]; myNodes[0]=node1; @@ -83,6 +84,7 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( const SMDS_MeshNode * node4, const SMDS_MeshNode * node5) { + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); myNbNodes = 5; myNodes = new const SMDS_MeshNode* [myNbNodes]; myNodes[0]=node1; @@ -100,6 +102,7 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( const SMDS_MeshNode * node5, const SMDS_MeshNode * node6) { + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); myNbNodes = 6; myNodes = new const SMDS_MeshNode* [myNbNodes]; myNodes[0]=node1; @@ -133,11 +136,6 @@ SMDS_VolumeOfNodes::~SMDS_VolumeOfNodes() } } -//======================================================================= -//function : Print -//purpose : -//======================================================================= - void SMDS_VolumeOfNodes::Print(ostream & OS) const { OS << "volume <" << GetID() << "> : "; @@ -177,12 +175,9 @@ int SMDS_VolumeOfNodes::NbEdges() const return 0; } -/// =================================================================== /*! * \brief Iterator on node of volume */ -/// =================================================================== - class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator { public: @@ -190,12 +185,9 @@ class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator SMDS_NodeArrayElemIterator( s, & s[ l ]) {} }; -/// =================================================================== /*! * \brief Iterator on faces or edges of volume */ -/// =================================================================== - class _MySubIterator : public SMDS_ElemIterator { vector< const SMDS_MeshElement* > myElems; @@ -261,3 +253,5 @@ SMDSAbs_EntityType SMDS_VolumeOfNodes::GetEntityType() const } return aType; } + + diff --git a/src/SMDS/SMDS_VolumeOfNodes.hxx b/src/SMDS/SMDS_VolumeOfNodes.hxx index 6f6600d39..c194ea3ba 100644 --- a/src/SMDS/SMDS_VolumeOfNodes.hxx +++ b/src/SMDS/SMDS_VolumeOfNodes.hxx @@ -85,5 +85,7 @@ class SMDS_EXPORT SMDS_VolumeOfNodes:public SMDS_MeshVolume elementsIterator(SMDSAbs_ElementType type) const; const SMDS_MeshNode** myNodes; int myNbNodes; + }; + #endif diff --git a/src/SMDS/SMDS_VolumeTool.cxx b/src/SMDS/SMDS_VolumeTool.cxx index 42640287c..913281eae 100644 --- a/src/SMDS/SMDS_VolumeTool.cxx +++ b/src/SMDS/SMDS_VolumeTool.cxx @@ -32,7 +32,7 @@ #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_VtkVolume.hxx" #include "SMDS_Mesh.hxx" #include "utilities.h" @@ -418,6 +418,7 @@ SMDS_VolumeTool::SMDS_VolumeTool () myFaceNodeIndices( NULL ), myFaceNodes( NULL ) { + //MESSAGE("******************************************************** SMDS_VolumeToo"); } //======================================================================= @@ -438,6 +439,7 @@ SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume) myFaceNodeIndices( NULL ), myFaceNodes( NULL ) { + //MESSAGE("******************************************************** SMDS_VolumeToo"); Set( theVolume ); } @@ -499,7 +501,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume) } if (myVolume->IsPoly()) { - myPolyedre = static_cast( myVolume ); + myPolyedre = dynamic_cast( myVolume ); if (!myPolyedre) { MESSAGE("Warning: bad volumic element"); return false; @@ -694,12 +696,13 @@ double SMDS_VolumeTool::GetSize() const if ( !myPolyedre ) return 0.; + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myPolyedre->getMeshId()]; // split a polyhedron into tetrahedrons SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this ); XYZ baryCenter; me->GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z); - SMDS_MeshNode bcNode ( baryCenter.x, baryCenter.y, baryCenter.z ); + SMDS_MeshNode *bcNode = mesh->AddNode( baryCenter.x, baryCenter.y, baryCenter.z ); for ( int f = 0; f < NbFaces(); ++f ) { @@ -709,11 +712,12 @@ double SMDS_VolumeTool::GetSize() const double Vn = getTetraVolume( myFaceNodes[ 0 ], myFaceNodes[ n-1 ], myFaceNodes[ n ], - & bcNode ); + bcNode ); /// cout <<"++++ " << Vn << " nodes " <GetID() << " " <GetID() << " " <GetID() << " < " << V << endl; V += externalFace ? -Vn : Vn; } } + mesh->RemoveNode(bcNode); } else { diff --git a/src/SMDS/SMDS_VolumeTool.hxx b/src/SMDS/SMDS_VolumeTool.hxx index 8d82a6091..2e17f145b 100644 --- a/src/SMDS/SMDS_VolumeTool.hxx +++ b/src/SMDS/SMDS_VolumeTool.hxx @@ -33,7 +33,7 @@ class SMDS_MeshElement; class SMDS_MeshNode; -class SMDS_PolyhedralVolumeOfNodes; +class SMDS_VtkVolume; class SMDS_MeshVolume; #include @@ -212,7 +212,7 @@ private: bool setFace( int faceIndex ); const SMDS_MeshElement* myVolume; - const SMDS_PolyhedralVolumeOfNodes* myPolyedre; + const SMDS_VtkVolume* myPolyedre; bool myVolForward; int myNbFaces; diff --git a/src/SMDS/SMDS_VtkCellIterator.cxx b/src/SMDS/SMDS_VtkCellIterator.cxx new file mode 100644 index 000000000..0a4163bb9 --- /dev/null +++ b/src/SMDS/SMDS_VtkCellIterator.cxx @@ -0,0 +1,234 @@ +#include "SMDS_VtkCellIterator.hxx" +#include "utilities.h" + +SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : + _mesh(mesh), _cellId(vtkCellId), _index(0), _type(aType) +{ + //MESSAGE("SMDS_VtkCellIterator " << _type); + _vtkIdList = vtkIdList::New(); + vtkUnstructuredGrid* grid = _mesh->getGrid(); + grid->GetCellPoints(_cellId, _vtkIdList); + _nbNodes = _vtkIdList->GetNumberOfIds(); + switch (_type) + { + case SMDSEntity_Tetra: + { + this->exchange(1, 2); + break; + } + case SMDSEntity_Pyramid: + { + this->exchange(1, 3); + break; + } + case SMDSEntity_Penta: + { + //this->exchange(1, 2); + //this->exchange(4, 5); + break; + } + case SMDSEntity_Hexa: + { + this->exchange(1, 3); + this->exchange(5, 7); + break; + } + case SMDSEntity_Quad_Tetra: + { + this->exchange(1, 2); + this->exchange(4, 6); + this->exchange(8, 9); + break; + } + case SMDSEntity_Quad_Pyramid: + { + this->exchange(1, 3); + this->exchange(5, 8); + this->exchange(6, 7); + this->exchange(10, 12); + break; + } + case SMDSEntity_Quad_Penta: + { + //this->exchange(1, 2); + //this->exchange(4, 5); + //this->exchange(6, 8); + //this->exchange(9, 11); + //this->exchange(13, 14); + break; + } + case SMDSEntity_Quad_Hexa: + { + MESSAGE("SMDS_VtkCellIterator Quad_Hexa"); + this->exchange(1, 3); + this->exchange(5, 7); + this->exchange(8, 11); + this->exchange(9, 10); + this->exchange(12, 15); + this->exchange(13, 14); + this->exchange(17, 19); + break; + } + case SMDSEntity_Polyhedra: + MESSAGE("SMDS_VtkCellIterator Polyhedra (iterate on actual nodes)"); + break; + default: + break; + } +} + +SMDS_VtkCellIterator::~SMDS_VtkCellIterator() +{ + _vtkIdList->Delete(); +} + +bool SMDS_VtkCellIterator::more() +{ + return (_index < _nbNodes); +} + +const SMDS_MeshElement* SMDS_VtkCellIterator::next() +{ + vtkIdType id = _vtkIdList->GetId(_index++); + return _mesh->FindNodeVtk(id); +} + +SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : + SMDS_VtkCellIterator() +{ + _mesh = mesh; + _cellId = vtkCellId; + _index = 0; + _type = aType; + //MESSAGE("SMDS_VtkCellInterlacedIterator (UNV)" << _type); + + _vtkIdList = vtkIdList::New(); + vtkIdType* pts; + vtkUnstructuredGrid* grid = _mesh->getGrid(); + grid->GetCellPoints(_cellId, _nbNodes, pts); + _vtkIdList->SetNumberOfIds(_nbNodes); + int *ids = 0; + switch (_type) + { + case SMDSEntity_Quad_Edge: + { + static int id[] = { 0, 2, 1 }; + ids = id; + break; + } + case SMDSEntity_Quad_Triangle: + { + static int id[] = { 0, 3, 1, 4, 2, 5 }; + ids = id; + break; + } + case SMDSEntity_Quad_Quadrangle: + { + static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 }; + ids = id; + break; + } + case SMDSEntity_Quad_Tetra: + { + static int id[] = { 0, 4, 1, 5, 2, 6, 7, 8, 9, 3 }; + ids = id; + break; + } + case SMDSEntity_Quad_Pyramid: + { + static int id[] = { 0, 5, 1, 6, 2, 7, 3, 8, 9, 10, 11, 12, 4 }; + ids = id; + break; + } + case SMDSEntity_Penta: + { + static int id[] = { 0, 2, 1, 3, 5, 4 }; + ids = id; + break; + } + case SMDSEntity_Quad_Penta: + { + static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 }; + ids = id; + break; + } + case SMDSEntity_Quad_Hexa: + { + static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 }; + ids = id; + break; + } + case SMDSEntity_Polygon: + case SMDSEntity_Quad_Polygon: + case SMDSEntity_Polyhedra: + case SMDSEntity_Quad_Polyhedra: + default: + { + static int id[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29 }; + ids = id; + break; + } + } + //MESSAGE("_nbNodes " << _nbNodes); + for (int i = 0; i < _nbNodes; i++) + _vtkIdList->SetId(i, pts[ids[i]]); +} + +SMDS_VtkCellIteratorToUNV::~SMDS_VtkCellIteratorToUNV() +{ +} + +SMDS_VtkCellIteratorPolyH::SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : + SMDS_VtkCellIterator() +{ + _mesh = mesh; + _cellId = vtkCellId; + _index = 0; + _type = aType; + //MESSAGE("SMDS_VtkCellIteratorPolyH " << _type); + _vtkIdList = vtkIdList::New(); + vtkUnstructuredGrid* grid = _mesh->getGrid(); + grid->GetCellPoints(_cellId, _vtkIdList); + _nbNodes = _vtkIdList->GetNumberOfIds(); + switch (_type) + { + case SMDSEntity_Polyhedra: + { + //MESSAGE("SMDS_VtkCellIterator Polyhedra"); + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(_cellId, nFaces, ptIds); + int id = 0; + _nbNodesInFaces = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + _nbNodesInFaces += nodesInFace; + id += (nodesInFace + 1); + } + _vtkIdList->SetNumberOfIds(_nbNodesInFaces); + id = 0; + int n = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + for (int k = 1; k <= nodesInFace; k++) + _vtkIdList->SetId(n++, ptIds[id + k]); + id += (nodesInFace + 1); + } + break; + } + default: + assert(0); + } +} + +SMDS_VtkCellIteratorPolyH::~SMDS_VtkCellIteratorPolyH() +{ +} + +bool SMDS_VtkCellIteratorPolyH::more() +{ + return (_index < _nbNodesInFaces); +} diff --git a/src/SMDS/SMDS_VtkCellIterator.hxx b/src/SMDS/SMDS_VtkCellIterator.hxx new file mode 100644 index 000000000..91ab3dcb8 --- /dev/null +++ b/src/SMDS/SMDS_VtkCellIterator.hxx @@ -0,0 +1,53 @@ +#ifndef _SMDS_VTKCELLITERATOR_HXX_ +#define _SMDS_VTKCELLITERATOR_HXX_ + +#include "SMDS_ElemIterator.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDSAbs_ElementType.hxx" + +#include +#include + +class SMDS_VtkCellIterator: public SMDS_ElemIterator +{ +public: + SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + virtual ~SMDS_VtkCellIterator(); + virtual bool more(); + virtual const SMDS_MeshElement* next(); + inline void exchange(vtkIdType a, vtkIdType b) + { + vtkIdType t = _vtkIdList->GetId(a); + _vtkIdList->SetId(a, _vtkIdList->GetId(b)); + _vtkIdList->SetId(b, t); + } + +protected: + SMDS_VtkCellIterator() {}; + + SMDS_Mesh* _mesh; + int _cellId; + int _index; + int _nbNodes; + SMDSAbs_EntityType _type; + vtkIdList* _vtkIdList; +}; + +class SMDS_VtkCellIteratorToUNV: public SMDS_VtkCellIterator +{ +public: + SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + virtual ~SMDS_VtkCellIteratorToUNV(); +}; + +class SMDS_VtkCellIteratorPolyH: public SMDS_VtkCellIterator +{ +public: + SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + virtual ~SMDS_VtkCellIteratorPolyH(); + virtual bool more(); +protected: + int _nbNodesInFaces; +}; + +#endif diff --git a/src/SMDS/SMDS_VtkEdge.cxx b/src/SMDS/SMDS_VtkEdge.cxx new file mode 100644 index 000000000..6cd006d51 --- /dev/null +++ b/src/SMDS/SMDS_VtkEdge.cxx @@ -0,0 +1,151 @@ +#include "SMDS_VtkEdge.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" + +#include "utilities.h" + +#include +#include + +using namespace std; + +SMDS_VtkEdge::SMDS_VtkEdge() +{ +} + +SMDS_VtkEdge::SMDS_VtkEdge(std::vector nodeIds, SMDS_Mesh* mesh) +{ + init(nodeIds, mesh); +} + +SMDS_VtkEdge::~SMDS_VtkEdge() +{ +} + +void SMDS_VtkEdge::init(std::vector nodeIds, SMDS_Mesh* mesh) +{ + vtkUnstructuredGrid* grid = mesh->getGrid(); + myIdInShape = -1; + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_LINE; + if (nodeIds.size() == 3) + aType = VTK_QUADRATIC_EDGE; + myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); + mesh->setMyModified(); + //MESSAGE("SMDS_VtkEdge::init myVtkID " << myVtkID); +} + +bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) +{ + const SMDS_MeshNode* nodes[] = { node1, node2 }; + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return ChangeNodes(nodes, 2); +} + +bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + for (int i = 0; i < nbNodes; i++) + { + pts[i] = nodes[i]->getVtkId(); + } + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +bool SMDS_VtkEdge::IsMediumNode(const SMDS_MeshNode* node) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + //MESSAGE("IsMediumNode " << npts << " " << (node->getVtkId() == pts[npts-1])); + return ((npts == 3) && (node->getVtkId() == pts[2])); +} + +void SMDS_VtkEdge::Print(std::ostream & OS) const +{ + OS << "edge <" << GetID() << "> : "; +} + +int SMDS_VtkEdge::NbNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); + assert(nbPoints >= 2); + return nbPoints; +} + +int SMDS_VtkEdge::NbEdges() const +{ + return 1; +} + +SMDSAbs_EntityType SMDS_VtkEdge::GetEntityType() const +{ + if (NbNodes() == 2) + return SMDSEntity_Edge; + else + return SMDSEntity_Quad_Edge; +} + +vtkIdType SMDS_VtkEdge::GetVtkType() const +{ + if (NbNodes() == 2) + return VTK_LINE; + else + return VTK_QUADRATIC_EDGE; + +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* +SMDS_VtkEdge::GetNode(const int ind) const +{ + // TODO optimize !! + return SMDS_MeshElement::GetNode(ind); +} + +bool SMDS_VtkEdge::IsQuadratic() const +{ + if (this->NbNodes() > 2) + return true; + else + return false; +} + +SMDS_ElemIteratorPtr SMDS_VtkEdge::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); + default: + MESSAGE("ERROR : Iterator not implemented") + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + +SMDS_ElemIteratorPtr SMDS_VtkEdge::nodesIteratorToUNV() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDS_ElemIteratorPtr SMDS_VtkEdge::interlacedNodesElemIterator() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} diff --git a/src/SMDS/SMDS_VtkEdge.hxx b/src/SMDS/SMDS_VtkEdge.hxx new file mode 100644 index 000000000..e7aa32bed --- /dev/null +++ b/src/SMDS/SMDS_VtkEdge.hxx @@ -0,0 +1,36 @@ +#ifndef _SMDS_VTKEDGE_HXX_ +#define _SMDS_VTKEDGE_HXX_ + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshEdge.hxx" +#include +#include + +class SMDS_EXPORT SMDS_VtkEdge: public SMDS_MeshEdge +{ + +public: + SMDS_VtkEdge(); + SMDS_VtkEdge(std::vector nodeIds, SMDS_Mesh* mesh); + ~SMDS_VtkEdge(); + void init(std::vector nodeIds, SMDS_Mesh* mesh); + bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + void Print(std::ostream & OS) const; + int NbNodes() const; + int NbEdges() const; + + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + virtual bool IsQuadratic() const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; +protected: +}; +#endif diff --git a/src/SMDS/SMDS_VtkFace.cxx b/src/SMDS/SMDS_VtkFace.cxx new file mode 100644 index 000000000..79a087709 --- /dev/null +++ b/src/SMDS/SMDS_VtkFace.cxx @@ -0,0 +1,262 @@ +#include "SMDS_VtkFace.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" + +#include "utilities.h" + +#include + +using namespace std; + +SMDS_VtkFace::SMDS_VtkFace() +{ +} + +SMDS_VtkFace::SMDS_VtkFace(std::vector nodeIds, SMDS_Mesh* mesh) +{ + init(nodeIds, mesh); +} + +SMDS_VtkFace::~SMDS_VtkFace() +{ +} + +void SMDS_VtkFace::init(std::vector nodeIds, SMDS_Mesh* mesh) +{ + vtkUnstructuredGrid* grid = mesh->getGrid(); + myIdInShape = -1; + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_TRIANGLE; + switch (nodeIds.size()) + { + case 3: + aType = VTK_TRIANGLE; + break; + case 4: + aType = VTK_QUAD; + break; + case 6: + aType = VTK_QUADRATIC_TRIANGLE; + break; + case 8: + aType = VTK_QUADRATIC_QUAD; + break; + default: + aType = VTK_POLYGON; + break; + } + myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); + mesh->setMyModified(); + //MESSAGE("SMDS_VtkFace::init myVtkID " << myVtkID); +} + +void SMDS_VtkFace::initPoly(std::vector nodeIds, SMDS_Mesh* mesh) +{ + vtkUnstructuredGrid* grid = mesh->getGrid(); + myIdInShape = -1; + myMeshId = mesh->getMeshId(); + myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), &nodeIds[0]); + mesh->setMyModified(); +} + +bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + for (int i = 0; i < nbNodes; i++) + { + pts[i] = nodes[i]->getVtkId(); + } + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +void SMDS_VtkFace::Print(std::ostream & OS) const +{ + OS << "face <" << GetID() << "> : "; +} + +int SMDS_VtkFace::NbEdges() const +{ + // TODO quadratic polygons ? + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbEdges = 3; + switch (aVtkType) + { + case VTK_TRIANGLE: + case VTK_QUADRATIC_TRIANGLE: + nbEdges = 3; + break; + case VTK_QUAD: + case VTK_QUADRATIC_QUAD: + nbEdges = 4; + break; + case VTK_POLYGON: + default: + nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints(); + break; + } + return nbEdges; +} + +int SMDS_VtkFace::NbFaces() const +{ + return 1; +} + +int SMDS_VtkFace::NbNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); + return nbPoints; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* +SMDS_VtkFace::GetNode(const int ind) const +{ + return SMDS_MeshElement::GetNode(ind); // --- a optimiser ! +} + +bool SMDS_VtkFace::IsQuadratic() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + // TODO quadratic polygons ? + switch (aVtkType) + { + case VTK_QUADRATIC_TRIANGLE: + case VTK_QUADRATIC_QUAD: + return true; + break; + default: + return false; + } +} + +bool SMDS_VtkFace::IsPoly() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return (aVtkType == VTK_POLYGON); +} + +bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int rankFirstMedium = 0; + switch (aVtkType) + { + case VTK_QUADRATIC_TRIANGLE: + rankFirstMedium = 3; // medium nodes are of rank 3,4,5 + break; + case VTK_QUADRATIC_QUAD: + rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7 + break; + default: + //MESSAGE("wrong element type " << aVtkType); + return false; + } + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + vtkIdType nodeId = node->getVtkId(); + for (int rank = 0; rank < npts; rank++) + { + if (pts[rank] == nodeId) + { + //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium)); + if (rank < rankFirstMedium) + return false; + else + return true; + } + } + //throw SALOME_Exception(LOCALIZED("node does not belong to this element")); + MESSAGE("======================================================"); + MESSAGE("= IsMediumNode: node does not belong to this element ="); + MESSAGE("======================================================"); + return false; +} + +SMDSAbs_EntityType SMDS_VtkFace::GetEntityType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + SMDSAbs_EntityType aType = SMDSEntity_Polygon; + switch (aVtkType) + { + case VTK_TRIANGLE: + aType = SMDSEntity_Triangle; + break; + case VTK_QUAD: + aType = SMDSEntity_Quadrangle; + break; + case VTK_QUADRATIC_TRIANGLE: + aType = SMDSEntity_Quad_Triangle; + break; + case VTK_QUADRATIC_QUAD: + aType = SMDSEntity_Quad_Quadrangle; + break; + default: + aType = SMDSEntity_Polygon; + } + return aType; +} + +vtkIdType SMDS_VtkFace::GetVtkType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return aVtkType; +} + +SMDS_ElemIteratorPtr SMDS_VtkFace::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); + default: + MESSAGE("ERROR : Iterator not implemented") + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + +SMDS_ElemIteratorPtr SMDS_VtkFace::nodesIteratorToUNV() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDS_ElemIteratorPtr SMDS_VtkFace::interlacedNodesElemIterator() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +//! change only the first node, used for temporary triangles in quadrangle to triangle adaptor +void SMDS_VtkFace::ChangeApex(const SMDS_MeshNode* node) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + grid->RemoveReferenceToCell(pts[0], myVtkID); + pts[0] = node->getVtkId(); + grid->AddReferenceToCell(pts[0], myVtkID); + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); +} diff --git a/src/SMDS/SMDS_VtkFace.hxx b/src/SMDS/SMDS_VtkFace.hxx new file mode 100644 index 000000000..7a346fd55 --- /dev/null +++ b/src/SMDS/SMDS_VtkFace.hxx @@ -0,0 +1,38 @@ +#ifndef _SMDS_VTKFACE_HXX_ +#define _SMDS_VTKFACE_HXX_ + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshFace.hxx" +#include +#include + +class SMDS_EXPORT SMDS_VtkFace: public SMDS_MeshFace +{ +public: + SMDS_VtkFace(); + SMDS_VtkFace(std::vector nodeIds, SMDS_Mesh* mesh); + ~SMDS_VtkFace(); + void init(std::vector nodeIds, SMDS_Mesh* mesh); + void initPoly(std::vector nodeIds, SMDS_Mesh* mesh); + bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + void ChangeApex(const SMDS_MeshNode* node); // to use only for tmp triangles + void Print(std::ostream & OS) const; + int NbEdges() const; + int NbFaces() const; + int NbNodes() const; + + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + virtual bool IsQuadratic() const; + virtual bool IsPoly() const; + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; +protected: +}; + +#endif diff --git a/src/SMDS/SMDS_VtkVolume.cxx b/src/SMDS/SMDS_VtkVolume.cxx new file mode 100644 index 000000000..45c61be31 --- /dev/null +++ b/src/SMDS/SMDS_VtkVolume.cxx @@ -0,0 +1,594 @@ +#include "SMDS_VtkVolume.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" + +#include "utilities.h" + +#include + +SMDS_VtkVolume::SMDS_VtkVolume() +{ +} + +SMDS_VtkVolume::SMDS_VtkVolume(std::vector nodeIds, SMDS_Mesh* mesh) +{ + init(nodeIds, mesh); +} +/*! + * typed used are vtk types (@see vtkCellType.h) + * see GetEntityType() for conversion in SMDS type (@see SMDSAbs_ElementType.hxx) + */ +void SMDS_VtkVolume::init(std::vector nodeIds, SMDS_Mesh* mesh) +{ + vtkUnstructuredGrid* grid = mesh->getGrid(); + myIdInShape = -1; + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_TETRA; + switch (nodeIds.size()) + { + case 4: + aType = VTK_TETRA; + break; + case 5: + aType = VTK_PYRAMID; + break; + case 6: + aType = VTK_WEDGE; + break; + case 8: + aType = VTK_HEXAHEDRON; + break; + case 10: + aType = VTK_QUADRATIC_TETRA; + break; + case 13: + aType = VTK_QUADRATIC_PYRAMID; + break; + case 15: + aType = VTK_QUADRATIC_WEDGE; + break; + case 20: + aType = VTK_QUADRATIC_HEXAHEDRON; + break; + default: + aType = VTK_HEXAHEDRON; + break; + } + myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); + mesh->setMyModified(); + //MESSAGE("SMDS_VtkVolume::init myVtkID " << myVtkID); +} + +//#ifdef VTK_HAVE_POLYHEDRON +void SMDS_VtkVolume::initPoly(std::vector nodeIds, std::vector nbNodesPerFace, SMDS_Mesh* mesh) +{ + MESSAGE("SMDS_VtkVolume::initPoly"); + SMDS_UnstructuredGrid* grid = mesh->getGrid(); + // TODO is it useful to orient faces ? + double center[3]; + this->gravityCenter(grid, &nodeIds[0], nodeIds.size(), ¢er[0]); + vector ptIds; + ptIds.clear(); + vtkIdType nbFaces = nbNodesPerFace.size(); + int k = 0; + for (int i = 0; i < nbFaces; i++) + { + int nf = nbNodesPerFace[i]; + ptIds.push_back(nf); +// double a[3]; +// double b[3]; +// double c[3]; +// grid->GetPoints()->GetPoint(nodeIds[k], a); +// grid->GetPoints()->GetPoint(nodeIds[k + 1], b); +// grid->GetPoints()->GetPoint(nodeIds[k + 2], c); +// bool isFaceForward = this->isForward(a, b, c, center); + bool isFaceForward = true; + //MESSAGE("isFaceForward " << i << " " << isFaceForward); + vtkIdType *facePts = &nodeIds[k]; + if (isFaceForward) + for (int n = 0; n < nf; n++) + ptIds.push_back(facePts[n]); + else + for (int n = nf - 1; n >= 0; n--) + ptIds.push_back(facePts[n]); + k += nf; + } + myVtkID = grid->InsertNextLinkedCell(VTK_POLYHEDRON, nbFaces, &ptIds[0]); + mesh->setMyModified(); +} +//#endif + +bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + for (int i = 0; i < nbNodes; i++) + { + pts[i] = nodes[i]->getVtkId(); + } + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +/*! + * Reorder in VTK order a list of nodes given in SMDS order. + * To be used before ChangeNodes: lists are given or computed in SMDS order. + */ +bool SMDS_VtkVolume::vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + if (nbNodes != this->NbNodes()) + { + MESSAGE("vtkOrder, wrong number of nodes " << nbNodes << " instead of "<< this->NbNodes()); + return false; + } + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + switch (aVtkType) + { + case VTK_TETRA: + this->exchange(nodes, 1, 2); + break; + case VTK_QUADRATIC_TETRA: + this->exchange(nodes, 1, 2); + this->exchange(nodes, 4, 6); + this->exchange(nodes, 8, 9); + break; + case VTK_PYRAMID: + this->exchange(nodes, 1, 3); + break; + case VTK_WEDGE: + break; + case VTK_QUADRATIC_PYRAMID: + this->exchange(nodes, 1, 3); + this->exchange(nodes, 5, 8); + this->exchange(nodes, 6, 7); + this->exchange(nodes, 10, 12); + break; + case VTK_QUADRATIC_WEDGE: + break; + case VTK_HEXAHEDRON: + this->exchange(nodes, 1, 3); + this->exchange(nodes, 5, 7); + break; + case VTK_QUADRATIC_HEXAHEDRON: + this->exchange(nodes, 1, 3); + this->exchange(nodes, 5, 7); + this->exchange(nodes, 8, 11); + this->exchange(nodes, 9, 10); + this->exchange(nodes, 12, 15); + this->exchange(nodes, 13, 14); + this->exchange(nodes, 17, 19); + break; + case VTK_POLYHEDRON: + default: + break; + } +} + +SMDS_VtkVolume::~SMDS_VtkVolume() +{ +} + +void SMDS_VtkVolume::Print(ostream & OS) const +{ + OS << "volume <" << GetID() << "> : "; +} + +int SMDS_VtkVolume::NbFaces() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbFaces = 4; + switch (aVtkType) + { + case VTK_TETRA: + case VTK_QUADRATIC_TETRA: + nbFaces = 4; + break; + case VTK_PYRAMID: + case VTK_WEDGE: + case VTK_QUADRATIC_PYRAMID: + case VTK_QUADRATIC_WEDGE: + nbFaces = 5; + break; + case VTK_HEXAHEDRON: + case VTK_QUADRATIC_HEXAHEDRON: + nbFaces = 6; + break; + case VTK_POLYHEDRON: + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + nbFaces = nFaces; + break; + } + default: + MESSAGE("invalid volume type") + ; + nbFaces = 0; + break; + } + return nbFaces; +} + +int SMDS_VtkVolume::NbNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbPoints = 0; + if (aVtkType != VTK_POLYHEDRON) + { + nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); + } + else + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; + nbPoints += nodesInFace; + id += (nodesInFace + 1); + } + } + return nbPoints; +} + +int SMDS_VtkVolume::NbEdges() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbEdges = 6; + switch (aVtkType) + { + case VTK_TETRA: + case VTK_QUADRATIC_TETRA: + nbEdges = 6; + break; + case VTK_PYRAMID: + case VTK_QUADRATIC_PYRAMID: + nbEdges = 8; + break; + case VTK_WEDGE: + case VTK_QUADRATIC_WEDGE: + nbEdges = 9; + break; + case VTK_HEXAHEDRON: + case VTK_QUADRATIC_HEXAHEDRON: + nbEdges = 12; + break; + case VTK_POLYHEDRON: + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + nbEdges = 0; + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int edgesInFace = ptIds[id]; + id += (edgesInFace + 1); + nbEdges += edgesInFace; + } + nbEdges = nbEdges / 2; + break; + } + default: + MESSAGE("invalid volume type") + ; + nbEdges = 0; + break; + } + return nbEdges; +} + +/*! polyhedron only, + * 1 <= face_ind <= NbFaces() + */ +int SMDS_VtkVolume::NbFaceNodes(const int face_ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbNodes = 0; + if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; + id += (nodesInFace + 1); + if (i == face_ind - 1) + { + nbNodes = nodesInFace; + break; + } + } + } + return nbNodes; +} + +/*! polyhedron only, + * 1 <= face_ind <= NbFaces() + * 1 <= node_ind <= NbFaceNodes() + */ +const SMDS_MeshNode* SMDS_VtkVolume::GetFaceNode(const int face_ind, const int node_ind) const +{ + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkUnstructuredGrid* grid = mesh->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + const SMDS_MeshNode* node = 0; + if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + if (i == face_ind - 1) // first face is number 1 + { + if ((node_ind > 0) && (node_ind <= nodesInFace)) + node = mesh->FindNodeVtk(ptIds[id + node_ind]); // ptIds[id+1] : first node + break; + } + id += (nodesInFace + 1); + } + } + return node; +} + +/*! polyhedron only, + * return number of nodes for each face + */ +const std::vector & SMDS_VtkVolume::GetQuantities() const +{ + vector quantities; + quantities.clear(); + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkUnstructuredGrid* grid = mesh->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + quantities.push_back(nodesInFace); + id += (nodesInFace + 1); + } + } + return quantities; +} + +SMDS_ElemIteratorPtr SMDS_VtkVolume::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + { + SMDSAbs_EntityType aType = this->GetEntityType(); + if (aType == SMDSEntity_Polyhedra) + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorPolyH(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType)); + else + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType)); + } + default: + MESSAGE("ERROR : Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + +SMDS_ElemIteratorPtr SMDS_VtkVolume::nodesIteratorToUNV() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDS_ElemIteratorPtr SMDS_VtkVolume::interlacedNodesElemIterator() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDSAbs_ElementType SMDS_VtkVolume::GetType() const +{ + return SMDSAbs_Volume; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const +{ + // TODO optimize if possible (vtkCellIterator) + return SMDS_MeshElement::GetNode(ind); +} + +bool SMDS_VtkVolume::IsQuadratic() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + // TODO quadratic polyhedrons ? + switch (aVtkType) + { + case VTK_QUADRATIC_TETRA: + case VTK_QUADRATIC_PYRAMID: + case VTK_QUADRATIC_WEDGE: + case VTK_QUADRATIC_HEXAHEDRON: + return true; + break; + default: + return false; + } +} + +bool SMDS_VtkVolume::IsPoly() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return (aVtkType == VTK_POLYHEDRON); +} + +bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int rankFirstMedium = 0; + switch (aVtkType) + { + case VTK_QUADRATIC_TETRA: + rankFirstMedium = 4; // medium nodes are of rank 4 to 9 + break; + case VTK_QUADRATIC_PYRAMID: + rankFirstMedium = 5; // medium nodes are of rank 5 to 12 + break; + case VTK_QUADRATIC_WEDGE: + rankFirstMedium = 6; // medium nodes are of rank 6 to 14 + break; + case VTK_QUADRATIC_HEXAHEDRON: + rankFirstMedium = 8; // medium nodes are of rank 8 to 19 + break; + default: + return false; + } + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + vtkIdType nodeId = node->getVtkId(); + for (int rank = 0; rank < npts; rank++) + { + if (pts[rank] == nodeId) + { + if (rank < rankFirstMedium) + return false; + else + return true; + } + } + //throw SALOME_Exception(LOCALIZED("node does not belong to this element")); + MESSAGE("======================================================"); + MESSAGE("= IsMediumNode: node does not belong to this element ="); + MESSAGE("======================================================"); + return false; +} + +SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + + SMDSAbs_EntityType aType = SMDSEntity_Tetra; + switch (aVtkType) + { + case VTK_TETRA: + aType = SMDSEntity_Tetra; + break; + case VTK_PYRAMID: + aType = SMDSEntity_Pyramid; + break; + case VTK_WEDGE: + aType = SMDSEntity_Penta; + break; + case VTK_HEXAHEDRON: + aType = SMDSEntity_Hexa; + break; + case VTK_QUADRATIC_TETRA: + aType = SMDSEntity_Quad_Tetra; + break; + case VTK_QUADRATIC_PYRAMID: + aType = SMDSEntity_Quad_Pyramid; + break; + case VTK_QUADRATIC_WEDGE: + aType = SMDSEntity_Quad_Penta; + break; + case VTK_QUADRATIC_HEXAHEDRON: + aType = SMDSEntity_Quad_Hexa; + break; +//#ifdef VTK_HAVE_POLYHEDRON + case VTK_POLYHEDRON: + aType = SMDSEntity_Polyhedra; + break; +//#endif + default: + aType = SMDSEntity_Polyhedra; + break; + } + return aType; +} + +vtkIdType SMDS_VtkVolume::GetVtkType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aType = grid->GetCellType(myVtkID); + return aType; +} + +void SMDS_VtkVolume::gravityCenter(SMDS_UnstructuredGrid* grid, vtkIdType *nodeIds, int nbNodes, double* result) +{ + for (int j = 0; j < 3; j++) + result[j] = 0; + if (nbNodes <= 0) + return; + for (int i = 0; i < nbNodes; i++) + { + double *coords = grid->GetPoint(nodeIds[i]); + for (int j = 0; j < 3; j++) + result[j] += coords[j]; + } + for (int j = 0; j < 3; j++) + result[j] = result[j] / nbNodes; + //MESSAGE("center " << result[0] << " " << result[1] << " " << result[2]); + return; +} + +bool SMDS_VtkVolume::isForward(double* a, double* b, double* c, double* d) +{ + double u[3], v[3], w[3]; + for (int j = 0; j < 3; j++) + { + //MESSAGE("a,b,c,d " << a[j] << " " << b[j] << " " << c[j] << " " << d[j]); + u[j] = b[j] - a[j]; + v[j] = c[j] - a[j]; + w[j] = d[j] - a[j]; + //MESSAGE("u,v,w " << u[j] << " " << v[j] << " " << w[j]); + } + double prodmixte = (u[2] * v[3] - u[3] * v[2]) * w[1] + (u[3] * v[1] - u[1] * v[3]) * w[2] + (u[1] * v[2] - u[2] + * v[1]) * w[3]; + return (prodmixte >= 0); +} + +/*! For polyhedron only + * @return actual number of nodes (not the sum of nodes of all faces) + */ +int SMDS_VtkVolume::NbUniqueNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + return grid->GetCell(myVtkID)->GetNumberOfPoints(); +} + +/*! For polyhedron use only + * @return iterator on actual nodes (not through the faces) + */ +SMDS_ElemIteratorPtr SMDS_VtkVolume::uniqueNodesIterator() const +{ + MESSAGE("uniqueNodesIterator"); + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} diff --git a/src/SMDS/SMDS_VtkVolume.hxx b/src/SMDS/SMDS_VtkVolume.hxx new file mode 100644 index 000000000..b43c73edf --- /dev/null +++ b/src/SMDS/SMDS_VtkVolume.hxx @@ -0,0 +1,57 @@ +#ifndef _SMDS_VTKVOLUME_HXX_ +#define _SMDS_VTKVOLUME_HXX_ + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshVolume.hxx" +#include "SMDS_UnstructuredGrid.hxx" +#include + +class SMDS_EXPORT SMDS_VtkVolume: public SMDS_MeshVolume +{ +public: + SMDS_VtkVolume(); + SMDS_VtkVolume(std::vector nodeIds, SMDS_Mesh* mesh); + ~SMDS_VtkVolume(); + void init(std::vector nodeIds, SMDS_Mesh* mesh); +//#ifdef VTK_HAVE_POLYHEDRON + void initPoly(std::vector nodeIds, std::vector nbNodesPerFace, SMDS_Mesh* mesh); +//#endif + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes); + + void Print(std::ostream & OS) const; + int NbFaces() const; + int NbNodes() const; + int NbEdges() const; + + // 1 <= face_ind <= NbFaces() + int NbFaceNodes (const int face_ind) const; + // 1 <= face_ind <= NbFaces() + // 1 <= node_ind <= NbFaceNodes() + const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const; + + virtual SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + virtual bool IsQuadratic() const; + virtual bool IsPoly() const; + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + static void gravityCenter(SMDS_UnstructuredGrid* grid, + vtkIdType *nodeIds, + int nbNodes, + double* result); + static bool isForward(double* a,double* b,double* c,double* d); + int NbUniqueNodes() const; + SMDS_ElemIteratorPtr uniqueNodesIterator() const; + const std::vector & GetQuantities() const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; + +protected: +}; + +#endif diff --git a/src/SMDS/chrono.cxx b/src/SMDS/chrono.cxx new file mode 100644 index 000000000..73fbddb20 --- /dev/null +++ b/src/SMDS/chrono.cxx @@ -0,0 +1,86 @@ +// Copyright (C) 2006-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "chrono.hxx" +#include "utilities.h" + +using namespace std; + +cntStruct* counters::_ctrs = 0; +int counters::_nbChrono = 0; + +counters::counters(int nb) +{ + MESSAGE("counters::counters(int nb)"); + _nbChrono = nb; + _ctrs = new cntStruct[_nbChrono]; + + for (int i = 0; i < _nbChrono; i++) + { + _ctrs[i]._ctrNames = 0; + _ctrs[i]._ctrLines = 0; + _ctrs[i]._ctrOccur = 0; + _ctrs[i]._ctrCumul = 0; + } + + MESSAGE("counters::counters()"); +} + +counters::~counters() +{ + stats(); +} + +void counters::stats() +{ + MESSAGE("counters::stats()"); + for (int i = 0; i < _nbChrono; i++) + if (_ctrs[i]._ctrOccur) + { + MESSAGE("Compteur[" << i << "]: "<< _ctrs[i]._ctrNames << "[" << _ctrs[i]._ctrLines << "]"); + MESSAGE(" " << _ctrs[i]._ctrOccur); + MESSAGE(" " << _ctrs[i]._ctrCumul); + } +} + +chrono::chrono(int i) : + _ctr(i), _run(true) +{ + //MESSAGE("chrono::chrono " << _ctr << " " << _run); + _start = clock(); +} + +chrono::~chrono() +{ + if (_run) + stop(); +} + +void chrono::stop() +{ + //MESSAGE("chrono::stop " << _ctr << " " << _run); + if (_run) + { + _run = false; + _end = clock(); + double elapse = double(_end - _start) / double(CLOCKS_PER_SEC); + counters::_ctrs[_ctr]._ctrOccur++; + counters::_ctrs[_ctr]._ctrCumul += elapse; + } +} diff --git a/src/SMDS/chrono.hxx b/src/SMDS/chrono.hxx new file mode 100644 index 000000000..6c7b3c976 --- /dev/null +++ b/src/SMDS/chrono.hxx @@ -0,0 +1,73 @@ +// Copyright (C) 2006-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _CHRONO_HXX_ +#define _CHRONO_HXX_ + +#include +#include +#include +#include + +typedef struct acnt +{ + char* _ctrNames; + int _ctrLines; + int _ctrOccur; + double _ctrCumul; +} cntStruct; + +class counters +{ +public: + static cntStruct *_ctrs; + counters(int nb); + ~counters(); + static void stats(); +protected: + static int _nbChrono; +}; + +class chrono +{ +public: + chrono(int i); + ~chrono(); + void stop(); +protected: + bool _run; + int _ctr; + clock_t _start, _end; +}; + +#ifdef CHRONODEF +#define CHRONO(i) counters::_ctrs[i]._ctrNames = (char *)__FILE__; \ + counters::_ctrs[i]._ctrLines = __LINE__; \ + chrono aChrono##i(i); + +#define CHRONOSTOP(i) aChrono##i.stop(); + +#else // CHRONODEF + +#define CHRONO(i) +#define CHRONOSTOP(i) + +#endif // CHRONODEF + +#endif // _CHRONO_HXX_ diff --git a/src/SMESH/Makefile.am b/src/SMESH/Makefile.am index ef7e491bb..9db3b1450 100644 --- a/src/SMESH/Makefile.am +++ b/src/SMESH/Makefile.am @@ -85,6 +85,7 @@ libSMESHimpl_la_CPPFLAGS = \ $(CAS_CPPFLAGS) \ $(MED_CXXFLAGS) \ $(GEOM_CXX_FLAGS) \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ @HDF5_INCLUDES@ \ -I$(srcdir)/../Controls \ diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 3a6a4efd9..953bf9e2b 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -255,10 +255,10 @@ bool SMESH_Algo::IsReversedSubMesh (const TopoDS_Face& theFace, const SMDS_PositionPtr& pos = node->GetPosition(); if ( !pos ) continue; if ( pos->GetTypeOfPosition() == SMDS_TOP_FACE ) { - fPos = dynamic_cast< const SMDS_FacePosition* >( pos.get() ); + fPos = dynamic_cast< const SMDS_FacePosition* >( pos ); } else if ( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) { - vID = pos->GetShapeId(); + vID = node->getshapeId(); } } if ( fPos || ( !normalOK && vID )) { @@ -366,7 +366,7 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh, if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE ) return false; const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); if ( !paramSet.insert( epos->GetUParameter() ).second ) return false; // equal parameters } @@ -433,8 +433,9 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE ) return false; const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); theNodes.insert( make_pair( epos->GetUParameter(), node )); + //MESSAGE("U " << epos->GetUParameter() << " ID " << node->GetID()); ++nbNodes; } } @@ -443,6 +444,7 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM TopExp::Vertices(theEdge, v1, v2); const SMDS_MeshNode* n1 = VertexNode( v1, (SMESHDS_Mesh*) theMesh ); const SMDS_MeshNode* n2 = VertexNode( v2, (SMESHDS_Mesh*) theMesh ); + //MESSAGE("Vertices ID " << n1->GetID() << " " << n2->GetID()); Standard_Real f, l; BRep_Tool::Range(theEdge, f, l); if ( v1.Orientation() != TopAbs_FORWARD ) diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 47947add9..2b19f938e 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -25,12 +25,14 @@ // Author : Paul RASCLE, EDF // Module : SMESH // +#define CHRONODEF #include "SMESH_Gen.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_HypoFilter.hxx" #include "SMESHDS_Document.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" #include "utilities.h" #include "OpUtil.hxx" @@ -41,6 +43,8 @@ #include #include +#include "memoire.h" + using namespace std; //============================================================================= @@ -51,10 +55,13 @@ using namespace std; SMESH_Gen::SMESH_Gen() { - MESSAGE("SMESH_Gen::SMESH_Gen"); - _localId = 0; - _hypId = 0; - _segmentation = _nbSegments = 10; + MESSAGE("SMESH_Gen::SMESH_Gen"); + _localId = 0; + _hypId = 0; + _segmentation = 10; + SMDS_Mesh::_meshList.clear(); + MESSAGE(SMDS_Mesh::_meshList.size()); + _counters = new counters(100); } //============================================================================= @@ -108,6 +115,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, TSetOfInt* aShapesId) { MESSAGE("SMESH_Gen::Compute"); + MEMOSTAT; bool ret = true; @@ -151,6 +159,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, else if ( aShapesId ) aShapesId->insert( smToCompute->GetId() ); } + //aMesh.GetMeshDS()->Modified(); return ret; } else @@ -265,6 +274,26 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret); + MEMOSTAT; + + SMESHDS_Mesh *myMesh = aMesh.GetMeshDS(); + myMesh->adjustStructure(); + MESSAGE("*** compactMesh after compute"); + myMesh->compactMesh(); + //myMesh->adjustStructure(); + list listind = myMesh->SubMeshIndices(); + list::iterator it = listind.begin(); + int total = 0; + for(; it != listind.end(); ++it) + { + ::SMESHDS_SubMesh *subMesh = myMesh->MeshElements(*it); + total += subMesh->getSize(); + } + MESSAGE("total elements and nodes in submesh sets:" << total); + MESSAGE("Number of node objects " << SMDS_MeshNode::nbNodes); + MESSAGE("Number of cell objects " << SMDS_MeshCell::nbCells); + //myMesh->dumpGrid(); + //aMesh.GetMeshDS()->Modified(); return ret; } diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index 606c96d18..a9af382ef 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -41,6 +41,8 @@ #include "SMESH_3D_Algo.hxx" #include "SMESH_Mesh.hxx" +#include "chrono.hxx" + #include #include @@ -159,6 +161,7 @@ private: int _segmentation; // default of segments int _nbSegments; + counters *_counters; }; #endif diff --git a/src/SMESH/SMESH_Hypothesis.cxx b/src/SMESH/SMESH_Hypothesis.cxx index 9ababf9e4..dca74e5d1 100644 --- a/src/SMESH/SMESH_Hypothesis.cxx +++ b/src/SMESH/SMESH_Hypothesis.cxx @@ -24,6 +24,7 @@ // File : SMESH_Hypothesis.cxx // Author : Paul RASCLE, EDF // Module : SMESH +// $Header$ // #include "SMESH_Hypothesis.hxx" #include "SMESH_Gen.hxx" diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index f26db9a0c..a5740a0d2 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -25,6 +25,7 @@ // Created : Mon Apr 12 16:10:22 2004 // Author : Edward AGAPOV (eap) // +#define CHRONODEF #include "SMESH_MeshEditor.hxx" #include "SMDS_FaceOfNodes.hxx" @@ -33,8 +34,10 @@ #include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_SpacePosition.hxx" -#include "SMDS_QuadraticFaceOfNodes.hxx" +//#include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_MeshGroup.hxx" +#include "SMDS_LinearEdge.hxx" +#include "SMDS_Downward.hxx" #include "SMDS_SetIterator.hxx" #include "SMESHDS_Group.hxx" @@ -124,75 +127,76 @@ SMESH_MeshEditor::AddElement(const vector & node, const bool isPoly, const int ID) { + //MESSAGE("AddElement " <Add0DElementWithID(node[0], ID); + if ( ID >= 0 ) e = mesh->Add0DElementWithID(node[0], ID); else e = mesh->Add0DElement (node[0] ); break; case SMDSAbs_Edge: if ( nbnode == 2 ) - if ( ID ) e = mesh->AddEdgeWithID(node[0], node[1], ID); + if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], ID); else e = mesh->AddEdge (node[0], node[1] ); else if ( nbnode == 3 ) - if ( ID ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID); + if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID); else e = mesh->AddEdge (node[0], node[1], node[2] ); break; case SMDSAbs_Face: if ( !isPoly ) { if (nbnode == 3) - if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID); + if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID); else e = mesh->AddFace (node[0], node[1], node[2] ); else if (nbnode == 4) - if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID); + if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID); else e = mesh->AddFace (node[0], node[1], node[2], node[3] ); else if (nbnode == 6) - if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], + if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], node[4], node[5], ID); else e = mesh->AddFace (node[0], node[1], node[2], node[3], node[4], node[5] ); else if (nbnode == 8) - if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], + if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7], ID); else e = mesh->AddFace (node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7] ); } else { - if ( ID ) e = mesh->AddPolygonalFaceWithID(node, ID); + if ( ID >= 0 ) e = mesh->AddPolygonalFaceWithID(node, ID); else e = mesh->AddPolygonalFace (node ); } break; case SMDSAbs_Volume: if ( !isPoly ) { if (nbnode == 4) - if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID); + if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID); else e = mesh->AddVolume (node[0], node[1], node[2], node[3] ); else if (nbnode == 5) - if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], + if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], node[4], ID); else e = mesh->AddVolume (node[0], node[1], node[2], node[3], node[4] ); else if (nbnode == 6) - if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], + if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], node[4], node[5], ID); else e = mesh->AddVolume (node[0], node[1], node[2], node[3], node[4], node[5] ); else if (nbnode == 8) - if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], + if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7], ID); else e = mesh->AddVolume (node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7] ); else if (nbnode == 10) - if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], + if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7], node[8], node[9], ID); else e = mesh->AddVolume (node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7], node[8], node[9] ); else if (nbnode == 13) - if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], + if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7], node[8], node[9], node[10],node[11], node[12],ID); @@ -201,7 +205,7 @@ SMESH_MeshEditor::AddElement(const vector & node, node[8], node[9], node[10],node[11], node[12] ); else if (nbnode == 15) - if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], + if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7], node[8], node[9], node[10],node[11], node[12],node[13],node[14],ID); @@ -210,7 +214,7 @@ SMESH_MeshEditor::AddElement(const vector & node, node[8], node[9], node[10],node[11], node[12],node[13],node[14] ); else if (nbnode == 20) - if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], + if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7], node[8], node[9], node[10],node[11], node[12],node[13],node[14],node[15], @@ -279,7 +283,7 @@ int SMESH_MeshEditor::Remove (const list< int >& theIDs, if ( isNodes ) { const SMDS_MeshNode* node = cast2Node( elem ); if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) - if ( int aShapeID = node->GetPosition()->GetShapeId() ) + if ( int aShapeID = node->getshapeId() ) if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) ) smmap.insert( sm ); } @@ -333,22 +337,21 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem) if ( aMesh->ShapeToMesh().IsNull() ) return 0; - if ( theElem->GetType() == SMDSAbs_Node ) { - const SMDS_PositionPtr& aPosition = - static_cast( theElem )->GetPosition(); - if ( aPosition.get() ) - return aPosition->GetShapeId(); - else - return 0; - } + if ( theElem->GetType() == SMDSAbs_Node ) + { + int aShapeID = theElem->getshapeId(); + if (aShapeID <= 0) + return 0; + else + return aShapeID; + } TopoDS_Shape aShape; // the shape a node is on SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); while ( nodeIt->more() ) { const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - const SMDS_PositionPtr& aPosition = node->GetPosition(); - if ( aPosition.get() ) { - int aShapeID = aPosition->GetShapeId(); + int aShapeID = node->getshapeId(); + if (aShapeID > 0) { SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID ); if ( sm ) { if ( sm->Contains( theElem )) @@ -479,15 +482,19 @@ static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1, bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, const SMDS_MeshElement * theTria2 ) { + MESSAGE("InverseDiag"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); if (!theTria1 || !theTria2) return false; - const SMDS_FaceOfNodes* F1 = dynamic_cast( theTria1 ); - const SMDS_FaceOfNodes* F2 = dynamic_cast( theTria2 ); - if (F1 && F2) { + const SMDS_VtkFace* F1 = dynamic_cast( theTria1 ); + if (!F1) return false; + const SMDS_VtkFace* F2 = dynamic_cast( theTria2 ); + if (!F2) return false; + if ((theTria1->GetEntityType() == SMDSEntity_Triangle) && + (theTria2->GetEntityType() == SMDSEntity_Triangle)) { // 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | @@ -540,24 +547,18 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, // 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 ); - 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; + if (theTria1->GetEntityType() != SMDSEntity_Quad_Triangle) + return false; + if (theTria2->GetEntityType() != SMDSEntity_Quad_Triangle) + 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) @@ -660,11 +661,12 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1, if ( !findTriangles( theNode1, theNode2, tr1, tr2 )) return false; - const SMDS_FaceOfNodes* F1 = dynamic_cast( tr1 ); - //if (!F1) return false; - const SMDS_FaceOfNodes* F2 = dynamic_cast( tr2 ); - //if (!F2) return false; - if (F1 && F2) { + const SMDS_VtkFace* F1 = dynamic_cast( tr1 ); + if (!F1) return false; + const SMDS_VtkFace* F2 = dynamic_cast( tr2 ); + if (!F2) return false; + if ((tr1->GetEntityType() == SMDSEntity_Triangle) && + (tr2->GetEntityType() == SMDSEntity_Triangle)) { // 1 +--+ A tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | @@ -702,23 +704,13 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1, // tr2: B->1 aNodes2[ iB2 ] = aNodes1[ i1 ]; - //MESSAGE( tr1 << tr2 ); - GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 ); GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 ); - //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); } @@ -792,34 +784,39 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, if ( !findTriangles( theNode1, theNode2, tr1, tr2 )) return false; - const SMDS_FaceOfNodes* F1 = dynamic_cast( tr1 ); - //if (!F1) return false; - const SMDS_FaceOfNodes* F2 = dynamic_cast( tr2 ); - //if (!F2) return false; - if (F1 && F2) { + const SMDS_VtkFace* F1 = dynamic_cast( tr1 ); + if (!F1) return false; + const SMDS_VtkFace* F2 = dynamic_cast( tr2 ); + if (!F2) return false; + SMESHDS_Mesh * aMesh = GetMeshDS(); + + if ((tr1->GetEntityType() == SMDSEntity_Triangle) && + (tr2->GetEntityType() == SMDSEntity_Triangle)) { const SMDS_MeshNode* aNodes [ 4 ]; if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 )) return false; - //MESSAGE( endl << tr1 << tr2 ); - - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 ); - myLastCreatedElems.Append(tr1); - GetMeshDS()->RemoveElement( tr2 ); - - //MESSAGE( endl << tr1 ); + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3] ); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( 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; + if (tr1->GetEntityType() != SMDSEntity_Quad_Triangle) + return false; + if (tr2->GetEntityType() != SMDSEntity_Quad_Triangle) + 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) @@ -849,9 +846,18 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, aNodes[6] = N2[3]; aNodes[7] = N1[5]; - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); - myLastCreatedElems.Append(tr1); - GetMeshDS()->RemoveElement( tr2 ); + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3], + aNodes[4], aNodes[5], aNodes[6], aNodes[7]); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr2 ); // remove middle node (9) GetMeshDS()->RemoveNode( N1[4] ); @@ -866,6 +872,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) { + MESSAGE("Reorient"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -912,8 +919,10 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) } case SMDSAbs_Volume: { if (theElem->IsPoly()) { - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - static_cast( theElem ); + // TODO reorient vtk polyhedron + MESSAGE("reorient vtk polyhedron ?"); + const SMDS_VtkVolume* aPolyedre = + dynamic_cast( theElem ); if (!aPolyedre) { MESSAGE("Warning: bad volumic element"); return false; @@ -942,6 +951,7 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) if ( !vTool.Set( theElem )) return false; vTool.Inverse(); + MESSAGE("ChangeElementNodes reorient: check vTool.Inverse"); return GetMeshDS()->ChangeElementNodes( theElem, vTool.GetNodes(), vTool.NbNodes() ); } } @@ -1014,21 +1024,21 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); int aShapeId = FindShape( elem ); - const SMDS_MeshElement* newElem = 0; + const SMDS_MeshElement* newElem1 = 0; + const SMDS_MeshElement* newElem2 = 0; if( !elem->IsQuadratic() ) { // split liner quadrangle - if ( aBadRate1 <= aBadRate2 ) { // tr1 + tr2 is better - aMesh->ChangeElementNodes( elem, aNodes, 3 ); - newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + newElem1 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + newElem2 = aMesh->AddFace( aNodes[2], aNodes[0], aNodes[1] ); } else { // tr3 + tr4 is better - aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); - newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + newElem1 = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + newElem2 = aMesh->AddFace( aNodes[3], aNodes[1], aNodes[2] ); } } else { @@ -1089,8 +1099,10 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, N[3] = aNodes[4]; N[4] = aNodes[5]; N[5] = newN; - newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], - aNodes[6], aNodes[7], newN ); + newElem1 = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], + aNodes[6], aNodes[7], newN ); + newElem2 = aMesh->AddFace(aNodes[2], aNodes[0], aNodes[1], + newN, aNodes[4], aNodes[5] ); } else { N[0] = aNodes[1]; @@ -1099,21 +1111,27 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, N[3] = aNodes[5]; N[4] = aNodes[6]; N[5] = newN; - newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], - aNodes[7], aNodes[4], newN ); + newElem1 = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], + aNodes[7], aNodes[4], newN ); + newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2], + newN, aNodes[5], aNodes[6] ); } - aMesh->ChangeElementNodes( elem, N, 6 ); - } // quadratic case // care of a new element - myLastCreatedElems.Append(newElem); - AddToSameGroups( newElem, elem, aMesh ); + myLastCreatedElems.Append(newElem1); + myLastCreatedElems.Append(newElem2); + AddToSameGroups( newElem1, elem, aMesh ); + AddToSameGroups( newElem2, elem, aMesh ); // put a new triangle on the same shape if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); + { + aMesh->SetMeshElementOnShape( newElem1, aShapeId ); + aMesh->SetMeshElementOnShape( newElem2, aShapeId ); + } + aMesh->RemoveElement( elem ); } return true; } @@ -1821,20 +1839,28 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, aNodes[ i++ ] = static_cast( itN->next() ); int aShapeId = FindShape( elem ); - const SMDS_MeshElement* newElem = 0; + const SMDS_MeshElement* newElem1 = 0; + const SMDS_MeshElement* newElem2 = 0; if ( the13Diag ) { - aMesh->ChangeElementNodes( elem, aNodes, 3 ); - newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + newElem1 = aMesh->AddFace( aNodes[2], aNodes[0], aNodes[1] ); + newElem2 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); } else { - aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); - newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + newElem1 = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + newElem2 = aMesh->AddFace( aNodes[3], aNodes[1], aNodes[2] ); } - myLastCreatedElems.Append(newElem); + myLastCreatedElems.Append(newElem1); + myLastCreatedElems.Append(newElem2); // put a new triangle on the same shape and add to the same groups if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); - AddToSameGroups( newElem, elem, aMesh ); + { + aMesh->SetMeshElementOnShape( newElem1, aShapeId ); + aMesh->SetMeshElementOnShape( newElem2, aShapeId ); + } + AddToSameGroups( newElem1, elem, aMesh ); + AddToSameGroups( newElem2, elem, aMesh ); + //aMesh->RemoveFreeElement(elem, aMesh->MeshElements(aShapeId), true); + aMesh->RemoveElement( elem ); } // Quadratic quadrangle @@ -1889,7 +1915,8 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, myLastCreatedNodes.Append(newN); // create a new element - const SMDS_MeshElement* newElem = 0; + const SMDS_MeshElement* newElem1 = 0; + const SMDS_MeshElement* newElem2 = 0; const SMDS_MeshNode* N[6]; if ( the13Diag ) { N[0] = aNodes[0]; @@ -1898,8 +1925,10 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, N[3] = aNodes[4]; N[4] = aNodes[5]; N[5] = newN; - newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], - aNodes[6], aNodes[7], newN ); + newElem1 = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], + aNodes[6], aNodes[7], newN ); + newElem2 = aMesh->AddFace(aNodes[2], aNodes[0], aNodes[1], + newN, aNodes[4], aNodes[5] ); } else { N[0] = aNodes[1]; @@ -1908,15 +1937,22 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, N[3] = aNodes[5]; N[4] = aNodes[6]; N[5] = newN; - newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], - aNodes[7], aNodes[4], newN ); + newElem1 = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], + aNodes[7], aNodes[4], newN ); + newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2], + newN, aNodes[5], aNodes[6] ); } - myLastCreatedElems.Append(newElem); - aMesh->ChangeElementNodes( elem, N, 6 ); + myLastCreatedElems.Append(newElem1); + myLastCreatedElems.Append(newElem2); // put a new triangle on the same shape and add to the same groups if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); - AddToSameGroups( newElem, elem, aMesh ); + { + aMesh->SetMeshElementOnShape( newElem1, aShapeId ); + aMesh->SetMeshElementOnShape( newElem2, aShapeId ); + } + AddToSameGroups( newElem1, elem, aMesh ); + AddToSameGroups( newElem2, elem, aMesh ); + aMesh->RemoveElement( elem ); } } @@ -2212,16 +2248,17 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, mapEl_setLi.erase( tr2 ); mapLi_listEl.erase( *link12 ); if(tr1->NbNodes()==3) { - if( tr1->GetID() < tr2->GetID() ) { - aMesh->ChangeElementNodes( tr1, n12, 4 ); - myLastCreatedElems.Append(tr1); - aMesh->RemoveElement( tr2 ); - } - else { - aMesh->ChangeElementNodes( tr2, n12, 4 ); - myLastCreatedElems.Append(tr2); - aMesh->RemoveElement( tr1); - } + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace(n12[0], n12[1], n12[2], n12[3] ); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr2 ); } else { const SMDS_MeshNode* N1 [6]; @@ -2239,16 +2276,18 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, aNodes[5] = N2[5]; aNodes[6] = N2[3]; aNodes[7] = N1[5]; - if( tr1->GetID() < tr2->GetID() ) { - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); - myLastCreatedElems.Append(tr1); - GetMeshDS()->RemoveElement( tr2 ); - } - else { - GetMeshDS()->ChangeElementNodes( tr2, aNodes, 8 ); - myLastCreatedElems.Append(tr2); - GetMeshDS()->RemoveElement( tr1 ); - } + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3], + aNodes[4], aNodes[5], aNodes[6], aNodes[7]); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr2 ); // remove middle node (9) GetMeshDS()->RemoveNode( N1[4] ); } @@ -2257,16 +2296,17 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, mapEl_setLi.erase( tr3 ); mapLi_listEl.erase( *link13 ); if(tr1->NbNodes()==3) { - if( tr1->GetID() < tr2->GetID() ) { - aMesh->ChangeElementNodes( tr1, n13, 4 ); - myLastCreatedElems.Append(tr1); - aMesh->RemoveElement( tr3 ); - } - else { - aMesh->ChangeElementNodes( tr3, n13, 4 ); - myLastCreatedElems.Append(tr3); - aMesh->RemoveElement( tr1 ); - } + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace(n13[0], n13[1], n13[2], n13[3] ); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr3 ); } else { const SMDS_MeshNode* N1 [6]; @@ -2284,16 +2324,18 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, aNodes[5] = N2[5]; aNodes[6] = N2[3]; aNodes[7] = N1[5]; - if( tr1->GetID() < tr2->GetID() ) { - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); - myLastCreatedElems.Append(tr1); - GetMeshDS()->RemoveElement( tr3 ); - } - else { - GetMeshDS()->ChangeElementNodes( tr3, aNodes, 8 ); - myLastCreatedElems.Append(tr3); - GetMeshDS()->RemoveElement( tr1 ); - } + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3], + aNodes[4], aNodes[5], aNodes[6], aNodes[7]); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr3 ); // remove middle node (9) GetMeshDS()->RemoveNode( N1[4] ); } @@ -2905,7 +2947,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, while ( nn++ < nbn ) { node = static_cast( itN->next() ); const SMDS_PositionPtr& pos = node->GetPosition(); - posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; + posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; if (posType != SMDS_TOP_EDGE && posType != SMDS_TOP_VERTEX && theFixedNodes.find( node ) == theFixedNodes.end()) @@ -2963,27 +3005,27 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, node = *n; gp_XY uv( 0, 0 ); const SMDS_PositionPtr& pos = node->GetPosition(); - posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; + posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; // get existing UV switch ( posType ) { case SMDS_TOP_FACE: { - SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos.get(); + SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos; uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() ); break; } case SMDS_TOP_EDGE: { - TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() ); + TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() ); Handle(Geom2d_Curve) pcurve; if ( !S.IsNull() && S.ShapeType() == TopAbs_EDGE ) pcurve = BRep_Tool::CurveOnSurface( TopoDS::Edge( S ), face, f,l ); if ( !pcurve.IsNull() ) { - double u = (( SMDS_EdgePosition* ) pos.get() )->GetUParameter(); + double u = (( SMDS_EdgePosition* ) pos )->GetUParameter(); uv = pcurve->Value( u ).XY(); } break; } case SMDS_TOP_VERTEX: { - TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() ); + TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() ); if ( !S.IsNull() && S.ShapeType() == TopAbs_VERTEX ) uv = BRep_Tool::Parameters( TopoDS::Vertex( S ), face ).XY(); break; @@ -3246,7 +3288,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, if ( node_uv != uvMap.end() ) { gp_XY* uv = node_uv->second; node->SetPosition - ( SMDS_PositionPtr( new SMDS_FacePosition( *fId, uv->X(), uv->Y() ))); + ( SMDS_PositionPtr( new SMDS_FacePosition( uv->X(), uv->Y() ))); } } @@ -3258,14 +3300,14 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, helper.SetSubShape( face ); list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { - const SMDS_QuadraticFaceOfNodes* QF = - dynamic_cast (*elemIt); - if(QF) { + const SMDS_VtkFace* QF = + dynamic_cast (*elemIt); + if(QF && QF->IsQuadratic()) { vector Ns; Ns.reserve(QF->NbNodes()+1); - SMDS_NodeIteratorPtr anIter = QF->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = QF->interlacedNodesElemIterator(); while ( anIter->more() ) - Ns.push_back( anIter->next() ); + Ns.push_back( cast2Node(anIter->next()) ); Ns.push_back( Ns[0] ); double x, y, z; for(int i=0; iNbNodes(); i=i+2) { @@ -3343,6 +3385,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, const int nbSteps, SMESH_SequenceOfElemPtr& srcElements) { + //MESSAGE("sweepElement " << nbSteps); SMESHDS_Mesh* aMesh = GetMeshDS(); // Loop on elem nodes: @@ -3381,7 +3424,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, } } - //cout<<" nbSame = "<GetID() ); //INFOS( " Too many same nodes of element " << elem->GetID() ); @@ -3418,6 +3461,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, } // make new elements + const SMDS_MeshElement* lastElem = elem; for (int iStep = 0; iStep < nbSteps; iStep++ ) { // get next nodes for ( iNode = 0; iNode < nbNodes; iNode++ ) { @@ -3433,7 +3477,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, nextNod[ iNode ] = *itNN[ iNode ]; itNN[ iNode ]++; } - else if(!elem->IsQuadratic() || elem->IsMediumNode(prevNod[iNode]) ) { + else if(!elem->IsQuadratic() || lastElem->IsMediumNode(prevNod[iNode]) ) { // we have to use each second node //itNN[ iNode ]++; nextNod[ iNode ] = *itNN[ iNode ]; @@ -3738,6 +3782,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, newElems.push_back( aNewElem ); myLastCreatedElems.Append(aNewElem); srcElements.Append( elem ); + lastElem = aNewElem; } // set new prev nodes @@ -3766,6 +3811,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, const int nbSteps, SMESH_SequenceOfElemPtr& srcElements) { + MESSAGE("makeWalls"); ASSERT( newElemsMap.size() == elemNewNodesMap.size() ); SMESHDS_Mesh* aMesh = GetMeshDS(); @@ -3966,7 +4012,10 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, if ( !f ) myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) - aMesh->ChangeElementNodes( f, nodes, nbn ); + { + myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); + aMesh->RemoveElement(f); + } break; } case 4: { ///// quadrangle @@ -3974,7 +4023,10 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, if ( !f ) myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] )); else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) - aMesh->ChangeElementNodes( f, nodes, nbn ); + { + myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] )); + aMesh->RemoveElement(f); + } break; } default: @@ -3994,7 +4046,9 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, tmpnodes[3] = nodes[1]; tmpnodes[4] = nodes[3]; tmpnodes[5] = nodes[5]; - aMesh->ChangeElementNodes( f, tmpnodes, nbn ); + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5])); + aMesh->RemoveElement(f); } } else { /////// quadratic quadrangle @@ -4014,7 +4068,9 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, tmpnodes[5] = nodes[3]; tmpnodes[6] = nodes[5]; tmpnodes[7] = nodes[7]; - aMesh->ChangeElementNodes( f, tmpnodes, nbn ); + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7])); + aMesh->RemoveElement(f); } } } @@ -4024,7 +4080,11 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, if ( !f ) myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes)); else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) + { + // TODO problem ChangeElementNodes : not the same number of nodes, not the same type + MESSAGE("ChangeElementNodes"); aMesh->ChangeElementNodes( f, nodes, nbn ); + } } } while ( srcElements.Length() < myLastCreatedElems.Length() ) @@ -4322,6 +4382,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, const int theFlags, const double theTolerance) { + MESSAGE("ExtrusionSweep " << theMakeGroups << " " << theFlags << " " << theTolerance); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -4522,6 +4583,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, const gp_Pnt& theRefPoint, const bool theMakeGroups) { + MESSAGE("ExtrusionAlongTrack"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -4580,7 +4642,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, while ( aItN->more() ) { const SMDS_MeshNode* pNode = aItN->next(); const SMDS_EdgePosition* pEPos = - static_cast( pNode->GetPosition().get() ); + static_cast( pNode->GetPosition() ); double aT = pEPos->GetUParameter(); aPrms.push_back( aT ); } @@ -4624,7 +4686,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, while ( aItN->more() ) { const SMDS_MeshNode* pNode = aItN->next(); const SMDS_EdgePosition* pEPos = - static_cast( pNode->GetPosition().get() ); + static_cast( pNode->GetPosition() ); double aT = pEPos->GetUParameter(); aPrms.push_back( aT ); } @@ -4752,7 +4814,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, const SMDS_MeshNode* pNode = aItN->next(); if( pNode==aN1 || pNode==aN2 ) continue; const SMDS_EdgePosition* pEPos = - static_cast( pNode->GetPosition().get() ); + static_cast( pNode->GetPosition() ); double aT = pEPos->GetUParameter(); aPrms.push_back( aT ); } @@ -4799,7 +4861,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, while ( aItN->more() ) { const SMDS_MeshNode* pNode = aItN->next(); const SMDS_EdgePosition* pEPos = - static_cast( pNode->GetPosition().get() ); + static_cast( pNode->GetPosition() ); double aT = pEPos->GetUParameter(); aPrms.push_back( aT ); } @@ -4925,6 +4987,7 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet& theElements, const gp_Pnt& theRefPoint, const bool theMakeGroups) { + MESSAGE("MakeExtrElements"); //cout<<"MakeExtrElements fullList.size() = "< aPPs(aNbTP); @@ -5080,6 +5143,7 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet& theElements, } // make new node + //MESSAGE("elem->IsQuadratic " << elem->IsQuadratic() << " " << elem->IsMediumNode(node)); if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { // create additional node double x = ( aPN1.X() + aPN0.X() )/2.; @@ -5262,35 +5326,35 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, // source elements for each generated one SMESH_SequenceOfElemPtr srcElems, srcNodes; - // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh - list orphanCopy; // copies of orphan nodes - vector orphanNode; // original orphan nodes - - if ( theElems.empty() ) // transform the whole mesh - { - // add all elements - SMDS_ElemIteratorPtr eIt = aMesh->elementsIterator(); - while ( eIt->more() ) theElems.insert( eIt->next() ); - // add orphan nodes - SMDS_MeshElementIDFactory idFactory; - SMDS_NodeIteratorPtr nIt = aMesh->nodesIterator(); - while ( nIt->more() ) - { - const SMDS_MeshNode* node = nIt->next(); - if ( node->NbInverseElements() == 0 && !theElems.insert( node ).second ) - { - // node was not inserted into theElems because an element with the same ID - // is already there. As a work around we insert a copy of node with - // an ID = - - orphanCopy.push_back( *node ); // copy node - SMDS_MeshNode* nodeCopy = &orphanCopy.back(); - int uniqueID = -orphanNode.size(); - orphanNode.push_back( node ); - idFactory.BindID( uniqueID, nodeCopy ); - theElems.insert( nodeCopy ); - } - } - } +// // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh +// list orphanCopy; // copies of orphan nodes +// vector orphanNode; // original orphan nodes +// +// if ( theElems.empty() ) // transform the whole mesh +// { +// // add all elements +// SMDS_ElemIteratorPtr eIt = aMesh->elementsIterator(); +// while ( eIt->more() ) theElems.insert( eIt->next() ); +// // add orphan nodes +// SMDS_MeshElementIDFactory idFactory; +// SMDS_NodeIteratorPtr nIt = aMesh->nodesIterator(); +// while ( nIt->more() ) +// { +// const SMDS_MeshNode* node = nIt->next(); +// if ( node->NbInverseElements() == 0 && !theElems.insert( node ).second ) +// { +// // node was not inserted into theElems because an element with the same ID +// // is already there. As a work around we insert a copy of node with +// // an ID = - +// orphanCopy.push_back( *node ); // copy node +// SMDS_MeshNode* nodeCopy = &orphanCopy.back(); +// int uniqueID = -orphanNode.size(); +// orphanNode.push_back( node ); +// idFactory.BindID( uniqueID, nodeCopy ); +// theElems.insert( nodeCopy ); +// } +// } +// } // loop on theElems to transorm nodes TIDSortedElemSet::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { @@ -5303,8 +5367,8 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, while ( itN->more() ) { const SMDS_MeshNode* node = cast2Node( itN->next() ); - if ( node->GetID() < 0 ) - node = orphanNode[ -node->GetID() ]; +// if ( node->GetID() < 0 ) +// node = orphanNode[ -node->GetID() ]; // check if a node has been already transformed pair n2n_isnew = nodeMap.insert( make_pair ( node, node )); @@ -5355,7 +5419,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, theElems.insert( *invElemIt ); // replicate or reverse elements - + // TODO revoir ordre reverse vtk enum { REV_TETRA = 0, // = nbNodes - 4 REV_PYRAMID = 1, // = nbNodes - 4 @@ -5423,8 +5487,8 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, case SMDSAbs_Volume: { // ATTENTION: Reversing is not yet done!!! - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - dynamic_cast( elem ); + const SMDS_VtkVolume* aPolyedre = + dynamic_cast( elem ); if (!aPolyedre) { MESSAGE("Warning: bad volumic element"); continue; @@ -5554,6 +5618,332 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, return newGroupIDs; } + +////======================================================================= +////function : Scale +////purpose : +////======================================================================= +// +//SMESH_MeshEditor::PGroupIDs +//SMESH_MeshEditor::Scale (TIDSortedElemSet & theElems, +// const gp_Pnt& thePoint, +// const std::list& theScaleFact, +// const bool theCopy, +// const bool theMakeGroups, +// SMESH_Mesh* theTargetMesh) +//{ +// MESSAGE("Scale"); +// myLastCreatedElems.Clear(); +// myLastCreatedNodes.Clear(); +// +// SMESH_MeshEditor targetMeshEditor( theTargetMesh ); +// SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0; +// SMESHDS_Mesh* aMesh = GetMeshDS(); +// +// double scaleX=1.0, scaleY=1.0, scaleZ=1.0; +// std::list::const_iterator itS = theScaleFact.begin(); +// scaleX = (*itS); +// if(theScaleFact.size()==1) { +// scaleY = (*itS); +// scaleZ= (*itS); +// } +// if(theScaleFact.size()==2) { +// itS++; +// scaleY = (*itS); +// scaleZ= (*itS); +// } +// if(theScaleFact.size()>2) { +// itS++; +// scaleY = (*itS); +// itS++; +// scaleZ= (*itS); +// } +// +// // map old node to new one +// TNodeNodeMap nodeMap; +// +// // elements sharing moved nodes; those of them which have all +// // nodes mirrored but are not in theElems are to be reversed +// TIDSortedElemSet inverseElemSet; +// +// // source elements for each generated one +// SMESH_SequenceOfElemPtr srcElems, srcNodes; +// +// // loop on theElems +// TIDSortedElemSet::iterator itElem; +// for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { +// const SMDS_MeshElement* elem = *itElem; +// if ( !elem ) +// continue; +// +// // loop on elem nodes +// SMDS_ElemIteratorPtr itN = elem->nodesIterator(); +// while ( itN->more() ) { +// +// // check if a node has been already transformed +// const SMDS_MeshNode* node = cast2Node( itN->next() ); +// pair n2n_isnew = +// nodeMap.insert( make_pair ( node, node )); +// if ( !n2n_isnew.second ) +// continue; +// +// //double coord[3]; +// //coord[0] = node->X(); +// //coord[1] = node->Y(); +// //coord[2] = node->Z(); +// //theTrsf.Transforms( coord[0], coord[1], coord[2] ); +// double dx = (node->X() - thePoint.X()) * scaleX; +// double dy = (node->Y() - thePoint.Y()) * scaleY; +// double dz = (node->Z() - thePoint.Z()) * scaleZ; +// if ( theTargetMesh ) { +// //const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] ); +// const SMDS_MeshNode * newNode = +// aTgtMesh->AddNode( thePoint.X()+dx, thePoint.Y()+dy, thePoint.Z()+dz ); +// n2n_isnew.first->second = newNode; +// myLastCreatedNodes.Append(newNode); +// srcNodes.Append( node ); +// } +// else if ( theCopy ) { +// //const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); +// const SMDS_MeshNode * newNode = +// aMesh->AddNode( thePoint.X()+dx, thePoint.Y()+dy, thePoint.Z()+dz ); +// n2n_isnew.first->second = newNode; +// myLastCreatedNodes.Append(newNode); +// srcNodes.Append( node ); +// } +// else { +// //aMesh->MoveNode( node, coord[0], coord[1], coord[2] ); +// aMesh->MoveNode( node, thePoint.X()+dx, thePoint.Y()+dy, thePoint.Z()+dz ); +// // node position on shape becomes invalid +// const_cast< SMDS_MeshNode* > ( node )->SetPosition +// ( SMDS_SpacePosition::originSpacePosition() ); +// } +// +// // keep inverse elements +// //if ( !theCopy && !theTargetMesh && needReverse ) { +// // SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator(); +// // while ( invElemIt->more() ) { +// // const SMDS_MeshElement* iel = invElemIt->next(); +// // inverseElemSet.insert( iel ); +// // } +// //} +// } +// } +// +// // either create new elements or reverse mirrored ones +// //if ( !theCopy && !needReverse && !theTargetMesh ) +// if ( !theCopy && !theTargetMesh ) +// return PGroupIDs(); +// +// TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin(); +// for ( ; invElemIt != inverseElemSet.end(); invElemIt++ ) +// theElems.insert( *invElemIt ); +// +// // replicate or reverse elements +// +// enum { +// REV_TETRA = 0, // = nbNodes - 4 +// REV_PYRAMID = 1, // = nbNodes - 4 +// REV_PENTA = 2, // = nbNodes - 4 +// REV_FACE = 3, +// REV_HEXA = 4, // = nbNodes - 4 +// FORWARD = 5 +// }; +// int index[][8] = { +// { 2, 1, 0, 3, 4, 0, 0, 0 }, // REV_TETRA +// { 2, 1, 0, 3, 4, 0, 0, 0 }, // REV_PYRAMID +// { 2, 1, 0, 5, 4, 3, 0, 0 }, // REV_PENTA +// { 2, 1, 0, 3, 0, 0, 0, 0 }, // REV_FACE +// { 2, 1, 0, 3, 6, 5, 4, 7 }, // REV_HEXA +// { 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD +// }; +// +// for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) +// { +// const SMDS_MeshElement* elem = *itElem; +// if ( !elem || elem->GetType() == SMDSAbs_Node ) +// continue; +// +// int nbNodes = elem->NbNodes(); +// int elemType = elem->GetType(); +// +// if (elem->IsPoly()) { +// // Polygon or Polyhedral Volume +// switch ( elemType ) { +// case SMDSAbs_Face: +// { +// vector poly_nodes (nbNodes); +// int iNode = 0; +// SMDS_ElemIteratorPtr itN = elem->nodesIterator(); +// while (itN->more()) { +// const SMDS_MeshNode* node = +// static_cast(itN->next()); +// TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node); +// if (nodeMapIt == nodeMap.end()) +// break; // not all nodes transformed +// //if (needReverse) { +// // // reverse mirrored faces and volumes +// // poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second; +// //} else { +// poly_nodes[iNode] = (*nodeMapIt).second; +// //} +// iNode++; +// } +// if ( iNode != nbNodes ) +// continue; // not all nodes transformed +// +// if ( theTargetMesh ) { +// myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes)); +// srcElems.Append( elem ); +// } +// else if ( theCopy ) { +// myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes)); +// srcElems.Append( elem ); +// } +// else { +// aMesh->ChangePolygonNodes(elem, poly_nodes); +// } +// } +// break; +// case SMDSAbs_Volume: +// { +// // ATTENTION: Reversing is not yet done!!! +// const SMDS_VtkVolume* aPolyedre = +// dynamic_cast( elem ); +// if (!aPolyedre) { +// MESSAGE("Warning: bad volumic element"); +// continue; +// } +// +// vector poly_nodes; +// vector quantities; +// +// bool allTransformed = true; +// int nbFaces = aPolyedre->NbFaces(); +// for (int iface = 1; iface <= nbFaces && allTransformed; iface++) { +// int nbFaceNodes = aPolyedre->NbFaceNodes(iface); +// for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) { +// const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode); +// TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node); +// if (nodeMapIt == nodeMap.end()) { +// allTransformed = false; // not all nodes transformed +// } else { +// poly_nodes.push_back((*nodeMapIt).second); +// } +// } +// quantities.push_back(nbFaceNodes); +// } +// if ( !allTransformed ) +// continue; // not all nodes transformed +// +// if ( theTargetMesh ) { +// myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities)); +// srcElems.Append( elem ); +// } +// else if ( theCopy ) { +// myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities)); +// srcElems.Append( elem ); +// } +// else { +// aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); +// } +// } +// break; +// default:; +// } +// continue; +// } +// +// // Regular elements +// int* i = index[ FORWARD ]; +// //if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes +// // if ( elemType == SMDSAbs_Face ) +// // i = index[ REV_FACE ]; +// // 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 +// vector nodes(nbNodes); +// int iNode = 0; +// SMDS_ElemIteratorPtr itN = elem->nodesIterator(); +// while ( itN->more() ) { +// const SMDS_MeshNode* node = +// static_cast( itN->next() ); +// TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node ); +// if ( nodeMapIt == nodeMap.end() ) +// break; // not all nodes transformed +// nodes[ i [ iNode++ ]] = (*nodeMapIt).second; +// } +// if ( iNode != nbNodes ) +// continue; // not all nodes transformed +// +// if ( theTargetMesh ) { +// if ( SMDS_MeshElement* copy = +// targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) { +// myLastCreatedElems.Append( copy ); +// srcElems.Append( elem ); +// } +// } +// else if ( theCopy ) { +// if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) { +// myLastCreatedElems.Append( copy ); +// srcElems.Append( elem ); +// } +// } +// else { +// // reverse element as it was reversed by transformation +// if ( nbNodes > 2 ) +// aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes ); +// } +// } +// +// PGroupIDs newGroupIDs; +// +// if ( theMakeGroups && theCopy || +// theMakeGroups && theTargetMesh ) { +// string groupPostfix = "scaled"; +// newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh ); +// } +// +// return newGroupIDs; +//} + + //======================================================================= /*! * \brief Create groups of elements made during transformation @@ -5757,9 +6147,8 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher */ const SMDS_MeshNode* FindClosestTo( const gp_Pnt& thePnt ) { - SMDS_MeshNode tgtNode( thePnt.X(), thePnt.Y(), thePnt.Z() ); map dist2Nodes; - myOctreeNode->NodesAround( &tgtNode, dist2Nodes, myHalfLeafSize ); + myOctreeNode->NodesAround( thePnt.Coord(), dist2Nodes, myHalfLeafSize ); if ( !dist2Nodes.empty() ) return dist2Nodes.begin()->second; list nodes; @@ -5775,14 +6164,14 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher list< SMESH_OctreeNode* >::iterator trIt; treeList.push_back( myOctreeNode ); - SMDS_MeshNode pointNode( thePnt.X(), thePnt.Y(), thePnt.Z() ); - bool pointInside = myOctreeNode->isInside( &pointNode, myHalfLeafSize ); + gp_XYZ pointNode( thePnt.X(), thePnt.Y(), thePnt.Z() ); + bool pointInside = myOctreeNode->isInside( pointNode, myHalfLeafSize ); for ( trIt = treeList.begin(); trIt != treeList.end(); ++trIt) { SMESH_OctreeNode* tree = *trIt; if ( !tree->isLeaf() ) // put children to the queue { - if ( pointInside && !tree->isInside( &pointNode, myHalfLeafSize )) continue; + if ( pointInside && !tree->isInside( pointNode, myHalfLeafSize )) continue; SMESH_OctreeNodeIteratorPtr cIt = tree->GetChildrenIterator(); while ( cIt->more() ) treeList.push_back( cIt->next() ); @@ -6138,7 +6527,6 @@ double SMESH_ElementSearcherImpl::getTolerance() meshInfo.NbElements( SMDSAbs_ElementType( complexType )) < 1 ) --complexType; if ( complexType == SMDSAbs_All ) return 0; // empty mesh - double elemSize; if ( complexType == int( SMDSAbs_Node )) { @@ -6149,8 +6537,9 @@ double SMESH_ElementSearcherImpl::getTolerance() } else { - const SMDS_MeshElement* elem = - _mesh->elementsIterator( SMDSAbs_ElementType( complexType ))->next(); + SMDS_ElemIteratorPtr elemIt = + _mesh->elementsIterator( SMDSAbs_ElementType( complexType )); + const SMDS_MeshElement* elem = elemIt->next(); SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); SMESH_MeshEditor::TNodeXYZ n1( cast2Node( nodeIt->next() )); while ( nodeIt->more() ) @@ -6632,16 +7021,21 @@ bool SMESH_MeshEditor::isOut( const SMDS_MeshElement* element, const gp_Pnt& poi // get ordered nodes vector< gp_XYZ > xyz; + vector nodeList; SMDS_ElemIteratorPtr nodeIt = element->nodesIterator(); if ( element->IsQuadratic() ) - if (const SMDS_QuadraticFaceOfNodes* f=dynamic_cast(element)) + if (const SMDS_VtkFace* f=dynamic_cast(element)) nodeIt = f->interlacedNodesElemIterator(); - else if (const SMDS_QuadraticEdge* e =dynamic_cast(element)) + else if (const SMDS_VtkEdge* e =dynamic_cast(element)) nodeIt = e->interlacedNodesElemIterator(); while ( nodeIt->more() ) - xyz.push_back( TNodeXYZ( cast2Node( nodeIt->next() ))); + { + const SMDS_MeshNode* node = cast2Node( nodeIt->next() ); + xyz.push_back( TNodeXYZ(node) ); + nodeList.push_back(node); + } int i, nbNodes = element->NbNodes(); @@ -6650,6 +7044,7 @@ bool SMESH_MeshEditor::isOut( const SMDS_MeshElement* element, const gp_Pnt& poi // compute face normal gp_Vec faceNorm(0,0,0); xyz.push_back( xyz.front() ); + nodeList.push_back( nodeList.front() ); for ( i = 0; i < nbNodes; ++i ) { gp_Vec edge1( xyz[i+1], xyz[i]); @@ -6662,9 +7057,7 @@ bool SMESH_MeshEditor::isOut( const SMDS_MeshElement* element, const gp_Pnt& poi // degenerated face: point is out if it is out of all face edges for ( i = 0; i < nbNodes; ++i ) { - SMDS_MeshNode n1( xyz[i].X(), xyz[i].Y(), xyz[i].Z() ); - SMDS_MeshNode n2( xyz[i+1].X(), xyz[i+1].Y(), xyz[i+1].Z() ); - SMDS_MeshEdge edge( &n1, &n2 ); + SMDS_LinearEdge edge( nodeList[i], nodeList[i+1] ); if ( !isOut( &edge, point, tol )) return false; } @@ -6862,6 +7255,7 @@ int SMESH_MeshEditor::SimplifyFace (const vector faceNode void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) { + MESSAGE("MergeNodes"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -6878,10 +7272,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) list& nodes = *grIt; list::iterator nIt = nodes.begin(); const SMDS_MeshNode* nToKeep = *nIt; + //MESSAGE("node to keep " << nToKeep->GetID()); for ( ++nIt; nIt != nodes.end(); nIt++ ) { const SMDS_MeshNode* nToRemove = *nIt; nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep )); if ( nToRemove != nToKeep ) { + //MESSAGE(" node to remove " << nToRemove->GetID()); rmNodeIds.push_back( nToRemove->GetID() ); AddToSameGroups( nToKeep, nToRemove, aMesh ); } @@ -6898,6 +7294,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) set::iterator eIt = elems.begin(); for ( ; eIt != elems.end(); eIt++ ) { const SMDS_MeshElement* elem = *eIt; + //MESSAGE(" ---- inverse elem on node to remove " << elem->GetID()); int nbNodes = elem->NbNodes(); int aShapeId = FindShape( elem ); @@ -6947,6 +7344,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) bool isOk = true; int nbUniqueNodes = nodeSet.size(); + //MESSAGE("nbNodes nbUniqueNodes " << nbNodes << " " << nbUniqueNodes); if ( nbNodes != nbUniqueNodes ) { // some nodes stick // Polygons and Polyhedral volumes if (elem->IsPoly()) { @@ -6976,7 +7374,19 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) if (aShapeId) aMesh->SetMeshElementOnShape(newElem, aShapeId); } - aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]); + + MESSAGE("ChangeElementNodes MergeNodes Polygon"); + //aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]); + vector polynodes(polygons_nodes.begin()+inode,polygons_nodes.end()); + int quid =0; + if (nbNew > 0) quid = nbNew - 1; + vector newquant(quantities.begin()+quid, quantities.end()); + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddPolyhedralVolume(polynodes, newquant); + myLastCreatedElems.Append(newElem); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + rmElemIds.push_back(elem->GetID()); } else { rmElemIds.push_back(elem->GetID()); @@ -6989,9 +7399,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) rmElemIds.push_back(elem->GetID()); } else { - // each face has to be analized in order to check volume validity - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - static_cast( elem ); + // each face has to be analyzed in order to check volume validity + const SMDS_VtkVolume* aPolyedre = + dynamic_cast( elem ); if (aPolyedre) { int nbFaces = aPolyedre->NbFaces(); @@ -7019,10 +7429,16 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } if (quantities.size() > 3) - aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); - else - rmElemIds.push_back(elem->GetID()); - + { + MESSAGE("ChangeElementNodes MergeNodes Polyhedron"); + //aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddPolyhedralVolume(poly_nodes, quantities); + myLastCreatedElems.Append(newElem); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + rmElemIds.push_back(elem->GetID()); + } } else { rmElemIds.push_back(elem->GetID()); @@ -7036,6 +7452,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } // Regular elements + // TODO not all the possible cases are solved. Find something more generic? switch ( nbNodes ) { case 2: ///////////////////////////////////// EDGE isOk = false; break; @@ -7049,6 +7466,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) isOk = false; else if ( nbRepl == 2 && iRepl[ 1 ] - iRepl[ 0 ] == 2 ) isOk = false; // opposite nodes stick + //MESSAGE("isOk " << isOk); } break; case 6: ///////////////////////////////////// PENTAHEDRON @@ -7113,7 +7531,11 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // +---+---+ // 0 7 3 isOk = false; + if(nbRepl==2) { + MESSAGE("nbRepl=2: " << iRepl[0] << " " << iRepl[1]); + } if(nbRepl==3) { + MESSAGE("nbRepl=3: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2]); nbUniqueNodes = 6; if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) { uniqueNodes[0] = curNodes[0]; @@ -7188,6 +7610,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) isOk = true; } } + if(nbRepl==4) { + MESSAGE("nbRepl=4: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3]); + } + if(nbRepl==5) { + MESSAGE("nbRepl=5: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3] << " " << iRepl[4]); + } break; } //////////////////////////////////// HEXAHEDRON @@ -7372,8 +7800,8 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) if ( isOk ) { if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume) { // Change nodes of polyedre - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - static_cast( elem ); + const SMDS_VtkVolume* aPolyedre = + dynamic_cast( elem ); if (aPolyedre) { int nbFaces = aPolyedre->NbFaces(); @@ -7398,21 +7826,32 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } } else { - // Change regular element or polygon - aMesh->ChangeElementNodes( elem, & uniqueNodes[0], nbUniqueNodes ); + int elemId = elem->GetID(); + //MESSAGE("Change regular element or polygon " << elemId); + SMDSAbs_ElementType etyp = elem->GetType(); + uniqueNodes.resize(nbUniqueNodes); + SMDS_MeshElement* newElem = this->AddElement(uniqueNodes, etyp, false); + if (newElem) + { + myLastCreatedElems.Append(newElem); + if ( aShapeId ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement(elem); } } else { // Remove invalid regular element or invalid polygon + //MESSAGE("Remove invalid " << elem->GetID()); rmElemIds.push_back( elem->GetID() ); } } // loop on elements - // Remove equal nodes and bad elements + // Remove bad elements, then equal nodes (order important) - Remove( rmNodeIds, true ); Remove( rmElemIds, false ); + Remove( rmNodeIds, true ); } @@ -7575,8 +8014,10 @@ SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode* n1, const SMDS_MeshElement* face = 0; SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(SMDSAbs_Face); + //MESSAGE("n1->GetInverseElementIterator(SMDSAbs_Face) " << invElemIt); while ( invElemIt->more() && !face ) // loop on inverse faces of n1 { + //MESSAGE("in while ( invElemIt->more() && !face )"); const SMDS_MeshElement* elem = invElemIt->next(); if (avoidSet.count( elem )) continue; @@ -7595,10 +8036,11 @@ SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode* n1, if ( !face && elem->IsQuadratic()) { // analysis for quadratic elements using all nodes - const SMDS_QuadraticFaceOfNodes* F = - static_cast(elem); + const SMDS_VtkFace* F = + dynamic_cast(elem); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); const SMDS_MeshNode* prevN = cast2Node( anIter->next() ); for ( i1 = -1, i2 = 0; anIter->more() && !face; i1++, i2++ ) { @@ -7682,12 +8124,13 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode* theFirst vector nodes(nbNodes+1); if(e->IsQuadratic()) { - const SMDS_QuadraticFaceOfNodes* F = - static_cast(e); + const SMDS_VtkFace* F = + dynamic_cast(e); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); while( anIter->more() ) { - nodes[ iNode++ ] = anIter->next(); + nodes[ iNode++ ] = cast2Node(anIter->next()); } } else { @@ -7857,7 +8300,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, // links of the free border // ------------------------------------------------------------------------- - // 1. Since sewing may brake if there are volumes to split on the side 2, + // 1. Since sewing may break if there are volumes to split on the side 2, // we wont move nodes but just compute new coordinates for them typedef map TNodeXYZMap; TNodeXYZMap nBordXYZ; @@ -7955,12 +8398,13 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, else if ( elem->GetType()==SMDSAbs_Face ) { // --face // retrieve all face nodes and find iPrevNode - an index of the prevSideNode if(elem->IsQuadratic()) { - const SMDS_QuadraticFaceOfNodes* F = - static_cast(elem); + const SMDS_VtkFace* F = + dynamic_cast(elem); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); while( anIter->more() ) { - nodes[ iNode ] = anIter->next(); + nodes[ iNode ] = cast2Node(anIter->next()); if ( nodes[ iNode++ ] == prevSideNode ) iPrevNode = iNode - 1; } @@ -8274,12 +8718,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, vector nodes( theFace->NbNodes() ); if(theFace->IsQuadratic()) { - const SMDS_QuadraticFaceOfNodes* F = - static_cast(theFace); + const SMDS_VtkFace* F = + dynamic_cast(theFace); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); while( anIter->more() ) { - const SMDS_MeshNode* n = anIter->next(); + const SMDS_MeshNode* n = cast2Node(anIter->next()); if ( n == theBetweenNode1 ) il1 = iNode; else if ( n == theBetweenNode2 ) @@ -8335,12 +8780,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, bool isFLN = false; if(theFace->IsQuadratic()) { - const SMDS_QuadraticFaceOfNodes* F = - static_cast(theFace); + const SMDS_VtkFace* F = + dynamic_cast(theFace); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); while( anIter->more() && !isFLN ) { - const SMDS_MeshNode* n = anIter->next(); + const SMDS_MeshNode* n = cast2Node(anIter->next()); poly_nodes[iNode++] = n; if (n == nodes[il1]) { isFLN = true; @@ -8353,7 +8799,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, } // add nodes of face starting from last node of link while ( anIter->more() ) { - poly_nodes[iNode++] = anIter->next(); + poly_nodes[iNode++] = cast2Node(anIter->next()); } } else { @@ -8396,6 +8842,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, return; } + SMESHDS_Mesh *aMesh = GetMeshDS(); if( !theFace->IsQuadratic() ) { // put aNodesToInsert between theBetweenNode1 and theBetweenNode2 @@ -8446,7 +8893,6 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, } // create new elements - SMESHDS_Mesh *aMesh = GetMeshDS(); int aShapeId = FindShape( theFace ); i1 = 0; i2 = 1; @@ -8472,8 +8918,16 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, 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()) + //aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 ); + const SMDS_MeshElement* newElem = 0; + if (iSplit == iBestQuad) + newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] ); + else + newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] ); + myLastCreatedElems.Append(newElem); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); +} // end if(!theFace->IsQuadratic()) else { // theFace is quadratic // we have to split theFace on simple triangles and one simple quadrangle int tmp = il1/2; @@ -8500,7 +8954,6 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, // n4 n6 n5 n4 // create new elements - SMESHDS_Mesh *aMesh = GetMeshDS(); int aShapeId = FindShape( theFace ); int n1,n2,n3; @@ -8583,9 +9036,9 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); } - // remove old quadratic face - aMesh->RemoveElement(theFace); } + // remove old face + aMesh->RemoveElement(theFace); } //======================================================================= @@ -8697,14 +9150,14 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, if( !elem || elem->IsQuadratic() ) continue; int id = elem->GetID(); + //MESSAGE("elem " << id); + id = 0; // get a free number for new elements int nbNodes = elem->NbNodes(); SMDSAbs_ElementType aType = elem->GetType(); vector nodes (elem->begin_nodes(), elem->end_nodes()); if ( elem->GetEntityType() == SMDSEntity_Polyhedra ) - nbNodeInFaces = static_cast( elem )->GetQuanities(); - - GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false); + nbNodeInFaces = static_cast( elem )->GetQuantities(); const SMDS_MeshElement* NewElem = 0; @@ -8759,7 +9212,11 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, ReplaceElemInGroups( elem, NewElem, GetMeshDS()); if( NewElem ) theSm->AddElement( NewElem ); + + GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false); } +// if (!GetMeshDS()->isCompacted()) +// GetMeshDS()->compactMesh(); return nbElem; } @@ -8800,6 +9257,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) if(edge && !edge->IsQuadratic()) { int id = edge->GetID(); + //MESSAGE("edge->GetID() " << id); const SMDS_MeshNode* n1 = edge->GetNode(0); const SMDS_MeshNode* n2 = edge->GetNode(1); @@ -8846,7 +9304,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) int nbNodes = volume->NbNodes(); vector nodes (volume->begin_nodes(), volume->end_nodes()); if ( volume->GetEntityType() == SMDSEntity_Polyhedra ) - nbNodeInFaces = static_cast(volume)->GetQuanities(); + nbNodeInFaces = static_cast(volume)->GetQuantities(); meshDS->RemoveFreeElement(volume, smDS, /*fromGroups=*/false); @@ -8881,6 +9339,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) aHelper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh aHelper.FixQuadraticElements(); } + if (!GetMeshDS()->isCompacted()) + GetMeshDS()->compactMesh(); } //======================================================================= @@ -8935,9 +9395,9 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, for ( ; nIt != mediumNodes.end(); ++nIt ) { const SMDS_MeshNode* n = *nIt; if ( n->NbInverseElements() == 0 ) { - if ( n->GetPosition()->GetShapeId() != theShapeID ) + if ( n->getshapeId() != theShapeID ) meshDS->RemoveFreeNode( n, meshDS->MeshElements - ( n->GetPosition()->GetShapeId() )); + ( n->getshapeId() )); else meshDS->RemoveFreeNode( n, theSm ); } @@ -9008,12 +9468,13 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, // 1. Build set of faces representing each side: // ======================================================================= // a. build set of nodes belonging to faces - // b. complete set of faces: find missing fices whose nodes are in set of nodes + // b. complete set of faces: find missing faces whose nodes are in set of nodes // c. create temporary faces representing side of volumes if correspondent // face does not exist SMESHDS_Mesh* aMesh = GetMeshDS(); - SMDS_Mesh aTmpFacesMesh; + // TODO algoritm not OK with vtkUnstructuredGrid: 2 meshes can't share nodes + //SMDS_Mesh aTmpFacesMesh; // try to use the same mesh set faceSet1, faceSet2; set volSet1, volSet2; set nodeSet1, nodeSet2; @@ -9023,6 +9484,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, TIDSortedElemSet * elemSetPtr[] = { &theSide1, &theSide2 }; int iSide, iFace, iNode; + list tempFaceList; for ( iSide = 0; iSide < 2; iSide++ ) { set * nodeSet = nodeSetPtr[ iSide ]; TIDSortedElemSet * elemSet = elemSetPtr[ iSide ]; @@ -9050,7 +9512,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, // ----------------------------------------------------------- // 1a. Collect nodes of existing faces // and build set of face nodes in order to detect missing - // faces corresponing to sides of volumes + // faces corresponding to sides of volumes // ----------------------------------------------------------- set< set > setOfFaceNodeSet; @@ -9074,7 +9536,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, volSet->insert( elem ); } // ------------------------------------------------------------------------------ - // 1b. Complete set of faces: find missing fices whose nodes are in set of nodes + // 1b. Complete set of faces: find missing faces whose nodes are in set of nodes // ------------------------------------------------------------------------------ for ( nIt = nodeSet->begin(); nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide @@ -9142,18 +9604,23 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, if ( !aFreeFace ) { // create a temporary face if ( nbNodes == 3 ) { - aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] ); + //aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] ); + aFreeFace = aMesh->AddFace( fNodes[0],fNodes[1],fNodes[2] ); } else if ( nbNodes == 4 ) { - aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); + //aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); + aFreeFace = aMesh->AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); } else { vector poly_nodes ( fNodes, & fNodes[nbNodes]); - aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes); + //aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes); + aFreeFace = aMesh->AddPolygonalFace(poly_nodes); } } - if ( aFreeFace ) + if ( aFreeFace ) { freeFaceList.push_back( aFreeFace ); + tempFaceList.push_back( aFreeFace ); + } } // loop on faces of a volume @@ -9183,7 +9650,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, fIt++; } else - freeFaceList.erase( fIt++ ); // here fIt++ occures before erase + freeFaceList.erase( fIt++ ); // here fIt++ occurs before erase } if ( freeFaceList.size() > 1 ) { @@ -9267,9 +9734,12 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, if ( faceSet1.size() != faceSet2.size() ) { // delete temporary faces: they are in reverseElements of actual nodes - SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator(); - while ( tmpFaceIt->more() ) - aTmpFacesMesh.RemoveElement( tmpFaceIt->next() ); +// SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator(); +// while ( tmpFaceIt->more() ) +// aTmpFacesMesh.RemoveElement( tmpFaceIt->next() ); +// list::iterator tmpFaceIt = tempFaceList.begin(); +// for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt) +// aMesh->RemoveElement(*tmpFaceIt); MESSAGE("Diff nb of faces"); return SEW_TOPO_DIFF_SETS_OF_ELEMENTS; } @@ -9382,10 +9852,11 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, } } else { // f->IsQuadratic() - const SMDS_QuadraticFaceOfNodes* F = - static_cast(f); + const SMDS_VtkFace* F = + dynamic_cast(f); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); while ( anIter->more() ) { const SMDS_MeshNode* n = static_cast( anIter->next() ); @@ -9524,9 +9995,12 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, // ==================================================================== // delete temporary faces: they are in reverseElements of actual nodes - SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator(); - while ( tmpFaceIt->more() ) - aTmpFacesMesh.RemoveElement( tmpFaceIt->next() ); +// SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator(); +// while ( tmpFaceIt->more() ) +// aTmpFacesMesh.RemoveElement( tmpFaceIt->next() ); +// list::iterator tmpFaceIt = tempFaceList.begin(); +// for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt) +// aMesh->RemoveElement(*tmpFaceIt); if ( aResult != SEW_OK) return aResult; @@ -9560,7 +10034,21 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, // elemIDsToRemove.push_back( e->GetID() ); // else if ( nbReplaced ) - aMesh->ChangeElementNodes( e, & nodes[0], nbNodes ); + { + SMDSAbs_ElementType etyp = e->GetType(); + SMDS_MeshElement* newElem = this->AddElement(nodes, etyp, false); + if (newElem) + { + myLastCreatedElems.Append(newElem); + AddToSameGroups(newElem, e, aMesh); + int aShapeId = e->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + } + aMesh->RemoveElement(e); + } } } @@ -9796,6 +10284,7 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS, const SMDS_MeshNode* >& theNodeNodeMap, const bool theIsDoubleElem ) { + MESSAGE("doubleNodes"); // iterate on through element and duplicate them (by nodes duplication) bool res = false; TIDSortedElemSet::const_iterator elemItr = theElems.begin(); @@ -9833,8 +10322,10 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS, if ( theIsDoubleElem ) AddElement(newNodes, anElem->GetType(), anElem->IsPoly()); else + { + MESSAGE("ChangeElementNodes"); theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() ); - + } res = true; } return res; @@ -9854,6 +10345,7 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS, bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, const std::list< int >& theListOfModifiedElems ) { + MESSAGE("DoubleNodes"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -9926,7 +10418,10 @@ bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, const SMDS_MeshElement* anElem = anElemToNodesIter->first; vector aNodeArr = anElemToNodesIter->second; if ( anElem ) + { + MESSAGE("ChangeElementNodes"); aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() ); + } } return true; @@ -10054,6 +10549,194 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems, return DoubleNodes( theElems, theNodesNot, anAffected ); } +/*! + * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. + * The list of groups must describe a partition of the mesh volumes. + * The nodes of the internal faces at the boundaries of the groups are doubled. + * In option, the internal faces are replaced by flat elements. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * @param theElems - list of groups of volumes, where a group of volume is a set of + * SMDS_MeshElements sorted by Id. + * @param createJointElems - if TRUE, create the elements + * @return TRUE if operation has been completed successfully, FALSE otherwise + */ +bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector& theElems, + bool createJointElems) +{ + MESSAGE("------------------------------------------------------"); + MESSAGE("SMESH_MeshEditor::CreateJointElementsOnGroupBoundaries"); + MESSAGE("------------------------------------------------------"); + + SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS(); + meshDS->BuildDownWardConnectivity(false); + CHRONO(50); + SMDS_UnstructuredGrid *grid = meshDS->getGrid(); + + // --- build the list of faces shared by 2 domains (group of elements), with their domain and volume indexes + // build the list of nodes shared by 2 or more domains, with their domain indexes + + std::map, DownIdCompare> faceDomains; // 2x(id domain --> id volume) + std::map > nodeDomains; //oldId -> (domainId -> newId) + faceDomains.clear(); + nodeDomains.clear(); + std::map emptyMap; + emptyMap.clear(); + + for (int idom = 0; idom < theElems.size(); idom++) + { + + // --- build a map (face to duplicate --> volume to modify) + // with all the faces shared by 2 domains (group of elements) + // and corresponding volume of this domain, for each shared face. + // a volume has a face shared by 2 domains if it has a neighbor which is not in is domain. + + const TIDSortedElemSet& domain = theElems[idom]; + TIDSortedElemSet::const_iterator elemItr = domain.begin(); + for (; elemItr != domain.end(); ++elemItr) + { + SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr; + if (!anElem) + continue; + int vtkId = anElem->getVtkId(); + int neighborsVtkIds[NBMAXNEIGHBORS]; + int downIds[NBMAXNEIGHBORS]; + unsigned char downTypes[NBMAXNEIGHBORS]; + int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); + for (int n = 0; n < nbNeighbors; n++) + { + int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]); + const SMDS_MeshElement* elem = meshDS->FindElement(smdsId); + if (! domain.count(elem)) // neighbor is in another domain : face is shared + { + DownIdType face(downIds[n], downTypes[n]); + if (!faceDomains.count(face)) + faceDomains[face] = emptyMap; // create an empty entry for face + if (!faceDomains[face].count(idom)) + { + faceDomains[face][idom] = vtkId; // volume associated to face in this domain + } + } + } + } + } + + MESSAGE("Number of shared faces " << faceDomains.size()); + + // --- for each shared face, get the nodes + // for each node, for each domain of the face, create a clone of the node + + std::map, DownIdCompare>::iterator itface = faceDomains.begin(); + for( ; itface != faceDomains.end();++itface ) + { + DownIdType face = itface->first; + std::map domvol = itface->second; + std::set oldNodes; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + std::set::iterator itn = oldNodes.begin(); + for (;itn != oldNodes.end(); ++itn) + { + int oldId = *itn; + if (!nodeDomains.count(oldId)) + nodeDomains[oldId] = emptyMap; // create an empty entry for node + std::map::iterator itdom = domvol.begin(); + for(; itdom != domvol.end(); ++itdom) + { + int idom = itdom->first; + if ( nodeDomains[oldId].empty() ) + nodeDomains[oldId][idom] = oldId; // keep the old node in the first domain + else + { + double *coords = grid->GetPoint(oldId); + SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]); + int newId = newNode->getVtkId(); + nodeDomains[oldId][idom] = newId; // cloned node for other domains + } + } + } + } + + // --- iterate on shared faces (volumes to modify, face to extrude) + // get node id's of the face (id SMDS = id VTK) + // create flat element with old and new nodes if requested + + if (createJointElems) + { + itface = faceDomains.begin(); + for( ; itface != faceDomains.end();++itface ) + { + DownIdType face = itface->first; + std::set oldNodes; + std::set::iterator itn; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + std::map localClonedNodeIds; + + std::map domvol = itface->second; + std::map::iterator itdom = domvol.begin(); + int dom1 = itdom->first; + int vtkVolId = itdom->second; + itdom++; + int dom2 = itdom->first; + + localClonedNodeIds.clear(); + for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn) + { + int oldId = *itn; + int refid = oldId; + if (nodeDomains[oldId].count(dom1)) + refid = nodeDomains[oldId][dom1]; + else + MESSAGE("--- problem domain node " << dom1 << " " << oldId); + int newid = oldId; + if (nodeDomains[oldId].count(dom2)) + newid = nodeDomains[oldId][dom2]; + else + MESSAGE("--- problem domain node " << dom2 << " " << oldId); + localClonedNodeIds[oldId] = newid; + } + meshDS->extrudeVolumeFromFace(vtkVolId, localClonedNodeIds); + } + } + + // --- iterate on shared faces (volumes to modify, face to extrude) + // get node id's of the face + // replace old nodes by new nodes in volumes, and update inverse connectivity + + itface = faceDomains.begin(); + for( ; itface != faceDomains.end();++itface ) + { + DownIdType face = itface->first; + std::set oldNodes; + std::set::iterator itn; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + std::map localClonedNodeIds; + + std::map domvol = itface->second; + std::map::iterator itdom = domvol.begin(); + for(; itdom != domvol.end(); ++itdom) + { + int idom = itdom->first; + int vtkVolId = itdom->second; + localClonedNodeIds.clear(); + for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn) + { + int oldId = *itn; + if (nodeDomains[oldId].count(idom)) + localClonedNodeIds[oldId] = nodeDomains[oldId][idom]; + } + meshDS->ModifyCellNodes(vtkVolId, localClonedNodeIds); + } + } + grid->BuildLinks(); + + // TODO replace also old nodes by new nodes in faces and edges + CHRONOSTOP(50); + counters::stats(); + return true; +} + //================================================================================ /*! * \brief Generates skin mesh (containing 2D cells) from 3D mesh @@ -10122,7 +10805,7 @@ namespace * \param group - a group to store created boundary elements in * \param targetMesh - a mesh to store created boundary elements in * \param toCopyElements - if true, the checked elements will be copied into the targetMesh - * \param toCopyExistingBondary - if true, not only new but also pre-existing + * \param toCopyExistingBondary - if true, not only new but also pre-existing * boundary elements will be copied into the targetMesh */ //================================================================================ @@ -10168,7 +10851,7 @@ void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, vector missingBndElems; TConnectivity nodes; if ( vTool.Set(elem) ) // elem is a volume ------------------------------------------ - { + { vTool.SetExternalNormal(); for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ ) { diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index dabe3f8db..6b61b3095 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -170,14 +170,14 @@ public: SMDS_MeshElement* AddElement(const std::vector & nodes, const SMDSAbs_ElementType type, const bool isPoly, - const int ID = 0); + const int ID = -1); /*! * \brief Add element */ SMDS_MeshElement* AddElement(const std::vector & nodeIDs, const SMDSAbs_ElementType type, const bool isPoly, - const int ID = 0); + const int ID = -1); int Remove (const std::list< int >& theElemIDs, const bool isNodes); // Remove a node or an element. @@ -624,6 +624,14 @@ public: const TIDSortedElemSet& theNodesNot, const TopoDS_Shape& theShape ); + bool DoubleNodesOnGroupBoundaries( const std::vector& theElems, + bool createJointElems); + + /*! + * \brief Generated skin mesh (containing 2D cells) from 3D mesh + * The created 2D mesh elements based on nodes of free faces of boundary volumes + * \return TRUE if operation has been completed successfully, FALSE otherwise + */ bool Make2DMeshFrom3D(); enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D }; diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index c3e284a47..bcdd2096a 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -293,7 +293,7 @@ bool SMESH_MesherHelper::IsMedium(const SMDS_MeshNode* node, TopoDS_Shape SMESH_MesherHelper::GetSubShapeByNode(const SMDS_MeshNode* node, SMESHDS_Mesh* meshDS) { - int shapeID = node->GetPosition()->GetShapeId(); + int shapeID = node->getshapeId(); if ( 0 < shapeID && shapeID <= meshDS->MaxShapeIndex() ) return meshDS->IndexToShape( shapeID ); else @@ -385,7 +385,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, { // node has position on face const SMDS_FacePosition* fpos = - static_cast(n->GetPosition().get()); + static_cast(n->GetPosition()); uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter()); if ( check ) uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F )); @@ -396,8 +396,8 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, // corresponding edge from face, get pcurve for this // edge and retrieve value from this pcurve const SMDS_EdgePosition* epos = - static_cast(n->GetPosition().get()); - int edgeID = Pos->GetShapeId(); + static_cast(n->GetPosition()); + int edgeID = n->getshapeId(); TopoDS_Edge E = TopoDS::Edge(GetMeshDS()->IndexToShape(edgeID)); double f, l, u = epos->GetUParameter(); Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); @@ -432,7 +432,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, } else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) { - if ( int vertexID = n->GetPosition()->GetShapeId() ) { + if ( int vertexID = n->getshapeId() ) { const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID)); try { uv = BRep_Tool::Parameters( V, F ); @@ -502,9 +502,12 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face& F, const double tol, const bool force) const { - int shapeID = n->GetPosition()->GetShapeId(); + int shapeID = n->getshapeId(); if ( force || toCheckPosOnShape( shapeID )) { + double toldis = tol; + double tolmin = 1.e-7*myMesh->GetMeshDS()->getMaxDim(); // nodes coordinates are stored in float format + if (toldis < tolmin) toldis = tolmin; // check that uv is correct TopLoc_Location loc; Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc ); @@ -512,7 +515,7 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face& F, if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() ); if ( Precision::IsInfinite( uv.X() ) || Precision::IsInfinite( uv.Y() ) || - nodePnt.Distance( surface->Value( uv.X(), uv.Y() )) > tol ) + nodePnt.Distance( surface->Value( uv.X(), uv.Y() )) > toldis ) { setPosOnShapeValidity( shapeID, false ); // uv incorrect, project the node to surface @@ -526,7 +529,7 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face& F, Quantity_Parameter U,V; projector.LowerDistanceParameters(U,V); uv.SetCoord( U,V ); - if ( nodePnt.Distance( surface->Value( U, V )) > tol ) + if ( nodePnt.Distance( surface->Value( U, V )) > toldis ) { MESSAGE( "SMESH_MesherHelper::CheckNodeUV(), invalid projection" ); return false; @@ -534,7 +537,7 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face& F, // store the fixed UV on the face if ( myShape.IsSame(F) && shapeID == myShapeID ) const_cast(n)->SetPosition - ( SMDS_PositionPtr( new SMDS_FacePosition( shapeID, U, V ))); + ( SMDS_PositionPtr( new SMDS_FacePosition( U, V ))); } else if ( uv.Modulus() > numeric_limits::min() ) { @@ -642,7 +645,7 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E, const SMDS_PositionPtr pos = n->GetPosition(); if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE ) { - const SMDS_EdgePosition* epos = static_cast( pos.get() ); + const SMDS_EdgePosition* epos = static_cast( pos ); param = epos->GetUParameter(); } else if( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) @@ -657,7 +660,7 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E, else { SMESHDS_Mesh * meshDS = GetMeshDS(); - int vertexID = pos->GetShapeId(); + int vertexID = n->getshapeId(); const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID)); param = BRep_Tool::Parameter( V, E ); } @@ -668,7 +671,7 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E, double f,l; BRep_Tool::Range( E, f,l ); bool force = ( param < f-tol || param > l+tol ); if ( !force && pos->GetTypeOfPosition()==SMDS_TOP_EDGE ) - force = ( GetMeshDS()->ShapeToIndex( E ) != pos->GetShapeId() ); + force = ( GetMeshDS()->ShapeToIndex( E ) != n->getshapeId() ); *check = CheckNodeU( E, n, param, 2*tol, force ); } @@ -688,9 +691,12 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, const bool force, double* distance) const { - int shapeID = n->GetPosition()->GetShapeId(); + int shapeID = n->getshapeId(); if ( force || toCheckPosOnShape( shapeID )) { + double toldis = tol; + double tolmin = 1.e-7*myMesh->GetMeshDS()->getMaxDim(); // nodes coordinates are stored in float format + if (toldis < tolmin) toldis = tolmin; // check that u is correct TopLoc_Location loc; double f,l; Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l ); @@ -708,7 +714,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() ); double dist = nodePnt.Distance( curve->Value( u )); if ( distance ) *distance = dist; - if ( dist > tol ) + if ( dist > toldis ) { setPosOnShapeValidity( shapeID, false ); // u incorrect, project the node to the curve @@ -732,15 +738,16 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, u = double( U ); dist = nodePnt.Distance( curve->Value( U )); if ( distance ) *distance = dist; - if ( dist > tol ) + if ( dist > toldis ) { MESSAGE( "SMESH_MesherHelper::CheckNodeU(), invalid projection" ); + MESSAGE("distance " << nodePnt.Distance(curve->Value( U )) << " " << toldis); return false; } // store the fixed U on the edge if ( myShape.IsSame(E) && shapeID == myShapeID ) const_cast(n)->SetPosition - ( SMDS_PositionPtr( new SMDS_EdgePosition( shapeID, U ))); + ( SMDS_PositionPtr( new SMDS_EdgePosition( U ))); } else if ( fabs( u ) > numeric_limits::min() ) { @@ -787,7 +794,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, SMDS_MeshNode* n12; SMESHDS_Mesh* meshDS = GetMeshDS(); - if ( IsSeamShape( n1->GetPosition()->GetShapeId() )) + if ( IsSeamShape( n1->getshapeId() )) // to get a correct UV of a node on seam, the second node must have checked UV std::swap( n1, n2 ); @@ -796,26 +803,27 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, const SMDS_PositionPtr Pos1 = n1->GetPosition(); const SMDS_PositionPtr Pos2 = n2->GetPosition(); + TopoDS_Edge E; double u [2]; + TopoDS_Face F; gp_XY uv[2]; + bool uvOK[2] = { false, false }; + if( myShape.IsNull() ) { if( Pos1->GetTypeOfPosition()==SMDS_TOP_FACE ) { - faceID = Pos1->GetShapeId(); + faceID = n1->getshapeId(); } else if( Pos2->GetTypeOfPosition()==SMDS_TOP_FACE ) { - faceID = Pos2->GetShapeId(); + faceID = n2->getshapeId(); } if( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE ) { - edgeID = Pos1->GetShapeId(); + edgeID = n1->getshapeId(); } if( Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE ) { - edgeID = Pos2->GetShapeId(); + edgeID = n2->getshapeId(); } } // get positions of the given nodes on shapes - TopoDS_Edge E; double u [2]; - TopoDS_Face F; gp_XY uv[2]; - bool uvOK[2] = { false, false }; TopAbs_ShapeEnum shapeType = myShape.IsNull() ? TopAbs_SHAPE : myShape.ShapeType(); if ( faceID>0 || shapeType == TopAbs_FACE) { @@ -832,7 +840,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, { if ( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE && Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE && - Pos1->GetShapeId() != Pos2->GetShapeId() ) // issue 0021006 + n1->getshapeId() != n2->getshapeId() ) // issue 0021006 return getMediumNodeOnComposedWire(n1,n2,force3d); if( myShape.IsNull() ) @@ -852,10 +860,10 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, { if ( uvOK[0] && uvOK[1] ) { - if ( IsDegenShape( Pos1->GetShapeId() )) + if ( IsDegenShape( n1->getshapeId() )) if ( myParIndex & U_periodic ) uv[0].SetCoord( 1, uv[1].Coord( 1 )); else uv[0].SetCoord( 2, uv[1].Coord( 2 )); - else if ( IsDegenShape( Pos2->GetShapeId() )) + else if ( IsDegenShape( n2->getshapeId() )) if ( myParIndex & U_periodic ) uv[1].SetCoord( 1, uv[0].Coord( 1 )); else uv[1].SetCoord( 2, uv[0].Coord( 2 )); @@ -894,11 +902,13 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, } } } + // 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); + if ( !F.IsNull() ) { gp_XY UV = ( uv[0] + uv[1] ) / 2.; @@ -915,6 +925,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, { meshDS->SetNodeInVolume(n12, myShapeID); } + myTLinkNodeMap.insert( make_pair( link, n12 )); return n12; } diff --git a/src/SMESH/SMESH_OctreeNode.cxx b/src/SMESH/SMESH_OctreeNode.cxx index 7cfe10d11..1ddb87f89 100644 --- a/src/SMESH/SMESH_OctreeNode.cxx +++ b/src/SMESH/SMESH_OctreeNode.cxx @@ -24,7 +24,7 @@ // inherites global class SMESH_Octree // File : SMESH_OctreeNode.cxx // Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux (OCC) +// Author : Nicolas Geimer & Aurelien Motteux (OCC) // Module : SMESH // #include "SMESH_OctreeNode.hxx" @@ -106,9 +106,8 @@ Bnd_B3d* SMESH_OctreeNode::buildRootBox() */ //==================================================================================== -const bool SMESH_OctreeNode::isInside (const SMDS_MeshNode * Node, const double precision) +const bool SMESH_OctreeNode::isInside (const gp_XYZ& p, const double precision) { - gp_XYZ p (Node->X(),Node->Y(),Node->Z()); if (precision <= 0.) return !(getBox().IsOut(p)); Bnd_B3d BoxWithPrecision = getBox(); @@ -158,7 +157,8 @@ void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node, list* Result, const double precision) { - if (isInside(Node,precision)) + gp_XYZ p(Node->X(), Node->Y(), Node->Z()); + if (isInside(p, precision)) { if (isLeaf()) { @@ -185,7 +185,7 @@ void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node, */ //================================================================================ -bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode * node, +bool SMESH_OctreeNode::NodesAround(const gp_XYZ &node, map& dist2Nodes, double precision) { @@ -194,13 +194,14 @@ bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode * node, else if ( precision == 0. ) precision = maxSize() / 2; - if (isInside(node,precision)) + //gp_XYZ p(node->X(), node->Y(), node->Z()); + if (isInside(node, precision)) { if (!isLeaf()) { // first check a child containing node gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.; - int nodeChild = getChildIndex( node->X(), node->Y(), node->Z(), mid ); + int nodeChild = getChildIndex( node.X(), node.Y(), node.Z(), mid ); if ( ((SMESH_OctreeNode*) myChildren[nodeChild])->NodesAround(node, dist2Nodes, precision)) return true; @@ -212,8 +213,8 @@ bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode * node, else if ( NbNodes() > 0 ) { double minDist = precision * precision; - gp_Pnt p1 ( node->X(), node->Y(), node->Z() ); - TIDSortedNodeSet::iterator nIt = myNodes.begin(); + gp_Pnt p1 ( node.X(), node.Y(), node.Z() ); + set::iterator nIt = myNodes.begin(); for ( ; nIt != myNodes.end(); ++nIt ) { gp_Pnt p2 ( (*nIt)->X(), (*nIt)->Y(), (*nIt)->Z() ); @@ -319,7 +320,8 @@ void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node, list* Result, const double precision) { - bool isInsideBool = isInside(Node,precision); + gp_XYZ p(Node->X(), Node->Y(), Node->Z()); + bool isInsideBool = isInside(p, precision); if (isInsideBool) { @@ -385,8 +387,7 @@ void SMESH_OctreeNode::UpdateByMoveNode( const SMDS_MeshNode* node, const gp_Pnt TIDSortedNodeSet::iterator pNode = myNodes.find( node ); bool nodeInMe = ( pNode != myNodes.end() ); - SMDS_MeshNode pointNode( toPnt.X(), toPnt.Y(), toPnt.Z() ); - bool pointInMe = isInside( &pointNode, 1e-10 ); + bool pointInMe = isInside( toPnt.Coord(), 1e-10 ); if ( pointInMe != nodeInMe ) { diff --git a/src/SMESH/SMESH_OctreeNode.hxx b/src/SMESH/SMESH_OctreeNode.hxx index 951d2bc14..3e837e948 100644 --- a/src/SMESH/SMESH_OctreeNode.hxx +++ b/src/SMESH/SMESH_OctreeNode.hxx @@ -24,13 +24,14 @@ // inherites global class SMESH_Octree // File : SMESH_OctreeNode.hxx // Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux (OCC) +// Author : Nicolas Geimer & Aurelien Motteux (OCC) // Module : SMESH // #ifndef _SMESH_OCTREENODE_HXX_ #define _SMESH_OCTREENODE_HXX_ #include "SMESH_Octree.hxx" +#include #include "SMDS_MeshNode.hxx" #include @@ -63,7 +64,7 @@ public: virtual ~SMESH_OctreeNode () {}; // Tells us if Node is inside the current box with the precision "precision" - virtual const bool isInside(const SMDS_MeshNode * Node, const double precision = 0.); + virtual const bool isInside(const gp_XYZ& p, const double precision = 0.); // Return in Result a list of Nodes potentials to be near Node void NodesAround(const SMDS_MeshNode * Node, @@ -71,7 +72,7 @@ public: const double precision = 0.); // Return in dist2Nodes nodes mapped to their square distance from Node - bool NodesAround(const SMDS_MeshNode * Node, + bool NodesAround(const gp_XYZ& node, std::map& dist2Nodes, double precision); diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index 0857f545d..6164ed8e9 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -463,8 +463,7 @@ template bool areNodesBound( TFaceIterator & faceItr ) while ( nIt->more() ) { const SMDS_MeshNode* node = smdsNode( nIt->next() ); - SMDS_PositionPtr pos = node->GetPosition(); - if ( !pos || !pos->GetShapeId() ) { + if (node->getshapeId() <0) { return false; } } @@ -740,7 +739,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, { const SMDS_MeshNode* node = smdsNode( nIt->next() ); const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); double u = epos->GetUParameter(); paramNodeMap.insert( make_pair( u, node )); } @@ -862,7 +861,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, p->myInitUV = project( node, projector ); else { const SMDS_FacePosition* pos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); p->myInitUV.SetCoord( pos->GetUParameter(), pos->GetVParameter() ); } p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 ); @@ -882,7 +881,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, const SMDS_MeshNode* node = smdsNode( nIt->next() ); iPoint = nodePointIDMap[ node ]; // point index of interest // for a node on a seam edge there are two points - if ( helper.IsRealSeam( node->GetPosition()->GetShapeId() ) && + if ( helper.IsRealSeam( node->getshapeId() ) && ( n_id = closeNodePointIDMap.find( node )) != not_found ) { TPoint & p1 = myPoints[ iPoint ]; @@ -893,7 +892,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, // find node not on a seam edge while ( nIt2->more() && !notSeamNode ) { const SMDS_MeshNode* n = smdsNode( nIt2->next() ); - if ( !helper.IsSeamShape( n->GetPosition()->GetShapeId() )) + if ( !helper.IsSeamShape( n->getshapeId() )) notSeamNode = n; } gp_Pnt2d uv = helper.GetNodeUV( theFace, node, notSeamNode ); @@ -3220,7 +3219,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, { const SMDS_MeshNode* node = smdsNode( nIt->next() ); const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); double u = ( epos->GetUParameter() - f ) / ( l - f ); (*pIt)->myInitXYZ.SetCoord( iCoord, isForward ? u : 1 - u ); } @@ -4119,7 +4118,7 @@ void SMESH_Pattern::createElements(SMESH_Mesh* theMes SMDS_ElemIteratorPtr noIt = elem->nodesIterator(); while ( noIt->more() ) { SMDS_MeshNode* node = const_cast(smdsNode( noIt->next() )); - if (!node->GetPosition()->GetShapeId() && + if (!node->getshapeId() && shellNodes.find( node ) == shellNodes.end() ) { if ( S.ShapeType() == TopAbs_FACE ) aMeshDS->SetNodeOnFace( node, shapeID ); diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index 2929c023f..58318b1e1 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -24,6 +24,7 @@ // File : SMESH_subMesh.hxx // Author : Paul RASCLE, EDF // Module : SMESH +// $Header$ // #ifndef _SMESH_SUBMESH_HXX_ #define _SMESH_SUBMESH_HXX_ diff --git a/src/SMESH/memoire.h b/src/SMESH/memoire.h new file mode 100644 index 000000000..f9323bc0e --- /dev/null +++ b/src/SMESH/memoire.h @@ -0,0 +1,20 @@ +#ifndef _MEMOIRE_H_ +#define _MEMOIRE_H_ + +#include +#include + +void memostat(const char* f, int l); + +void memostat(const char* f, int l) +{ + /* struct mallinfo mem = mallinfo(); */ + /* std::cerr << f << ":"<< l << " " << mem.arena << " " << mem.ordblks << " " << mem.hblks << " " << mem.hblkhd << " " << mem.uordblks << " " << mem.fordblks << " " << mem.keepcost << std::endl; */ + std::cerr << f << ":" << l << " --------------------------" << std::endl; + malloc_stats(); + std::cerr << f << ":" << l << " --------------------------" << std::endl; +} + +#define MEMOSTAT memostat( __FILE__, __LINE__ ) + +#endif diff --git a/src/SMESHClient/Makefile.am b/src/SMESHClient/Makefile.am index beb28b056..b9a7174b8 100644 --- a/src/SMESHClient/Makefile.am +++ b/src/SMESHClient/Makefile.am @@ -45,6 +45,7 @@ libSMESHClient_la_CPPFLAGS = \ $(MED_CXXFLAGS) \ $(GEOM_CXXFLAGS) \ $(BOOST_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(CAS_CPPFLAGS) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ diff --git a/src/SMESHClient/SMESH_Client.cxx b/src/SMESHClient/SMESH_Client.cxx index 7124ca615..061028c30 100644 --- a/src/SMESHClient/SMESH_Client.cxx +++ b/src/SMESHClient/SMESH_Client.cxx @@ -55,7 +55,7 @@ #endif #ifdef _DEBUG_ -static int MYDEBUG = 0; +static int MYDEBUG = 1; #else static int MYDEBUG = 0; #endif @@ -635,6 +635,7 @@ SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB, mySMESHDSMesh(NULL), mySMDSMesh(NULL) { + MESSAGE("SMESH_Client::SMESH_Client"); myMeshServer->Register(); CORBA::Boolean anIsEmbeddedMode; @@ -650,7 +651,8 @@ SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB, SMESH_Mesh* aMesh = reinterpret_cast (pointeur); if ( MYDEBUG ) MESSAGE("SMESH_Client::SMESH_Client aMesh "<GetMeshDS()->IsEmbeddedMode()){ + //if(aMesh->GetMeshDS()->IsEmbeddedMode()){ + if(anIsEmbeddedMode){ mySMESHDSMesh = aMesh->GetMeshDS(); mySMDSMesh = mySMESHDSMesh; } @@ -705,10 +707,12 @@ SMESH_Client::Update(bool theIsClear) { bool anIsModified = true; if(mySMESHDSMesh){ + MESSAGE("Update mySMESHDSMesh"); SMESHDS_Script* aScript = mySMESHDSMesh->GetScript(); anIsModified = aScript->IsModified(); aScript->SetModified(false); }else{ + MESSAGE("Update CORBA"); SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear ); CORBA::Long aLength = aSeq->length(); anIsModified = aLength > 0; diff --git a/src/SMESHDS/Makefile.am b/src/SMESHDS/Makefile.am index aaa916686..91b485dae 100644 --- a/src/SMESHDS/Makefile.am +++ b/src/SMESHDS/Makefile.am @@ -58,6 +58,7 @@ dist_libSMESHDS_la_SOURCES = \ libSMESHDS_la_CPPFLAGS = \ $(KERNEL_CXXFLAGS) \ $(CAS_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ -I$(srcdir)/../SMDS diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 0ae03d0c5..93a428be3 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -33,6 +33,7 @@ #include "SMDS_EdgePosition.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_SpacePosition.hxx" +#include "SMDS_Downward.hxx" #include "SMESHDS_GroupOnGeom.hxx" #include @@ -109,7 +110,7 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) if ( !i_sub->second->IsComplexSubmesh() ) { SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes(); while ( nIt->more() ) - nIt->next()->GetPosition()->SetShapeId( 0 ); + i_sub->second->RemoveNode(nIt->next(), false); } } // - sub-meshes @@ -215,6 +216,7 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, const SMDS_MeshNode * nodes[], const int nbnodes) { + MESSAGE("SMESHDS_Mesh::ChangeElementNodes"); if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes )) return false; @@ -270,8 +272,11 @@ bool SMESHDS_Mesh::ChangePolyhedronNodes void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) { - SMDS_Mesh::Renumber( isNodes, startID, deltaID ); - myScript->Renumber( isNodes, startID, deltaID ); + // TODO not possible yet to have node numbers not starting to O and continuous. + if (!this->isCompacted()) + this->compactMesh(); +// SMDS_Mesh::Renumber( isNodes, startID, deltaID ); +// myScript->Renumber( isNodes, startID, deltaID ); } //======================================================================= @@ -748,7 +753,7 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) { SMESHDS_SubMesh* subMesh=0; map::iterator SubIt = - myShapeIndexToSubMesh.find( n->GetPosition()->GetShapeId() ); + myShapeIndexToSubMesh.find( n->getshapeId() ); if ( SubIt != myShapeIndexToSubMesh.end() ) subMesh = SubIt->second; else @@ -819,7 +824,7 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ ) if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt )) subMesh = SubIt->second; - + //MESSAGE("subMesh " << elt->getshapeId()); RemoveFreeElement( elt, subMesh, true); return; } @@ -842,6 +847,7 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, SMESHDS_SubMesh * subMesh, bool fromGroups) { + //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups); if (elt->GetType() == SMDSAbs_Node) { RemoveFreeNode( static_cast(elt), subMesh); return; @@ -937,7 +943,7 @@ SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index ) if ( Index != myCurSubID ) { map::iterator it = myShapeIndexToSubMesh.find( Index ); if ( it == myShapeIndexToSubMesh.end() ) - it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first; + it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first; myCurSubMesh = it->second; myCurSubID = Index; myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh @@ -965,22 +971,6 @@ bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh ) return false; } -namespace { - - //================================================================================ - /*! - * \brief Creates a node position in volume - */ - //================================================================================ - - inline SMDS_PositionPtr volumePosition(int volId) - { - SMDS_SpacePosition* pos = new SMDS_SpacePosition(); - pos->SetShapeId( volId ); - return SMDS_PositionPtr(pos); - } -} - //======================================================================= //function : SetNodeOnVolume //purpose : @@ -989,8 +979,9 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition ( volumePosition( myCurSubID )); + aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() ); } + //======================================================================= //function : SetNodeOnVolume //purpose : @@ -999,7 +990,7 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Solid & S) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition ( volumePosition( myCurSubID )); + aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() ); } //======================================================================= @@ -1012,7 +1003,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode, double v) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v))); } //======================================================================= @@ -1024,7 +1015,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode, double u) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u))); } //======================================================================= @@ -1035,7 +1026,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode, const TopoDS_Vertex & S) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition())); } //======================================================================= @@ -1044,12 +1035,13 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode, //======================================================================= void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode) { - if ( aNode && aNode->GetPosition() ) { - map::iterator it = - myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() ); - if ( it != myShapeIndexToSubMesh.end() ) - it->second->RemoveNode( aNode, /*deleted=*/false ); - } + int shapeId = aNode->getshapeId(); + if (shapeId >= 0) + { + map::iterator it = myShapeIndexToSubMesh.find(shapeId); + if (it != myShapeIndexToSubMesh.end()) + it->second->RemoveNode(aNode, /*deleted=*/false); + } } //======================================================================= @@ -1209,7 +1201,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index) TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index); if (anIter == myShapeIndexToSubMesh.end()) { - SM = new SMESHDS_SubMesh(); + SM = new SMESHDS_SubMesh(this, Index); myShapeIndexToSubMesh[Index]=SM; } else @@ -1301,8 +1293,9 @@ int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const //======================================================================= void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index) { + //add(aNode, getSubmesh(Index)); if ( add( aNode, getSubmesh( Index ))) - ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index )); + ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition()); } //======================================================================= @@ -1313,7 +1306,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, doub { //Set Position on Node if ( add( aNode, getSubmesh( Index ))) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v))); } //======================================================================= @@ -1326,7 +1319,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, { //Set Position on Node if ( add( aNode, getSubmesh( Index ))) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u))); } //======================================================================= @@ -1337,7 +1330,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index) { //Set Position on Node if ( add( aNode, getSubmesh( Index ))) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition())); } //======================================================================= @@ -1818,4 +1811,201 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, ID); } +void SMESHDS_Mesh::compactMesh() +{ + int newNodeSize = 0; + int nbNodes = myNodes.size(); + int nbVtkNodes = myGrid->GetNumberOfPoints(); + MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes); + int nbNodeTemp = nbVtkNodes; + if (nbNodes > nbVtkNodes) + nbNodeTemp = nbNodes; + vector idNodesOldToNew; + idNodesOldToNew.clear(); + idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1 + + for (int i = 0; i < nbNodes; i++) + { + if (myNodes[i]) + { + int vtkid = myNodes[i]->getVtkId(); + idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0) + newNodeSize++; + } + } + bool areNodesModified = (newNodeSize < nbVtkNodes); + MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified); + areNodesModified = true; + + int newCellSize = 0; + int nbCells = myCells.size(); + int nbVtkCells = myGrid->GetNumberOfCells(); + MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells); + int nbCellTemp = nbVtkCells; + if (nbCells > nbVtkCells) + nbCellTemp = nbCells; + vector idCellsOldToNew; + idCellsOldToNew.clear(); + idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1 + + for (int i = 0; i < nbCells; i++) + { + if (myCells[i]) + { +// //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0 +// int vtkid = myCells[i]->getVtkId(); +// idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input) + newCellSize++; + } + } + if (areNodesModified) + myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize); + else + myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize); + + int nbVtkPts = myGrid->GetNumberOfPoints(); + nbVtkCells = myGrid->GetNumberOfCells(); + if (nbVtkPts != newNodeSize) + { + MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize); + if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id + } + if (nbVtkCells != newCellSize) + { + MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize); + if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id + } + + // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory + + if (areNodesModified) + { + MESSAGE("-------------- modify myNodes"); + SetOfNodes newNodes; + newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n + int newSmdsId = 0; + for (int i = 0; i < nbNodes; i++) + { + if (myNodes[i]) + { + newSmdsId++; // SMDS id start to 1 + int oldVtkId = myNodes[i]->getVtkId(); + int newVtkId = idNodesOldToNew[oldVtkId]; + //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId); + myNodes[i]->setVtkId(newVtkId); + myNodes[i]->setId(newSmdsId); + newNodes[newSmdsId] = myNodes[i]; + //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]"); + } + } + myNodes.swap(newNodes); + this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes + MESSAGE("myNodes.size " << myNodes.size()); + } + + // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells + + int vtkIndexSize = myCellIdVtkToSmds.size(); + int maxVtkId = -1; + for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++) + { + int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId]; + if (oldSmdsId > 0) + { + int newVtkId = idCellsOldToNew[oldVtkId]; + if (newVtkId > maxVtkId) + maxVtkId = newVtkId; + //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId); + myCells[oldSmdsId]->setVtkId(newVtkId); + } + } +// MESSAGE("myCells.size()=" << myCells.size() +// << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size() +// << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() ); + + SetOfCells newCells; + //vector newSmdsToVtk; + vector newVtkToSmds; + + assert(maxVtkId < newCellSize); + newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n + //newSmdsToVtk.resize(newCellSize+1, -1); + newVtkToSmds.resize(newCellSize+1, -1); + + int myCellsSize = myCells.size(); + int newSmdsId = 0; + for (int i = 0; i < myCellsSize; i++) + { + if (myCells[i]) + { + newSmdsId++; // SMDS id start to 1 + assert(newSmdsId <= newCellSize); + newCells[newSmdsId] = myCells[i]; + newCells[newSmdsId]->setId(newSmdsId); + //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]"); + int idvtk = myCells[i]->getVtkId(); + //newSmdsToVtk[newSmdsId] = idvtk; + assert(idvtk < newCellSize); + newVtkToSmds[idvtk] = newSmdsId; + } + } + + myCells.swap(newCells); + //myCellIdSmdsToVtk.swap(newSmdsToVtk); + myCellIdVtkToSmds.swap(newVtkToSmds); + MESSAGE("myCells.size()=" << myCells.size() + << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() ); + this->myElementIDFactory->emptyPool(newSmdsId); + + this->myScript->SetModified(true); // notify GUI client for buildPrs when update + + // --- compact list myNodes and myElements in submeshes + + map::iterator it = myShapeIndexToSubMesh.begin(); + for(; it != myShapeIndexToSubMesh.end(); ++it) + { + (*it).second->compactList(); + } + +} + +void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges) +{ + myGrid->BuildDownwardConnectivity(withEdges); +} + +/*! change some nodes in cell without modifying type or internal connectivity. + * Nodes inverse connectivity is maintained up to date. + * @param vtkVolId vtk id of the cell. + * @param localClonedNodeIds map old node id to new node id. + * @return ok if success. + */ +bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map localClonedNodeIds) +{ + myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds); + return true; +} + +/*! Create a volume (prism or hexahedron) by duplication of a face. + * the nodes of the new face are already created. + * @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face. + * @param localClonedNodeIds map old node id to new node id. The old nodes define the face in the volume. + * @return ok if success. + */ +bool SMESHDS_Mesh::extrudeVolumeFromFace(int vtkVolId, std::map& localClonedNodeIds) +{ + //MESSAGE("extrudeVolumeFromFace " << vtkVolId); + vector orderedNodes; + orderedNodes.clear(); + map::const_iterator it = localClonedNodeIds.begin(); + for (; it != localClonedNodeIds.end(); ++it) + orderedNodes.push_back(it->first); + int nbNodes = myGrid->getOrderedNodesOfFace(vtkVolId, orderedNodes); + for (int i=0; iAddVolumeFromVtkIds(orderedNodes); + + // TODO update subshape list of elements and nodes + return vol; +} diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index 7e852c774..3c3f4d4ca 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -56,6 +56,7 @@ #include "SMESHDS_DataMapOfShape.hxx" class SMESHDS_GroupBase; +class DownIdType; class SMESHDS_EXPORT SMESHDS_Mesh:public SMDS_Mesh{ public: @@ -399,6 +400,8 @@ public: bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, std::vector nodes, std::vector quantities); + bool ModifyCellNodes(int smdsVolId, std::map localClonedNodeIds); + bool extrudeVolumeFromFace(int vtkVolId, std::map& localClonedNodeIds); void Renumber (const bool isNodes, const int startID=1, const int deltaID=1); void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S); @@ -442,6 +445,9 @@ public: bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const; + virtual void compactMesh(); + void BuildDownWardConnectivity(bool withEdges); + ~SMESHDS_Mesh(); private: @@ -450,7 +456,7 @@ private: //Update or build submesh std::map::iterator it = myShapeIndexToSubMesh.find( Index ); if ( it == myShapeIndexToSubMesh.end() ) - it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh() )).first; + it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first; it->second->AddNode( aNode ); // add aNode to submesh } diff --git a/src/SMESHDS/SMESHDS_Script.cxx b/src/SMESHDS/SMESHDS_Script.cxx index 8474e1116..21183a18f 100644 --- a/src/SMESHDS/SMESHDS_Script.cxx +++ b/src/SMESHDS/SMESHDS_Script.cxx @@ -27,6 +27,7 @@ // $Header: // #include "SMESHDS_Script.hxx" +#include using namespace std; @@ -36,7 +37,9 @@ using namespace std; //======================================================================= SMESHDS_Script::SMESHDS_Script(bool theIsEmbeddedMode): myIsEmbeddedMode(theIsEmbeddedMode) -{} +{ + cerr << "=========================== myIsEmbeddedMode " << myIsEmbeddedMode << endl; +} //======================================================================= //function : Destructor diff --git a/src/SMESHDS/SMESHDS_SubMesh.cxx b/src/SMESHDS/SMESHDS_SubMesh.cxx index 92704eb37..aa85c9c96 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.cxx +++ b/src/SMESHDS/SMESHDS_SubMesh.cxx @@ -27,20 +27,46 @@ // $Header: // #include "SMESHDS_SubMesh.hxx" +#include "SMESHDS_Mesh.hxx" #include "utilities.h" #include "SMDS_SetIterator.hxx" +#include +#include using namespace std; +SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index) +{ + myParent = parent; + myElements.clear(); + myNodes.clear(); + myIndex = index; + myUnusedIdNodes = 0; + myUnusedIdElements = 0; +} + //======================================================================= //function : AddElement //purpose : //======================================================================= void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME) { - if ( !IsComplexSubmesh() ) - myElements.insert(ME); + if (!IsComplexSubmesh()) + { + //MESSAGE("in " << myIndex << " AddElement "<< ME->GetID()); + int idInSubShape = ME->getIdInShape(); + if (idInSubShape != -1) + { + MESSAGE("add element in subshape already belonging to a subshape " + << ME->GetID() << " " << ME->getIdInShape() << " " << ME->getshapeId()); + throw SALOME_Exception(LOCALIZED("add element in subshape already belonging to a subshape")); + } + SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME); + elem->setShapeId(myIndex); + elem->setIdInShape(myElements.size()); + myElements.push_back(ME); + } } //======================================================================= @@ -49,19 +75,31 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME) //======================================================================= bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted) { - if ( !IsComplexSubmesh() && NbElements() ) { - - if (!isElemDeleted) // alive element has valid ID and can be found - return myElements.erase(ME); - - TElemSet::iterator e = myElements.begin(), eEnd = myElements.end(); - for ( ; e != eEnd; ++e ) - if ( ME == *e ) { - myElements.erase( e ); - return true; - } - } - + if (!ME) + { + MESSAGE("-----------------> Remove Null Element " << isElemDeleted); + return false; + } + //MESSAGE("-----------------> RemoveElement "<< ME->GetID() << " " << isElemDeleted); + if (!IsComplexSubmesh()) + { + // if (!isElemDeleted) // alive element has valid ID and can be found + // { + int idInSubShape = ME->getIdInShape(); + //MESSAGE("in "<< myIndex << " RemoveElement " << ME->GetID() << " " << idInSubShape << " " << myUnusedIdElements); + SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME); + elem->setShapeId(0); + elem->setIdInShape(-1); + if ((idInSubShape >= 0) && (idInSubShape < myElements.size())) + { + myElements[idInSubShape] = 0; // this vector entry is no more used + myUnusedIdElements++; + return true; + } + return false; + // } + } + MESSAGE("Try to remove an element from a complex submesh "); return false; } @@ -72,7 +110,22 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDele void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) { if ( !IsComplexSubmesh() ) - myNodes.insert(N); + { + int idInSubShape = N->getIdInShape(); + int shapeId = N->getshapeId(); + if ((shapeId > 0) && (idInSubShape >= 0)) + { + MESSAGE("========== AddNode already belonging to other subShape " << N->GetID()); + // OK for vertex nodes + //this->getParent()->UnSetNodeOnShape(N); + } + SMDS_MeshNode* node = (SMDS_MeshNode*)(N); + node->setShapeId(myIndex); + node->setIdInShape(myNodes.size()); + myNodes.push_back(N); + //MESSAGE("in "<< myIndex << " AddNode " << node->GetID()); + } + //MESSAGE("try to add node in a complex submesh " << N->GetID()); } //======================================================================= @@ -82,19 +135,26 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted) { - if ( !IsComplexSubmesh() && NbNodes() ) { - - if (!isNodeDeleted) // alive node has valid ID and can be found - return myNodes.erase(N); - - TElemSet::iterator e = myNodes.begin(), eEnd = myNodes.end(); - for ( ; e != eEnd; ++e ) - if ( N == *e ) { - myNodes.erase( e ); - return true; - } - } - + if (!IsComplexSubmesh()) + { + // if (!isNodeDeleted) // alive node has valid ID and can be found + // { + int idInSubShape = N->getIdInShape(); + int shapeId = N->getshapeId(); + //MESSAGE("in "<< myIndex << " RemoveNode " << shapeId << " " << idInSubShape << " " << N->GetID()); + SMDS_MeshNode* node = (SMDS_MeshNode*) (N); + node->setShapeId(0); + node->setIdInShape(-1); + if ((idInSubShape >= 0) && (idInSubShape < myNodes.size())) + { + myNodes[idInSubShape] = 0; // this vector entry is no more used + myUnusedIdNodes++; + return true; + } + return false; + // } + } + MESSAGE("Try to remove a node from a complex submesh"); return false; } @@ -104,8 +164,9 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted) //======================================================================= int SMESHDS_SubMesh::NbElements() const { + //MESSAGE(this << " NbElements " << IsComplexSubmesh() << " " << myElements.size() - myUnusedIdElements); if ( !IsComplexSubmesh() ) - return myElements.size(); + return myElements.size() - myUnusedIdElements; int nbElems = 0; set::const_iterator it = mySubMeshes.begin(); @@ -122,8 +183,9 @@ int SMESHDS_SubMesh::NbElements() const int SMESHDS_SubMesh::NbNodes() const { - if ( !IsComplexSubmesh() ) - return myNodes.size(); + //MESSAGE(this << " NbNodes " << IsComplexSubmesh() << " " << myNodes.size() - myUnusedIdNodes); + if ( !IsComplexSubmesh() ) + return myNodes.size() - myUnusedIdNodes; int nbElems = 0; set::const_iterator it = mySubMeshes.begin(); @@ -133,18 +195,41 @@ int SMESHDS_SubMesh::NbNodes() const return nbElems; } -// ===================== -// class MySetIterator -// ===================== - -template class MySetIterator: - public SMDS_SetIterator +/*! + * template class used for iteration on submesh elements. Interface of iterator remains + * unchanged after redesign of SMDS to avoid modification everywhere in SMESH. + * instances are stored in shared_ptr for automatic destruction. + * Container is copied for iteration, because original can be modified + * by addition of elements, for instance, and then reallocated (vector) + */ +template class MySetIterator : public SMDS_Iterator { - typedef SMDS_SetIterator TFather; - public: - MySetIterator(const TSET& s):TFather(s.begin(),s.end()) - { - } +protected: + typename TSET::const_iterator _it, _end; + TSET _table; +public: + MySetIterator(const TSET& table) + { + _table = table; + _it = _table.begin(); + _end = _table.end(); + while ((_it != _end) && (*_it == 0)) + _it++; + } + + virtual bool more() + { + while ((_it != _end) && (*_it == 0)) + _it++; + return (_it != _end); + } + + virtual ELEM next() + { + ELEM e = *_it; + _it++; + return e; + } }; // ===================== @@ -219,8 +304,7 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const { if ( IsComplexSubmesh() ) return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes )); - - return SMDS_ElemIteratorPtr(new MySetIterator(myElements)); + return SMDS_ElemIteratorPtr(new MySetIterator >(myElements)); } //======================================================================= @@ -233,7 +317,7 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const if ( IsComplexSubmesh() ) return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes )); - return SMDS_NodeIteratorPtr(new MySetIterator(myNodes)); + return SMDS_NodeIteratorPtr(new MySetIterator >(myNodes)); } //======================================================================= @@ -245,22 +329,33 @@ bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const { // DO NOT TRY TO FIND A REMOVED ELEMENT !! //if ( IsComplexSubmesh() || !ME ) - if (!ME ) - return false; - - if ( IsComplexSubmesh() ) - { - set::const_iterator aSubIt = mySubMeshes.begin(); - for ( ; aSubIt != mySubMeshes.end(); aSubIt++ ) - if ( (*aSubIt)->Contains( ME )) - return true; + if (!ME) return false; - } - if ( ME->GetType() == SMDSAbs_Node ) - return ( myNodes.find( ME ) != myNodes.end() ); + if (IsComplexSubmesh()) + { + set::const_iterator aSubIt = mySubMeshes.begin(); + for (; aSubIt != mySubMeshes.end(); aSubIt++) + if ((*aSubIt)->Contains(ME)) + return true; + return false; + } - return ( myElements.find( ME ) != myElements.end() ); + if (ME->GetType() == SMDSAbs_Node) + { + int idInShape = ME->getIdInShape(); + if ((idInShape >= 0) && (idInShape < myNodes.size())) + if (myNodes[idInShape] == ME) + return true; + } + else + { + int idInShape = ME->getIdInShape(); + if ((idInShape >= 0) && (idInShape < myElements.size())) + if (myElements[idInShape] == ME) + return true; + } + return false; } //======================================================================= @@ -316,9 +411,66 @@ void SMESHDS_SubMesh::Clear() { myElements.clear(); myNodes.clear(); + myUnusedIdNodes = 0; + myUnusedIdElements = 0; SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator(); while ( sub->more() ) { if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next()) sm->Clear(); } } + +int SMESHDS_SubMesh::getSize() +{ + int c = NbNodes(); + int d = NbElements(); + //cerr << "SMESHDS_SubMesh::NbNodes " << c << endl; + //cerr << "SMESHDS_SubMesh::NbElements " << d << endl; + return c+d; +} + +void SMESHDS_SubMesh::compactList() +{ + //MESSAGE("compactList old: nodes " << myNodes.size() << " elements " << myElements.size()); + //stringstream a; + //stringstream b; + //stringstream c; + //stringstream d; + + std::vector newElems; + newElems.clear(); + for (int i = 0; i < myElements.size(); i++) + if (myElements[i]) + { + SMDS_MeshElement* elem = (SMDS_MeshElement*)myElements[i]; + elem->setIdInShape(newElems.size()); + newElems.push_back(elem); + //a << elem->GetID() << " "; + //b << elem->GetID() << " "; + } + //else + // a << "_ "; + myElements.swap(newElems); + myUnusedIdElements = 0; + //MESSAGE("in " << myIndex << " oldElems " << a.str()); + //MESSAGE("in " << myIndex << " newElems " << b.str()); + + std::vector newNodes; + newNodes.clear(); + for (int i = 0; i < myNodes.size(); i++) + if (myNodes[i]) + { + SMDS_MeshNode* node = (SMDS_MeshNode*)myNodes[i]; + node->setIdInShape(newNodes.size()); + newNodes.push_back(node); + //c << node->GetID() << " "; + //d << node->GetID() << " "; + } + //else + // c << "_ "; + myNodes.swap(newNodes); + myUnusedIdNodes = 0; + //MESSAGE("in " << myIndex << " oldNodes " << c.str()); + //MESSAGE("in " << myIndex << " newNodes " << d.str()); + //MESSAGE("compactList new: nodes " << myNodes.size() << " elements " << myElements.size()); +} diff --git a/src/SMESHDS/SMESHDS_SubMesh.hxx b/src/SMESHDS/SMESHDS_SubMesh.hxx index de086ddaa..53493254c 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.hxx +++ b/src/SMESHDS/SMESHDS_SubMesh.hxx @@ -31,14 +31,18 @@ #include "SMDS_Mesh.hxx" #include +#include class SMESHDS_SubMesh; typedef SMDS_Iterator SMESHDS_SubMeshIterator; typedef boost::shared_ptr< SMESHDS_SubMeshIterator > SMESHDS_SubMeshIteratorPtr; +class SMESHDS_Mesh; + class SMESHDS_EXPORT SMESHDS_SubMesh { public: + SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index); bool IsComplexSubmesh() const { return !mySubMeshes.empty(); } @@ -64,11 +68,19 @@ class SMESHDS_EXPORT SMESHDS_SubMesh // clear the contents void Clear(); + int getSize(); + void compactList(); + + inline SMESHDS_Mesh *getParent() {return myParent; }; private: + SMESHDS_Mesh * myParent; + std::vector myElements; + std::vector myNodes; - typedef std::set TElemSet; - TElemSet myElements, myNodes; + int myUnusedIdNodes; + int myUnusedIdElements; + int myIndex; std::set mySubMeshes; }; diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 6ea18bbf0..efc9c9ea1 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -1433,6 +1433,7 @@ LightApp_Module( "SMESH" ) { CORBA::Boolean anIsEmbeddedMode; myComponentSMESH = SMESH_Client::GetSMESHGen(getApp()->orb(),anIsEmbeddedMode); + MESSAGE("-------------------------------> anIsEmbeddedMode=" << anIsEmbeddedMode); // 0019923: EDF 765 SMESH : default values of hypothesis SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this); @@ -1927,7 +1928,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) aSel->selectedObjects( sel_objects ); if( theCommandID==302 ) + { + MESSAGE("anAction = SMESH::eDisplayOnly"); startOperation( myEraseAll ); + } extractContainers( sel_objects, to_process ); @@ -1938,20 +1942,26 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if (vtkwnd) { SALOME_ListIteratorOfListIO It( to_process ); for ( ; It.More(); It.Next()) { + MESSAGE("---"); Handle(SALOME_InteractiveObject) IOS = It.Value(); if (IOS->hasEntry()) { + MESSAGE("---"); if (!SMESH::UpdateView(anAction, IOS->getEntry())) { SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged(); break; // PAL16774 (Crash after display of many groups) } if (anAction == SMESH::eDisplayOnly) + { + MESSAGE("anAction = SMESH::eDisplayOnly"); anAction = SMESH::eDisplay; + } } } } // PAL13338 + PAL15161 --> if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy)) { + MESSAGE("anAction = SMESH::eDisplayOnly"); SMESH::UpdateView(); SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged(); } @@ -1962,6 +1972,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } if (anAction == SMESH::eErase) { + MESSAGE("anAction == SMESH::eErase"); SALOME_ListIO l1; aSel->setSelectedObjects( l1 ); } diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index b31a1b8e9..147d19bb9 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -710,6 +710,7 @@ void SMESHGUI_BaseComputeOp::computeMesh() #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif + SMESH::UpdateNulData(myIObject, true); if (gen->Compute(myMesh, myMainShape)) computeFailed = false; } diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index c663c74da..772dd80f5 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -122,7 +122,7 @@ namespace SMESH TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey); if(anIter != VISUAL_OBJ_CONT.end()) { // for unknown reason, object destructor is not called, so clear object manually - anIter->second->GetUnstructuredGrid()->SetCells(0,0,0); + anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0); anIter->second->GetUnstructuredGrid()->SetPoints(0); } VISUAL_OBJ_CONT.erase(aKey); @@ -164,7 +164,7 @@ namespace SMESH TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin(); for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) { // for unknown reason, object destructor is not called, so clear object manually - anIter->second->GetUnstructuredGrid()->SetCells(0,0,0); + anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0); anIter->second->GetUnstructuredGrid()->SetPoints(0); } VISUAL_OBJ_CONT.clear(); @@ -209,7 +209,7 @@ namespace SMESH int curId = anIter->first.first; if ( curId == studyID ) { // for unknown reason, object destructor is not called, so clear object manually - anIter->second->GetUnstructuredGrid()->SetCells(0,0,0); + anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0); anIter->second->GetUnstructuredGrid()->SetPoints(0); VISUAL_OBJ_CONT.erase( anIter++ ); // anIter++ returns a copy of self before incrementing } @@ -257,7 +257,7 @@ namespace SMESH */ //================================================================================ - TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){ + TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry, bool nulData){ TVisualObjPtr aVisualObj; TVisualObjCont::key_type aKey(theStudyId,theEntry); try{ @@ -331,7 +331,11 @@ namespace SMESH #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif - objModified = aVisualObj->Update(); + //MESSAGE("GetVisualObj"); + if (nulData) + objModified = aVisualObj->NulData(); + else + objModified = aVisualObj->Update(); } catch (...) { #ifdef _DEBUG_ @@ -355,24 +359,24 @@ namespace SMESH MESSAGE ( "SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB << ", usedMB=" << usedMB ); #endif - bool continu = false; - if ( usedMB * 10 > freeMB ) - // even dont try to show - SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_NO_MESH_VISUALIZATION")); - else - // there is a chance to succeed - continu = SUIT_MessageBox::warning - (SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes; - if ( !continu ) { - // remove the corresponding actors from all views - RemoveVisualObjectWithActors( theEntry ); - aVisualObj.reset(); - } +// bool continu = false; +// if ( usedMB * 10 > freeMB ) +// // even dont try to show +// SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), +// QObject::tr("SMESH_NO_MESH_VISUALIZATION")); +// else +// // there is a chance to succeed +// continu = SUIT_MessageBox::warning +// (SMESHGUI::desktop(), +// QObject::tr("SMESH_WRN_WARNING"), +// QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"), +// SUIT_MessageBox::Yes | SUIT_MessageBox::No, +// SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes; +// if ( !continu ) { +// // remove the corresponding actors from all views +// RemoveVisualObjectWithActors( theEntry ); +// aVisualObj.reset(); +// } } } @@ -606,6 +610,7 @@ namespace SMESH } } } + MESSAGE("CreateActor " << anActor); if( anActor ) if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() ) aSMESHGUI->addActorAsObserver( anActor ); @@ -619,6 +624,7 @@ namespace SMESH #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif + MESSAGE("DisplayActor " << theActor); vtkWnd->AddActor(theActor); vtkWnd->Repaint(); } @@ -634,6 +640,7 @@ namespace SMESH void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){ if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){ + MESSAGE("RemoveActor " << theActor); vtkWnd->RemoveActor(theActor); if(theActor->hasIO()){ Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); @@ -672,6 +679,7 @@ namespace SMESH bool UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry) { + //MESSAGE("UpdateView"); bool OK = false; SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd); if (!aViewWnd) @@ -688,6 +696,7 @@ namespace SMESH case eDisplayAll: { while (vtkActor *anAct = aCollection->GetNextActor()) { if (SMESH_Actor *anActor = dynamic_cast(anAct)) { + MESSAGE("--- display " << anActor); anActor->SetVisibility(true); } } @@ -695,8 +704,10 @@ namespace SMESH } case eDisplayOnly: case eEraseAll: { + //MESSAGE("---case eDisplayOnly"); while (vtkActor *anAct = aCollection->GetNextActor()) { if (SMESH_Actor *anActor = dynamic_cast(anAct)) { + //MESSAGE("--- erase " << anActor); anActor->SetVisibility(false); } } @@ -706,10 +717,12 @@ namespace SMESH switch (theAction) { case eDisplay: case eDisplayOnly: + //MESSAGE("--- display " << anActor); anActor->SetVisibility(true); if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange(); break; case eErase: + //MESSAGE("--- erase " << anActor); anActor->SetVisibility(false); break; } @@ -718,6 +731,7 @@ namespace SMESH case eDisplay: case eDisplayOnly: { + //MESSAGE("---"); SalomeApp_Study* aStudy = dynamic_cast(theWnd->getViewManager()->study()); _PTR(Study) aDocument = aStudy->studyDS(); // Pass non-visual objects (hypotheses, etc.), return true in this case @@ -746,6 +760,7 @@ namespace SMESH bool UpdateView(EDisplaing theAction, const char* theEntry){ + //MESSAGE("UpdateView"); SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() ); SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() ); SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView(); @@ -784,6 +799,7 @@ namespace SMESH bool Update(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay) { + MESSAGE("Update"); _PTR(Study) aStudy = GetActiveStudyDocument(); CORBA::Long anId = aStudy->StudyId(); if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) { @@ -794,6 +810,18 @@ namespace SMESH return false; } + bool UpdateNulData(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay) + { + MESSAGE("UpdateNulData"); + _PTR(Study) aStudy = GetActiveStudyDocument(); + CORBA::Long anId = aStudy->StudyId(); + if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry(), true)) { + if ( theDisplay ) + UpdateView(SMESH::eDisplay,theIO->getEntry()); + return true; + } + return false; + } void UpdateSelectionProp( SMESHGUI* theModule ) { if( !theModule ) diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.h b/src/SMESHGUI/SMESHGUI_VTKUtils.h index 5a9b09c25..712e33a05 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.h +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.h @@ -65,7 +65,7 @@ namespace SMESH typedef std::pair TKeyOfVisualObj; SMESHGUI_EXPORT - TVisualObjPtr GetVisualObj( int, const char* ); + TVisualObjPtr GetVisualObj( int, const char*, bool nulData =false ); SMESHGUI_EXPORT void OnVisuException(); // PAL16631 @@ -122,7 +122,10 @@ SMESHGUI_EXPORT void UpdateView(); SMESHGUI_EXPORT - bool Update( const Handle(SALOME_InteractiveObject)&, bool ); + bool UpdateNulData( const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay); + +SMESHGUI_EXPORT + bool Update( const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay); //---------------------------------------------------------------------------- SMESHGUI_EXPORT diff --git a/src/SMESH_I/Makefile.am b/src/SMESH_I/Makefile.am index 53f285528..32c44b368 100644 --- a/src/SMESH_I/Makefile.am +++ b/src/SMESH_I/Makefile.am @@ -92,6 +92,7 @@ libSMESHEngine_la_CPPFLAGS = \ $(CORBA_INCLUDES) \ $(CAS_CPPFLAGS) \ @HDF5_INCLUDES@ \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ $(KERNEL_CXXFLAGS) \ $(GUI_CXXFLAGS) \ @@ -108,6 +109,7 @@ libSMESHEngine_la_CPPFLAGS = \ libSMESHEngine_la_LDFLAGS = \ ../../idl/libSalomeIDLSMESH.la \ ../SMESH/libSMESHimpl.la \ + ../SMDS/libSMDS.la \ ../Controls/libSMESHControls.la \ $(KERNEL_LDFLAGS) \ -lSalomeContainer \ diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index a0ce885aa..47e0fad99 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -113,6 +113,7 @@ #include "GEOM_Client.hxx" #include "Utils_ExceptHandlers.hxx" +#include "memoire.h" #include "Basics_Utils.hxx" #include @@ -484,6 +485,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 + MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode); meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode )); // activate the CORBA servant of Mesh @@ -541,6 +543,7 @@ void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo ) void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode ) { myIsEmbeddedMode = theMode; + MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode); if ( !myIsEmbeddedMode ) { //PAL10867: disable signals catching with "noexcepthandler" option @@ -900,6 +903,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName // Dump creation of groups aServant->GetGroups(); + aServant->GetImpl().GetMeshDS()->Modified(); return aMesh._retn(); } @@ -968,6 +972,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, theStatus = status1; aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh ); + meshServant->GetImpl().GetMeshDS()->Modified(); } aStudyBuilder->CommitCommand(); } @@ -1014,6 +1019,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName SMESH_Mesh_i* aServant = dynamic_cast( GetServant( aMesh ).in() ); ASSERT( aServant ); aServant->ImportSTLFile( theFileName ); + aServant->GetImpl().GetMeshDS()->Modified(); return aMesh._retn(); } @@ -1396,6 +1402,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theShapeObject ) throw ( SALOME::SALOME_Exception ) { + MEMOSTAT; Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" ); @@ -1428,6 +1435,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); bool ok = myGen.Compute( myLocMesh, myLocShape); meshServant->CreateGroupServants(); // algos can create groups (issue 0020918) + myLocMesh.GetMeshDS()->Modified(); return ok; } } @@ -1917,11 +1925,12 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, // create mesh SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh(); + SMESHDS_Mesh* aNewMeshDS = 0; if ( !aNewMesh->_is_nil() ) { SMESH_Mesh_i* aNewImpl = dynamic_cast( GetServant( aNewMesh ).in() ); if ( aNewImpl ) { ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl(); - SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS(); + aNewMeshDS = aLocMesh.GetMeshDS(); TGroupsMap aGroupsMap; TListOfNewGroups aListOfNewGroups; @@ -1990,11 +1999,11 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, // creates a corresponding element on existent nodes in new mesh if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume ) { - const SMDS_PolyhedralVolumeOfNodes* aVolume = - dynamic_cast (anElem); + const SMDS_VtkVolume* aVolume = + dynamic_cast (anElem); if ( aVolume ) { aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, - aVolume->GetQuanities()); + aVolume->GetQuantities()); elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); if( theCommonGroups ) anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); @@ -2197,7 +2206,8 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); aPixmap->SetPixMap("ICON_SMESH_TREE_MESH"); } - + if (aNewMeshDS) + aNewMeshDS->Modified(); return aNewMesh._retn(); } @@ -3132,7 +3142,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, const SMDS_PositionPtr pos = node->GetPosition(); if ( onFace ) { // on FACE const SMDS_FacePosition* fPos = - dynamic_cast( pos.get() ); + dynamic_cast( pos ); if ( fPos ) { aUPos[ iNode ] = fPos->GetUParameter(); aVPos[ iNode ] = fPos->GetVParameter(); @@ -3143,7 +3153,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, } else { // on EDGE const SMDS_EdgePosition* ePos = - dynamic_cast( pos.get() ); + dynamic_cast( pos ); if ( ePos ) { aUPos[ iNode ] = ePos->GetUParameter(); iNode++; @@ -4043,7 +4053,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // add if ( isNode ) { SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]); - pos->SetShapeId( smID ); SMDS_MeshNode* node = const_cast( static_cast( elem )); node->SetPosition( pos ); sm->AddNode( node ); @@ -4147,7 +4156,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // not fixed bugs in SMDS_MeshInfo if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) { SMDS_FacePosition* fPos = const_cast - ( static_cast( aPos.get() )); + ( static_cast( aPos )); fPos->SetUParameter( aUPos[ iNode ]); fPos->SetVParameter( aVPos[ iNode ]); } @@ -4156,7 +4165,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182 if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) { SMDS_EdgePosition* fPos = const_cast - ( static_cast( aPos.get() )); + ( static_cast( aPos )); fPos->SetUParameter( aUPos[ iNode ]); } } diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index d442601d5..d6185e107 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -32,7 +32,7 @@ #include "SMESH_MeshEditor_i.hxx" #include "SMDS_Mesh0DElement.hxx" -#include "SMDS_MeshEdge.hxx" +#include "SMDS_LinearEdge.hxx" #include "SMDS_MeshFace.hxx" #include "SMDS_MeshVolume.hxx" #include "SMDS_PolyhedralVolumeOfNodes.hxx" @@ -134,11 +134,11 @@ namespace { SMDS_MeshElement* anElemCopy = 0; if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume ) { - const SMDS_PolyhedralVolumeOfNodes* ph = - dynamic_cast (anElem); + const SMDS_VtkVolume* ph = + dynamic_cast (anElem); if ( ph ) anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID - (anElemNodesID, ph->GetQuanities(),anElem->GetID()); + (anElemNodesID, ph->GetQuantities(),anElem->GetID()); } else { anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID, @@ -416,11 +416,12 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements) // Update Python script TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )"; + // Remove Elements + bool ret = anEditor.Remove( IdList, false ); + myMesh->GetMeshDS()->Modified(); if ( IDsOfElements.length() ) myMesh->SetIsModified( true ); // issue 0020693 - - // Remove Elements - return anEditor.Remove( IdList, false ); + return ret; } //============================================================================= @@ -441,10 +442,11 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo // Update Python script TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )"; + bool ret = anEditor.Remove( IdList, true ); + myMesh->GetMeshDS()->Modified(); if ( IDsOfNodes.length() ) myMesh->SetIsModified( true ); // issue 0020693 - - return anEditor.Remove( IdList, true ); + return ret; } //============================================================================= @@ -495,8 +497,8 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x, TPythonDump() << "nodeID = " << this << ".AddNode( " << x << ", " << y << ", " << z << " )"; + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); // issue 0020693 - return N->GetID(); } @@ -515,6 +517,7 @@ CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode) // Update Python script TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )"; + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); // issue 0020693 if (elem) @@ -557,6 +560,7 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) <GetMeshDS()->Modified(); if(elem) return myMesh->SetIsModified( true ), elem->GetID(); @@ -605,6 +609,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) // Update Python script TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )"; + myMesh->GetMeshDS()->Modified(); if(elem) return myMesh->SetIsModified( true ), elem->GetID(); @@ -630,6 +635,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO // Update Python script TPythonDump() <<"faceID = "<GetMeshDS()->Modified(); return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0; } @@ -673,6 +679,7 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes) // Update Python script TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )"; + myMesh->GetMeshDS()->Modified(); if(elem) return myMesh->SetIsModified( true ), elem->GetID(); @@ -692,7 +699,11 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I int NbNodes = IDsOfNodes.length(); std::vector n (NbNodes); for (int i = 0; i < NbNodes; i++) - n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]); + { + const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]); + if (!aNode) return 0; + n[i] = aNode; + } int NbFaces = Quantities.length(); std::vector q (NbFaces); @@ -704,6 +715,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I // Update Python script TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( " << IDsOfNodes << ", " << Quantities << " )"; + myMesh->GetMeshDS()->Modified(); return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0; } @@ -736,6 +748,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_ar // Update Python script TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( " << IdsOfFaces << " )"; + myMesh->GetMeshDS()->Modified(); return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0; } @@ -856,7 +869,6 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID, } mesh->SetNodeOnFace( node, FaceID, u, v ); - myMesh->SetIsModified( true ); } @@ -947,10 +959,12 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1, TPythonDump() << "isDone = " << this << ".InverseDiag( " << NodeID1 << ", " << NodeID2 << " )"; - myMesh->SetIsModified( true ); ::SMESH_MeshEditor aMeshEditor( myMesh ); - return aMeshEditor.InverseDiag ( n1, n2 ); + int ret = aMeshEditor.InverseDiag ( n1, n2 ); + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + return ret; } //============================================================================= @@ -977,6 +991,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1, bool stat = aMeshEditor.DeleteDiag ( n1, n2 ); + myMesh->GetMeshDS()->Modified(); if ( stat ) myMesh->SetIsModified( true ); // issue 0020693 @@ -1006,6 +1021,7 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme // Update Python script TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )"; + myMesh->GetMeshDS()->Modified(); if ( IDsOfElements.length() ) myMesh->SetIsModified( true ); // issue 0020693 @@ -1064,6 +1080,7 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE ::SMESH_MeshEditor anEditor( myMesh ); bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle ); + myMesh->GetMeshDS()->Modified(); if ( stat ) myMesh->SetIsModified( true ); // issue 0020693 @@ -1127,6 +1144,7 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfE ::SMESH_MeshEditor anEditor( myMesh ); CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit ); + myMesh->GetMeshDS()->Modified(); if ( stat ) myMesh->SetIsModified( true ); // issue 0020693 @@ -1181,6 +1199,7 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle ::SMESH_MeshEditor anEditor( myMesh ); CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 ); + myMesh->GetMeshDS()->Modified(); if ( stat ) myMesh->SetIsModified( true ); // issue 0020693 @@ -1261,6 +1280,7 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, ::SMESH_MeshEditor anEditor (myMesh); anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags )); + myMesh->GetMeshDS()->Modified(); storeResult(anEditor); @@ -1375,6 +1395,7 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements, anEditor.Smooth(elements, fixedNodes, method, MaxNbOfIterations, MaxAspectRatio, IsParametric ); + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); // issue 0020693 storeResult(anEditor); @@ -1514,6 +1535,7 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements, anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians, theNbOfSteps, theTolerance, theMakeGroups, makeWalls); storeResult(anEditor); + myMesh->GetMeshDS()->Modified(); // myMesh->SetIsModified( true ); -- it does not influence Compute() @@ -1792,6 +1814,7 @@ SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements, ::SMESH_MeshEditor::PGroupIDs groupIds = anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups); + myMesh->GetMeshDS()->Modified(); storeResult(anEditor); return theMakeGroups ? getGroups(groupIds.get()) : 0; @@ -2090,6 +2113,7 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfEleme SMESH::SMESH_MeshEditor::Extrusion_Error & theError, const SMDSAbs_ElementType theElementType) { + MESSAGE("extrusionAlongPath"); initData(); if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) { @@ -2129,6 +2153,7 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfEleme anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart, theHasAngles, angles, false, theHasRefPoint, refPnt, theMakeGroups ); + myMesh->GetMeshDS()->Modified(); storeResult(anEditor); theError = convExtrError( error ); @@ -2195,6 +2220,7 @@ SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements error = anEditor.ExtrusionAlongTrack( elements, &(aMeshImp->GetImpl()), aNodeStart, HasAngles, angles, LinearVariation, HasRefPoint, refPnt, MakeGroups ); + myMesh->GetMeshDS()->Modified(); } else { SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast( Path ); @@ -2213,6 +2239,7 @@ SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements error = anEditor.ExtrusionAlongTrack( elements, aSubMesh, aNodeStart, HasAngles, angles, LinearVariation, HasRefPoint, refPnt, MakeGroups ); + myMesh->GetMeshDS()->Modified(); } else { SMESH_Group_i* aGroupImp = SMESH::DownCast( Path ); @@ -2256,6 +2283,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfEleme CORBA::Boolean theHasRefPoint, const SMESH::PointStruct & theRefPoint) { + MESSAGE("ExtrusionAlongPath"); if ( !myPreviewMode ) { TPythonDump() << "error = " << this << ".ExtrusionAlongPath( " << theIDsOfElements << ", " @@ -2867,7 +2895,10 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements, if(theCopy) storeResult(anEditor); else - myMesh->SetIsModified( true ); + { + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + } return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -3093,7 +3124,10 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements, if(theCopy) storeResult(anEditor); else - myMesh->SetIsModified( true ); + { + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + } return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -3309,7 +3343,10 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements, if(theCopy) storeResult(anEditor); else - myMesh->SetIsModified( true ); + { + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + } return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -3550,8 +3587,10 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, if(theCopy) storeResult(anEditor); else - myMesh->SetIsModified( true ); - + { + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + } return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -3796,7 +3835,7 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN anEditor.MergeNodes( aListOfListOfNodes ); aTPythonDump << "])"; - + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); } @@ -3878,7 +3917,7 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO ::SMESH_MeshEditor anEditor( myMesh ); anEditor.MergeElements(aListOfListOfElementsID); - + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); aTPythonDump << "] )"; @@ -3926,15 +3965,15 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID, TIDSortedElemSet linkedNodes; ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes ); TIDSortedElemSet::iterator nIt = linkedNodes.begin(); + SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node); for ( ; nIt != linkedNodes.end(); ++nIt ) { - SMDS_MeshEdge edge( node, cast2Node( *nIt )); - tmpMesh.Copy( &edge ); + SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt )); + tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2); } // move copied node - node = tmpMesh.GetMeshDS()->FindNode( NodeID ); - if ( node ) - tmpMesh.GetMeshDS()->MoveNode(node, x, y, z); + if ( nodeCpy1 ) + tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z); // fill preview data ::SMESH_MeshEditor anEditor( & tmpMesh ); storeResult( anEditor ); @@ -3949,7 +3988,7 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID, // Update Python script TPythonDump() << "isDone = " << this << ".MoveNode( " << NodeID << ", " << x << ", " << y << ", " << z << " )"; - + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); } @@ -4021,7 +4060,7 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, TIDSortedElemSet::iterator nIt = linkedNodes.begin(); for ( ; nIt != linkedNodes.end(); ++nIt ) { - SMDS_MeshEdge edge( node, cast2Node( *nIt )); + SMDS_LinearEdge edge( node, cast2Node( *nIt )); tmpMesh.Copy( &edge ); } // move copied node @@ -4048,6 +4087,7 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z << ", " << nodeID << " )"; + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); } @@ -4193,6 +4233,7 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1, storeResult(anEditor); + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); return error; @@ -4250,6 +4291,7 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1, storeResult(anEditor); + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); return error; @@ -4312,6 +4354,7 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, storeResult(anEditor); + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); return error; @@ -4369,6 +4412,7 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements, storeResult(anEditor); + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); return error; @@ -4405,8 +4449,10 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide, TPythonDump() << "isDone = " << this << ".ChangeElemNodes( " << ide << ", " << newIDs << " )"; + MESSAGE("ChangeElementNodes"); bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 ); + myMesh->GetMeshDS()->Modified(); if ( res ) myMesh->SetIsModified( true ); @@ -4558,6 +4604,7 @@ void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d) ::SMESH_MeshEditor anEditor( myMesh ); anEditor.ConvertToQuadratic(theForce3d); TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )"; + myMesh->GetMeshDS()->Modified(); myMesh->SetIsModified( true ); } @@ -4571,6 +4618,7 @@ CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic() ::SMESH_MeshEditor anEditor( myMesh ); CORBA::Boolean isDone = anEditor.ConvertFromQuadratic(); TPythonDump() << this << ".ConvertFromQuadratic()"; + myMesh->GetMeshDS()->Modified(); if ( isDone ) myMesh->SetIsModified( true ); return isDone; @@ -4675,6 +4723,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems ); + myMesh->GetMeshDS()->Modified(); storeResult( aMeshEditor) ; if ( aResult ) myMesh->SetIsModified( true ); @@ -4843,6 +4892,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& t storeResult( aMeshEditor) ; + myMesh->GetMeshDS()->Modified(); if ( aResult ) myMesh->SetIsModified( true ); @@ -4884,6 +4934,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theE storeResult( aMeshEditor) ; + myMesh->GetMeshDS()->Modified(); if ( aResult ) myMesh->SetIsModified( true ); @@ -4926,6 +4977,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_ar storeResult( aMeshEditor) ; + myMesh->GetMeshDS()->Modified(); if ( aResult ) myMesh->SetIsModified( true ); @@ -4968,6 +5020,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_pt storeResult( aMeshEditor) ; + myMesh->GetMeshDS()->Modified(); if ( aResult ) myMesh->SetIsModified( true ); @@ -5066,6 +5119,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_Grou storeResult( aMeshEditor) ; + myMesh->GetMeshDS()->Modified(); if ( aResult ) myMesh->SetIsModified( true ); @@ -5123,6 +5177,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroup storeResult( aMeshEditor) ; + myMesh->GetMeshDS()->Modified(); if ( aResult ) myMesh->SetIsModified( true ); @@ -5165,6 +5220,7 @@ SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theE storeResult( aMeshEditor) ; + myMesh->GetMeshDS()->Modified(); if ( aResult ) myMesh->SetIsModified( true ); @@ -5189,11 +5245,60 @@ CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D() ::SMESH_MeshEditor aMeshEditor( myMesh ); bool aResult = aMeshEditor.Make2DMeshFrom3D(); storeResult( aMeshEditor) ; - + myMesh->GetMeshDS()->Modified(); TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()"; return aResult; } +//================================================================================ +/*! + * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. + * The list of groups must describe a partition of the mesh volumes. + * The nodes of the internal faces at the boundaries of the groups are doubled. + * In option, the internal faces are replaced by flat elements. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * @param theDomains - list of groups of volumes + * @param createJointElems - if TRUE, create the elements + * @return TRUE if operation has been completed successfully, FALSE otherwise + */ +//================================================================================ + +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains, + CORBA::Boolean createJointElems ) +{ + initData(); + + ::SMESH_MeshEditor aMeshEditor( myMesh ); + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + + vector domains; + domains.clear(); + + for ( int i = 0, n = theDomains.length(); i < n; i++ ) + { + SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ]; + if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) ) + { + TIDSortedElemSet domain; + domain.clear(); + domains.push_back(domain); + SMESH::long_array_var anIDs = aGrp->GetIDs(); + arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All ); + } + } + + bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems ); + + storeResult( aMeshEditor) ; + myMesh->GetMeshDS()->Modified(); + + // Update Python script + TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains + << ", " << createJointElems << " )"; + return aResult; +} + // issue 20749 =================================================================== /*! * \brief Creates missing boundary elements diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index 3a96b87cd..e90fe857e 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -686,6 +686,20 @@ public: CORBA::Boolean toCopyMissingBondary, SMESH::SMESH_Group_out group); + /*! + * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. + * The list of groups must describe a partition of the mesh volumes. + * The nodes of the internal faces at the boundaries of the groups are doubled. + * In option, the internal faces are replaced by flat elements. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * @param theDomains - list of groups of volumes + * @param createJointElems - if TRUE, create the elements + * @return TRUE if operation has been completed successfully, FALSE otherwise + */ + CORBA::Boolean DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains, + CORBA::Boolean createJointElems ); + + private: //!< private methods SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); } diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index c3be622ae..1733a315e 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1007,7 +1007,7 @@ throw (SALOME::SALOME_Exception) try { - NCollection_Map< int > anIds; + vector< int > anIds; SMESH::ElementType aType = SMESH::ALL; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { @@ -1030,7 +1030,7 @@ throw (SALOME::SALOME_Exception) for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) { int aCurrId = aCurrIds[ i ]; - anIds.Add( aCurrId ); + anIds.push_back( aCurrId ); } } @@ -1041,12 +1041,12 @@ throw (SALOME::SALOME_Exception) // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.Extent() ); + aResIds->length( anIds.size() ); - NCollection_Map< int >::Iterator anIter( anIds ); - for ( int i = 0; anIter.More(); anIter.Next(), i++ ) + //NCollection_Map< int >::Iterator anIter( anIds ); + for ( int i = 0; iAdd( aResIds ); @@ -1172,14 +1172,14 @@ throw (SALOME::SALOME_Exception) // create map of ids int nbGrp = theGroups.length(); - NCollection_Map< int > anIds; + vector< int > anIds; NCollection_DataMap< int, int >::Iterator anIter( anIdToCount ); for ( ; anIter.More(); anIter.Next() ) { int aCurrId = anIter.Key(); int aCurrNb = anIter.Value(); if ( aCurrNb == nbGrp ) - anIds.Add( aCurrId ); + anIds.push_back( aCurrId ); } // Create group @@ -1189,12 +1189,12 @@ throw (SALOME::SALOME_Exception) // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.Extent() ); + aResIds->length( anIds.size() ); - NCollection_Map< int >::Iterator aListIter( anIds ); - for ( int i = 0; aListIter.More(); aListIter.Next(), i++ ) + //NCollection_Map< int >::Iterator aListIter( anIds ); + for ( int i = 0; iAdd( aResIds ); @@ -1291,7 +1291,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( try { - NCollection_Map< int > aToolIds; + set< int > aToolIds; SMESH::ElementType aType = SMESH::ALL; int g, n; // iterate through tool groups @@ -1316,11 +1316,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) { int aCurrId = aCurrIds[ i ]; - aToolIds.Add( aCurrId ); + aToolIds.insert( aCurrId ); } } - NCollection_Map< int > anIds; // result + vector< int > anIds; // result // Iterate through main group for ( g = 0, n = theMainGroups.length(); g < n; g++ ) @@ -1344,8 +1344,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) { int aCurrId = aCurrIds[ i ]; - if ( !aToolIds.Contains( aCurrId ) ) - anIds.Add( aCurrId ); + if ( !aToolIds.count( aCurrId ) ) + anIds.push_back( aCurrId ); } } @@ -1356,12 +1356,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.Extent() ); + aResIds->length( anIds.size() ); - NCollection_Map< int >::Iterator anIter( anIds ); - for ( int i = 0; anIter.More(); anIter.Next(), i++ ) + for (int i=0; iAdd( aResIds ); @@ -1413,7 +1412,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( { // Create map of nodes from all groups - NCollection_Map< int > aNodeMap; + set< int > aNodeMap; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { @@ -1432,7 +1431,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( int aCurrId = aCurrIds[ i ]; const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId ); if ( aNode ) - aNodeMap.Add( aNode->GetID() ); + aNodeMap.insert( aNode->GetID() ); } } else @@ -1450,7 +1449,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( const SMDS_MeshNode* aNode = dynamic_cast( aNodeIter->next() ); if ( aNode ) - aNodeMap.Add( aNode->GetID() ); + aNodeMap.insert( aNode->GetID() ); } } } @@ -1458,22 +1457,25 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( // Get result identifiers - NCollection_Map< int > aResultIds; + vector< int > aResultIds; if ( theElemType == SMESH::NODE ) { - NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); - for ( ; aNodeIter.More(); aNodeIter.Next() ) - aResultIds.Add( aNodeIter.Value() ); + //NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); + set::iterator iter = aNodeMap.begin(); + for ( ; iter != aNodeMap.end(); iter++ ) + aResultIds.push_back( *iter); } else { // Create list of elements of given dimension constructed on the nodes - NCollection_Map< int > anElemList; - NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); - for ( ; aNodeIter.More(); aNodeIter.Next() ) + vector< int > anElemList; + //NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); + //for ( ; aNodeIter.More(); aNodeIter.Next() ) + set::iterator iter = aNodeMap.begin(); + for ( ; iter != aNodeMap.end(); iter++ ) { const SMDS_MeshElement* aNode = - dynamic_cast( aMeshDS->FindNode( aNodeIter.Value() ) ); + dynamic_cast( aMeshDS->FindNode( *iter ) ); if ( !aNode ) continue; @@ -1483,15 +1485,16 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( const SMDS_MeshElement* anElem = dynamic_cast( anElemIter->next() ); if ( anElem && anElem->GetType() == anElemType ) - anElemList.Add( anElem->GetID() ); + anElemList.push_back( anElem->GetID() ); } } // check whether all nodes of elements are present in nodes map - NCollection_Map< int >::Iterator anIter( anElemList ); - for ( ; anIter.More(); anIter.Next() ) + //NCollection_Map< int >::Iterator anIter( anElemList ); + //for ( ; anIter.More(); anIter.Next() ) + for (int i=0; i< anElemList.size(); i++) { - const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() ); + const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] ); if ( !anElem ) continue; @@ -1501,14 +1504,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( { const SMDS_MeshNode* aNode = dynamic_cast( aNodeIter->next() ); - if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) ) + if ( !aNode || !aNodeMap.count( aNode->GetID() ) ) { isOk = false; break; } } if ( isOk ) - aResultIds.Add( anElem->GetID() ); + aResultIds.push_back( anElem->GetID() ); } } @@ -1520,11 +1523,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aResultIds.Extent() ); + aResIds->length( aResultIds.size() ); - NCollection_Map< int >::Iterator aResIter( aResultIds ); - for ( int i = 0; aResIter.More(); aResIter.Next(), i++ ) - aResIds[ i ] = aResIter.Value(); + //NCollection_Map< int >::Iterator aResIter( aResultIds ); + //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ ) + for (int i=0; i< aResultIds.size(); i++) + aResIds[ i ] = aResultIds[i]; aResGrp->Add( aResIds ); // Remove strings corresponding to group creation @@ -3037,21 +3041,21 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID) { if ( SMDS_PositionPtr pos = aNode->GetPosition() ) { - aNodePosition->shapeID = pos->GetShapeId(); + aNodePosition->shapeID = aNode->getshapeId(); switch ( pos->GetTypeOfPosition() ) { case SMDS_TOP_EDGE: aNodePosition->shapeType = GEOM::EDGE; aNodePosition->params.length(1); aNodePosition->params[0] = - static_cast( pos.get() )->GetUParameter(); + static_cast( pos )->GetUParameter(); break; case SMDS_TOP_FACE: aNodePosition->shapeType = GEOM::FACE; aNodePosition->params.length(2); aNodePosition->params[0] = - static_cast( pos.get() )->GetUParameter(); + static_cast( pos )->GetUParameter(); aNodePosition->params[1] = - static_cast( pos.get() )->GetVParameter(); + static_cast( pos )->GetVParameter(); break; case SMDS_TOP_VERTEX: aNodePosition->shapeType = GEOM::VERTEX; @@ -3085,11 +3089,7 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) // try to find node const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id); if(aNode) { - SMDS_PositionPtr pos = aNode->GetPosition(); - if(!pos) - return -1; - else - return pos->GetShapeId(); + return aNode->getshapeId(); } return -1; diff --git a/src/SMESH_I/SMESH_Pattern_i.cxx b/src/SMESH_I/SMESH_Pattern_i.cxx index 2a799a5b6..fec31a820 100644 --- a/src/SMESH_I/SMESH_Pattern_i.cxx +++ b/src/SMESH_I/SMESH_Pattern_i.cxx @@ -215,7 +215,6 @@ SMESH::point_array* SMESH_Pattern_i::ApplyToFace(GEOM::GEOM_Object_ptr theFace, (*xyzIt)->Coord( p.x, p.y, p.z ); } } - // Update Python script TPythonDump() << "pattern.ApplyToFace( " << theFace << ", " << theVertexOnKeyPoint1 << ", " << theReverse << " )"; @@ -392,8 +391,10 @@ CORBA::Boolean SMESH_Pattern_i::MakeMesh (SMESH::SMESH_Mesh_ptr theMesh, bool res = myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs ); if ( nb > 0 && nb != aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes()) - aMesh->SetIsModified(true); - + { + aMesh->SetIsModified(true); + aMesh->GetMeshDS()->Modified(); + } return res; } diff --git a/src/SMESH_SWIG/SMESH_AdvancedEditor.py b/src/SMESH_SWIG/SMESH_AdvancedEditor.py index 2e5ae0bfc..ae7ef4265 100644 --- a/src/SMESH_SWIG/SMESH_AdvancedEditor.py +++ b/src/SMESH_SWIG/SMESH_AdvancedEditor.py @@ -1,4 +1,4 @@ -# -*- coding: iso-8859-1 -*- +# -*- coding: utf-8 -*- # Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, @@ -25,6 +25,8 @@ import salome import smesh import math +salome.salome_init() + def GetNewNodes(mesh,Elems,OldNodes): """ Auxilary function, which return list of nodes from diff --git a/src/SMESH_SWIG/SMESH_mechanic_editor.py b/src/SMESH_SWIG/SMESH_mechanic_editor.py index 94c0719ff..85e12a3a7 100644 --- a/src/SMESH_SWIG/SMESH_mechanic_editor.py +++ b/src/SMESH_SWIG/SMESH_mechanic_editor.py @@ -1,4 +1,4 @@ -# -*- coding: iso-8859-1 -*- +# -*- coding: utf-8 -*- # Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, @@ -31,6 +31,7 @@ import salome import geompy import smesh +salome.salome_init() # ---------------------------- GEOM -------------------------------------- # ---- define contigous arcs and segment to define a closed wire @@ -192,7 +193,7 @@ print "Number of tetrahedrons: ", mesh.NbTetras() mesh.SplitQuadObject(submesh2, 1) #2 cutting of triangles of the group -FacesTriToQuad = [2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422] +FacesTriToQuad = [ 2391, 2824, 2825, 2826, 2827, 2828, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2841, 2844, 2845, 2847, 2854, 2861, 2863, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2940, 2941, 2946, 2951, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 2985 ] GroupTriToQuad = mesh.MakeGroupByIds("Group of faces (quad)", smesh.FACE, FacesTriToQuad) mesh.TriToQuadObject(GroupTriToQuad, None , 1.57) diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index a2476107a..f07cf3c23 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -4059,6 +4059,17 @@ class Mesh: # @ingroup l2_modif_edit def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape): return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape) + + ## Double nodes on shared faces between groups of volumes and create flat elements on demand. + # The list of groups must describe a partition of the mesh volumes. + # The nodes of the internal faces at the boundaries of the groups are doubled. + # In option, the internal faces are replaced by flat elements. + # Triangles are transformed in prisms, and quadrangles in hexahedrons. + # @param theDomains - list of groups of volumes + # @param createJointElems - if TRUE, create the elements + # @return TRUE if operation has been completed successfully, FALSE otherwise + def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems ): + return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems ) def _valueFromFunctor(self, funcType, elemId): fn = self.smeshpyD.GetFunctor(funcType) diff --git a/src/StdMeshers/Makefile.am b/src/StdMeshers/Makefile.am index 08c312ead..abf30eb28 100644 --- a/src/StdMeshers/Makefile.am +++ b/src/StdMeshers/Makefile.am @@ -136,6 +136,7 @@ dist_libStdMeshers_la_SOURCES = \ libStdMeshers_la_CPPFLAGS = \ $(CAS_CPPFLAGS) \ $(BOOST_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(KERNEL_CXXFLAGS) \ $(GUI_CXXFLAGS) \ -I$(srcdir)/../SMESHImpl \ diff --git a/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx b/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx index 24a1e3fa9..d278711db 100644 --- a/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx @@ -1004,8 +1004,8 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh ) // store the rest nodes row by row - SMDS_MeshNode dummy(0,0,0); - const SMDS_MeshElement* firstQuad = &dummy;// most left face above the last row of found nodes + const SMDS_MeshNode* dummy = mesh.GetMeshDS()->AddNode(0,0,0); + const SMDS_MeshElement* firstQuad = dummy; // most left face above the last row of found nodes int nbFoundNodes = myIndexer._xSize; while ( nbFoundNodes != myGrid.size() ) @@ -1072,7 +1072,7 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh ) n1up = n2up; } } - + mesh.GetMeshDS()->RemoveNode(dummy); DumpGrid(); // debug return true; diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index f882f5c92..dc436d74f 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -341,7 +341,7 @@ const vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst, paramSize = myNormPar[ EdgeIndex ] - prevNormPar; } const SMDS_EdgePosition* epos = - dynamic_cast(uvPt.node->GetPosition().get()); + dynamic_cast(uvPt.node->GetPosition()); if ( epos ) { uvPt.param = epos->GetUParameter(); } diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index 7745eee72..4701c050d 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -165,7 +165,7 @@ inline bool isCloser(const int i, const int j, const int nbhoriz, static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& I, int& J) { const SMDS_FacePosition* fpos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); if ( ! fpos ) return false; gp_Pnt2d uv( fpos->GetUParameter(), fpos->GetVParameter() ); @@ -210,9 +210,9 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& * -0. - shape and face mesh verification * -1. - identify faces and vertices of the "cube" * -2. - Algorithm from: - * "Application de l'interpolation transfinie à la création de maillages + * "Application de l'interpolation transfinie a la creation de maillages * C0 ou G1 continus sur des triangles, quadrangles, tetraedres, pentaedres - * et hexaedres déformés." + * et hexaedres deformes." * Alain PERONNET - 8 janvier 1999 */ //============================================================================= @@ -411,6 +411,9 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, int i1, j1, nbxyz = nbx * nby * nbz; Point3DStruct *np = new Point3DStruct[nbxyz]; + + aMesh.GetMeshDS()->incrementNodesCapacity(nbx * nby * nbz); + aMesh.GetMeshDS()->incrementCellsCapacity((nbx-1) * (nby-1) * (nbz-1)); // 1.9 - store node indexes of faces diff --git a/src/StdMeshers/StdMeshers_Import_1D.cxx b/src/StdMeshers/StdMeshers_Import_1D.cxx index fe0f05476..b3dac25ab 100644 --- a/src/StdMeshers/StdMeshers_Import_1D.cxx +++ b/src/StdMeshers/StdMeshers_Import_1D.cxx @@ -575,7 +575,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); vector newNodes; - SMDS_MeshNode tmpNode(0,0,0); + SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0); double u; while ( srcElems->more() ) // loop on group contents { @@ -589,7 +589,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; if ( n2nIt->second ) { - if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() )) + if ( !subShapeIDs.count( n2nIt->second->getshapeId() )) break; } else @@ -606,8 +606,8 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th if ( !n2nIt->second ) { // find out if node lies on theShape - tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); - if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true )) + tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); + if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, /*force=*/true )) { SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); n2nIt->second = newNode; @@ -629,6 +629,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th tgtMesh->SetMeshElementOnShape( newEdge, shapeID ); e2e->insert( make_pair( edge, newEdge )); } + helper.GetMeshDS()->RemoveNode(tmpNode); } if ( n2n->empty()) return error("Empty source groups"); @@ -892,7 +893,7 @@ bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh & theMesh, { const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); - SMDS_MeshNode tmpNode(0,0,0); + SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0); while ( srcElems->more() ) // loop on group contents { const SMDS_MeshElement* edge = srcElems->next(); @@ -901,11 +902,12 @@ bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh & theMesh, SMESH_MeshEditor::TNodeXYZ p1( edge->GetNode(0)); SMESH_MeshEditor::TNodeXYZ p2( edge->GetNode(1)); gp_XYZ middle = ( p1 + p2 ) / 2.; - tmpNode.setXYZ( middle.X(), middle.Y(), middle.Z()); + tmpNode->setXYZ( middle.X(), middle.Y(), middle.Z()); double u = 0; - if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true )) + if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, /*force=*/true )) ++( edge->IsQuadratic() ? nbQuadEdges : nbEdges); } + helper.GetMeshDS()->RemoveNode(tmpNode); } int nbNodes = nbEdges + 2 * nbQuadEdges - 1; diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.cxx b/src/StdMeshers/StdMeshers_Import_1D2D.cxx index 5513a1077..5d89cd128 100644 --- a/src/StdMeshers/StdMeshers_Import_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_Import_1D2D.cxx @@ -200,7 +200,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e ); SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); - SMDS_MeshNode tmpNode(0,0,0); + SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0); gp_XY uv; while ( srcElems->more() ) // loop on group contents { @@ -215,7 +215,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; if ( n2nIt->second ) { - if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() )) + if ( !subShapeIDs.count( n2nIt->second->getshapeId() )) break; } else @@ -232,8 +232,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & if ( !n2nIt->second ) { // find out if node lies on theShape - tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); - if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true )) + tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); + if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, /*force=*/true )) { SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); n2nIt->second = newNode; @@ -315,6 +315,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & ++link2Nb->second; } } + helper.GetMeshDS()->RemoveNode(tmpNode); } // ========================================================== @@ -346,7 +347,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN ) { const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2(); - if ( !subShapeIDs.count( n->GetPosition()->GetShapeId() )) + if ( !subShapeIDs.count( n->getshapeId() )) { for ( unsigned iE = 0; iE < edges.size(); ++iE ) if ( helper.CheckNodeU( edges[iE], n, u, 10 * faceTol, /*force=*/true )) @@ -358,7 +359,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u ); break; } - nodesOnBoundary = subShapeIDs.count( n->GetPosition()->GetShapeId()); + nodesOnBoundary = subShapeIDs.count( n->getshapeId()); } if ( nodesOnBoundary ) { @@ -554,7 +555,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh & theMesh, { const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); - SMDS_MeshNode tmpNode(0,0,0); + SMDS_MeshNode *tmpNode =helper.AddNode(0,0,0); while ( srcElems->more() ) // loop on group contents { const SMDS_MeshElement* face = srcElems->next(); @@ -562,8 +563,8 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh & theMesh, // a gravity center of face to geomFace gp_XYZ gc(0,0,0); gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes(); - tmpNode.setXYZ( gc.X(), gc.Y(), gc.Z()); - if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true )) + tmpNode->setXYZ( gc.X(), gc.Y(), gc.Z()); + if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, /*force=*/true )) { ++aVec[ face->GetEntityType() ]; @@ -585,6 +586,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh & theMesh, } } } + helper.GetMeshDS()->RemoveNode(tmpNode); } int nbNodes = allNodes.size(); diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx index 46f7b9e39..894899686 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -512,7 +512,7 @@ static bool fixCommonVertexUV (R2 & theUV, if ( theCreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge )) continue; const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); double u = epos->GetUParameter(); if ( u < umin ) umin = u; @@ -613,9 +613,9 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires, case SMDS_TOP_EDGE: // In order to detect degenerated faces easily, we replace // nodes on a degenerated edge by node on the vertex of that edge - if ( myTool->IsDegenShape( uvPt->node->GetPosition()->GetShapeId() )) + if ( myTool->IsDegenShape( uvPt->node->getshapeId() )) { - int edgeID = uvPt->node->GetPosition()->GetShapeId(); + int edgeID = uvPt->node->getshapeId(); SMESH_subMesh* edgeSM = myTool->GetMesh()->GetSubMeshContaining( edgeID ); SMESH_subMeshIteratorPtr smIt = edgeSM->getDependsOnIterator( /*includeSelf=*/0, /*complexShapeFirst=*/0); @@ -640,7 +640,7 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires, int m = *mIt; if ( iW && !VWMap.IsEmpty()) { // except outer wire // avoid passing same uv point for a vertex common to 2 wires - int vID = mefistoToDS[m]->GetPosition()->GetShapeId(); + int vID = mefistoToDS[m]->getshapeId(); TopoDS_Vertex V = TopoDS::Vertex( myTool->GetMeshDS()->IndexToShape( vID )); if ( fixCommonVertexUV( uvslf[m], V, F, VWMap, *myTool->GetMesh(), scalex, scaley, _quadraticMesh )) { diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx index b9d46da9e..2ad53b1d7 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.cxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.cxx @@ -235,7 +235,7 @@ void StdMeshers_Penta_3D::MakeNodes() // if ( SMESH_Block::IsEdgeID (aSID)) { const SMDS_EdgePosition* epos = - static_cast(aNode->GetPosition().get()); + static_cast(aNode->GetPosition()); myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords ); } else { @@ -1465,7 +1465,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, if(myTool->IsMedium(node)) continue; const SMDS_EdgePosition* pos = - dynamic_cast( node->GetPosition().get() ); + dynamic_cast( node->GetPosition() ); if ( !pos ) { return false; } @@ -1488,7 +1488,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, if(myTool->IsMedium(node)) continue; const SMDS_EdgePosition* pos = - dynamic_cast( node->GetPosition().get() ); + dynamic_cast( node->GetPosition() ); if ( !pos ) { return false; } diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index c7bf42004..5a2a1a3fe 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -478,7 +478,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE, topParams )) return error(TCom("Can't compute normalized parameters ") << "for node " << column.back()->GetID() - << " on the face #"<< column.back()->GetPosition()->GetShapeId() ); + << " on the face #"<< column.back()->getshapeId() ); } // vertical loop @@ -806,6 +806,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() botSMDS->NbElements() != topSMDS->NbElements() || botSMDS->NbNodes() != topSMDS->NbNodes()) { + MESSAGE("nb elem bot " << botSMDS->NbElements() << " top " << topSMDS->NbElements()); + MESSAGE("nb node bot " << botSMDS->NbNodes() << " top " << topSMDS->NbNodes()); if ( myBlock.HasNotQuadElemOnTop() ) return error(TCom("Mesh on faces #") << botSM->GetId() <<" and #"<< topSM->GetId() << " seems different" ); @@ -1208,6 +1210,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, } myNotQuadOnTop = ( nbNotQuadMeshed > 1 ); + MESSAGE("myNotQuadOnTop " << myNotQuadOnTop << " nbNotQuadMeshed " << nbNotQuadMeshed); // ---------------------------------------------------------- @@ -1364,11 +1367,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // columns for vertices // 1 const SMDS_MeshNode* n0 = faceColumns.begin()->second.front(); - id = n0->GetPosition()->GetShapeId(); + id = n0->getshapeId(); myShapeIndex2ColumnMap[ id ] = make_pair( & faceColumns, isForward ); // 2 const SMDS_MeshNode* n1 = faceColumns.rbegin()->second.front(); - id = n1->GetPosition()->GetShapeId(); + id = n1->getshapeId(); myShapeIndex2ColumnMap[ id ] = make_pair( & faceColumns, isForward ); // SHOWYXZ("\np1 F "<second.front() )); // SHOWYXZ("p2 F "<second.front() )); @@ -1578,11 +1581,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // columns for vertices const SMDS_MeshNode* n0 = cols->begin()->second.front(); - id = n0->GetPosition()->GetShapeId(); + id = n0->getshapeId(); myShapeIndex2ColumnMap[ id ] = make_pair( cols, isForward ); const SMDS_MeshNode* n1 = cols->rbegin()->second.front(); - id = n1->GetPosition()->GetShapeId(); + id = n1->getshapeId(); myShapeIndex2ColumnMap[ id ] = make_pair( cols, !isForward ); } } @@ -1609,7 +1612,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, const TNodeColumn* StdMeshers_PrismAsBlock::GetNodeColumn(const SMDS_MeshNode* node) const { - int sID = node->GetPosition()->GetShapeId(); + int sID = node->getshapeId(); map >::const_iterator col_frw = myShapeIndex2ColumnMap.find( sID ); diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index 38028c2d7..86edbacfd 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -1753,7 +1753,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, const SMDS_MeshElement* f = ( iF ? f2 : f1 ); for ( int i = 0; !notSeamNode[ iF ] && i < f->NbNodes(); ++i ) { const SMDS_MeshNode* node = f->GetNode( i ); - if ( !helper->IsSeamShape( node->GetPosition()->GetShapeId() )) + if ( !helper->IsSeamShape( node->getshapeId() )) notSeamNode[ iF ] = node; } } @@ -1821,7 +1821,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, while ( nIt->more() ) { const SMDS_MeshNode* node = nIt->next(); const SMDS_EdgePosition* pos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); pos2nodes.insert( make_pair( pos->GetUParameter(), node )); } if ( pos2nodes.size() != edgeSM->NbNodes() ) diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index e234d0a91..db8cec568 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -341,7 +341,7 @@ namespace { RETURN_BAD_RESULT("Bad node position type: node " << node->GetID() << " pos type " << node->GetPosition()->GetTypeOfPosition()); const SMDS_EdgePosition* pos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); u2nodes.insert( make_pair( pos->GetUParameter(), node )); seamNodes.insert( node ); } @@ -374,7 +374,8 @@ namespace { SMESH_Mesh * srcMesh, const TAssocTool::TShapeShapeMap& shape2ShapeMap) { - const double tol = 1e-6; + MESSAGE("projectPartner"); + const double tol = 1.e-7*srcMesh->GetMeshDS()->getMaxDim(); gp_Trsf trsf; // transformation to get location of target nodes from source ones if ( tgtFace.IsPartner( srcFace )) @@ -406,12 +407,13 @@ namespace { { case 0: pOK = true; break; - case 1: pOK = ( srcPP[0].SquareDistance( p ) > tol ); break; + case 1: pOK = ( srcPP[0].SquareDistance( p ) > 10*tol ); break; case 2: { gp_Vec p0p1( srcPP[0], srcPP[1] ), p0p( srcPP[0], p ); - pOK = !p0p1.IsParallel( p0p, tol ); + // pOK = !p0p1.IsParallel( p0p, tol ); + pOK = !p0p1.IsParallel( p0p, 3.14/20 ); // angle min 18 degrees break; } } @@ -434,6 +436,7 @@ namespace { { double srcDist = srcPP[0].Distance( p ); double eTol = BRep_Tool::Tolerance( TopoDS::Edge( tgtShape )); + if (eTol < tol) eTol = tol; SMDS_NodeIteratorPtr nItT = tgtSmds->GetNodes(); while ( nItT->more() && !pOK ) { @@ -490,7 +493,7 @@ namespace { if ( !tgtEdge.IsPartner( srcEdge.Current() )) { - // check that transormation is OK by three nodes + // check that transformation is OK by three nodes gp_Pnt p0S = SMESH_MeshEditor::TNodeXYZ( (srcNodes.begin()) ->second); gp_Pnt p1S = SMESH_MeshEditor::TNodeXYZ( (srcNodes.rbegin()) ->second); gp_Pnt p2S = SMESH_MeshEditor::TNodeXYZ( (++srcNodes.begin())->second); @@ -499,7 +502,7 @@ namespace { gp_Pnt p1T = SMESH_MeshEditor::TNodeXYZ( (tgtNodes.rbegin()) ->second); gp_Pnt p2T = SMESH_MeshEditor::TNodeXYZ( (++tgtNodes.begin())->second); - // transform source points, they must coinside with target ones + // transform source points, they must coincide with target ones if ( p0T.SquareDistance( p0S.Transformed( trsf )) > tol || p1T.SquareDistance( p1S.Transformed( trsf )) > tol || p2T.SquareDistance( p2S.Transformed( trsf )) > tol ) @@ -522,6 +525,7 @@ namespace { // prepare the helper adding quadratic elements if necessary SMESH_MesherHelper helper( *tgtMesh ); + helper.SetSubShape( tgtFace ); helper.IsQuadraticSubMesh( tgtFace ); helper.SetElementsOnShape( true ); @@ -538,20 +542,31 @@ namespace { while ( nodeIt->more() ) // loop on nodes of the source element { const SMDS_MeshNode* srcNode = (const SMDS_MeshNode*) nodeIt->next(); + if (elem->IsMediumNode(srcNode)) + continue; srcN_tgtN = src2tgtNodes.insert( make_pair( srcNode, nullNode )).first; if ( srcN_tgtN->second == nullNode ) { // create a new node gp_Pnt tgtP = gp_Pnt(srcNode->X(),srcNode->Y(),srcNode->Z()).Transformed( trsf ); srcN_tgtN->second = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() ); + //MESSAGE(tgtP.X() << " " << tgtP.Y() << " " << tgtP.Z()); } tgtFaceNodes.push_back( srcN_tgtN->second ); } // create a new face (with reversed orientation) - if ( tgtFaceNodes.size() == 3 ) - helper.AddFace( tgtFaceNodes[0],tgtFaceNodes[2],tgtFaceNodes[1]); - else - helper.AddFace( tgtFaceNodes[0],tgtFaceNodes[3],tgtFaceNodes[2],tgtFaceNodes[1]); + //MESSAGE("tgtFaceNodes.size() " << tgtFaceNodes.size()); + switch (tgtFaceNodes.size()) + { + case 3: + case 6: + helper.AddFace(tgtFaceNodes[0], tgtFaceNodes[2], tgtFaceNodes[1]); + break; + case 4: + case 8: + helper.AddFace(tgtFaceNodes[0], tgtFaceNodes[3], tgtFaceNodes[2], tgtFaceNodes[1]); + break; + } } return true; } @@ -566,6 +581,7 @@ namespace { bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape) { + MESSAGE("Projection_2D Compute"); if ( !_sourceHypo ) return false; @@ -752,7 +768,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& } case SMDS_TOP_EDGE: { const SMDS_EdgePosition* pos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); pos2nodes.insert( make_pair( pos->GetUParameter(), node )); break; } diff --git a/src/StdMeshers/StdMeshers_Projection_3D.cxx b/src/StdMeshers/StdMeshers_Projection_3D.cxx index e30980e32..689c92006 100644 --- a/src/StdMeshers/StdMeshers_Projection_3D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_3D.cxx @@ -407,11 +407,13 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS nodes[6], nodes[7], id, force3d); break; default: // polyhedron - const SMDS_PolyhedralVolumeOfNodes * poly = - dynamic_cast( srcVol ); + const SMDS_VtkVolume * poly = + dynamic_cast( srcVol ); if ( !poly ) RETURN_BAD_RESULT("Unexpected volume type"); - tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuanities() ); + if ( !poly->IsPoly()) + RETURN_BAD_RESULT("Unexpected volume type"); + tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuantities() ); } if ( tgtVol ) { tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() ); diff --git a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx index 8e2718dd0..25b472c3e 100644 --- a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx +++ b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx @@ -51,53 +51,6 @@ typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXy namespace { - const int Q2TAbs_TmpTriangle = SMDSEntity_Last + 1; - - //================================================================================ - /*! - * \brief Temporary face. It's key feature is that it adds itself to an apex node - * as inverse element, so that tmp triangles of a piramid can be easily found - */ - //================================================================================ - - class STDMESHERS_EXPORT Q2TAdaptor_Triangle : public SMDS_MeshFace - { - const SMDS_MeshNode* _nodes[3]; - public: - Q2TAdaptor_Triangle(const SMDS_MeshNode* apexNode, - const SMDS_MeshNode* node2, - const SMDS_MeshNode* node3) - { - _nodes[0]=0; ChangeApex(apexNode); - _nodes[1]=node2; - _nodes[2]=node3; - } - ~Q2TAdaptor_Triangle() { MarkAsRemoved(); } - void ChangeApex(const SMDS_MeshNode* node) - { - MarkAsRemoved(); - _nodes[0]=node; - const_cast(node)->AddInverseElement(this); - } - void MarkAsRemoved() - { - if ( _nodes[0] ) - const_cast(_nodes[0])->RemoveInverseElement(this), _nodes[0] = 0; - } - bool IsRemoved() const { return !_nodes[0]; } - virtual int NbNodes() const { return 3; } - virtual const SMDS_MeshNode* GetNode(const int ind) const { return _nodes[ind]; } - virtual SMDSAbs_EntityType GetEntityType() const - { - return SMDSAbs_EntityType( Q2TAbs_TmpTriangle ); - } - virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const - { - if ( type == SMDSAbs_Node ) - return SMDS_ElemIteratorPtr( new SMDS_NodeArrayElemIterator( _nodes, _nodes+3 )); - throw SALOME_Exception(LOCALIZED("Not implemented")); - } - }; //================================================================================ /*! @@ -118,9 +71,10 @@ namespace */ //================================================================================ - void MergePiramids( const SMDS_MeshElement* PrmI, + void MergePyramids( const SMDS_MeshElement* PrmI, const SMDS_MeshElement* PrmJ, SMESHDS_Mesh* meshDS, + TRemTrias& tempTrias, set & nodesToMove) { const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove @@ -131,6 +85,7 @@ namespace SMDS_MeshNode* CommonNode = const_cast(PrmI->GetNode(4)); if ( CommonNode == Nrem ) return; // already merged int nbI = CommonNode->NbInverseElements( SMDSAbs_Volume ); + //cerr << __LINE__ << " " << nbI << " " << nbJ << endl; SMESH_MeshEditor::TNodeXYZ Pi( CommonNode ); gp_XYZ Pnew = ( nbI*Pi + nbJ*Pj ) / (nbI+nbJ); CommonNode->setXYZ( Pnew.X(), Pnew.Y(), Pnew.Z() ); @@ -153,12 +108,15 @@ namespace } if ( FJEqual ) { - ((Q2TAdaptor_Triangle*) FI)->MarkAsRemoved(); - ((Q2TAdaptor_Triangle*) FJEqual)->MarkAsRemoved(); + //meshDS->RemoveFreeElement(FI, 0, false); + //meshDS->RemoveFreeElement(FJEqual, 0, false); + tempTrias[FI] = false; + tempTrias[FJEqual] = false; } } // set the common apex node to pyramids and triangles merged with J + //cerr << __LINE__ << " NbInverseElements " << Nrem->NbInverseElements() << endl; SMDS_ElemIteratorPtr itJ = Nrem->GetInverseElementIterator(); while ( itJ->more() ) { @@ -166,17 +124,25 @@ namespace if ( elem->GetType() == SMDSAbs_Volume ) // pyramid { vector< const SMDS_MeshNode* > nodes( elem->begin_nodes(), elem->end_nodes() ); + //cerr << __LINE__ << " volId " << elem->GetID() << " nbNodes " << nodes.size() << endl; nodes[4] = CommonNode; + MESSAGE("ChangeElementNodes"); meshDS->ChangeElementNodes( elem, &nodes[0], nodes.size()); } - else if ( elem->GetEntityType() == Q2TAbs_TmpTriangle ) // tmp triangle + else if ( tempTrias.count(elem) ) // tmp triangles { - ((Q2TAdaptor_Triangle*) elem )->ChangeApex( CommonNode ); + //cerr << __LINE__ << " triaId " << elem->GetID() << endl; + ((SMDS_VtkFace*) elem )->ChangeApex( CommonNode ); } +// else +// { +// cerr << __LINE__ << " other " << elem->GetVtkType() << endl; +// } } + //cerr << __LINE__ << " NbInverseElements " << Nrem->NbInverseElements() << endl; ASSERT( Nrem->NbInverseElements() == 0 ); meshDS->RemoveFreeNode( Nrem, - meshDS->MeshElements( Nrem->GetPosition()->GetShapeId()), + meshDS->MeshElements( Nrem->getshapeId()), /*fromGroups=*/false); } @@ -194,7 +160,7 @@ namespace const SMDS_MeshNode* nApexI = PrmI->GetNode(4); const SMDS_MeshNode* nApexJ = PrmJ->GetNode(4); if ( nApexI == nApexJ || - nApexI->GetPosition()->GetShapeId() != nApexJ->GetPosition()->GetShapeId() ) + nApexI->getshapeId() != nApexJ->getshapeId() ) return false; // Find two common base nodes and their indices within PrmI and PrmJ @@ -295,6 +261,7 @@ namespace void MergeAdjacent(const SMDS_MeshElement* PrmI, SMESH_Mesh& mesh, + TRemTrias & tempTrias, set& nodesToMove) { TIDSortedElemSet adjacentPyrams, mergedPyrams; @@ -309,7 +276,7 @@ namespace continue; if ( PrmI != PrmJ && TooCloseAdjacent( PrmI, PrmJ, mesh.HasShapeToMesh() )) { - MergePiramids( PrmI, PrmJ, mesh.GetMeshDS(), nodesToMove ); + MergePyramids( PrmI, PrmJ, mesh.GetMeshDS(), tempTrias, nodesToMove ); mergedPyrams.insert( PrmJ ); } } @@ -318,10 +285,10 @@ namespace { TIDSortedElemSet::iterator prm; // for (prm = mergedPyrams.begin(); prm != mergedPyrams.end(); ++prm) -// MergeAdjacent( *prm, mesh, nodesToMove ); +// MergeAdjacent( *prm, mesh, tempTrias, nodesToMove ); for (prm = adjacentPyrams.begin(); prm != adjacentPyrams.end(); ++prm) - MergeAdjacent( *prm, mesh, nodesToMove ); + MergeAdjacent( *prm, mesh, tempTrias, nodesToMove ); } } } @@ -352,7 +319,10 @@ StdMeshers_QuadToTriaAdaptor::~StdMeshers_QuadToTriaAdaptor() TTriaList& fList = f_f->second; TTriaList::iterator f = fList.begin(), fEnd = fList.end(); for ( ; f != fEnd; ++f ) - delete *f; + { + const SMDS_MeshElement *elem = *f; + SMDS_Mesh::_meshList[elem->getMeshId()]->RemoveFreeElement(elem); + } } myResMap.clear(); @@ -735,9 +705,10 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape // add triangles to result map SMDS_MeshFace* NewFace; if(!isRev) - NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[1], FNodes[2] ); + NewFace = meshDS->AddFace( FNodes[0], FNodes[1], FNodes[2] ); else - NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[2], FNodes[1] ); + NewFace = meshDS->AddFace( FNodes[0], FNodes[2], FNodes[1] ); + myTempTriangles[NewFace] =true; TTriaList aList( 1, NewFace ); myResMap.insert(make_pair(face,aList)); continue; @@ -794,7 +765,11 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape // add triangles to result map TTriaList& triaList = myResMap.insert( make_pair( face, TTriaList() ))->second; for(i=0; i<4; i++) - triaList.push_back( new Q2TAdaptor_Triangle( NewNode, FNodes[i], FNodes[i+1] )); + { + SMDS_MeshFace* newFace =meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] ); + triaList.push_back( newFace ); + myTempTriangles[newFace] = true; + } // create a pyramid if ( isRev ) swap( FNodes[1], FNodes[3]); @@ -916,9 +891,10 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) } } if(!IsRev) - NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[1], FNodes[2] ); + NewFace = meshDS->AddFace( FNodes[0], FNodes[1], FNodes[2] ); else - NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[2], FNodes[1] ); + NewFace = meshDS->AddFace( FNodes[0], FNodes[2], FNodes[1] ); + myTempTriangles[NewFace] = true; aList.push_back(NewFace); myResMap.insert(make_pair(face,aList)); continue; @@ -996,9 +972,10 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) for(i=0; i<4; i++) { SMDS_MeshFace* NewFace; if(isRev) - NewFace = new Q2TAdaptor_Triangle( NewNode, FNodes[i], FNodes[i+1] ); + NewFace = meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] ); else - NewFace = new Q2TAdaptor_Triangle( NewNode, FNodes[i+1], FNodes[i] ); + NewFace = meshDS->AddFace( NewNode, FNodes[i+1], FNodes[i] ); + myTempTriangles[NewFace] = true; aList.push_back(NewFace); } // create a pyramid @@ -1026,7 +1003,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) return true; SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->GetPosition()->GetShapeId(); + int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->getshapeId(); if ( !myElemSearcher ) myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher(); @@ -1039,7 +1016,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) for ( i = 0; i < myPyramids.size(); ++i ) { const SMDS_MeshElement* PrmI = myPyramids[i]; - MergeAdjacent( PrmI, aMesh, nodesToMove ); + MergeAdjacent( PrmI, aMesh, myTempTriangles, nodesToMove ); } // iterate on all pyramids @@ -1076,7 +1053,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) const SMDS_MeshElement* PrmJ = suspectPyrams[j]; if ( PrmJ == PrmI || PrmJ->NbCornerNodes() != 5 ) continue; - if ( myShapeID != PrmJ->GetNode(4)->GetPosition()->GetShapeId()) + if ( myShapeID != PrmJ->GetNode(4)->getshapeId()) continue; // pyramid from other SOLID if ( PrmI->GetNode(4) == PrmJ->GetNode(4) ) continue; // pyramids PrmI and PrmJ already merged @@ -1116,7 +1093,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) if(nbc>0) { // Merge the two pyramids and others already merged with them - MergePiramids( PrmI, PrmJ, meshDS, nodesToMove ); + MergePyramids( PrmI, PrmJ, meshDS, myTempTriangles, nodesToMove ); } else { // nbc==0 @@ -1149,8 +1126,8 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) nodesToMove.insert( aNode2 ); } // fix intersections that could appear after apex movement - MergeAdjacent( PrmI, aMesh, nodesToMove ); - MergeAdjacent( PrmJ, aMesh, nodesToMove ); + MergeAdjacent( PrmI, aMesh, myTempTriangles, nodesToMove ); + MergeAdjacent( PrmJ, aMesh, myTempTriangles, nodesToMove ); } // end if(hasInt) } // loop on suspectPyrams @@ -1171,18 +1148,34 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) for ( ++q2t; q2t != myResMap.end(); ++q2t, ++q2tPrev ) { if ( q2t->first == q2tPrev->first ) - q2tPrev->second.splice( q2tPrev->second.end(), q2t->second ); + { + //cerr << __LINE__ << " splice" << endl; + q2tPrev->second.splice( q2tPrev->second.end(), q2t->second ); + } } // delete removed triangles and count resulting nb of triangles - for ( q2t = myResMap.begin(); q2t != myResMap.end(); ++q2t ) - { - TTriaList & trias = q2t->second; - for ( TTriaList::iterator tri = trias.begin(); tri != trias.end(); ) - if ( ((const Q2TAdaptor_Triangle*) *tri)->IsRemoved() ) - delete *tri, trias.erase( tri++ ); - else - tri++, myNbTriangles++; - } + for (q2t = myResMap.begin(); q2t != myResMap.end(); ++q2t) + { + TTriaList & trias = q2t->second; + vector faceToErase; + faceToErase.clear(); + //cerr << __LINE__ << " " << trias.size() << endl; + for (TTriaList::iterator tri = trias.begin(); tri != trias.end(); ++tri) + { + //cerr << " " << __LINE__ << endl; + const SMDS_MeshFace* face = *tri; + if (myTempTriangles.count(face) && (myTempTriangles[face] == false)) + faceToErase.push_back(face); + else + myNbTriangles++; + } + for (vector::iterator it = faceToErase.begin(); it != faceToErase.end(); ++it) + { + const SMDS_MeshFace *face = dynamic_cast(*it); + if (face) trias.remove(face); + meshDS->RemoveFreeElement(face, 0, false); + } + } myPyramids.clear(); // no more needed myDegNodes.clear(); diff --git a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx index ceccb2542..95ed9a622 100644 --- a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx +++ b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx @@ -43,6 +43,8 @@ class gp_Vec; #include +typedef std::map TRemTrias; + /*! * \brief "Transforms" quadrilateral faces into triangular ones by creation of pyramids */ @@ -87,8 +89,9 @@ protected: typedef std::list TTriaList; typedef std::multimap TQuad2Trias; - TQuad2Trias myResMap; + TRemTrias myTempTriangles; + std::vector myPyramids; std::list< const SMDS_MeshNode* > myDegNodes; diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 1075db412..174a24411 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -1186,10 +1186,10 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, const TopoDS_Shape& aShape, FaceQuadStruct* & quad) //throw (SALOME_Exception) { - // Algorithme décrit dans "Génération automatique de maillages" - // P.L. GEORGE, MASSON, § 6.4.1 p. 84-85 - // traitement dans le domaine paramétrique 2d u,v - // transport - projection sur le carré unité + // Algorithme décrit dans "Génération automatique de maillages" + // P.L. GEORGE, MASSON, § 6.4.1 p. 84-85 + // traitement dans le domaine paramétrique 2d u,v + // transport - projection sur le carré unité // MESSAGE("StdMeshers_Quadrangle_2D::SetNormalizedGrid"); // const TopoDS_Face& F = TopoDS::Face(aShape); diff --git a/src/StdMeshers_I/Makefile.am b/src/StdMeshers_I/Makefile.am index 17d7c9f6f..ab1e6c9c0 100644 --- a/src/StdMeshers_I/Makefile.am +++ b/src/StdMeshers_I/Makefile.am @@ -123,6 +123,7 @@ libStdMeshersEngine_la_CPPFLAGS = \ $(GEOM_CXXFLAGS) \ $(MED_CXXFLAGS) \ $(BOOST_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ -I$(srcdir)/../SMESHImpl \