--- /dev/null
+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
--- /dev/null
+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 <QApplication>
+#include <qwt_plot.h>
+, 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
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
--- /dev/null
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>$title</title>
+ <link href="doxygen.css" rel="stylesheet" type="text/css">
+</head>
+<hr>
+<center>
+SALOME documentation central
+</center>
+<hr>
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
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
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
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
#---------------------------------------------------------------------------
# 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 =
#---------------------------------------------------------------------------
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
#---------------------------------------------------------------------------
# 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
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
#---------------------------------------------------------------------------
--- /dev/null
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.73 [en] (WinNT; I) [Netscape]">
+ <title>Main Page</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+<link href="tabs.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+
+</body>
+</html>
*/
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
# additionnal information to compil and link file
libSMESHControls_la_CPPFLAGS = \
$(CAS_CPPFLAGS) \
+ $(VTK_INCLUDES) \
$(BOOST_CPPFLAGS) \
$(KERNEL_CXXFLAGS) \
-I$(srcdir)/../SMDS \
if ( anElem->IsQuadratic() ) {
switch ( anElem->GetType() ) {
case SMDSAbs_Edge:
- anIter = static_cast<const SMDS_QuadraticEdge*>
+ anIter = dynamic_cast<const SMDS_VtkEdge*>
(anElem)->interlacedNodesElemIterator();
break;
case SMDSAbs_Face:
- anIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+ anIter = dynamic_cast<const SMDS_VtkFace*>
(anElem)->interlacedNodesElemIterator();
break;
default:
const SMDS_MeshFace* anElem = anIter->next();
if(anElem->IsQuadratic()) {
- const SMDS_QuadraticFaceOfNodes* F =
- static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem);
+ const SMDS_VtkFace* F =
+ dynamic_cast<const SMDS_VtkFace*>(anElem);
// use special nodes iterator
- SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+ SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
long aNodeId[4];
gp_Pnt P[4];
const SMDS_MeshFace* anElem = anIter->next();
SMDS_ElemIteratorPtr aNodesIter;
if ( anElem->IsQuadratic() )
- aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+ aNodesIter = dynamic_cast<const SMDS_VtkFace*>
(anElem)->interlacedNodesElemIterator();
else
aNodesIter = anElem->nodesIterator();
SMDS_ElemIteratorPtr anIter;
if ( aFace->IsQuadratic() ) {
- anIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+ anIter = dynamic_cast<const SMDS_VtkFace*>
(aFace)->interlacedNodesElemIterator();
}
else {
long anElemId = anElem->GetID();
SMDS_ElemIteratorPtr aNodesIter;
if ( anElem->IsQuadratic() )
- aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem)->
+ aNodesIter = static_cast<const SMDS_VtkFace*>(anElem)->
interlacedNodesElemIterator();
else
aNodesIter = anElem->nodesIterator();
void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
ManifoldPart::TVectorOfFacePtr& theFaces ) const
{
- SMDS_Mesh::SetOfFaces aSetOfFaces;
+ std::set<SMDS_MeshCell *> aSetOfFaces;
// take all faces that shared first node
SMDS_ElemIteratorPtr anItr = theLink.myNode1->facesIterator();
for ( ; anItr->more(); )
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();
for ( ; anItr->more(); )
{
SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next();
- if ( aSetOfFaces.Contains( aFace ) )
+ if ( aSetOfFaces.count( aFace ) )
theFaces.push_back( aFace );
}
}
libMeshDriverDAT_la_CPPFLAGS = \
$(KERNEL_CXXFLAGS) \
$(CAS_CPPFLAGS) \
+ $(VTK_INCLUDES) \
$(BOOST_CPPFLAGS) \
-I$(srcdir)/../Driver \
-I$(srcdir)/../SMDS \
// File : DriverMED_Family.cxx
// Author : Julia DOROVSKIKH
// Module : SMESH
+// $Header$
//
#include "DriverMED_Family.h"
#include "MED_Factory.hxx"
// File : DriverMED_Family.hxx
// Author : Julia DOROVSKIKH
// Module : SMESH
+// $Header$
//
#ifndef _INCLUDE_DRIVERMED_FAMILY
#define _INCLUDE_DRIVERMED_FAMILY
#include <stdlib.h>
#ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
//#define _DEXCEPT_
#else
static int MYDEBUG = 0;
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<<aNode->GetID()<<": "<<aNode->X()<<", "<<aNode->Y()<<", "<<aNode->Z()<<endl;
if(anIsElemNum){
TInt anElemId = aPolygoneInfo->GetElemNum(iElem);
anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId);
+ //MESSAGE("AddPolygonalFaceWithID " << anElemId);
}
if(!anElement){
vector<const SMDS_MeshNode*> 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_
typedef MED::TVector<int> 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
}
if(anIsElemNum){
TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
+ //MESSAGE("AddPolyhedralVolumeWithID " << anElemId);
}
if(!anElement){
vector<const SMDS_MeshNode*> 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_
anIsValidConnect = true;
#ifndef _DEXCEPT_
}catch(const std::exception& exc){
- //INFOS("Follow exception was cought:\n\t"<<exc.what());
+ INFOS("Following exception was caught:\n\t"<<exc.what());
aResult = DRS_FAIL;
}catch(...){
- //INFOS("Unknown exception was cought !!!");
+ INFOS("Unknown exception was cought !!!");
aResult = DRS_FAIL;
}
#endif
break;
case ePYRA13:
aNbNodes = 13;
- // There is some differnce between SMDS and MED
+ // There is some difference between SMDS and MED
if(anIsElemNum)
anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
aNodeIds[2], aNodeIds[3],
}
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"<<exc.what());
+ INFOS("The following exception was caught:\n\t"<<exc.what());
aResult = DRS_FAIL;
}catch(...){
- //INFOS("Unknown exception was cought !!!");
+ INFOS("Unknown exception was caught !!!");
aResult = DRS_FAIL;
}
#endif
}
#ifndef _DEXCEPT_
}catch(const std::exception& exc){
- INFOS("Follow exception was cought:\n\t"<<exc.what());
+ INFOS("The following exception was caught:\n\t"<<exc.what());
aResult = DRS_FAIL;
}catch(...){
- INFOS("Unknown exception was cought !!!");
+ INFOS("Unknown exception was caught !!!");
aResult = DRS_FAIL;
}
#endif
+ if (myMesh)
+ myMesh->compactMesh();
if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
return aResult;
}
}
}
}catch(const std::exception& exc){
- INFOS("Follow exception was cought:\n\t"<<exc.what());
+ INFOS("Following exception was caught:\n\t"<<exc.what());
theStatus = DRS_FAIL;
}catch(...){
- INFOS("Unknown exception was cought !!!");
+ INFOS("Unknown exception was caught !!!");
theStatus = DRS_FAIL;
}
for(MED::TInt iDim=0;iDim<aMeshDim;iDim++)
aCoords[(int)iDim] = aMEDNodeCoord[(int)iDim];
aNode = myMesh->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);
default:
break;
}
-
+ if (!anElement) {
+ EXCEPTION(runtime_error,"buildMeshGrille Error. Element not created! "<<iCell);
+ }
if((aGrilleInfo->myFamNum).size() > 0){
TInt aFamNum = aGrilleInfo->GetFamNum(iCell);
if ( checkFamilyID ( aFamily, aFamNum )){
nbElemInfo.NbHexas( ORDER_QUADRATIC ),
SMDSAbs_Volume));
if ( polyTypesSupported ) {
+ //MESSAGE("polyTypesSupported");
aTElemTypeDatas.push_back( TElemTypeData(anEntity,
ePOLYEDRE,
nbElemInfo.NbPolyhedrons(),
// ----------------
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<const SMDS_PolyhedralVolumeOfNodes*>( anElem );
- if ( aPolyedre ) {
+ const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(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
TInt iFace = 0, iNode = 0;
while ( const SMDS_MeshElement* anElem = elemIterator->next() )
{
- const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
- dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( anElem );
+ const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(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();
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;
}
}
catch(const std::exception& exc) {
- INFOS("Follow exception was cought:\n\t"<<exc.what());
+ INFOS("The following exception was caught:\n\t"<<exc.what());
throw;
}
catch(...) {
- INFOS("Unknown exception was cought !!!");
+ INFOS("Unknown exception was caught !!!");
throw;
}
@HDF5_INCLUDES@ \
$(KERNEL_CXXFLAGS) \
$(CAS_CPPFLAGS) \
+ $(VTK_INCLUDES) \
$(BOOST_CPPFLAGS) \
-I$(srcdir)/../Driver \
-I$(srcdir)/../SMDS \
libMeshDriverSTL_la_CPPFLAGS = \
$(KERNEL_CXXFLAGS) \
$(CAS_CPPFLAGS) \
+ $(VTK_INCLUDES) \
$(BOOST_CPPFLAGS) \
-I$(srcdir)/../Driver \
-I$(srcdir)/../SMDS
#ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
#else
static int MYDEBUG = 0;
#endif
for(; anIter != aDataSet2411.end(); anIter++){
const TNodeLab& aLabel = anIter->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);
}
}
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],
}
}
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
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],
}
}
else if(IsVolume(aRec.fe_descriptor_id)){
+ //MESSAGE("add volume " << aLabel);
switch(aRec.fe_descriptor_id){
case 111: // Solid Linear Tetrahedron - TET4
catch(...){
INFOS("Unknown exception was cought !!!");
}
+ if (myMesh)
+ myMesh->compactMesh();
return aResult;
}
TRecord aRec;
aRec.node_labels.reserve(aNbNodes);
SMDS_ElemIteratorPtr aNodesIter;
+ aNodesIter = anElem->nodesIteratorToUNV();
if( anElem->IsQuadratic() ) {
- aNodesIter = static_cast<const SMDS_QuadraticEdge* >
- ( anElem )->interlacedNodesElemIterator();
aRec.fe_descriptor_id = 22;
} else {
- aNodesIter = anElem->nodesIterator();
aRec.fe_descriptor_id = 11;
}
for(; aNodesIter->more();){
TRecord aRec;
aRec.node_labels.reserve(aNbNodes);
SMDS_ElemIteratorPtr aNodesIter;
- if( anElem->IsQuadratic() )
- aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes* >
- ( 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());
TElementLab aLabel = anElem->GetID();
int aNbNodes = anElem->NbNodes();
- SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+ //MESSAGE("aNbNodes="<<aNbNodes);
+ SMDS_ElemIteratorPtr aNodesIter;
+ aNodesIter = anElem->nodesIteratorToUNV();
if ( anElem->IsPoly() ) {
- if ( const SMDS_PolyhedralVolumeOfNodes* ph =
- dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+ MESSAGE("anElem->IsPoly");
+ if ( const SMDS_VtkVolume* ph =
+ dynamic_cast<const SMDS_VtkVolume*> (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));
}
$(CAS_CPPFLAGS) \
$(CORBA_CXXFLAGS) \
$(CORBA_INCLUDES) \
+ $(VTK_INCLUDES) \
$(BOOST_CPPFLAGS) \
-I$(srcdir)/../Driver \
-I$(srcdir)/../SMDS \
SMESH_FaceOrientationFilter.h \
SMESH_ScalarBarActor.h
-
# Libraries targets
lib_LTLIBRARIES = libSMESHObject.la
#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"
#ifdef _DEBUG_
static int MYDEBUG = 1;
#else
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
#endif
static int aLineWidthInc = 2;
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
//---------------------------------
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);
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());
#include "utilities.h"
#include <vtkUnstructuredGrid.h>
+#include <vtkXMLUnstructuredGridWriter.h>
#include <vtkUnstructuredGridWriter.h>
#ifdef _DEBUG_
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();
}
#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;
//=================================================================================
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();
}
//=================================================================================
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 )
TEntityList aNodes;
vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes );
thePoints->SetNumberOfPoints( nbNodes );
-
+
int nbPoints = 0;
TEntityList::const_iterator anIter;
// 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() = "<<myGrid->GetNumberOfCells() );
+ //MESSAGE( "Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints() );
+ if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"buildPrs.vtu" );
}
-
- if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->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 );
}
//=================================================================================
void SMESH_VisualObjDef::buildElemPrs()
{
// Create points
-
+
vtkPoints* aPoints = vtkPoints::New();
createPoints( aPoints );
myGrid->SetPoints( aPoints );
aPoints->Delete();
-
+
if ( MYDEBUG )
MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
// 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 ];
vtkIdType aNbCells = nbEnts[ SMDSAbs_0DElement ] + nbEnts[ SMDSAbs_Edge ] +
nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
-
+
if ( MYDEBUG )
MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
vtkCellArray* aConnectivity = vtkCellArray::New();
aConnectivity->Allocate( aCellsSize, 0 );
- SMDS_Mesh::CheckMemory(); // PAL16631
+ // SMDS_Mesh::CheckMemory(); // PAL16631
vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
aCellTypesArray->SetNumberOfComponents( 1 );
aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
- SMDS_Mesh::CheckMemory(); // PAL16631
+ // SMDS_Mesh::CheckMemory(); // PAL16631
vtkIdList *anIdList = vtkIdList::New();
vtkIdType iElem = 0;
TConnect aConnect;
aConnect.reserve(VTK_CELL_SIZE);
- SMDS_Mesh::CheckMemory(); // PAL16631
+ // SMDS_Mesh::CheckMemory(); // PAL16631
for ( int i = 0; i <= 3; i++ ) // iterate through 0d elements, edges, faces and volumes
{
// Convertions connectivities from SMDS to VTK
if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
- if ( const SMDS_PolyhedralVolumeOfNodes* ph =
- dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+ if ( const SMDS_VtkVolume* ph =
+ dynamic_cast<const SMDS_VtkVolume*> (anElem))
{
aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
anIdList->SetNumberOfIds( aNbNodes );
iElem++;
}
}
- SMDS_Mesh::CheckMemory(); // PAL16631
+ // SMDS_Mesh::CheckMemory(); // PAL16631
}
// Insert cells in grid
-
+
VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
aCellLocationsArray->SetNumberOfComponents( 1 );
aCellLocationsArray->SetNumberOfTuples( aNbCells );
-
- SMDS_Mesh::CheckMemory(); // PAL16631
+
+ // SMDS_Mesh::CheckMemory(); // PAL16631
aConnectivity->InitTraversal();
for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
-
+
aCellLocationsArray->Delete();
aCellTypesArray->Delete();
aConnectivity->Delete();
anIdList->Delete();
- SMDS_Mesh::CheckMemory(); // PAL16631
+ // SMDS_Mesh::CheckMemory(); // PAL16631
}
//=================================================================================
return true;
}
+vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
+{
+ //MESSAGE("SMESH_VisualObjDef::GetUnstructuredGrid " << myGrid);
+ return myGrid;
+}
+
+
//=================================================================================
// function : IsValid
// purpose : Return true if there are some entities
//=================================================================================
bool SMESH_VisualObjDef::IsValid() const
{
+ //MESSAGE("SMESH_VisualObjDef::IsValid");
return GetNbEntities(SMDSAbs_Node) > 0 ||
GetNbEntities(SMDSAbs_0DElement) > 0 ||
GetNbEntities(SMDSAbs_Edge) > 0 ||
SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh):
myClient(SalomeApp_Application::orb(),theMesh)
{
+ myEmptyGrid = 0;
if ( MYDEBUG )
MESSAGE("SMESH_MeshObj - this = "<<this<<"; theMesh->_is_nil() = "<<theMesh->_is_nil());
}
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
//=================================================================================
bool SMESH_SubMeshObj::Update( int theIsClear )
{
+ MESSAGE("SMESH_SubMeshObj::Update " << this)
bool changed = myMeshObj->Update( theIsClear );
- buildPrs();
+ buildPrs(true);
return changed;
}
{
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;
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;
int& theNodeId1,
int& theNodeId2 ) const;
- virtual vtkUnstructuredGrid* GetUnstructuredGrid() { return myGrid; }
+ virtual vtkUnstructuredGrid* GetUnstructuredGrid();
virtual vtkIdType GetNodeObjId( int theVTKID );
virtual vtkIdType GetNodeVTKId( int theObjID );
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;
};
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;
protected:
SMESH_Client myClient;
+ vtkUnstructuredGrid* myEmptyGrid;
};
--- /dev/null
+/*=========================================================================
+
+ 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 <vtkstd/map>
+
+#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;
+}
--- /dev/null
+/*=========================================================================
+
+ 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
# header files
salomeinclude_HEADERS = \
+ chrono.hxx \
+ ObjectPool.hxx \
SMDS_TypeOfPosition.hxx \
SMDSAbs_ElementType.hxx \
SMDS_EdgePosition.hxx \
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 \
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 \
SMDS_SetIterator.hxx \
SMESH_SMDS.hxx \
SMDS_MeshInfo.hxx \
+ SMDS_UnstructuredGrid.hxx \
+ SMDS_Downward.hxx \
SMDS_StdIterator.hxx
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 \
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 \
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 \
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)
--- /dev/null
+--> 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<SMDS_Mesh*> _meshList; --> retrouver un SMDS_Mesh
+ vtkUnstructuredGrid* myGrid;
+
+ vector<SMDS_MeshNode *> myNodes; --> meme index que dans le pointSet de myGrid
+ vector<SMDS_MeshCell *> 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<int> 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<int> myIDElements; // index = ID client, value = ID vtk --> A SUPPRIMER, ne sert que dans SMDS_MeshElementIDFactory
+ vector<int> 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> --> 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)
+
--- /dev/null
+#ifndef _OBJECTPOOL_HXX_
+#define _OBJECTPOOL_HXX_
+
+#include <vector>
+#include <stack>
+#include <iostream>
+
+template<class X> class ObjectPool
+{
+
+private:
+ std::vector<X*> _chunkList;
+ std::vector<bool> _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
--- /dev/null
+/*
+ * SMDS_Downward.cxx
+ *
+ * Created on: Jun 3, 2010
+ * Author: prascle
+ */
+
+#include "SMDS_Downward.hxx"
+#include "SMDS_Mesh.hxx"
+#include "utilities.h"
+
+#include <vtkCellType.h>
+#include <vtkCellLinks.h>
+
+#include <map>
+
+using namespace std;
+
+// ---------------------------------------------------------------------------
+
+vector<int> 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<int>& 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<int>& 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<int>& 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<SMDS_Down2D*> (_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<int>& 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<int> 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<int>& 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<int>& orderedNodes)
+{
+ set<int> 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<int> 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<int>& 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<int>& 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<int>& 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<int>& 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<int>& 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<int>& 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<int>& 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;
+}
+
+// ---------------------------------------------------------------------------
+
--- /dev/null
+/*
+ * SMDS_Downward.hxx
+ *
+ * Created on: Jun 3, 2010
+ * Author: prascle
+ */
+
+#ifndef SMDS_DOWNWARD_HXX_
+#define SMDS_DOWNWARD_HXX_
+
+#include "SMDS_UnstructuredGrid.hxx"
+
+#include <vector>
+#include <set>
+
+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<int>& 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<int> _cellIds; //!< growing size: all the down cell id's, size = _maxId * _nbDownCells
+ std::vector<int> _vtkCellIds; //!< growing size: size = _maxId, either vtkId or -1
+ std::vector<unsigned char> _cellTypes; //!< fixed size: the same vector for all cells of a derived class
+
+ static std::vector<int> _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<int>& 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<int>& vtkIds);
+ int computeVtkCells(int* pts, std::vector<int>& 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<std::vector<int> > _upCellIdsVector; //!< the number of faces sharing an edge is not known
+ std::vector<std::vector<unsigned char> > _upCellTypesVector; //!< the number of faces sharing an edge is not known
+ std::vector<int> _upCellIds; //!< compacted storage after connectivity calculation
+ std::vector<unsigned char> _upCellTypes; //!< compacted storage after connectivity calculation
+ std::vector<int> _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<int>& 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<int> _upCellIds; //!< 2 volumes max. per face
+ std::vector<unsigned char> _upCellTypes; //!< 2 volume types per face
+ std::vector<int> _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<int>& nodeSet);
+ virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& 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<int>& 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<int>& 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<int>& 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<int>& 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<int>& 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<int>& 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<int>& 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<int>& 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_ */
//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;
}
double SMDS_EdgePosition::GetUParameter() const
{
+ //MESSAGE("########################## SMDS_EdgePosition::GetUParameter " << myUParameter);
return myUParameter;
}
{
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;
#include "SMDS_FaceOfEdges.hxx"
#include "SMDS_IteratorOfElements.hxx"
#include "SMDS_MeshNode.hxx"
+#include "utilities.h"
using namespace std;
const SMDS_MeshEdge* edge2,
const SMDS_MeshEdge* edge3)
{
+ //MESSAGE("****************************************************** SMDS_FaceOfEdges");
myNbEdges = 3;
myEdges[0]=edge1;
myEdges[1]=edge2;
const SMDS_MeshEdge* edge3,
const SMDS_MeshEdge* edge4)
{
+ //MESSAGE("****************************************************** SMDS_FaceOfEdges");
myNbEdges = 4;
myEdges[0]=edge1;
myEdges[1]=edge2;
// 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
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;
const SMDS_MeshNode* node2,
const SMDS_MeshNode* node3)
{
+ //MESSAGE("******************************************************* SMDS_FaceOfNodes");
myNbNodes = 3;
myNodes[0]=node1;
myNodes[1]=node2;
const SMDS_MeshNode* node3,
const SMDS_MeshNode* node4)
{
+ //MESSAGE("******************************************************* SMDS_FaceOfNodes");
myNbNodes = 4;
myNodes[0]=node1;
myNodes[1]=node2;
//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");
}
/**
{
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);
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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 <iostream>
+
+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
// 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)
#include "SMDS_QuadraticEdge.hxx"
#include "SMDS_QuadraticFaceOfNodes.hxx"
#include "SMDS_QuadraticVolumeOfNodes.hxx"
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
+
+#include <vtkUnstructuredGrid.h>
+#include <vtkUnstructuredGridWriter.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkCell.h>
+#include <vtkCellLinks.h>
+#include <vtkIdList.h>
#include <algorithm>
#include <map>
+#include <iostream>
+#include <fstream>
using namespace std;
#ifndef WIN32
#include <sys/sysinfo.h>
#endif
-// number of added entitis to check memory after
+// number of added entities to check memory after
#define CHECKMEMORY_INTERVAL 1000
+vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
+int SMDS_Mesh::chunkSize = 1024;
+
+
//================================================================================
/*!
* \brief Raise an exception if free memory (ram+swap) too low
///////////////////////////////////////////////////////////////////////////////
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_MeshNode>(SMDS_Mesh::chunkSize);
+ myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
+ myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
+ myVolumePool = new ObjectPool<SMDS_VtkVolume>(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();
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
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)
{
}
// 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;
{
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<SMDS_MeshNode*>(n);
- node->AddInverseElement(el0d);
- my0DElements.Add(el0d);
+ //node->AddInverseElement(el0d);// --- fait avec BindID
+ adjustmyCellsCapacity(ID);
+ myCells[ID] = el0d;
myInfo.myNb0DElements++;
return el0d;
}
int ID)
{
if ( !n1 || !n2 ) return 0;
+ SMDS_MeshEdge * edge = 0;
- if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+ // --- retreive nodes ID
+ vector<vtkIdType> 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<SMDS_MeshNode*>(n1);
- node2=const_cast<SMDS_MeshNode*>(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;
}
///////////////////////////////////////////////////////////////////////////////
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;
}
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;
}
{
if (!hasConstructionEdges())
return NULL;
- return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
+ //MESSAGE("AddFaceWithID");
+ return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
}
///////////////////////////////////////////////////////////////////////////////
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;
}
{
if (!hasConstructionEdges())
return NULL;
- return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
+ //MESSAGE("AddFaceWithID" );
+ return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
}
///////////////////////////////////////////////////////////////////////////////
{
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;
}
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;
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);
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()) {
return NULL;
}
else {
- volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
- myVolumes.Add(volume);
+ // --- retrieve nodes ID
+ vector<vtkIdType> 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;
}
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;
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);
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()) {
return NULL;
}
else {
- volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
- myVolumes.Add(volume);
+ // --- retrieve nodes ID
+ vector<vtkIdType> 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;
}
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;
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);
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);
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()) {
return NULL;
}
else {
- volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
- myVolumes.Add(volume);
+ // --- retrieve nodes ID
+ vector<vtkIdType> 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;
}
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;
}
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);
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);
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()) {
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<vtkIdType> 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;
}
const SMDS_MeshFace * f3,
const SMDS_MeshFace * f4)
{
+ //MESSAGE("AddVolumeWithID");
if (!hasConstructionFaces())
return NULL;
return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
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;
}
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());
}
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;
}
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());
}
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;
}
{
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<vtkIdType> nodeIds;
+ nodeIds.clear();
+ vector<const SMDS_MeshNode*>::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;
}
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
(vector<const SMDS_MeshNode*> nodes,
vector<int> 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<vtkIdType> nodeIds;
+ nodeIds.clear();
+ vector<const SMDS_MeshNode*>::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;
}
return v;
}
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<int>& 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<int>& 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<SMDS_MeshNode*>
- (const_cast<SMDS_MeshElement*>(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<SMDS_MeshCell*>(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;
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<vtkIdType> 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;
}
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);
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<vtkIdType> 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;
}
void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
{
+ MESSAGE("RemoveNode");
RemoveElement(node, true);
}
void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
{
+ MESSAGE("Remove0DElement");
RemoveElement(elem0d,true);
}
void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
{
+ MESSAGE("RemoveEdge");
RemoveElement(edge,true);
}
void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
{
+ MESSAGE("RemoveFace");
RemoveElement(face, true);
}
void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
{
+ MESSAGE("RemoveVolume");
RemoveElement(volume, true);
}
const SMDS_MeshNode * nodes[],
const int nbnodes)
{
+ MESSAGE("SMDS_Mesh::ChangeElementNodes");
// keep current nodes of elem
set<const SMDS_MeshElement*> 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<SMDS_MeshElement*>(element);
- switch ( elem->GetType() )
- {
- case SMDSAbs_0DElement: {
- if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
- Ok = elem0d->ChangeNode( nodes[0] );
- break;
- }
- case SMDSAbs_Edge: {
- if ( nbnodes == 2 ) {
- if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
- Ok = edge->ChangeNodes( nodes[0], nodes[1] );
- }
- else if ( nbnodes == 3 ) {
- if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
- Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
+ SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((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<SMDS_FaceOfNodes*>( elem ))
- Ok = face->ChangeNodes( nodes, nbnodes );
- else
- if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
- Ok = QF->ChangeNodes( nodes, nbnodes );
- else
- if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
- Ok = face->ChangeNodes(nodes, nbnodes);
- break;
- }
- case SMDSAbs_Volume: {
- if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
- Ok = vol->ChangeNodes( nodes, nbnodes );
- else
- if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
- Ok = QV->ChangeNodes( nodes, nbnodes );
- break;
- }
- default:
- MESSAGE ( "WRONG ELEM TYPE");
- }
if ( Ok ) { // update InverseElements
it = oldNodes.find( nodes[i] );
if ( it == oldNodes.end() )
// new node
- const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
+ const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
else
// remove from oldNodes a node that remains in elem
oldNodes.erase( it );
{
SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
(const_cast<SMDS_MeshElement *>( *it ));
- n->RemoveInverseElement( elem );
+ n->RemoveInverseElement( cell );
}
}
- if ( !element->IsPoly() )
- myInfo.add( element ); // element may change type
-
return Ok;
}
return false;
}
- const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
+ const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
if (!vol) {
return false;
}
}
// change nodes
- bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
+ // TODO remove this function
+ //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
+ bool Ok = false;
if (!Ok) {
return false;
}
//function : Find0DElementOrCreate
//purpose :
//=======================================================================
-SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
-{
- if (!node) return 0;
- SMDS_Mesh0DElement * toReturn = NULL;
- toReturn = const_cast<SMDS_Mesh0DElement*>(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<SMDS_Mesh0DElement*>(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_MeshEdge * toReturn=NULL;
toReturn=const_cast<SMDS_MeshEdge*>(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<vtkIdType> 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;
SMDS_MeshFace * toReturn=NULL;
toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
if(toReturn==NULL) {
- toReturn = createTriangle(node1,node2,node3);
+ int ID = myElementIDFactory->GetFreeID();
+ toReturn = createTriangle(node1,node2,node3, ID);
}
return toReturn;
}
SMDS_MeshFace * toReturn=NULL;
toReturn=const_cast<SMDS_MeshFace*>(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;
}
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];
}
//=======================================================================
{
MESSAGE("dump nodes of mesh : ");
SMDS_NodeIteratorPtr itnode=nodesIterator();
- while(itnode->more()) MESSAGE(itnode->next());
+ while(itnode->more()) ; //MESSAGE(itnode->next());
}
//=======================================================================
{
MESSAGE("dump 0D elements of mesh : ");
SMDS_0DElementIteratorPtr it0d = elements0dIterator();
- while(it0d->more()) MESSAGE(it0d->next());
+ while(it0d->more()) ; //MESSAGE(it0d->next());
}
//=======================================================================
{
MESSAGE("dump edges of mesh : ");
SMDS_EdgeIteratorPtr itedge=edgesIterator();
- while(itedge->more()) MESSAGE(itedge->next());
+ while(itedge->more()) ; //MESSAGE(itedge->next());
}
//=======================================================================
{
MESSAGE("dump faces of mesh : ");
SMDS_FaceIteratorPtr itface=facesIterator();
- while(itface->more()) MESSAGE(itface->next());
+ while(itface->more()) ; //MESSAGE(itface->next());
}
//=======================================================================
{
MESSAGE("dump volumes of mesh : ");
SMDS_VolumeIteratorPtr itvol=volumesIterator();
- while(itvol->more()) MESSAGE(itvol->next());
+ while(itvol->more()) ; //MESSAGE(itvol->next());
}
//=======================================================================
///////////////////////////////////////////////////////////////////////////////
int SMDS_Mesh::NbNodes() const
{
- return myNodes.Size();
+ //MESSAGE(myGrid->GetNumberOfPoints());
+ //MESSAGE(myInfo.NbNodes());
+ //MESSAGE(myNodeMax);
+ return myInfo.NbNodes();
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int SMDS_Mesh::Nb0DElements() const
{
- return my0DElements.Size();
+ return myInfo.Nb0DElements(); // -PR- a verfier
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int SMDS_Mesh::NbEdges() const
{
- return myEdges.Size();
+ return myInfo.NbEdges(); // -PR- a verfier
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int SMDS_Mesh::NbFaces() const
{
- return myFaces.Size();
+ return myInfo.NbFaces(); // -PR- a verfier
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int SMDS_Mesh::NbVolumes() const
{
- return myVolumes.Size();
+ return myInfo.NbVolumes(); // -PR- a verfier
}
///////////////////////////////////////////////////////////////////////////////
{
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;
+// }
}
//================================================================================
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<SMDS_VtkEdge*>(elem));
+ break;
+ case SMDSAbs_Face:
+ myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
+ break;
+ case SMDSAbs_Volume:
+ myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(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<SMDS_Mesh*>::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();
}
///////////////////////////////////////////////////////////////////////////////
namespace {
- ///////////////////////////////////////////////////////////////////////////////
- ///Iterator on NCollection_Map
- ///////////////////////////////////////////////////////////////////////////////
- template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
- struct MYNCollection_Map_Iterator: public FATHER
+///////////////////////////////////////////////////////////////////////////////
+///Iterator on NCollection_Map
+///////////////////////////////////////////////////////////////////////////////
+template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
+struct MYNode_Map_Iterator: public FATHER
+{
+ int _ctr;
+ const MAP& _map;
+ MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
{
- 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 <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
+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<ELEM>
+ {
+ _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<ELEM> (_map[_ctr]);
+ _ctr++;
+ return current;
+ }
+};
+
+//================================================================================
/*!
* \brief Iterator on elements in id increasing order
*/
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)));
}
///////////////////////////////////////////////////////////////////////////////
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)));
}
///////////////////////////////////////////////////////////////////////////////
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)));
}
///////////////////////////////////////////////////////////////////////////////
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)));
}
///////////////////////////////////////////////////////////////////////////////
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)));
}
///////////////////////////////////////////////////////////////////////////////
{
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();
}
///////////////////////////////////////////////////////////////////////////////
-/// 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<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
{
int i=0;
while(itNodes->more())
{
- const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+ const SMDS_MeshElement* node = itNodes->next();
+ MYASSERT(node);
+ const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
//initSet[i]=set<const SMDS_MeshElement*>();
while(itFe->more())
- initSet[i].insert(itFe->next());
+ {
+ const SMDS_MeshElement* elem = itFe->next();
+ MYASSERT(elem);
+ initSet[i].insert(elem);
+
+ }
i++;
}
set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+ MESSAGE("nb elems " << i << " intersection " << retSet->size());
delete [] initSet;
return retSet;
}
switch(element->GetType())
{
case SMDSAbs_Node:
- MESSAGE("Internal Error: This should not happend");
+ MESSAGE("Internal Error: This should not happen");
break;
case SMDSAbs_0DElement:
{
///////////////////////////////////////////////////////////////////////////////
///@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,
list<const SMDS_MeshElement *>& removedNodes,
bool removenodes)
{
+ //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
// get finite elements built on elem
set<const SMDS_MeshElement*> * s1;
- if (elem->GetType() == SMDSAbs_0DElement ||
- elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
- elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
- elem->GetType() == SMDSAbs_Volume)
- {
- s1 = new set<const SMDS_MeshElement*>();
- 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<const SMDS_MeshElement*> ();
+ s1->insert(elem);
+ }
else
s1 = getFinitElements(elem);
// get exclusive nodes (which would become free afterwards)
set<const SMDS_MeshElement*> * s2;
if (elem->GetType() == SMDSAbs_Node) // a node is removed
- {
- // do not remove nodes except elem
- s2 = new set<const SMDS_MeshElement*>();
- s2->insert(elem);
- removenodes = true;
- }
+ {
+ // do not remove nodes except elem
+ s2 = new set<const SMDS_MeshElement*> ();
+ s2->insert(elem);
+ removenodes = true;
+ }
else
s2 = getExclusiveNodes(*s1);
// form the set of finite and construction elements to remove
set<const SMDS_MeshElement*> s3;
- set<const SMDS_MeshElement*>::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 <InverseElements> of its nodes
- SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
- while(itn->more())
+ set<const SMDS_MeshElement*>::iterator it = s1->begin();
+ while (it != s1->end())
{
- SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
- (const_cast<SMDS_MeshElement *>(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<SMDS_Mesh0DElement*>
- (const_cast<SMDS_MeshElement*>(*it)));
- //myInfo.Remove0DElement(*it);
- myInfo.remove(*it);
- break;
- case SMDSAbs_Edge:
- myEdges.Remove(static_cast<SMDS_MeshEdge*>
- (const_cast<SMDS_MeshElement*>(*it)));
- myInfo.RemoveEdge(*it);
- break;
- case SMDSAbs_Face:
- myFaces.Remove(static_cast<SMDS_MeshFace*>
- (const_cast<SMDS_MeshElement*>(*it)));
- myInfo.RemoveFace(*it);
- break;
- case SMDSAbs_Volume:
- myVolumes.Remove(static_cast<SMDS_MeshVolume*>
- (const_cast<SMDS_MeshElement*>(*it)));
- myInfo.RemoveVolume(*it);
- break;
+ // Remove element from <InverseElements> of its nodes
+ SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
+ while (itn->more())
+ {
+ SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (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<const SMDS_VtkEdge*>(*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<const SMDS_VtkFace*>(*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<const SMDS_VtkVolume*>(*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<SMDS_MeshNode*>
- (const_cast<SMDS_MeshElement*>(*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<const SMDS_MeshNode*>(*it))
+ myNodePool->destroy((SMDS_MeshNode*) vtkElem);
+ else
+ delete (*it);
+ it++;
+ }
}
- }
delete s2;
delete s1;
///////////////////////////////////////////////////////////////////////////////
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<const SMDS_MeshNode*>(elem);
+ const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
if (!itFe->more()) { // free node
- myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
+ myNodes[elemId] = 0;
myInfo.myNbNodes--;
- myNodeIDFactory->ReleaseID(elem->GetID());
- delete elem;
+ myNodePool->destroy(static_cast<SMDS_MeshNode*>(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 <InverseElements> of its nodes
SMDS_ElemIteratorPtr itn = elem->nodesIterator();
while (itn->more()) {
}
// in meshes without descendants elements are always free
- switch (aType) {
+ switch (aType) {
case SMDSAbs_0DElement:
- my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
- (const_cast<SMDS_MeshElement*>(elem)));
- //myInfo.Remove0DElement(elem);
+ myCells[elemId] = 0;
myInfo.remove(elem);
+ delete elem;
break;
case SMDSAbs_Edge:
- myEdges.Remove(static_cast<SMDS_MeshEdge*>
- (const_cast<SMDS_MeshElement*>(elem)));
+ myCells[elemId] = 0;
myInfo.RemoveEdge(elem);
+ myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
break;
case SMDSAbs_Face:
- myFaces.Remove(static_cast<SMDS_MeshFace*>
- (const_cast<SMDS_MeshElement*>(elem)));
+ myCells[elemId] = 0;
myInfo.RemoveFace(elem);
+ myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
break;
case SMDSAbs_Volume:
- myVolumes.Remove(static_cast<SMDS_MeshVolume*>
- (const_cast<SMDS_MeshElement*>(elem)));
+ myCells[elemId] = 0;
myInfo.RemoveVolume(elem);
+ myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(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
}
}
int SMDS_Mesh::MaxNodeID() const
{
- return myNodeIDFactory->GetMaxID();
+ return myNodeMax;
}
//=======================================================================
int SMDS_Mesh::MinNodeID() const
{
- return myNodeIDFactory->GetMinID();
+ return myNodeMin;
}
//=======================================================================
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
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<SMDS_MeshNode*>(n1);
- node2 = const_cast<SMDS_MeshNode*>(n2);
- node12 = const_cast<SMDS_MeshNode*>(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<vtkIdType> 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;
+
}
// 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<vtkIdType> 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;
}
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<vtkIdType> 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;
}
// 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<vtkIdType> 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;
}
// 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<vtkIdType> 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;
}
// 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<vtkIdType> 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;
}
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<vtkIdType> 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<myNodes.size()))
+ myNodeMin++;
+ myNodeMax=myNodes.size()-1;
+ while (!myNodes[myNodeMax] && (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; i<nbPoints; i++)
+ {
+ ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
+ }
+ int nbCells = myGrid->GetNumberOfCells();
+ ficcon << "-------------------------------- cells " << nbCells << endl;
+ for (int i=0; i<nbCells; i++)
+ {
+// MESSAGE(i << " " << myGrid->GetCell(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; j<nbptcell; j++)
+ {
+ ficcon << " " << listid->GetId(j);
+ }
+ ficcon << endl;
+ }
+ ficcon << "-------------------------------- connectivity " << nbPoints << endl;
+ vtkCellLinks *links = myGrid->GetCellLinks();
+ for (int i=0; i<nbPoints; i++)
+ {
+ int ncells = links->GetNcells(i);
+ vtkIdType *cells = links->GetCells(i);
+ ficcon << i << " - " << ncells << " -";
+ for (int j=0; j<ncells; j++)
+ {
+ ficcon << " " << cells[j];
+ }
+ ficcon << endl;
+ }
+ ficcon.close();
+
+}
+
+void SMDS_Mesh::compactMesh()
+{
+ MESSAGE("SMDS_Mesh::compactMesh do nothing!");
+}
+
+int SMDS_Mesh::fromVtkToSmds(int vtkid)
+{
+ if (vtkid >= 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;
}
#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 <NCollection_Map.hxx>
+#include "SMDS_VolumeOfNodes.hxx"
+#include "SMDS_VtkEdge.hxx"
+#include "SMDS_VtkFace.hxx"
+#include "SMDS_VtkVolume.hxx"
+#include "ObjectPool.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
#include <boost/shared_ptr.hpp>
#include <set>
#include <list>
+#include <vector>
+#include <vtkSystemIncludes.h>
+
+#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<SMDS_Mesh*> _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;
(std::vector<const SMDS_MeshNode*> nodes,
std::vector<int> quantities);
+ virtual SMDS_MeshVolume* AddVolumeFromVtkIds(const std::vector<int>& vtkNodeIds);
+
+ virtual SMDS_MeshVolume* AddVolumeFromVtkIdsWithID(const std::vector<int>& vtkNodeIds,
+ const int ID);
+
virtual void RemoveElement(const SMDS_MeshElement * elem,
std::list<const SMDS_MeshElement *>& removedElems,
std::list<const SMDS_MeshElement *>& removedNodes,
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;
*/
bool Contains (const SMDS_MeshElement* elem) const;
- typedef NCollection_Map<SMDS_MeshNode *> SetOfNodes;
- typedef NCollection_Map<SMDS_Mesh0DElement *> SetOf0DElements;
- typedef NCollection_Map<SMDS_MeshEdge *> SetOfEdges;
- typedef NCollection_Map<SMDS_MeshFace *> SetOfFaces;
- typedef NCollection_Map<SMDS_MeshVolume *> SetOfVolumes;
+ typedef std::vector<SMDS_MeshNode *> SetOfNodes;
+ typedef std::vector<SMDS_MeshCell *> 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,
const SMDS_MeshElement * element,
std::set<const SMDS_MeshElement*>& 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<SMDS_Mesh*> _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<SMDS_MeshNode>* myNodePool;
+
+ //! Small objects like SMDS_VtkVolume are allocated by chunks to limit memory costs of new
+ ObjectPool<SMDS_VtkVolume>* myVolumePool;
+ ObjectPool<SMDS_VtkFace>* myFacePool;
+ ObjectPool<SMDS_VtkEdge>* 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<int> myCellIdSmdsToVtk;
+
+ //! for cells only: index = ID in vtkUnstructuredGrid, value = ID for SMDS users
+ std::vector<int> myCellIdVtkToSmds;
+
SMDS_Mesh * myParent;
std::list<SMDS_Mesh *> 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;
};
#include "SMDS_Mesh0DElement.hxx"
#include "SMDS_IteratorOfElements.hxx"
#include "SMDS_MeshNode.hxx"
+#include "utilities.h"
using namespace std;
//purpose :
//=======================================================================
SMDS_Mesh0DElement::SMDS_Mesh0DElement (const SMDS_MeshNode * node)
-{
+{
+ MESSAGE("SMDS_Mesh0DElement " << GetID());
myNode = node;
}
return SMDSAbs_0DElement;
}
+vtkIdType SMDS_Mesh0DElement::GetVtkType() const
+{
+ return VTK_VERTEX;
+}
+
//=======================================================================
//function : elementsIterator
//purpose :
//=======================================================================
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);
}
#include "SMESH_SMDS.hxx"
-#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshCell.hxx"
#include <iostream>
-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;
--- /dev/null
+#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--;
+}
--- /dev/null
+#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
-// 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<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_MeshEdge::GetNode(const int ind) const
-{
- return myNodes[ ind ];
-}
-
-//=======================================================================
-//function : ChangeNodes
-//purpose :
-//=======================================================================
-
-bool SMDS_MeshEdge::ChangeNodes(const SMDS_MeshNode * node1,
- const SMDS_MeshNode * node2)
+vtkIdType SMDS_MeshEdge::GetVtkType() const
{
- myNodes[0]=node1;
- myNodes[1]=node2;
- return true;
+ return VTK_POLY_VERTEX; // --- must be reimplemented in derived classes
}
#include "SMESH_SMDS.hxx"
-#include "SMDS_MeshElement.hxx"
-#include <iostream>
+#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
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)
{
}
return myElement;
}
};
+
SMDS_ElemIteratorPtr SMDS_MeshElement::
elementsIterator(SMDSAbs_ElementType type) const
{
}
}
-///////////////////////////////////////////////////////////////////////////////
-///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)
#include <vector>
#include <iostream>
+#include <vtkType.h>
+#include <vtkCellType.h>
+
+//typedef unsigned short UShortType;
+typedef short ShortType;
+
class SMDS_MeshNode;
class SMDS_MeshEdge;
-class SMDS_MeshFace;
+class SMDS_MeshFace;
+class SMDS_Mesh;
// ============================================================
/*!
*/
// ============================================================
+
class SMDS_EXPORT SMDS_MeshElement:public SMDS_MeshObject
{
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;
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;
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
*/
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
#include "SMDS_MeshElementIDFactory.hxx"
#include "SMDS_MeshElement.hxx"
+#include "SMDS_Mesh.hxx"
+
+#include "utilities.h"
+
+#include <SMDS_UnstructuredGrid.hxx>
+#include <vtkCellType.h>
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<SMDS_MeshCell*>(elem);
+ assert(cell);
+ vector<vtkIdType> nodeIds;
+ SMDS_ElemIteratorPtr it = elem->nodesIterator();
+ while(it->more())
+ {
+ int nodeId = (static_cast<const SMDS_MeshNode*>(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;
}
//=======================================================================
{
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;
}
//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];
+}
#include "SMESH_SMDS.hxx"
-#include "SMDS_MeshIDFactory.hxx"
-#include "SMDS_ElemIterator.hxx"
+#include "SMDS_MeshNodeIDFactory.hxx"
-#include <NCollection_DataMap.hxx>
+#include <vector>
class SMDS_MeshElement;
+class SMDS_Mesh;
-typedef NCollection_DataMap<int, SMDS_MeshElement *> 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
{
if (id < myMin) myMin = id;
}
- SMDS_IdElementMap myIDElements;
- mutable int myMin, myMax;
+ std::vector<int> myVtkCellTypes;
};
{
return SMDSAbs_Face;
}
+
+vtkIdType SMDS_MeshFace::GetVtkType() const
+{
+ return VTK_POLY_LINE; // --- must be reimplemented in derived classes
+}
#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
// Module : SMESH
//
#include "SMDS_MeshIDFactory.hxx"
+#include "SMDS_Mesh.hxx"
+#include "utilities.h"
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<int>::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 )
{
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();
}
+
#include "SMDS_MeshObject.hxx"
#include <set>
+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<int> 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<int> myPoolOfID;
+ SMDS_Mesh *myMesh;
};
#endif
#include "SMDS_MeshNode.hxx"
#include "SMDS_SpacePosition.hxx"
#include "SMDS_IteratorOfElements.hxx"
+#include "SMDS_Mesh.hxx"
+#include <vtkUnstructuredGrid.h>
+
+#define protected public
+#include <vtkCellLinks.h>
+#define protected protected
+
+#include "utilities.h"
+#include "Utils_SALOME_Exception.hxx"
+#include <cassert>
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--;
}
//=======================================================================
void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent)
{
- NCollection_List<const SMDS_MeshElement*>::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<const SMDS_MeshCell*>(parent);
+ MYASSERT(cell);
+ SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId());
}
//=======================================================================
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;
}
//=======================================================================
*/
//=======================================================================
-class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator
+class SMDS_MeshNode_MyInvIterator: public SMDS_ElemIterator
{
- NCollection_List<const SMDS_MeshElement*>::Iterator myIterator;
- SMDSAbs_ElementType myType;
- public:
- SMDS_MeshNode_MyInvIterator(const NCollection_List<const SMDS_MeshElement*>& s,
- SMDSAbs_ElementType type):
- myIterator(s), myType(type)
- {}
+private:
+ SMDS_Mesh* myMesh;
+ vtkIdType* myCells;
+ int myNcells;
+ SMDSAbs_ElementType myType;
+ int iter;
+ vector<vtkIdType> 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="<<myNcells);
+ }
bool more()
{
- if ( myType != SMDSAbs_All ) {
- while ( myIterator.More() && myIterator.Value()->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<const SMDS_MeshElement*> mySet;
- NCollection_List<const SMDS_MeshElement*>::Iterator myIterator;
+private:
+ SMDS_Mesh* myMesh;
+ vtkIdType* myCells;
+ int myNcells;
+ SMDSAbs_ElementType myType;
+ int iter;
+ vector<SMDS_MeshElement*> myFiltCells;
+
public:
- SMDS_MeshNode_MyIterator(SMDSAbs_ElementType type,
- const NCollection_List<const SMDS_MeshElement*>& 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<const SMDS_MeshElement*>::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 (; iter<ncells; iter++)
+ {
+ int vtkId = myCells[iter];
+ int smdsId = myMesh->fromVtkToSmds(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;
}
};
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
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
return SMDSAbs_Node;
}
+vtkIdType SMDS_MeshNode::GetVtkType() const
+{
+ return VTK_VERTEX;
+}
+
//=======================================================================
//function : AddInverseElement
//purpose :
//=======================================================================
void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME)
{
- NCollection_List<const SMDS_MeshElement*>::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<const SMDS_MeshCell*>(ME);
+ assert(cell);
+ SMDS_Mesh::_meshList[myMeshId]->getGrid()->AddReferenceToCell(myVtkID, cell->getVtkId());
}
//=======================================================================
//=======================================================================
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);
}
//================================================================================
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<const SMDS_MeshElement*>::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; i<l.ncells; i++)
+ {
+ const SMDS_MeshElement* elem = mesh->FindElement(mesh->fromVtkToSmds(l.cells[i]));
+ if (elem->GetType() == type)
+ nb++;
+ }
return nb;
}
///////////////////////////////////////////////////////////////////////////////
bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2)
{
- return e1.GetID()<e2.GetID();
+ return e1.getVtkId()<e2.getVtkId();
/*if(e1.myX<e2.myX) return true;
else if(e1.myX==e2.myX)
{
#include "SMDS_MeshElement.hxx"
#include "SMDS_Position.hxx"
+#include "ObjectPool.hxx"
#include <NCollection_List.hxx>
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<SMDS_MeshNode>;
+ 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<const SMDS_MeshElement*> myInverseElements;
};
#endif
--- /dev/null
+// 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 <vtkUnstructuredGrid.h>
+#include <vtkCellType.h>
+
+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;
+}
--- /dev/null
+// 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 <vector>
+
+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
return SMDSAbs_Volume;
}
+vtkIdType SMDS_MeshVolume::GetVtkType() const
+{
+ return VTK_CONVEX_POINT_SET; // --- must be reimplemented in derived classes
+}
#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
SMDS_PolygonalFaceOfNodes::SMDS_PolygonalFaceOfNodes
(std::vector<const SMDS_MeshNode *> nodes)
{
+ //MESSAGE("******************************************** SMDS_PolygonalFaceOfNodes");
myNodes = nodes;
}
vector<int> quantities)
: SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL)
{
+ //MESSAGE("****************************************** SMDS_PolyhedralVolumeOfNodes");
ChangeNodes(nodes, quantities);
}
// 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 ");
}
//=======================================================================
#include <boost/shared_ptr.hpp>
class SMDS_Position;
-typedef boost::shared_ptr<SMDS_Position> SMDS_PositionPtr;
+//typedef boost::shared_ptr<SMDS_Position> 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();
};
#include "SMDS_SetIterator.hxx"
#include "SMDS_IteratorOfElements.hxx"
#include "SMDS_MeshNode.hxx"
+#include "utilities.h"
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;
}
#include "SMESH_SMDS.hxx"
-#include "SMDS_MeshEdge.hxx"
+#include "SMDS_LinearEdge.hxx"
#include <iostream>
-class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_MeshEdge
+class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_LinearEdge
{
public:
const SMDS_MeshNode * n23,
const SMDS_MeshNode * n31)
{
+ //MESSAGE("********************************************** SMDS_QuadraticFaceOfNodes 1");
myNodes.resize( 6 );
myNodes[ 0 ] = n1;
myNodes[ 1 ] = n2;
const SMDS_MeshNode * n34,
const SMDS_MeshNode * n41)
{
+ //MESSAGE("********************************************* SMDS_QuadraticFaceOfNodes 2");
myNodes.resize( 8 );
myNodes[ 0 ] = n1;
myNodes[ 1 ] = n2;
const SMDS_MeshNode * n24,
const SMDS_MeshNode * n34)
{
+ //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
myNodes.resize( 10 );
myNodes[ 0 ] = n1;
myNodes[ 1 ] = n2;
const SMDS_MeshNode * n35,
const SMDS_MeshNode * n45)
{
+ //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
myNodes.resize( 13 );
myNodes[ 0 ] = n1;
myNodes[ 1 ] = n2;
const SMDS_MeshNode * n25,
const SMDS_MeshNode * n36)
{
+ //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
myNodes.resize( 15 );
myNodes[ 0 ] = n1;
myNodes[ 1 ] = n2;
const SMDS_MeshNode * n37,
const SMDS_MeshNode * n48)
{
+ //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
myNodes.resize( 20 );
myNodes[ 0 ] = n1;
myNodes[ 1 ] = n2;
// 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;
}
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
--- /dev/null
+#define CHRONODEF
+#include "SMDS_UnstructuredGrid.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshInfo.hxx"
+#include "SMDS_Downward.hxx"
+
+#include "utilities.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellLinks.h>
+#include <vtkIdTypeArray.h>
+#include <vtkUnsignedCharArray.h>
+
+#include <list>
+
+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<vtkIdType> 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<vtkIdType>::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<int>& idNodesOldToNew, int newNodeSize,
+ std::vector<int>& 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<int>& 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<int>& idCellsOldToNew,
+ std::vector<int>& 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<SMDS_Down2D*> (_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<SMDS_Down3D*> (_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<SMDS_Down2D*> (_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<SMDS_Down3D*> (_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<SMDS_Down1D*> (_downArray[vtkEdgeType]);
+ downEdge->setNodes(connEdgeId, vtkEdgeId);
+ vector<int> 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<SMDS_Down2D*> (_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<int> vtkIds;
+ unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType;
+ int *pts = &edgesWithNodes.elems[iedge].nodeIds[0];
+ SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_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<SMDS_Down2D*> (_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<SMDS_Down2D*> (_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<vector int>> by a single vector<int>
+ // 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<int>& 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<int, int> 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<int>& orderedNodes)
+{
+ int vtkType = this->GetCellType(vtkVolId);
+ int cellDim = SMDS_Downward::getCellDimension(vtkType);
+ if (cellDim != 3)
+ return 0;
+ SMDS_Down3D *downvol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
+ int downVolId = this->_cellIdToDownId[vtkVolId];
+ downvol->getOrderedNodesOfFace(downVolId, orderedNodes);
+ return orderedNodes.size();
+}
+
--- /dev/null
+/*
+ * File: SMDS_UnstructuredGrid.hxx
+ * Author: prascle
+ *
+ * Created on September 16, 2009, 10:28 PM
+ */
+
+#ifndef _SMDS_UNSTRUCTUREDGRID_HXX
+#define _SMDS_UNSTRUCTUREDGRID_HXX
+
+#include <vtkUnstructuredGrid.h>
+#include "chrono.hxx"
+
+#include <vector>
+#include <set>
+#include <map>
+
+//#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<int>& idNodesOldToNew, int newNodeSize, std::vector<int>& 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<int>& nodeSet, int downId, unsigned char downType);
+ void ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds);
+ int getOrderedNodesOfFace(int vtkVolId, std::vector<int>& 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<int>& idNodesOldToNew, int& alreadyCopied, int start, int end);
+ void copyBloc(vtkUnsignedCharArray *newTypes, std::vector<int>& idCellsOldToNew, std::vector<int>& idNodesOldToNew,
+ vtkCellArray* newConnectivity, vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied,
+ int start, int end);
+
+ std::vector<int> _cellIdToDownId; //!< convert vtk Id to downward[vtkType] id, initialized with -1
+ std::vector<unsigned char> _downTypes;
+ std::vector<SMDS_Downward*> _downArray;
+};
+
+#endif /* _SMDS_UNSTRUCTUREDGRID_HXX */
+
//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;
}
public:
SMDS_TypeOfPosition GetTypeOfPosition() const;
- SMDS_VertexPosition(int aVertexId=0);
- const double *Coords() const;
+ SMDS_VertexPosition();
};
#endif
#include "SMDS_VolumeOfFaces.hxx"
#include "SMDS_IteratorOfElements.hxx"
+#include "utilities.h"
using namespace std;
const SMDS_MeshFace * face3,
const SMDS_MeshFace * face4)
{
+ //MESSAGE("****************************************************** SMDS_VolumeOfFaces");
myNbFaces = 4;
myFaces[0]=face1;
myFaces[1]=face2;
const SMDS_MeshFace * face4,
const SMDS_MeshFace * face5)
{
+ //MESSAGE("****************************************************** SMDS_VolumeOfFaces");
myNbFaces = 5;
myFaces[0]=face1;
myFaces[1]=face2;
const SMDS_MeshFace * face5,
const SMDS_MeshFace * face6)
{
+ //MESSAGE("****************************************************** SMDS_VolumeOfFaces");
myNbFaces = 6;
myFaces[0]=face1;
myFaces[1]=face2;
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:
#include "SMDS_MeshNode.hxx"
#include "SMDS_SetIterator.hxx"
#include "SMDS_VolumeTool.hxx"
+#include "SMDS_Mesh.hxx"
#include "utilities.h"
-#include <vector>
-
using namespace std;
///////////////////////////////////////////////////////////////////////////////
const SMDS_MeshNode * node7,
const SMDS_MeshNode * node8)
{
+ //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
myNbNodes = 8;
myNodes = new const SMDS_MeshNode* [myNbNodes];
myNodes[0]=node1;
const SMDS_MeshNode * node3,
const SMDS_MeshNode * node4)
{
+ //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
myNbNodes = 4;
myNodes = new const SMDS_MeshNode* [myNbNodes];
myNodes[0]=node1;
const SMDS_MeshNode * node4,
const SMDS_MeshNode * node5)
{
+ //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
myNbNodes = 5;
myNodes = new const SMDS_MeshNode* [myNbNodes];
myNodes[0]=node1;
const SMDS_MeshNode * node5,
const SMDS_MeshNode * node6)
{
+ //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
myNbNodes = 6;
myNodes = new const SMDS_MeshNode* [myNbNodes];
myNodes[0]=node1;
}
}
-//=======================================================================
-//function : Print
-//purpose :
-//=======================================================================
-
void SMDS_VolumeOfNodes::Print(ostream & OS) const
{
OS << "volume <" << GetID() << "> : ";
return 0;
}
-/// ===================================================================
/*!
* \brief Iterator on node of volume
*/
-/// ===================================================================
-
class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
{
public:
SMDS_NodeArrayElemIterator( s, & s[ l ]) {}
};
-/// ===================================================================
/*!
* \brief Iterator on faces or edges of volume
*/
-/// ===================================================================
-
class _MySubIterator : public SMDS_ElemIterator
{
vector< const SMDS_MeshElement* > myElems;
}
return aType;
}
+
+
elementsIterator(SMDSAbs_ElementType type) const;
const SMDS_MeshNode** myNodes;
int myNbNodes;
+
};
+
#endif
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_VtkVolume.hxx"
#include "SMDS_Mesh.hxx"
#include "utilities.h"
myFaceNodeIndices( NULL ),
myFaceNodes( NULL )
{
+ //MESSAGE("******************************************************** SMDS_VolumeToo");
}
//=======================================================================
myFaceNodeIndices( NULL ),
myFaceNodes( NULL )
{
+ //MESSAGE("******************************************************** SMDS_VolumeToo");
Set( theVolume );
}
}
if (myVolume->IsPoly()) {
- myPolyedre = static_cast<const SMDS_PolyhedralVolumeOfNodes*>( myVolume );
+ myPolyedre = dynamic_cast<const SMDS_VtkVolume*>( myVolume );
if (!myPolyedre) {
MESSAGE("Warning: bad volumic element");
return false;
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 )
{
double Vn = getTetraVolume( myFaceNodes[ 0 ],
myFaceNodes[ n-1 ],
myFaceNodes[ n ],
- & bcNode );
+ bcNode );
/// cout <<"++++ " << Vn << " nodes " <<myFaceNodes[ 0 ]->GetID() << " " <<myFaceNodes[ n-1 ]->GetID() << " " <<myFaceNodes[ n ]->GetID() << " < " << V << endl;
V += externalFace ? -Vn : Vn;
}
}
+ mesh->RemoveNode(bcNode);
}
else
{
class SMDS_MeshElement;
class SMDS_MeshNode;
-class SMDS_PolyhedralVolumeOfNodes;
+class SMDS_VtkVolume;
class SMDS_MeshVolume;
#include <vector>
bool setFace( int faceIndex );
const SMDS_MeshElement* myVolume;
- const SMDS_PolyhedralVolumeOfNodes* myPolyedre;
+ const SMDS_VtkVolume* myPolyedre;
bool myVolForward;
int myNbFaces;
--- /dev/null
+#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);
+}
--- /dev/null
+#ifndef _SMDS_VTKCELLITERATOR_HXX_
+#define _SMDS_VTKCELLITERATOR_HXX_
+
+#include "SMDS_ElemIterator.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDSAbs_ElementType.hxx"
+
+#include <vtkCell.h>
+#include <vtkIdList.h>
+
+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
--- /dev/null
+#include "SMDS_VtkEdge.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+#include <cassert>
+
+using namespace std;
+
+SMDS_VtkEdge::SMDS_VtkEdge()
+{
+}
+
+SMDS_VtkEdge::SMDS_VtkEdge(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+ init(nodeIds, mesh);
+}
+
+SMDS_VtkEdge::~SMDS_VtkEdge()
+{
+}
+
+void SMDS_VtkEdge::init(std::vector<vtkIdType> 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()));
+}
--- /dev/null
+#ifndef _SMDS_VTKEDGE_HXX_
+#define _SMDS_VTKEDGE_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshEdge.hxx"
+#include <vtkUnstructuredGrid.h>
+#include <vector>
+
+class SMDS_EXPORT SMDS_VtkEdge: public SMDS_MeshEdge
+{
+
+public:
+ SMDS_VtkEdge();
+ SMDS_VtkEdge(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+ ~SMDS_VtkEdge();
+ void init(std::vector<vtkIdType> 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
--- /dev/null
+#include "SMDS_VtkFace.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+
+using namespace std;
+
+SMDS_VtkFace::SMDS_VtkFace()
+{
+}
+
+SMDS_VtkFace::SMDS_VtkFace(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+ init(nodeIds, mesh);
+}
+
+SMDS_VtkFace::~SMDS_VtkFace()
+{
+}
+
+void SMDS_VtkFace::init(std::vector<vtkIdType> 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<vtkIdType> 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();
+}
--- /dev/null
+#ifndef _SMDS_VTKFACE_HXX_
+#define _SMDS_VTKFACE_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshFace.hxx"
+#include <vtkUnstructuredGrid.h>
+#include <vector>
+
+class SMDS_EXPORT SMDS_VtkFace: public SMDS_MeshFace
+{
+public:
+ SMDS_VtkFace();
+ SMDS_VtkFace(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+ ~SMDS_VtkFace();
+ void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+ void initPoly(std::vector<vtkIdType> 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
--- /dev/null
+#include "SMDS_VtkVolume.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+
+SMDS_VtkVolume::SMDS_VtkVolume()
+{
+}
+
+SMDS_VtkVolume::SMDS_VtkVolume(std::vector<vtkIdType> 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<vtkIdType> 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<vtkIdType> nodeIds, std::vector<int> 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<vtkIdType> 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<int> & SMDS_VtkVolume::GetQuantities() const
+{
+ vector<int> 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()));
+}
--- /dev/null
+#ifndef _SMDS_VTKVOLUME_HXX_
+#define _SMDS_VTKVOLUME_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshVolume.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
+#include <vector>
+
+class SMDS_EXPORT SMDS_VtkVolume: public SMDS_MeshVolume
+{
+public:
+ SMDS_VtkVolume();
+ SMDS_VtkVolume(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+ ~SMDS_VtkVolume();
+ void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+//#ifdef VTK_HAVE_POLYHEDRON
+ void initPoly(std::vector<vtkIdType> nodeIds, std::vector<int> 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<int> & GetQuantities() const;
+
+ virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+ virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
+ virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const;
+
+protected:
+};
+
+#endif
--- /dev/null
+// 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;
+ }
+}
--- /dev/null
+// 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 <vector>
+#include <string>
+#include <iostream>
+#include <ctime>
+
+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_
$(CAS_CPPFLAGS) \
$(MED_CXXFLAGS) \
$(GEOM_CXX_FLAGS) \
+ $(VTK_INCLUDES) \
$(BOOST_CPPFLAGS) \
@HDF5_INCLUDES@ \
-I$(srcdir)/../Controls \
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 )) {
if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
return false;
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
if ( !paramSet.insert( epos->GetUParameter() ).second )
return false; // equal parameters
}
if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
return false;
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
theNodes.insert( make_pair( epos->GetUParameter(), node ));
+ //MESSAGE("U " << epos->GetUParameter() << " ID " << node->GetID());
++nbNodes;
}
}
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 )
// 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"
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include "memoire.h"
+
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);
}
//=============================================================================
TSetOfInt* aShapesId)
{
MESSAGE("SMESH_Gen::Compute");
+ MEMOSTAT;
bool ret = true;
else if ( aShapesId )
aShapesId->insert( smToCompute->GetId() );
}
+ //aMesh.GetMeshDS()->Modified();
return ret;
}
else
}
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<int> listind = myMesh->SubMeshIndices();
+ list<int>::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;
}
#include "SMESH_3D_Algo.hxx"
#include "SMESH_Mesh.hxx"
+#include "chrono.hxx"
+
#include <TopoDS_Shape.hxx>
#include <map>
int _segmentation;
// default of segments
int _nbSegments;
+ counters *_counters;
};
#endif
// File : SMESH_Hypothesis.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
+// $Header$
//
#include "SMESH_Hypothesis.hxx"
#include "SMESH_Gen.hxx"
// Created : Mon Apr 12 16:10:22 2004
// Author : Edward AGAPOV (eap)
//
+#define CHRONODEF
#include "SMESH_MeshEditor.hxx"
#include "SMDS_FaceOfNodes.hxx"
#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"
const bool isPoly,
const int ID)
{
+ //MESSAGE("AddElement " <<node.size() << " " << type << " " << isPoly << " " << ID);
SMDS_MeshElement* e = 0;
int nbnode = node.size();
SMESHDS_Mesh* mesh = GetMeshDS();
switch ( type ) {
case SMDSAbs_0DElement:
if ( nbnode == 1 )
- if ( ID ) e = mesh->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);
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);
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],
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 );
}
if ( aMesh->ShapeToMesh().IsNull() )
return 0;
- if ( theElem->GetType() == SMDSAbs_Node ) {
- const SMDS_PositionPtr& aPosition =
- static_cast<const SMDS_MeshNode*>( 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<const SMDS_MeshNode*>( 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 ))
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<const SMDS_FaceOfNodes*>( theTria1 );
- const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( theTria2 );
- if (F1 && F2) {
+ const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( theTria1 );
+ if (!F1) return false;
+ const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( 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 ) |\ |
// 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<const SMDS_QuadraticFaceOfNodes*> (theTria1);
- if(!QF1) return false;
- const SMDS_QuadraticFaceOfNodes* QF2 =
- dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (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)
if ( !findTriangles( theNode1, theNode2, tr1, tr2 ))
return false;
- const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
- //if (!F1) return false;
- const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
- //if (!F2) return false;
- if (F1 && F2) {
+ const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( tr1 );
+ if (!F1) return false;
+ const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( 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 ) |\ |
// 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<const SMDS_QuadraticFaceOfNodes*> (tr1);
- if(!QF1) return false;
- const SMDS_QuadraticFaceOfNodes* QF2 =
- dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr2);
- if(!QF2) return false;
return InverseDiag(tr1,tr2);
}
if ( !findTriangles( theNode1, theNode2, tr1, tr2 ))
return false;
- const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
- //if (!F1) return false;
- const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
- //if (!F2) return false;
- if (F1 && F2) {
+ const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( tr1 );
+ if (!F1) return false;
+ const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( 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<const SMDS_QuadraticFaceOfNodes*> (tr1);
- if(!QF1) return false;
- const SMDS_QuadraticFaceOfNodes* QF2 =
- dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (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)
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] );
bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
{
+ MESSAGE("Reorient");
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
}
case SMDSAbs_Volume: {
if (theElem->IsPoly()) {
- const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
- static_cast<const SMDS_PolyhedralVolumeOfNodes*>( theElem );
+ // TODO reorient vtk polyhedron
+ MESSAGE("reorient vtk polyhedron ?");
+ const SMDS_VtkVolume* aPolyedre =
+ dynamic_cast<const SMDS_VtkVolume*>( theElem );
if (!aPolyedre) {
MESSAGE("Warning: bad volumic element");
return false;
if ( !vTool.Set( theElem ))
return false;
vTool.Inverse();
+ MESSAGE("ChangeElementNodes reorient: check vTool.Inverse");
return GetMeshDS()->ChangeElementNodes( theElem, vTool.GetNodes(), vTool.NbNodes() );
}
}
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 {
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];
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;
}
aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( 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
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];
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];
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 );
}
}
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];
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] );
}
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];
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] );
}
while ( nn++ < nbn ) {
node = static_cast<const SMDS_MeshNode*>( 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())
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;
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() )));
}
}
helper.SetSubShape( face );
list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
- const SMDS_QuadraticFaceOfNodes* QF =
- dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (*elemIt);
- if(QF) {
+ const SMDS_VtkFace* QF =
+ dynamic_cast<const SMDS_VtkFace*> (*elemIt);
+ if(QF && QF->IsQuadratic()) {
vector<const SMDS_MeshNode*> 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; i<QF->NbNodes(); i=i+2) {
const int nbSteps,
SMESH_SequenceOfElemPtr& srcElements)
{
+ //MESSAGE("sweepElement " << nbSteps);
SMESHDS_Mesh* aMesh = GetMeshDS();
// Loop on elem nodes:
}
}
- //cout<<" nbSame = "<<nbSame<<endl;
+ //cerr<<" nbSame = "<<nbSame<<endl;
if ( nbSame == nbNodes || nbSame > 2) {
MESSAGE( " Too many same nodes of element " << elem->GetID() );
//INFOS( " Too many same nodes of element " << elem->GetID() );
}
// make new elements
+ const SMDS_MeshElement* lastElem = elem;
for (int iStep = 0; iStep < nbSteps; iStep++ ) {
// get next nodes
for ( iNode = 0; iNode < nbNodes; iNode++ ) {
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 ];
newElems.push_back( aNewElem );
myLastCreatedElems.Append(aNewElem);
srcElements.Append( elem );
+ lastElem = aNewElem;
}
// set new prev nodes
const int nbSteps,
SMESH_SequenceOfElemPtr& srcElements)
{
+ MESSAGE("makeWalls");
ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
SMESHDS_Mesh* aMesh = GetMeshDS();
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
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:
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
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);
}
}
}
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() )
const int theFlags,
const double theTolerance)
{
+ MESSAGE("ExtrusionSweep " << theMakeGroups << " " << theFlags << " " << theTolerance);
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
const gp_Pnt& theRefPoint,
const bool theMakeGroups)
{
+ MESSAGE("ExtrusionAlongTrack");
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
while ( aItN->more() ) {
const SMDS_MeshNode* pNode = aItN->next();
const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+ static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
double aT = pEPos->GetUParameter();
aPrms.push_back( aT );
}
while ( aItN->more() ) {
const SMDS_MeshNode* pNode = aItN->next();
const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+ static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
double aT = pEPos->GetUParameter();
aPrms.push_back( aT );
}
const SMDS_MeshNode* pNode = aItN->next();
if( pNode==aN1 || pNode==aN2 ) continue;
const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+ static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
double aT = pEPos->GetUParameter();
aPrms.push_back( aT );
}
while ( aItN->more() ) {
const SMDS_MeshNode* pNode = aItN->next();
const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+ static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
double aT = pEPos->GetUParameter();
aPrms.push_back( aT );
}
const gp_Pnt& theRefPoint,
const bool theMakeGroups)
{
+ MESSAGE("MakeExtrElements");
//cout<<"MakeExtrElements fullList.size() = "<<fullList.size()<<endl;
int aNbTP = fullList.size();
vector<SMESH_MeshEditor_PathPoint> aPPs(aNbTP);
}
// 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.;
// source elements for each generated one
SMESH_SequenceOfElemPtr srcElems, srcNodes;
- // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh
- list<SMDS_MeshNode> orphanCopy; // copies of orphan nodes
- vector<const SMDS_MeshNode*> 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 = -<index in orphanNode>
- 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<SMDS_MeshNode> orphanCopy; // copies of orphan nodes
+// vector<const SMDS_MeshNode*> 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 = -<index in orphanNode>
+// 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++ ) {
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<TNodeNodeMap::iterator,bool> n2n_isnew =
nodeMap.insert( make_pair ( node, node ));
theElems.insert( *invElemIt );
// replicate or reverse elements
-
+ // TODO revoir ordre reverse vtk
enum {
REV_TETRA = 0, // = nbNodes - 4
REV_PYRAMID = 1, // = nbNodes - 4
case SMDSAbs_Volume:
{
// ATTENTION: Reversing is not yet done!!!
- const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
- dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+ const SMDS_VtkVolume* aPolyedre =
+ dynamic_cast<const SMDS_VtkVolume*>( elem );
if (!aPolyedre) {
MESSAGE("Warning: bad volumic element");
continue;
return newGroupIDs;
}
+
+////=======================================================================
+////function : Scale
+////purpose :
+////=======================================================================
+//
+//SMESH_MeshEditor::PGroupIDs
+//SMESH_MeshEditor::Scale (TIDSortedElemSet & theElems,
+// const gp_Pnt& thePoint,
+// const std::list<double>& 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<double>::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<TNodeNodeMap::iterator,bool> 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<const SMDS_MeshNode*> poly_nodes (nbNodes);
+// int iNode = 0;
+// SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+// while (itN->more()) {
+// const SMDS_MeshNode* node =
+// static_cast<const SMDS_MeshNode*>(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<const SMDS_VtkVolume*>( elem );
+// if (!aPolyedre) {
+// MESSAGE("Warning: bad volumic element");
+// continue;
+// }
+//
+// vector<const SMDS_MeshNode*> poly_nodes;
+// vector<int> 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<const SMDS_MeshNode*> nodes(nbNodes);
+// int iNode = 0;
+// SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+// while ( itN->more() ) {
+// const SMDS_MeshNode* node =
+// static_cast<const SMDS_MeshNode*>( 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
*/
const SMDS_MeshNode* FindClosestTo( const gp_Pnt& thePnt )
{
- SMDS_MeshNode tgtNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
map<double, const SMDS_MeshNode*> dist2Nodes;
- myOctreeNode->NodesAround( &tgtNode, dist2Nodes, myHalfLeafSize );
+ myOctreeNode->NodesAround( thePnt.Coord(), dist2Nodes, myHalfLeafSize );
if ( !dist2Nodes.empty() )
return dist2Nodes.begin()->second;
list<const SMDS_MeshNode*> nodes;
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() );
meshInfo.NbElements( SMDSAbs_ElementType( complexType )) < 1 )
--complexType;
if ( complexType == SMDSAbs_All ) return 0; // empty mesh
-
double elemSize;
if ( complexType == int( SMDSAbs_Node ))
{
}
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() )
// get ordered nodes
vector< gp_XYZ > xyz;
+ vector<const SMDS_MeshNode*> nodeList;
SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
if ( element->IsQuadratic() )
- if (const SMDS_QuadraticFaceOfNodes* f=dynamic_cast<const SMDS_QuadraticFaceOfNodes*>(element))
+ if (const SMDS_VtkFace* f=dynamic_cast<const SMDS_VtkFace*>(element))
nodeIt = f->interlacedNodesElemIterator();
- else if (const SMDS_QuadraticEdge* e =dynamic_cast<const SMDS_QuadraticEdge*>(element))
+ else if (const SMDS_VtkEdge* e =dynamic_cast<const SMDS_VtkEdge*>(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();
// 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]);
// 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;
}
void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
{
+ MESSAGE("MergeNodes");
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
list<const SMDS_MeshNode*>& nodes = *grIt;
list<const SMDS_MeshNode*>::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 );
}
set<const SMDS_MeshElement*>::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 );
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()) {
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<const SMDS_MeshNode *> polynodes(polygons_nodes.begin()+inode,polygons_nodes.end());
+ int quid =0;
+ if (nbNew > 0) quid = nbNew - 1;
+ vector<int> 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());
rmElemIds.push_back(elem->GetID());
}
else {
- // each face has to be analized in order to check volume validity
- const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
- static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+ // each face has to be analyzed in order to check volume validity
+ const SMDS_VtkVolume* aPolyedre =
+ dynamic_cast<const SMDS_VtkVolume*>( elem );
if (aPolyedre) {
int nbFaces = aPolyedre->NbFaces();
}
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());
}
// Regular elements
+ // TODO not all the possible cases are solved. Find something more generic?
switch ( nbNodes ) {
case 2: ///////////////////////////////////// EDGE
isOk = false; break;
isOk = false;
else if ( nbRepl == 2 && iRepl[ 1 ] - iRepl[ 0 ] == 2 )
isOk = false; // opposite nodes stick
+ //MESSAGE("isOk " << isOk);
}
break;
case 6: ///////////////////////////////////// PENTAHEDRON
// +---+---+
// 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];
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
if ( isOk ) {
if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume) {
// Change nodes of polyedre
- const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
- static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+ const SMDS_VtkVolume* aPolyedre =
+ dynamic_cast<const SMDS_VtkVolume*>( elem );
if (aPolyedre) {
int nbFaces = aPolyedre->NbFaces();
}
}
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 );
}
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;
if ( !face && elem->IsQuadratic())
{
// analysis for quadratic elements using all nodes
- const SMDS_QuadraticFaceOfNodes* F =
- static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+ const SMDS_VtkFace* F =
+ dynamic_cast<const SMDS_VtkFace*>(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++ )
{
vector<const SMDS_MeshNode*> nodes(nbNodes+1);
if(e->IsQuadratic()) {
- const SMDS_QuadraticFaceOfNodes* F =
- static_cast<const SMDS_QuadraticFaceOfNodes*>(e);
+ const SMDS_VtkFace* F =
+ dynamic_cast<const SMDS_VtkFace*>(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 {
// 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<const SMDS_MeshNode*, gp_XYZ> TNodeXYZMap;
TNodeXYZMap nBordXYZ;
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<const SMDS_QuadraticFaceOfNodes*>(elem);
+ const SMDS_VtkFace* F =
+ dynamic_cast<const SMDS_VtkFace*>(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;
}
vector<const SMDS_MeshNode*> nodes( theFace->NbNodes() );
if(theFace->IsQuadratic()) {
- const SMDS_QuadraticFaceOfNodes* F =
- static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+ const SMDS_VtkFace* F =
+ dynamic_cast<const SMDS_VtkFace*>(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 )
bool isFLN = false;
if(theFace->IsQuadratic()) {
- const SMDS_QuadraticFaceOfNodes* F =
- static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+ const SMDS_VtkFace* F =
+ dynamic_cast<const SMDS_VtkFace*>(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;
}
// 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 {
return;
}
+ SMESHDS_Mesh *aMesh = GetMeshDS();
if( !theFace->IsQuadratic() ) {
// put aNodesToInsert between theBetweenNode1 and theBetweenNode2
}
// create new elements
- SMESHDS_Mesh *aMesh = GetMeshDS();
int aShapeId = FindShape( theFace );
i1 = 0; i2 = 1;
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;
// n4 n6 n5 n4
// create new elements
- SMESHDS_Mesh *aMesh = GetMeshDS();
int aShapeId = FindShape( theFace );
int n1,n2,n3;
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
}
- // remove old quadratic face
- aMesh->RemoveElement(theFace);
}
+ // remove old face
+ aMesh->RemoveElement(theFace);
}
//=======================================================================
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<const SMDS_MeshNode *> nodes (elem->begin_nodes(), elem->end_nodes());
if ( elem->GetEntityType() == SMDSEntity_Polyhedra )
- nbNodeInFaces = static_cast<const SMDS_PolyhedralVolumeOfNodes* >( elem )->GetQuanities();
-
- GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false);
+ nbNodeInFaces = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities();
const SMDS_MeshElement* NewElem = 0;
ReplaceElemInGroups( elem, NewElem, GetMeshDS());
if( NewElem )
theSm->AddElement( NewElem );
+
+ GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false);
}
+// if (!GetMeshDS()->isCompacted())
+// GetMeshDS()->compactMesh();
return nbElem;
}
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);
int nbNodes = volume->NbNodes();
vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes());
if ( volume->GetEntityType() == SMDSEntity_Polyhedra )
- nbNodeInFaces = static_cast<const SMDS_PolyhedralVolumeOfNodes* >(volume)->GetQuanities();
+ nbNodeInFaces = static_cast<const SMDS_VtkVolume* >(volume)->GetQuantities();
meshDS->RemoveFreeElement(volume, smDS, /*fromGroups=*/false);
aHelper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh
aHelper.FixQuadraticElements();
}
+ if (!GetMeshDS()->isCompacted())
+ GetMeshDS()->compactMesh();
}
//=======================================================================
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 );
}
// 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<const SMDS_MeshElement*> faceSet1, faceSet2;
set<const SMDS_MeshElement*> volSet1, volSet2;
set<const SMDS_MeshNode*> nodeSet1, nodeSet2;
TIDSortedElemSet * elemSetPtr[] = { &theSide1, &theSide2 };
int iSide, iFace, iNode;
+ list<const SMDS_MeshElement* > tempFaceList;
for ( iSide = 0; iSide < 2; iSide++ ) {
set<const SMDS_MeshNode*> * nodeSet = nodeSetPtr[ iSide ];
TIDSortedElemSet * elemSet = elemSetPtr[ iSide ];
// -----------------------------------------------------------
// 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 <const SMDS_MeshNode*> > setOfFaceNodeSet;
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
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<const SMDS_MeshNode *> 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
fIt++;
}
else
- freeFaceList.erase( fIt++ ); // here fIt++ occures before erase
+ freeFaceList.erase( fIt++ ); // here fIt++ occurs before erase
}
if ( freeFaceList.size() > 1 )
{
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<const SMDS_MeshElement* >::iterator tmpFaceIt = tempFaceList.begin();
+// for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt)
+// aMesh->RemoveElement(*tmpFaceIt);
MESSAGE("Diff nb of faces");
return SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
}
}
}
else { // f->IsQuadratic()
- const SMDS_QuadraticFaceOfNodes* F =
- static_cast<const SMDS_QuadraticFaceOfNodes*>(f);
+ const SMDS_VtkFace* F =
+ dynamic_cast<const SMDS_VtkFace*>(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<const SMDS_MeshNode*>( anIter->next() );
// ====================================================================
// 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<const SMDS_MeshElement* >::iterator tmpFaceIt = tempFaceList.begin();
+// for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt)
+// aMesh->RemoveElement(*tmpFaceIt);
if ( aResult != SEW_OK)
return aResult;
// 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);
+ }
}
}
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();
if ( theIsDoubleElem )
AddElement(newNodes, anElem->GetType(), anElem->IsPoly());
else
+ {
+ MESSAGE("ChangeElementNodes");
theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() );
-
+ }
res = true;
}
return res;
bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes,
const std::list< int >& theListOfModifiedElems )
{
+ MESSAGE("DoubleNodes");
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
const SMDS_MeshElement* anElem = anElemToNodesIter->first;
vector<const SMDS_MeshNode*> aNodeArr = anElemToNodesIter->second;
if ( anElem )
+ {
+ MESSAGE("ChangeElementNodes");
aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() );
+ }
}
return true;
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<TIDSortedElemSet>& 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<DownIdType, std::map<int,int>, DownIdCompare> faceDomains; // 2x(id domain --> id volume)
+ std::map<int, std::map<int,int> > nodeDomains; //oldId -> (domainId -> newId)
+ faceDomains.clear();
+ nodeDomains.clear();
+ std::map<int,int> 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<DownIdType, std::map<int,int>, DownIdCompare>::iterator itface = faceDomains.begin();
+ for( ; itface != faceDomains.end();++itface )
+ {
+ DownIdType face = itface->first;
+ std::map<int,int> domvol = itface->second;
+ std::set<int> oldNodes;
+ oldNodes.clear();
+ grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+ std::set<int>::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<int,int>::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<int> oldNodes;
+ std::set<int>::iterator itn;
+ oldNodes.clear();
+ grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+ std::map<int,int> localClonedNodeIds;
+
+ std::map<int,int> domvol = itface->second;
+ std::map<int,int>::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<int> oldNodes;
+ std::set<int>::iterator itn;
+ oldNodes.clear();
+ grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+ std::map<int,int> localClonedNodeIds;
+
+ std::map<int,int> domvol = itface->second;
+ std::map<int,int>::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
* \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
*/
//================================================================================
vector<TConnectivity> missingBndElems;
TConnectivity nodes;
if ( vTool.Set(elem) ) // elem is a volume ------------------------------------------
- {
+ {
vTool.SetExternalNormal();
for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
{
SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & 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<int> & 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.
const TIDSortedElemSet& theNodesNot,
const TopoDS_Shape& theShape );
+ bool DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& 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 };
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
{
// node has position on face
const SMDS_FacePosition* fpos =
- static_cast<const SMDS_FacePosition*>(n->GetPosition().get());
+ static_cast<const SMDS_FacePosition*>(n->GetPosition());
uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
if ( check )
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
// corresponding edge from face, get pcurve for this
// edge and retrieve value from this pcurve
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
- int edgeID = Pos->GetShapeId();
+ static_cast<const SMDS_EdgePosition*>(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);
}
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 );
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 );
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
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;
// store the fixed UV on the face
if ( myShape.IsSame(F) && shapeID == myShapeID )
const_cast<SMDS_MeshNode*>(n)->SetPosition
- ( SMDS_PositionPtr( new SMDS_FacePosition( shapeID, U, V )));
+ ( SMDS_PositionPtr( new SMDS_FacePosition( U, V )));
}
else if ( uv.Modulus() > numeric_limits<double>::min() )
{
const SMDS_PositionPtr pos = n->GetPosition();
if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
{
- const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( pos.get() );
+ const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( pos );
param = epos->GetUParameter();
}
else if( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX )
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 );
}
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 );
}
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 );
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
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<SMDS_MeshNode*>(n)->SetPosition
- ( SMDS_PositionPtr( new SMDS_EdgePosition( shapeID, U )));
+ ( SMDS_PositionPtr( new SMDS_EdgePosition( U )));
}
else if ( fabs( u ) > numeric_limits<double>::min() )
{
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 );
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)
{
{
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() )
{
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 ));
}
}
}
+
// 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.;
{
meshDS->SetNodeInVolume(n12, myShapeID);
}
+
myTLinkNodeMap.insert( make_pair( link, n12 ));
return n12;
}
// 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"
*/
//====================================================================================
-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();
list<const SMDS_MeshNode*>* Result,
const double precision)
{
- if (isInside(Node,precision))
+ gp_XYZ p(Node->X(), Node->Y(), Node->Z());
+ if (isInside(p, precision))
{
if (isLeaf())
{
*/
//================================================================================
-bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode * node,
+bool SMESH_OctreeNode::NodesAround(const gp_XYZ &node,
map<double, const SMDS_MeshNode*>& dist2Nodes,
double precision)
{
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;
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<const SMDS_MeshNode*>::iterator nIt = myNodes.begin();
for ( ; nIt != myNodes.end(); ++nIt )
{
gp_Pnt p2 ( (*nIt)->X(), (*nIt)->Y(), (*nIt)->Z() );
list<const SMDS_MeshNode*>* 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)
{
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 )
{
// 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 <gp_Pnt.hxx>
#include "SMDS_MeshNode.hxx"
#include <list>
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,
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<double, const SMDS_MeshNode*>& dist2Nodes,
double precision);
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;
}
}
{
const SMDS_MeshNode* node = smdsNode( nIt->next() );
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
double u = epos->GetUParameter();
paramNodeMap.insert( make_pair( u, node ));
}
p->myInitUV = project( node, projector );
else {
const SMDS_FacePosition* pos =
- static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_FacePosition*>(node->GetPosition());
p->myInitUV.SetCoord( pos->GetUParameter(), pos->GetVParameter() );
}
p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
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 ];
// 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 );
{
const SMDS_MeshNode* node = smdsNode( nIt->next() );
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
double u = ( epos->GetUParameter() - f ) / ( l - f );
(*pIt)->myInitXYZ.SetCoord( iCoord, isForward ? u : 1 - u );
}
SMDS_ElemIteratorPtr noIt = elem->nodesIterator();
while ( noIt->more() ) {
SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>(smdsNode( noIt->next() ));
- if (!node->GetPosition()->GetShapeId() &&
+ if (!node->getshapeId() &&
shellNodes.find( node ) == shellNodes.end() ) {
if ( S.ShapeType() == TopAbs_FACE )
aMeshDS->SetNodeOnFace( node, shapeID );
// File : SMESH_subMesh.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
+// $Header$
//
#ifndef _SMESH_SUBMESH_HXX_
#define _SMESH_SUBMESH_HXX_
--- /dev/null
+#ifndef _MEMOIRE_H_
+#define _MEMOIRE_H_
+
+#include <malloc.h>
+#include <iostream>
+
+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
$(MED_CXXFLAGS) \
$(GEOM_CXXFLAGS) \
$(BOOST_CPPFLAGS) \
+ $(VTK_INCLUDES) \
$(CAS_CPPFLAGS) \
$(CORBA_CXXFLAGS) \
$(CORBA_INCLUDES) \
#endif
#ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
#else
static int MYDEBUG = 0;
#endif
mySMESHDSMesh(NULL),
mySMDSMesh(NULL)
{
+ MESSAGE("SMESH_Client::SMESH_Client");
myMeshServer->Register();
CORBA::Boolean anIsEmbeddedMode;
SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*> (pointeur);
if ( MYDEBUG )
MESSAGE("SMESH_Client::SMESH_Client aMesh "<<aMesh);
- if(aMesh->GetMeshDS()->IsEmbeddedMode()){
+ //if(aMesh->GetMeshDS()->IsEmbeddedMode()){
+ if(anIsEmbeddedMode){
mySMESHDSMesh = aMesh->GetMeshDS();
mySMDSMesh = mySMESHDSMesh;
}
{
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;
libSMESHDS_la_CPPFLAGS = \
$(KERNEL_CXXFLAGS) \
$(CAS_CPPFLAGS) \
+ $(VTK_INCLUDES) \
$(BOOST_CPPFLAGS) \
-I$(srcdir)/../SMDS
#include "SMDS_EdgePosition.hxx"
#include "SMDS_FacePosition.hxx"
#include "SMDS_SpacePosition.hxx"
+#include "SMDS_Downward.hxx"
#include "SMESHDS_GroupOnGeom.hxx"
#include <Standard_ErrorHandler.hxx>
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
const SMDS_MeshNode * nodes[],
const int nbnodes)
{
+ MESSAGE("SMESHDS_Mesh::ChangeElementNodes");
if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
return false;
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 );
}
//=======================================================================
{
SMESHDS_SubMesh* subMesh=0;
map<int,SMESHDS_SubMesh*>::iterator SubIt =
- myShapeIndexToSubMesh.find( n->GetPosition()->GetShapeId() );
+ myShapeIndexToSubMesh.find( n->getshapeId() );
if ( SubIt != myShapeIndexToSubMesh.end() )
subMesh = SubIt->second;
else
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;
}
SMESHDS_SubMesh * subMesh,
bool fromGroups)
{
+ //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
if (elt->GetType() == SMDSAbs_Node) {
RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
return;
if ( Index != myCurSubID ) {
map<int,SMESHDS_SubMesh*>::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
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 :
const TopoDS_Shell & S)
{
if ( add( aNode, getSubmesh(S) ))
- aNode->SetPosition ( volumePosition( myCurSubID ));
+ aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
}
+
//=======================================================================
//function : SetNodeOnVolume
//purpose :
const TopoDS_Solid & S)
{
if ( add( aNode, getSubmesh(S) ))
- aNode->SetPosition ( volumePosition( myCurSubID ));
+ aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
}
//=======================================================================
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)));
}
//=======================================================================
double u)
{
if ( add( aNode, getSubmesh(S) ))
- aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u)));
+ aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
}
//=======================================================================
const TopoDS_Vertex & S)
{
if ( add( aNode, getSubmesh(S) ))
- aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID)));
+ aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
}
//=======================================================================
//=======================================================================
void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
{
- if ( aNode && aNode->GetPosition() ) {
- map<int,SMESHDS_SubMesh*>::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<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
+ if (it != myShapeIndexToSubMesh.end())
+ it->second->RemoveNode(aNode, /*deleted=*/false);
+ }
}
//=======================================================================
TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
if (anIter == myShapeIndexToSubMesh.end())
{
- SM = new SMESHDS_SubMesh();
+ SM = new SMESHDS_SubMesh(this, Index);
myShapeIndexToSubMesh[Index]=SM;
}
else
//=======================================================================
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());
}
//=======================================================================
{
//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)));
}
//=======================================================================
{
//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)));
}
//=======================================================================
{
//Set Position on Node
if ( add( aNode, getSubmesh( Index )))
- aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
+ aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
}
//=======================================================================
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<int> 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<int> 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<int> newSmdsToVtk;
+ vector<int> 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<int,SMESHDS_SubMesh*>::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<int,int> 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<int,int>& localClonedNodeIds)
+{
+ //MESSAGE("extrudeVolumeFromFace " << vtkVolId);
+ vector<int> orderedNodes;
+ orderedNodes.clear();
+ map<int, int>::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; i<nbNodes; i++)
+ orderedNodes.push_back(localClonedNodeIds[orderedNodes[i]]);
+ SMDS_MeshVolume *vol = this->AddVolumeFromVtkIds(orderedNodes);
+
+ // TODO update subshape list of elements and nodes
+ return vol;
+}
#include "SMESHDS_DataMapOfShape.hxx"
class SMESHDS_GroupBase;
+class DownIdType;
class SMESHDS_EXPORT SMESHDS_Mesh:public SMDS_Mesh{
public:
bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
std::vector<const SMDS_MeshNode*> nodes,
std::vector<int> quantities);
+ bool ModifyCellNodes(int smdsVolId, std::map<int,int> localClonedNodeIds);
+ bool extrudeVolumeFromFace(int vtkVolId, std::map<int,int>& localClonedNodeIds);
void Renumber (const bool isNodes, const int startID=1, const int deltaID=1);
void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);
bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const;
+ virtual void compactMesh();
+ void BuildDownWardConnectivity(bool withEdges);
+
~SMESHDS_Mesh();
private:
//Update or build submesh
std::map<int,SMESHDS_SubMesh*>::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
}
// $Header:
//
#include "SMESHDS_Script.hxx"
+#include <iostream>
using namespace std;
//=======================================================================
SMESHDS_Script::SMESHDS_Script(bool theIsEmbeddedMode):
myIsEmbeddedMode(theIsEmbeddedMode)
-{}
+{
+ cerr << "=========================== myIsEmbeddedMode " << myIsEmbeddedMode << endl;
+}
//=======================================================================
//function : Destructor
// $Header:
//
#include "SMESHDS_SubMesh.hxx"
+#include "SMESHDS_Mesh.hxx"
#include "utilities.h"
#include "SMDS_SetIterator.hxx"
+#include <iostream>
+#include <cassert>
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);
+ }
}
//=======================================================================
//=======================================================================
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;
}
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());
}
//=======================================================================
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;
}
//=======================================================================
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 SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
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 SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
return nbElems;
}
-// =====================
-// class MySetIterator
-// =====================
-
-template<class ELEM, typename TSET> class MySetIterator:
- public SMDS_SetIterator<ELEM, typename TSET::const_iterator >
+/*!
+ * 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 ELEM, typename TSET> class MySetIterator : public SMDS_Iterator<ELEM>
{
- typedef SMDS_SetIterator<ELEM, typename TSET::const_iterator > 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;
+ }
};
// =====================
{
if ( IsComplexSubmesh() )
return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
-
- return SMDS_ElemIteratorPtr(new MySetIterator<const SMDS_MeshElement*,TElemSet>(myElements));
+ return SMDS_ElemIteratorPtr(new MySetIterator<const SMDS_MeshElement*, std::vector<const SMDS_MeshElement*> >(myElements));
}
//=======================================================================
if ( IsComplexSubmesh() )
return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
- return SMDS_NodeIteratorPtr(new MySetIterator<const SMDS_MeshNode*,TElemSet>(myNodes));
+ return SMDS_NodeIteratorPtr(new MySetIterator<const SMDS_MeshNode*, std::vector<const SMDS_MeshNode*> >(myNodes));
}
//=======================================================================
{
// DO NOT TRY TO FIND A REMOVED ELEMENT !!
//if ( IsComplexSubmesh() || !ME )
- if (!ME )
- return false;
-
- if ( IsComplexSubmesh() )
- {
- set<const SMESHDS_SubMesh*>::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 SMESHDS_SubMesh*>::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;
}
//=======================================================================
{
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<const SMDS_MeshElement*> 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<const SMDS_MeshNode*> 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());
+}
#include "SMDS_Mesh.hxx"
#include <set>
+#include <vector>
class SMESHDS_SubMesh;
typedef SMDS_Iterator<const SMESHDS_SubMesh*> 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(); }
// clear the contents
void Clear();
+ int getSize();
+ void compactList();
+
+ inline SMESHDS_Mesh *getParent() {return myParent; };
private:
+ SMESHDS_Mesh * myParent;
+ std::vector<const SMDS_MeshElement*> myElements;
+ std::vector<const SMDS_MeshNode*> myNodes;
- typedef std::set<const SMDS_MeshElement*, TIDCompare > TElemSet;
- TElemSet myElements, myNodes;
+ int myUnusedIdNodes;
+ int myUnusedIdElements;
+ int myIndex;
std::set<const SMESHDS_SubMesh*> mySubMeshes;
};
{
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);
aSel->selectedObjects( sel_objects );
if( theCommandID==302 )
+ {
+ MESSAGE("anAction = SMESH::eDisplayOnly");
startOperation( myEraseAll );
+ }
extractContainers( sel_objects, to_process );
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();
}
}
if (anAction == SMESH::eErase) {
+ MESSAGE("anAction == SMESH::eErase");
SALOME_ListIO l1;
aSel->setSelectedObjects( l1 );
}
#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;
}
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);
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();
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
}
*/
//================================================================================
- 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{
#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_
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();
+// }
}
}
}
}
}
+ MESSAGE("CreateActor " << anActor);
if( anActor )
if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
aSMESHGUI->addActorAsObserver( anActor );
#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();
}
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();
bool UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
{
+ //MESSAGE("UpdateView");
bool OK = false;
SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd);
if (!aViewWnd)
case eDisplayAll: {
while (vtkActor *anAct = aCollection->GetNextActor()) {
if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
+ MESSAGE("--- display " << anActor);
anActor->SetVisibility(true);
}
}
}
case eDisplayOnly:
case eEraseAll: {
+ //MESSAGE("---case eDisplayOnly");
while (vtkActor *anAct = aCollection->GetNextActor()) {
if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
+ //MESSAGE("--- erase " << anActor);
anActor->SetVisibility(false);
}
}
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;
}
case eDisplay:
case eDisplayOnly:
{
+ //MESSAGE("---");
SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(theWnd->getViewManager()->study());
_PTR(Study) aDocument = aStudy->studyDS();
// Pass non-visual objects (hypotheses, etc.), return true in this case
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();
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())) {
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 )
typedef std::pair<int,std::string> TKeyOfVisualObj;
SMESHGUI_EXPORT
- TVisualObjPtr GetVisualObj( int, const char* );
+ TVisualObjPtr GetVisualObj( int, const char*, bool nulData =false );
SMESHGUI_EXPORT
void OnVisuException(); // PAL16631
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
$(CORBA_INCLUDES) \
$(CAS_CPPFLAGS) \
@HDF5_INCLUDES@ \
+ $(VTK_INCLUDES) \
$(BOOST_CPPFLAGS) \
$(KERNEL_CXXFLAGS) \
$(GUI_CXXFLAGS) \
libSMESHEngine_la_LDFLAGS = \
../../idl/libSalomeIDLSMESH.la \
../SMESH/libSMESHimpl.la \
+ ../SMDS/libSMDS.la \
../Controls/libSMESHControls.la \
$(KERNEL_LDFLAGS) \
-lSalomeContainer \
#include "GEOM_Client.hxx"
#include "Utils_ExceptHandlers.hxx"
+#include "memoire.h"
#include "Basics_Utils.hxx"
#include <map>
// 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
void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode )
{
myIsEmbeddedMode = theMode;
+ MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
if ( !myIsEmbeddedMode ) {
//PAL10867: disable signals catching with "noexcepthandler" option
// Dump creation of groups
aServant->GetGroups();
+ aServant->GetImpl().GetMeshDS()->Modified();
return aMesh._retn();
}
theStatus = status1;
aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh );
+ meshServant->GetImpl().GetMeshDS()->Modified();
}
aStudyBuilder->CommitCommand();
}
SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
ASSERT( aServant );
aServant->ImportSTLFile( theFileName );
+ aServant->GetImpl().GetMeshDS()->Modified();
return aMesh._retn();
}
GEOM::GEOM_Object_ptr theShapeObject )
throw ( SALOME::SALOME_Exception )
{
+ MEMOSTAT;
Unexpect aCatch(SALOME_SalomeException);
if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" );
::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
bool ok = myGen.Compute( myLocMesh, myLocShape);
meshServant->CreateGroupServants(); // algos can create groups (issue 0020918)
+ myLocMesh.GetMeshDS()->Modified();
return ok;
}
}
// create mesh
SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh();
+ SMESHDS_Mesh* aNewMeshDS = 0;
if ( !aNewMesh->_is_nil() ) {
SMESH_Mesh_i* aNewImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( aNewMesh ).in() );
if ( aNewImpl ) {
::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl();
- SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS();
+ aNewMeshDS = aLocMesh.GetMeshDS();
TGroupsMap aGroupsMap;
TListOfNewGroups aListOfNewGroups;
// creates a corresponding element on existent nodes in new mesh
if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume )
{
- const SMDS_PolyhedralVolumeOfNodes* aVolume =
- dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
+ const SMDS_VtkVolume* aVolume =
+ dynamic_cast<const SMDS_VtkVolume*> (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();
SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
}
-
+ if (aNewMeshDS)
+ aNewMeshDS->Modified();
return aNewMesh._retn();
}
const SMDS_PositionPtr pos = node->GetPosition();
if ( onFace ) { // on FACE
const SMDS_FacePosition* fPos =
- dynamic_cast<const SMDS_FacePosition*>( pos.get() );
+ dynamic_cast<const SMDS_FacePosition*>( pos );
if ( fPos ) {
aUPos[ iNode ] = fPos->GetUParameter();
aVPos[ iNode ] = fPos->GetVParameter();
}
else { // on EDGE
const SMDS_EdgePosition* ePos =
- dynamic_cast<const SMDS_EdgePosition*>( pos.get() );
+ dynamic_cast<const SMDS_EdgePosition*>( pos );
if ( ePos ) {
aUPos[ iNode ] = ePos->GetUParameter();
iNode++;
// add
if ( isNode ) {
SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]);
- pos->SetShapeId( smID );
SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( static_cast<const SMDS_MeshNode*>( elem ));
node->SetPosition( pos );
sm->AddNode( node );
// not fixed bugs in SMDS_MeshInfo
if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) {
SMDS_FacePosition* fPos = const_cast<SMDS_FacePosition*>
- ( static_cast<const SMDS_FacePosition*>( aPos.get() ));
+ ( static_cast<const SMDS_FacePosition*>( aPos ));
fPos->SetUParameter( aUPos[ iNode ]);
fPos->SetVParameter( aVPos[ iNode ]);
}
// ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182
if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) {
SMDS_EdgePosition* fPos = const_cast<SMDS_EdgePosition*>
- ( static_cast<const SMDS_EdgePosition*>( aPos.get() ));
+ ( static_cast<const SMDS_EdgePosition*>( aPos ));
fPos->SetUParameter( aUPos[ iNode ]);
}
}
#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"
SMDS_MeshElement* anElemCopy = 0;
if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
{
- const SMDS_PolyhedralVolumeOfNodes* ph =
- dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
+ const SMDS_VtkVolume* ph =
+ dynamic_cast<const SMDS_VtkVolume*> (anElem);
if ( ph )
anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
- (anElemNodesID, ph->GetQuanities(),anElem->GetID());
+ (anElemNodesID, ph->GetQuantities(),anElem->GetID());
}
else {
anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
// 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;
}
//=============================================================================
// 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;
}
//=============================================================================
TPythonDump() << "nodeID = " << this << ".AddNode( "
<< x << ", " << y << ", " << z << " )";
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true ); // issue 0020693
-
return N->GetID();
}
// Update Python script
TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true ); // issue 0020693
if (elem)
<<n1<<", "<<n2<<", "<<n12<<" ])";
}
+ myMesh->GetMeshDS()->Modified();
if(elem)
return myMesh->SetIsModified( true ), elem->GetID();
// Update Python script
TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
+ myMesh->GetMeshDS()->Modified();
if(elem)
return myMesh->SetIsModified( true ), elem->GetID();
// Update Python script
TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
+ myMesh->GetMeshDS()->Modified();
return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
}
// Update Python script
TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
+ myMesh->GetMeshDS()->Modified();
if(elem)
return myMesh->SetIsModified( true ), elem->GetID();
int NbNodes = IDsOfNodes.length();
std::vector<const SMDS_MeshNode*> 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<int> q (NbFaces);
// Update Python script
TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
<< IDsOfNodes << ", " << Quantities << " )";
+ myMesh->GetMeshDS()->Modified();
return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
}
// Update Python script
TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
<< IdsOfFaces << " )";
+ myMesh->GetMeshDS()->Modified();
return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
}
}
mesh->SetNodeOnFace( node, FaceID, u, v );
-
myMesh->SetIsModified( true );
}
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;
}
//=============================================================================
bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
+ myMesh->GetMeshDS()->Modified();
if ( stat )
myMesh->SetIsModified( true ); // issue 0020693
// Update Python script
TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
+ myMesh->GetMeshDS()->Modified();
if ( IDsOfElements.length() )
myMesh->SetIsModified( true ); // issue 0020693
::SMESH_MeshEditor anEditor( myMesh );
bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
+ myMesh->GetMeshDS()->Modified();
if ( stat )
myMesh->SetIsModified( true ); // issue 0020693
::SMESH_MeshEditor anEditor( myMesh );
CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
+ myMesh->GetMeshDS()->Modified();
if ( stat )
myMesh->SetIsModified( true ); // issue 0020693
::SMESH_MeshEditor anEditor( myMesh );
CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
+ myMesh->GetMeshDS()->Modified();
if ( stat )
myMesh->SetIsModified( true ); // issue 0020693
::SMESH_MeshEditor anEditor (myMesh);
anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
+ myMesh->GetMeshDS()->Modified();
storeResult(anEditor);
anEditor.Smooth(elements, fixedNodes, method,
MaxNbOfIterations, MaxAspectRatio, IsParametric );
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true ); // issue 0020693
storeResult(anEditor);
anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
storeResult(anEditor);
+ myMesh->GetMeshDS()->Modified();
// myMesh->SetIsModified( true ); -- it does not influence Compute()
::SMESH_MeshEditor::PGroupIDs groupIds =
anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
+ myMesh->GetMeshDS()->Modified();
storeResult(anEditor);
return theMakeGroups ? getGroups(groupIds.get()) : 0;
SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
const SMDSAbs_ElementType theElementType)
{
+ MESSAGE("extrusionAlongPath");
initData();
if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
theHasAngles, angles, false,
theHasRefPoint, refPnt, theMakeGroups );
+ myMesh->GetMeshDS()->Modified();
storeResult(anEditor);
theError = convExtrError( error );
error = anEditor.ExtrusionAlongTrack( elements, &(aMeshImp->GetImpl()), aNodeStart,
HasAngles, angles, LinearVariation,
HasRefPoint, refPnt, MakeGroups );
+ myMesh->GetMeshDS()->Modified();
}
else {
SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path );
error = anEditor.ExtrusionAlongTrack( elements, aSubMesh, aNodeStart,
HasAngles, angles, LinearVariation,
HasRefPoint, refPnt, MakeGroups );
+ myMesh->GetMeshDS()->Modified();
}
else {
SMESH_Group_i* aGroupImp = SMESH::DownCast<SMESH_Group_i*>( Path );
CORBA::Boolean theHasRefPoint,
const SMESH::PointStruct & theRefPoint)
{
+ MESSAGE("ExtrusionAlongPath");
if ( !myPreviewMode ) {
TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
<< theIDsOfElements << ", "
if(theCopy)
storeResult(anEditor);
else
- myMesh->SetIsModified( true );
+ {
+ myMesh->GetMeshDS()->Modified();
+ myMesh->SetIsModified( true );
+ }
return theMakeGroups ? getGroups(groupIds.get()) : 0;
}
if(theCopy)
storeResult(anEditor);
else
- myMesh->SetIsModified( true );
+ {
+ myMesh->GetMeshDS()->Modified();
+ myMesh->SetIsModified( true );
+ }
return theMakeGroups ? getGroups(groupIds.get()) : 0;
}
if(theCopy)
storeResult(anEditor);
else
- myMesh->SetIsModified( true );
+ {
+ myMesh->GetMeshDS()->Modified();
+ myMesh->SetIsModified( true );
+ }
return theMakeGroups ? getGroups(groupIds.get()) : 0;
}
if(theCopy)
storeResult(anEditor);
else
- myMesh->SetIsModified( true );
-
+ {
+ myMesh->GetMeshDS()->Modified();
+ myMesh->SetIsModified( true );
+ }
return theMakeGroups ? getGroups(groupIds.get()) : 0;
}
anEditor.MergeNodes( aListOfListOfNodes );
aTPythonDump << "])";
-
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true );
}
::SMESH_MeshEditor anEditor( myMesh );
anEditor.MergeElements(aListOfListOfElementsID);
-
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true );
aTPythonDump << "] )";
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 );
// Update Python script
TPythonDump() << "isDone = " << this << ".MoveNode( "
<< NodeID << ", " << x << ", " << y << ", " << z << " )";
-
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true );
}
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
<< ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
<< ", " << nodeID << " )";
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true );
}
storeResult(anEditor);
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true );
return error;
storeResult(anEditor);
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true );
return error;
storeResult(anEditor);
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true );
return error;
storeResult(anEditor);
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true );
return error;
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 );
::SMESH_MeshEditor anEditor( myMesh );
anEditor.ConvertToQuadratic(theForce3d);
TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
+ myMesh->GetMeshDS()->Modified();
myMesh->SetIsModified( true );
}
::SMESH_MeshEditor anEditor( myMesh );
CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
TPythonDump() << this << ".ConvertFromQuadratic()";
+ myMesh->GetMeshDS()->Modified();
if ( isDone )
myMesh->SetIsModified( true );
return isDone;
bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
+ myMesh->GetMeshDS()->Modified();
storeResult( aMeshEditor) ;
if ( aResult )
myMesh->SetIsModified( true );
storeResult( aMeshEditor) ;
+ myMesh->GetMeshDS()->Modified();
if ( aResult )
myMesh->SetIsModified( true );
storeResult( aMeshEditor) ;
+ myMesh->GetMeshDS()->Modified();
if ( aResult )
myMesh->SetIsModified( true );
storeResult( aMeshEditor) ;
+ myMesh->GetMeshDS()->Modified();
if ( aResult )
myMesh->SetIsModified( true );
storeResult( aMeshEditor) ;
+ myMesh->GetMeshDS()->Modified();
if ( aResult )
myMesh->SetIsModified( true );
storeResult( aMeshEditor) ;
+ myMesh->GetMeshDS()->Modified();
if ( aResult )
myMesh->SetIsModified( true );
storeResult( aMeshEditor) ;
+ myMesh->GetMeshDS()->Modified();
if ( aResult )
myMesh->SetIsModified( true );
storeResult( aMeshEditor) ;
+ myMesh->GetMeshDS()->Modified();
if ( aResult )
myMesh->SetIsModified( true );
::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<TIDSortedElemSet> 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
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(); }
try
{
- NCollection_Map< int > anIds;
+ vector< int > anIds;
SMESH::ElementType aType = SMESH::ALL;
for ( int g = 0, n = theGroups.length(); g < n; g++ )
{
for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
{
int aCurrId = aCurrIds[ i ];
- anIds.Add( aCurrId );
+ anIds.push_back( aCurrId );
}
}
// 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; i<anIds.size(); i++ )
{
- aResIds[ i ] = anIter.Value();
+ aResIds[ i ] = anIds[i];
}
aResGrp->Add( aResIds );
// 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
// 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; i<anIds.size(); i++ )
{
- aResIds[ i ] = aListIter.Value();
+ aResIds[ i ] = anIds[i];
}
aResGrp->Add( aResIds );
try
{
- NCollection_Map< int > aToolIds;
+ set< int > aToolIds;
SMESH::ElementType aType = SMESH::ALL;
int g, n;
// iterate through tool groups
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++ )
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 );
}
}
// 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; i<anIds.size(); i++ )
{
- aResIds[ i ] = anIter.Value();
+ aResIds[ i ] = anIds[i];
}
aResGrp->Add( aResIds );
{
// Create map of nodes from all groups
- NCollection_Map< int > aNodeMap;
+ set< int > aNodeMap;
for ( int g = 0, n = theGroups.length(); g < n; g++ )
{
int aCurrId = aCurrIds[ i ];
const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
if ( aNode )
- aNodeMap.Add( aNode->GetID() );
+ aNodeMap.insert( aNode->GetID() );
}
}
else
const SMDS_MeshNode* aNode =
dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
if ( aNode )
- aNodeMap.Add( aNode->GetID() );
+ aNodeMap.insert( aNode->GetID() );
}
}
}
// 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<int>::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<int>::iterator iter = aNodeMap.begin();
+ for ( ; iter != aNodeMap.end(); iter++ )
{
const SMDS_MeshElement* aNode =
- dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
+ dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
if ( !aNode )
continue;
const SMDS_MeshElement* anElem =
dynamic_cast<const SMDS_MeshElement*>( 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;
{
const SMDS_MeshNode* aNode =
dynamic_cast<const SMDS_MeshNode*>( 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() );
}
}
// 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
{
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<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
+ static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
break;
case SMDS_TOP_FACE:
aNodePosition->shapeType = GEOM::FACE;
aNodePosition->params.length(2);
aNodePosition->params[0] =
- static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
+ static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
aNodePosition->params[1] =
- static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
+ static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
break;
case SMDS_TOP_VERTEX:
aNodePosition->shapeType = GEOM::VERTEX;
// 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;
(*xyzIt)->Coord( p.x, p.y, p.z );
}
}
-
// Update Python script
TPythonDump() << "pattern.ApplyToFace( " << theFace << ", "
<< theVertexOnKeyPoint1 << ", " << theReverse << " )";
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;
}
-# -*- 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,
import smesh
import math
+salome.salome_init()
+
def GetNewNodes(mesh,Elems,OldNodes):
"""
Auxilary function, which return list of nodes from
-# -*- 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,
import geompy
import smesh
+salome.salome_init()
# ---------------------------- GEOM --------------------------------------
# ---- define contigous arcs and segment to define a closed wire
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)
# @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)
libStdMeshers_la_CPPFLAGS = \
$(CAS_CPPFLAGS) \
$(BOOST_CPPFLAGS) \
+ $(VTK_INCLUDES) \
$(KERNEL_CXXFLAGS) \
$(GUI_CXXFLAGS) \
-I$(srcdir)/../SMESHImpl \
// 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() )
n1up = n2up;
}
}
-
+ mesh.GetMeshDS()->RemoveNode(dummy);
DumpGrid(); // debug
return true;
paramSize = myNormPar[ EdgeIndex ] - prevNormPar;
}
const SMDS_EdgePosition* epos =
- dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition().get());
+ dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition());
if ( epos ) {
uvPt.param = epos->GetUParameter();
}
static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& I, int& J)
{
const SMDS_FacePosition* fpos =
- static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_FacePosition*>(node->GetPosition());
if ( ! fpos ) return false;
gp_Pnt2d uv( fpos->GetUParameter(), fpos->GetVParameter() );
* -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
*/
//=============================================================================
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
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
vector<const SMDS_MeshNode*> newNodes;
- SMDS_MeshNode tmpNode(0,0,0);
+ SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
double u;
while ( srcElems->more() ) // loop on group contents
{
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
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;
tgtMesh->SetMeshElementOnShape( newEdge, shapeID );
e2e->insert( make_pair( edge, newEdge ));
}
+ helper.GetMeshDS()->RemoveNode(tmpNode);
}
if ( n2n->empty())
return error("Empty source groups");
{
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();
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;
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
{
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
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;
++link2Nb->second;
}
}
+ helper.GetMeshDS()->RemoveNode(tmpNode);
}
// ==========================================================
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 ))
tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u );
break;
}
- nodesOnBoundary = subShapeIDs.count( n->GetPosition()->GetShapeId());
+ nodesOnBoundary = subShapeIDs.count( n->getshapeId());
}
if ( nodesOnBoundary )
{
{
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();
// 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() ];
}
}
}
+ helper.GetMeshDS()->RemoveNode(tmpNode);
}
int nbNodes = allNodes.size();
if ( theCreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
continue;
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
double u = epos->GetUParameter();
if ( u < umin )
umin = u;
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);
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 )) {
//
if ( SMESH_Block::IsEdgeID (aSID)) {
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(aNode->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(aNode->GetPosition());
myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords );
}
else {
if(myTool->IsMedium(node))
continue;
const SMDS_EdgePosition* pos =
- dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
+ dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition() );
if ( !pos ) {
return false;
}
if(myTool->IsMedium(node))
continue;
const SMDS_EdgePosition* pos =
- dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
+ dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition() );
if ( !pos ) {
return false;
}
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
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" );
}
myNotQuadOnTop = ( nbNotQuadMeshed > 1 );
+ MESSAGE("myNotQuadOnTop " << myNotQuadOnTop << " nbNotQuadMeshed " << nbNotQuadMeshed);
// ----------------------------------------------------------
// 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 "<<iE, gpXYZ(faceColumns.begin()->second.front() ));
// SHOWYXZ("p2 F "<<iE, gpXYZ(faceColumns.rbegin()->second.front() ));
// 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 );
}
}
const TNodeColumn* StdMeshers_PrismAsBlock::GetNodeColumn(const SMDS_MeshNode* node) const
{
- int sID = node->GetPosition()->GetShapeId();
+ int sID = node->getshapeId();
map<int, pair< TParam2ColumnMap*, bool > >::const_iterator col_frw =
myShapeIndex2ColumnMap.find( sID );
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;
}
}
while ( nIt->more() ) {
const SMDS_MeshNode* node = nIt->next();
const SMDS_EdgePosition* pos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
}
if ( pos2nodes.size() != edgeSM->NbNodes() )
RETURN_BAD_RESULT("Bad node position type: node " << node->GetID() <<
" pos type " << node->GetPosition()->GetTypeOfPosition());
const SMDS_EdgePosition* pos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
u2nodes.insert( make_pair( pos->GetUParameter(), node ));
seamNodes.insert( node );
}
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 ))
{
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;
}
}
{
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 )
{
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);
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 )
// prepare the helper adding quadratic elements if necessary
SMESH_MesherHelper helper( *tgtMesh );
+ helper.SetSubShape( tgtFace );
helper.IsQuadraticSubMesh( tgtFace );
helper.SetElementsOnShape( true );
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;
}
bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape)
{
+ MESSAGE("Projection_2D Compute");
if ( !_sourceHypo )
return false;
}
case SMDS_TOP_EDGE: {
const SMDS_EdgePosition* pos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
break;
}
nodes[6],
nodes[7], id, force3d); break;
default: // polyhedron
- const SMDS_PolyhedralVolumeOfNodes * poly =
- dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( srcVol );
+ const SMDS_VtkVolume * poly =
+ dynamic_cast<const SMDS_VtkVolume*>( 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() );
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<SMDS_MeshNode*>(node)->AddInverseElement(this);
- }
- void MarkAsRemoved()
- {
- if ( _nodes[0] )
- const_cast<SMDS_MeshNode*>(_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"));
- }
- };
//================================================================================
/*!
*/
//================================================================================
- void MergePiramids( const SMDS_MeshElement* PrmI,
+ void MergePyramids( const SMDS_MeshElement* PrmI,
const SMDS_MeshElement* PrmJ,
SMESHDS_Mesh* meshDS,
+ TRemTrias& tempTrias,
set<const SMDS_MeshNode*> & nodesToMove)
{
const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove
SMDS_MeshNode* CommonNode = const_cast<SMDS_MeshNode*>(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() );
}
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() )
{
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);
}
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
void MergeAdjacent(const SMDS_MeshElement* PrmI,
SMESH_Mesh& mesh,
+ TRemTrias & tempTrias,
set<const SMDS_MeshNode*>& nodesToMove)
{
TIDSortedElemSet adjacentPyrams, mergedPyrams;
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 );
}
}
{
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 );
}
}
}
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();
// 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;
// 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]);
}
}
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;
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
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();
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
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
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
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
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<const SMDS_MeshFace*> 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<const SMDS_MeshFace*>::iterator it = faceToErase.begin(); it != faceToErase.end(); ++it)
+ {
+ const SMDS_MeshFace *face = dynamic_cast<const SMDS_MeshFace*>(*it);
+ if (face) trias.remove(face);
+ meshDS->RemoveFreeElement(face, 0, false);
+ }
+ }
myPyramids.clear(); // no more needed
myDegNodes.clear();
#include <TopoDS_Shape.hxx>
+typedef std::map<const SMDS_MeshElement*, bool> TRemTrias;
+
/*!
* \brief "Transforms" quadrilateral faces into triangular ones by creation of pyramids
*/
typedef std::list<const SMDS_MeshFace* > TTriaList;
typedef std::multimap<const SMDS_MeshElement*, TTriaList > TQuad2Trias;
-
TQuad2Trias myResMap;
+ TRemTrias myTempTriangles;
+
std::vector<const SMDS_MeshElement*> myPyramids;
std::list< const SMDS_MeshNode* > myDegNodes;
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);
$(GEOM_CXXFLAGS) \
$(MED_CXXFLAGS) \
$(BOOST_CPPFLAGS) \
+ $(VTK_INCLUDES) \
$(CORBA_CXXFLAGS) \
$(CORBA_INCLUDES) \
-I$(srcdir)/../SMESHImpl \